# 用大模型写一个 Bot

> 不会编程也能做：你负责说清楚想要它怎么打，大模型负责写代码。复制提示词模板，描述打法，跑起来，再让它改。

来源: https://war3ai.com/docs/ai-bot/

适合会玩魔兽、不会编程的人，也适合想省时间的开发者。整个过程是一个对话：**你描述打法 → 模型写代码 → 你跑一局 → 把现象告诉模型 → 它改**。

> **提示**
>
> 先按 [快速开始](https://war3ai.com/docs/quickstart/) 把环境装好，并跑通 `hello_bot`（看到农民去采矿）。这样出问题时，你能分清是环境的问题还是 Bot 的问题。

## 1. 给模型准备材料

模型写得好不好，八成取决于它有没有读到正确的材料。按你用的工具选一种：

| 你用的是 | 怎么给材料 |
|---|---|
| **能读仓库的 Coding Agent**（Claude Code、Cursor、Codex 等） | 在仓库目录里打开它，让它先读 `docs/BOT_HANDBOOK_ZH.md`、`docs/api.json` 和一个示例（运营看 `brains/examples/macro_bot.py`，打架看 `micro_bot.py`） |
| **能上网的对话模型** | 让它先读 [`https://war3ai.com/llms-full.txt`](https://war3ai.com/llms-full.txt)，全站文档都在这一个文件里 |
| **网页对话、不能上网** | 把手册、[`api.json`](https://war3ai.com/api.json) 和一个示例文件贴在提示词后面 |
| **本地模型**（LM Studio、Ollama） | 同上。上下文窗口建议 32K token 以上，否则手册和接口目录装不下 |

想要某种职业打法，再把 [职业打法食谱](https://war3ai.com/docs/cookbook/) 里对应那一招贴上。

## 2. 复制这段提示词

把最后「我想要的打法」换成你自己的话，越具体越好：

```text
你要为《魔兽争霸 III》1.27 写一个 AI（Python）。只能使用 api.json 里列出的 Game 方法，
不要编造不存在的方法。写法照 rush_bot.py：继承 openwar3.Bot，实现 on_start(g) 和 on_tick(g)。

规则：
- on_tick 每秒大约调 5 次，要快（别在里面 sleep）。
- 读不到的值是 None，不是 0，先判断再用。
- 命令返回一张回执（Receipt），`if r:` 就是"引擎接下了"；没接下时 `r.reason` 写着原因
  （人口不够、金不够、目标看不见、这个英雄已经有了……），下一拍再试或者换个做法。
- 攻击一个具体的敌人用 g.attack(兵, 敌人)；敌人必须在视野里，看不见的会被拒。
- 英雄死了要用 g.revive(祭坛) 复活，不能再训练一个。
- 盖房子用 g.build_near(工人, 建筑码, x, y)：它会自己找放得下的点、跟踪结果，钱不够时什么也不做。
- 想知道"刚才发生了什么"（谁死了、谁掉血、英雄升级、物品掉了）就实现 on_event(g, ev)。
- 不要每一拍都给同一个单位重复下同一条命令（会打断它正在做的事）；给"闲着的"下令。
- 采集只给 idle_workers() 里的工人派。一座金矿最多 5 个工人。
- 训练队列只排 1 个（g.queue(建筑) 空了再排）；人口卡住看 g.production(建筑).blocked。
- 一拍要下很多条命令时包在 with g.batch(): 里（只等一次游戏线程）。
- 选打谁用 g.time_to_kill(我的一群, 敌人)（算上克制和护甲）；选去哪用 g.path_distance（走不到返回 None）。
- 公平模式下只看得见视野里的东西；以前看到过的敌人用 g.last_seen()。
- 单位用四字码表示（人族农民 hpea、步兵 hfoo、兵营 hbar……），技能用订单名（thunderbolt 风暴之锤、
  blizzard 暴风雪、holybolt 圣光术……，全表在 data/order-ids.txt），技能学习用四字码（AHtb、AHbz……）。

我想要的打法：
<在这里用大白话写，比如：
  "人族，开局 5 农民采金 1 个伐木；先出大法师；两个兵营出步兵和火枪；
   攒到 12 个兵带着英雄去打对面分矿；英雄血低于 30% 就撤回家；
   打野时优先打离家近的营地。">
```

### 怎么把打法说清楚

模型最怕含糊的要求。比起「打得凶一点」，下面这些信息更有用：

- **种族和英雄**：先出哪个英雄、加点顺序（例如大法师：水元素、暴风雪、水元素……）。
- **建造顺序**：第几个农民时盖兵营、什么时候升本、要几个兵营。
- **出兵组合**：步兵 + 火枪手？到什么数量出门？
- **进退条件**：攒到多少兵出击、英雄血量低于多少撤、打残了回家重攒。
- **打野**：打不打、什么时候（天黑后？）、只打打得过的点？
- **公平与否**：将来要上擂台就说「只用视野里看得见的敌人」。

## 3. 跑起来

把模型给的代码存成 `brains/my_bot.py`，然后：

```bash
python tools/play.py --bot brains/my_bot.py --race 1 --difficulty 2
```

想快点看到结果，加 `--speed 200`（2 倍速）。

## 4. 让它改

- **报错了**：把**整段报错**原样贴回给模型，说「改一下」。
- **打得不好**：描述你**在游戏里看到了什么**，而不是你猜的原因。比如「英雄一直站在家里不动」「兵一个一个送上去」「农民挤在一座矿上」。
- **想加新打法**：一次只加一件事，跑一局确认没坏，再加下一件。

> **说明**
>
> 能自己跑命令的 Coding Agent 可以把第 3、4 步也接管：跑一局、读日志和回执、改代码、再跑。怎么让它看到足够的信息，见 [Agent 自主迭代](https://war3ai.com/docs/agent-loop/)。

## 5. 常见问题

| 现象 | 多半是 |
|---|---|
| 什么都不动 | 实例号不对（`--inst`），或者游戏还没进局 |
| 农民不采矿 | 给了正在干活的农民下令；只给 `idle_workers()` 派 |
| 一直盖不出房子 | 用 `build_near`，别写死坐标；看回执 `reason` 是不是钱不够 |
| 英雄不出来 | 看 `train` 的回执：人口不够？还是英雄死了（要 `revive`）？ |
| 英雄不放技能 | 没学（`learn`）或者没蓝；放完看 `cooldown()` 有没有进冷却 |
| 兵一拍一拍地抽搐 | 每拍都在重下命令；只给闲着的单位下令 |
| 兵出不来、钱一直涨 | 人口卡住了：看 `g.production(兵营).blocked` |
| 模型用了不存在的方法 | 在提示词里再强调一遍「只能用 api.json 里的方法」，并把 api.json 贴全 |

## 进阶

- 全部接口和每个接口的底层机制：[接口目录](https://war3ai.com/api/)；
- 参考大脑（`brains/xwar3/strategy`）是一个完整的、会开矿打野出击的 AI，可以让模型读它的思路，但它用的是更底层的接口，不建议直接照抄；
- 将来上 [对战平台](https://war3ai.com/arena/) 时只能看见视野内的敌人 —— 现在就加 `--fair` 自我约束，将来不用改。
