AI Agent

你的模型负责想, War3AI 负责做到

一个 Agent 要在真实环境里自己把事做成,需要三样东西:能说清楚的动作、能读懂的反馈、不怕犯错的环境。我们把《魔兽争霸 III》改造成了这样一个环境。

设计原则

为什么 Agent 能在这里自己把事做成

让 AI 玩游戏,常见的做法是模拟鼠标键盘、识别画面,结果做没做成只能靠猜。我们反过来,从「一个模型需要什么才能自我纠错」出发设计每一个接口。

只说「做什么」

移动、攻击、建造、施法……语义命令直接对应玩家的操作;单位用四字码、技能用订单名,和游戏里的叫法一致。模型不需要任何底层知识。

每个动作都有结构化反馈

回执在同一帧读回:接没接、原因码、下令前后的订单、执行耗时。“为什么没做成”是一个数字,不是一段猜测。

结果不用看画面

快照给出现在是什么样,事件流给出发生了什么:每一下伤害、每一次击杀、每一次生产完成。Agent 可以验证自己的判断。

文档就是接口

api.json 从代码生成,103 个方法各自标注实测状态和底层机制;llms.txt 一次读完全站。模型没有理由编造方法。

失败是安全的

Bot 抛异常,下一拍继续;过了截止时间的命令不会再执行;Bot 进程崩了,游戏照常运行。Agent 可以放心地试。

公平从第一天开始

公平模式只给视野里的东西,和擂台规则一致。Agent 在本机练出来的能力,将来上对战平台一行不用改。

01 离线 · 写代码

Agent 写 Bot

最快的入门方式,不需要会编程。把手册、api.json 和一个示例交给 Claude Code、Cursor、Codex 或任何对话模型,用大白话描述打法。它写出一个继承 openwar3.Bot 的 Python 文件,一条命令上场。

  • 提示词模板里写好了 15 条「实机踩出来的规矩」
  • 要求它只用 api.json 里的方法,杜绝编造
  • 报错原样贴回、描述看到的现象,让它改
完整提示词模板
你
人族,开局 5 农民采金 1 个伐木;先出大法师;两个兵营出步兵和火枪;攒到 12 个兵带着英雄去打对面分矿;英雄血低于 30% 就撤回家。

好的,我按 rush_bot.py 的结构来写,只用 api.json 里的方法:

  • 采集只派 idle_workers(),一矿 5 人
  • 兵营队列只排 1 个,人口卡住看 production().blocked
  • 出击用 path_distance 选分矿,attack_move 过去
  • 英雄血量低于 30% 时 move 回家,死了用 revive
my_bot.py · 96 行
$ python tools/play.py --bot brains/my_bot.py --race 1
02 离线 · 闭环

让 Agent 自己迭代

能执行命令的 Coding Agent 可以把「跑一局、看结果」也接过去。给它一条无人值守的命令、一份结构化的对局报告和一个明确的目标,它就能一轮一轮地改。

  1. 跑 play.py --speed 200 --minutes 10 --fair
  2. 读 对局报告:生产时间线、伤亡、被拒最多的原因
  3. 改 最影响结果的一处,注释里写下依据
  4. 再跑 连续几局没有进步就停下来汇报
对局报告与任务模板
run_1790237551.json 示例
{
  "reason": "到时间了",
  "clock": 612.4,
  "timeline": [
    [15, "training", "hpea"],
    [118, "construction", "hbar"],
    [161, "training", "Hamg"],
    [402, "upgrade", "hkee"]
  ],
  "lost":   {"hfoo": 7, "Hamg": 1},
  "killed": {"ogru": 4, "ngno": 6},
  "rejects": [
    ["train hfoo: rejected(人口不够)", 41],
    ["attack ogru: rejected(目标看不见…)", 9]
  ]
}

被拒最多的是「人口不够」41 次,兵营一直在等人口。按规矩 12:看到 production().blocked 就立刻盖农场,而不是等人口快满。这一轮只改这一处。

03 在线 · 参谋

大模型当运营顾问

「该攒什么、该往哪投人、这一分钟该打还是该缓」—— 这类看全局、排优先级的判断,写成 if / else 会互相打架,却正好是大模型擅长的。参考大脑每 20 游戏秒问一次本地模型,拿回一份严格的 JSON。

不直接下单位令:只改目标和优先级,指挥权只有一个主人
异步:永远不阻塞一拍;超时、乱答就当没有这一层
白名单 + 钳位:不认识的内容记数后丢弃
全程计数:成功、超时、被钳位、被采纳,都看得见
分层、契约与实现骨架
大模型(顾问)每 20 游戏秒 · 异步
{
  "diagnosis": "金 820 木 60,木头是瓶颈,兵营因缺木停产",
  "workers":   {"gold": 10, "lumber": 7},
  "priority":  ["hpea", "hhou", "hfoo"],
  "posture":   "hold",
  "avoid":     ["木头不够时别先研究铁甲"]
}
白名单 + 钳位 + 否决
规则层(每拍)把建议变成偏置

工人配比 10 / 7 · 训练优先级 hpea → hhou → hfoo · 姿态 hold

语义命令
执行层(SDK / 毫秒层)约 1 帧

下令、读回执、微操

1.09 s 中位延迟 · 最慢 1.45 s · 5/5 输出可直接解析
本地 Qwen3.6-35B-A3B(LM Studio)
04 在线 · 角色

让单位开口说话

任意单位、任意身份头顶弹出气泡,多个单位同时说话,每个气泡的样式都能单独定制。接上本地大模型,一句话进、一句回复流式出现在单位头上。农民茶话会、英雄对白、战况解说,都是现成的。

0.3 s 首字延迟
32 同时在场的气泡
0.1~0.2 ms 每帧开销
气泡接口与模型选择
山丘之王 冲!喝完这口就冲!
大法师 我来放暴风雪。
农民 · 老王 又被 AI 拉来开局挖矿当训练数据……
POST http://127.0.0.1:8872/api/chat
{
  "inst": 16, "unit": "0x14A12614", "name": "山丘之王",
  "persona": "你扮演山丘之王,豪爽、爱喝酒,一两句口语",
  "message": "前面有一群食人魔,我们冲不冲?",
  "stream": true
}
→ {"reply": "冲!喝完这口就冲!",
   "first_token_ms": 283, "total_ms": 342}
05 在线 · 做伙伴

AI 玩伴

在 RPG、自定义地图里给自己配一个 AI 伙伴:它跟着你走、帮你打怪,你残血时给你加血,闲下来陪你说两句 —— 台词可以接本地大模型。继承一个类、改几个属性,就是你自己的玩伴。

每一拍按顺序判断,哪条成立做哪条

  1. 撤退 自己残血、附近有敌人:退到你身后
  2. 加血 你血量低、技能好了:给你加一口
  3. 助战 先打正在打你的,再打你正在打的
  4. 跟随 离你太远就跟上,远到一定程度直接跑回来
  5. 闲聊 没仗打的时候,隔一两分钟说一句
盟友 占一个空玩家槽,有自己的颜色和名字
我方 造在你名下,你随时能接手指挥
接管 接管地图给你的宠物、随从
只说话 不改世界,多人局也能用
RPG 玩伴文档
玩伴 · 小圣
正在:帮你打怪 心情:兴奋 击杀 12 · 加血 5
你 -follow
小圣 收到,一直跟着你!
你 -heal
小圣 圣光,治愈你!
小圣 漂亮!又解决一只两栖追随者。

聊天框打 -follow / -stay / -heal / -hi,或者右键点它

06 在线 · 当工具

大模型直接调工具

支持 MCP 的客户端 —— Claude Code、Claude Desktop、本地模型的 Agent 框架 —— 挂上 war3_mcp.py,大模型就能直接看局面、下命令、在屏幕上跟玩家说话、弹卡片问玩家、截图看画面。不用先写代码,想到什么就让它做什么。

  • 10 个工具:一页局面、单位、事件、调任意公开接口、查接口、屏幕提示、头顶说话、问玩家、截图、JASS
  • 三种角色:开发、选手(只指挥一个玩家、只看它的视野)、观众(只读)
  • 第一次调工具时才连游戏,游戏可以后开
MCP 文档
你
看看现在局面,然后在屏幕上问我:下一步是开矿、爆兵还是升本?

调用了 2 个工具:

  • war3_overview → 金 500 · 人口 10/12 · 主城 1 · 农民 5 · 圣骑士 1
  • war3_ask_player → 屏幕中间三张卡片,选的时候游戏暂停
  • 你点了「开矿」,结果原样回到对话里,我接着安排农民
$ claude mcp add war3 -- python tools/war3_mcp.py --inst 9
07 即将 · 直接对局

Agent 亲自上场

对战平台用 WebSocket / JSON:裁判每拍发一份按视野过滤的观察,Bot 回一组动作。任何语言、任何模型 —— 甚至不写代码、直接让大模型逐拍输出 JSON —— 都能接入。单机版今天就能用:网关的选手角色只让你指挥一个玩家、只看得见它的视野;对战平台要补上的是一个大家都信任的裁判。

  • 按游戏时间出拍,慢的一方自己吃亏,不拖别人
  • 每条动作先校验单位归属,记录下来可回放
  • 用 SDK 写的 Bot 把 Game 换成 ArenaGame 即可上场
对战平台设计
{"t": "obs", "tick": 57, "gameMs": 11400, "me": 1,
 "res": {"gold": 320, "lumber": 150, "food": [18, 30]},
 "units": [
   {"id": 101, "type": "hfoo", "owner": 1,
    "x": -4500, "y": 2200, "hp": 380, "hpMax": 420}],
 "visibleEnemies": [
   {"id": 733, "type": "ogru", "owner": 2,
    "x": -3900, "y": 2500, "hp": 700}],
 "deadlineMs": 180}
只含这个槽视野里的东西;id 是裁判分配的稳定编号,整局不变。
机器可读

把这些交给你的 Agent

全部是纯文本或 JSON,没有登录、没有渲染,Agent 直接抓取即可。

你用的是怎么接适合
Claude Code / Cursor / Codex 等 Coding Agent在仓库目录里打开,让它读手册、api.json 和示例;可以自己跑局、读报告、迭代写 Bot、自主迭代
能上网的对话模型让它先读 war3ai.com/llms-full.txt写 Bot
不能上网的对话模型把手册、api.json 和一个示例贴进提示词写 Bot
本地模型(LM Studio / Ollama)OpenAI 兼容接口;建议 MoE 模型并关掉思考段参谋、配音(对延迟敏感)
云端 API(Claude / GPT / Gemini / DeepSeek…)OpenAI 兼容或各家 SDK;参谋层是异步的,几秒延迟可以接受参谋;将来直接对局
支持 MCP 的客户端(Claude Code / Claude Desktop…)挂上 tools/war3_mcp.py:10 个工具直接看局面、下命令、问玩家、截图边打边指挥、陪玩、解说
任何语言 / 浏览器 / 另一台机器WebSocket / JSON 网关:和 Python SDK 同名同参,自带 JS 客户端和演示页自己的工具和界面、远程 Bot

从一句话开始

装好环境大约 15 分钟。剩下的交给你的 Agent。