AI Agent 长任务的底层逻辑,还是 Plan → Dev → Test → Review
你让 AI 改一个 bug,它写几行代码,跑个测试,搞定了。
但如果你让它做一个需要改十几个文件、跨好几个模块的大任务呢?
大部分人的经验是:它要么中间跑偏了,要么做到一半 session 断了重来,要么最后说”完成了”但你自己都说不清到底完成没有。
OpenAI 今年 2 月发了一篇文章叫 Harness Engineering,讲他们怎么用 Codex 从零写了一百万行代码。Anthropic 也发了一篇,讲多个 Agent 协作跑了将近四小时,造出一个能用的数字音频工作站。Factory.ai 把类似的思路做成了产品功能叫 Missions。
我自己基于这些想法,实现了一个叫 mission 的 skill(可以理解为一套 AI Agent 的工作流程和规则),在 Claude Code 里跑。
这些东西听起来很新,名字也唬人——Harness、Mission、Orchestrator、Validator。但拆到底层,逻辑其实很熟悉:
Plan(规划)→ Dev(开发)→ Test(测试)→ Review(验收)
跟每个程序员每天做的事一模一样。区别在哪?在于执行者从人变成了 AI,每个环节加了具体的保障机制。
这是我这个系列的第三篇。第一篇讲了从 OpenAI 文章里提取出的四个 worker 级别的 skill;第二篇横向比较了 OpenAI、Anthropic、Factory 三种做法。这篇讲底层逻辑到底是什么,以及怎么用。
先说一个词:Harness
Harness 这个词最近在 AI 工程圈用得很多。你可以把它理解成”缰绳”或者”脚手架”。
OpenAI 给了一个公式:Agent = 模型 + Harness。
模型是 Claude、GPT 这些大语言模型本身的能力。Harness 是模型之外的所有东西:你给它的指令、任务拆分方式、状态记录文件、测试检查、review 流程。
打个比方:模型是一个能力很强的新人,Harness 是你给这个新人定的工作流程——先看需求文档,再写代码,写完跑测试,测试过了请别人 review。没有这套流程,新人能力再强也可能自由发挥把项目搞乱。
我实现的 mission skill,它本身就是一个 Harness。它的设计文档第一行写着:
This mission skill is itself a harness.
这个 Harness 里面装的是什么?就是 Plan → Dev → Test → Review,外加一套文件来保证每一步可追溯、可恢复、可验证。
整体结构:一张图说清楚
先看全貌,后面逐步拆解:
Plan(写验收标准 → 拆任务)
│
├─ 里程碑 1
│ ├─ Dev(派 AI-A 写代码,交作业)
│ ├─ Dev(派 AI-B 写下一个功能,交作业)
│ ├─ Test(派 AI-C 做工程检查 + AI-D 做行为验证)
│ │ └─ 没过?→ 自动生成修复任务 → Dev → 重新 Test
│ └─ 里程碑封存 ✓
│
├─ 里程碑 2
│ ├─ Dev → Test → 修 → 重新 Test …
│ └─ 里程碑封存 ✓
│
└─ Review(完成门控:所有验收标准 passed 才能结束)
注意几个跟人类开发流程不同的地方:
- Plan 阶段先写验收标准,再拆任务——类似 TDD(测试驱动开发),先说清楚”什么叫做完了”,再想怎么做
- Dev 和 Test 不是同一个 AI——写代码的和验证的必须是不同的 session,防止”自己给自己打高分”
- Test → Fix 是自动循环——测试没过不是任务失败,是自动生成修复任务,修完只重跑没过的部分
- Review 是机械门控——不是人拍脑袋说”差不多了”,是所有验收标准全部 passed 才能结束,否则 session 退不了
下面逐步说每个环节怎么做到的。
Plan:先定义”完成”,再拆怎么做
人在做大任务之前会列个计划。AI 也需要,但 AI 有个人没有的问题:它记不住前面说了什么。
AI 的对话窗口是有限的。跑久了,前面说过的需求、约定、上下文会被清掉。如果计划只活在对话里,session 一断就丢了。
所以 mission 的 Plan 阶段要做两件核心的事,都落文件。
第一件:把”什么叫完成”写成验收标准
这个文件叫 validation-contract.md。不是模糊的”用户能登录”,而是具体到工具和证据:
## 用户能登录
Surface: api
Tool: curl
Evidence: status-code, json-shape, response-body
POST /api/login 带正确凭证返回 200,body 包含 token 字段。
每一条验收标准必须写清楚三件事:
| 你要说清楚的 | 例子 | 为什么要写 |
|---|---|---|
| 在哪验(Surface) | api / ui / cli / 数据层 / 业务流程 | 决定了用什么工具去检查 |
| 用什么验(Tool) | curl / 浏览器自动化 / 命令行 | 防止 AI 自己编一个”我看了一下,通过了” |
| 要什么证据(Evidence) | 状态码、响应结构、截图、交互轨迹 | 防止假验证——截个图说”能打开”不算通过 |
举几个具体的证据要求:
- 验 API 接口:必须有请求内容、状态码、JSON 响应结构、响应内容——不是返回 200 就算过,得验 JSON 里有没有你要的字段
- 验 用户界面:必须有截图、页面结构、交互轨迹——不是截个静态页面就行,得有真实的点击操作记录
- 验 业务流程:必须有操作前状态、操作后状态、副作用——得证明状态确实变了
为什么要这么细?因为后面 Test 阶段,另一个 AI 会拿着这些标准一条一条去验。标准模糊,检查就是走过场。
还有一条规则:默认用真实环境验证,不用假数据。 设计文档原文:「默认用真实集成测试。mock 只能由用户主动选择退出,不能由 AI 悄悄降级。」
第二件:把大任务拆成小任务
拆完存在 features.json 里。每个小任务写清楚:
- 要做什么
- 前置条件是什么(哪些任务必须先完成)
- 做完之后应该能观察到什么行为
- 用什么命令可以验证
注意顺序:先写验收标准,再拆任务。 这是 mission 设计文档里明确规定的:
Write validation-contract.md before features.json. This is mission-level TDD.
先定义什么叫完成,再想怎么做。这和 TDD(测试驱动开发)是同一个思路,只不过尺度从函数级别放大到了整个任务级别。
Factory.ai 的文档对 Plan 阶段说得直接:「规划阶段产生的价值最大(The biggest value we have found in Missions is in the planning phase)。」规划不好,后面 AI 就是随机漫步。
Dev:派任务给 AI,它写代码交作业
Plan 完之后,进入开发阶段。mission 会按顺序把小任务一个一个派出去。
这里有个关键设计:负责分配任务的 AI 自己不写代码。
为什么?因为 AI 的”注意力”(上下文窗口)是有限的。如果负责统筹的那个 AI 自己跑去读代码、写实现,它的上下文很快被实现细节填满了,后面还有十几个任务要协调,空间就不够了。
所以 mission 把角色分成两种:
- 项目经理(Orchestrator):统筹调度,分配任务,看交接报告,决定下一步。自己不写代码。
- 开发人员(Worker / Subagent):每次接一个任务,干完交作业,下次再来是一个全新的 session。
每个 Worker 干完之后要写一个”交接文件”(handoff.json),记录:改了哪些文件、跑了什么测试、测试结果是什么、有没有遗留问题。项目经理读这个文件来判断进度,不需要自己去看代码。
这跟现实中的项目管理一样——项目经理把任务分配给不同的开发人员,每个人做完提交工作汇报。
Worker 的”开工仪式”
每个 Worker 开始工作之前,有一套强制步骤——必须先读这些文件:
- 项目目标(mission.md)
- 约束边界(AGENTS.md)
- 系统架构(architecture.md)
- 环境配置(environment.md)
- 服务清单(services.yaml)
不读就开始改代码,很容易改出和项目风格完全不同的东西。这些文件里缺了任何一个,Worker 要在交接文件里报”卡住了”(blocked),不允许跳过。
这相当于新同事入职第一天先看技术文档、了解项目规范,而不是上来就写代码。
Test:不是自己测自己,是另一个 AI 来测
这是整个设计里最重要的一个选择,也是跟人类开发流程区别最大的地方。
人可以自己写完代码自己跑测试(虽然不建议自己 review 自己的 PR,但日常开发中经常这么做)。但 AI 不行。
Anthropic 做过实验:让 AI 审查自己写的代码,结果是——
质量明显很差,但还是自信地夸自己。(confident praise even when the quality is obviously mediocre)
跟人一样,自己 review 自己的 PR,总觉得写得挺好。但 AI 的这个问题比人更严重,因为它没有那种”我是不是哪里没想到”的自觉。
所以 mission 里有一条硬规则:写代码的 AI 和测试的 AI 必须是不同的 session。 不是建议,是代码层面的强制——如果你试图手动创建验证任务,系统会拒绝。验证任务只能由系统在里程碑边界自动生成。
两种自动验证
每完成一个里程碑(一组相关的小任务),系统自动派出两个独立的验证 AI:
工程检查(scrutiny-validator):
- 跑项目的测试套件
- 跑类型检查
- 跑代码规范检查
- 逐个 feature 做代码 review
- 综合结论写进报告文件
行为检查(user-testing-validator):
- 拿着 Plan 阶段写的验收标准
- 在真实环境里一条一条地验
- API 就真的发请求,UI 就真的打开浏览器点
- 检查证据是否达到要求(有没有交互轨迹、有没有响应结构)
这两个验证 AI 是全新的 session,不知道写代码的那个 AI 是怎么想的、怎么实现的。它们只看行为,对着验收标准打分。
这就是日常开发里的 CI + Code Review,只不过执行者从人变成了 AI。
没过怎么办?自动修,自动重测
验证没过不等于任务失败。系统会:
- 看哪条验收标准没过
- 自动生成一个针对性的修复任务
- 把修复任务排到队列最前面
- 派一个新的 Worker 去修
- 修完之后重新验证,只重跑之前没过的部分
这个 Dev → Test → Fix → Re-Test 的循环是自动的,不需要人来推。直到全部通过或者碰到真的解决不了的问题才停下来。
Review:什么叫真的做完了
人做项目,容易在最后一步偷懒——“差不多了吧”。AI 更容易这样。
所以 mission 设计了一个”完成门控”(Completion Gate)。不是项目经理 AI 说”完成了”就完成了,而是必须通过一组机械检查:
- 之前写的每一条验收标准都 passed——一条没过都不行
- 项目文档在这次任务期间有更新——README 或 SKILL.md 必须改过
- 所有验证报告格式合法——不能有格式坏掉的报告混进来
- 没有残留的临时代码、存根、假数据——不能有半成品留在仓库里
第 2 条很实际:如果做了一堆改动但没更新文档,下一个接手的人(或者下一次运行的 AI)就不知道系统变成什么样了。mission 会直接卡住,不让你说”完成”。
门控没过,session 退不了——hook 会拦住。这跟 CI 卡住不让你 merge 一样:流水线是红的,你就是合不了。
把四步串起来:所有状态都存文件
你可能注意到了,每一步都在产生文件:
| 阶段 | 产生的文件 | 干什么用的 |
|---|---|---|
| Plan | validation-contract.md |
验收标准 |
| Plan | features.json |
任务列表和依赖关系 |
| Dev | assignment.json |
派给 Worker 的任务说明 |
| Dev | handoff.json |
Worker 交回的工作汇报 |
| Test | synthesis.json |
验证结论 |
| Review | validation-state.json |
每条验收标准的通过/失败状态 |
这不是为了仪式感。这是为了解决一个实际问题:AI 的对话窗口是有限的,跑久了前面的内容会被清掉。
如果任务进度只活在对话里,session 一断就什么都没了。所以 mission 的规则是:每一个重要的事实,在 AI 继续工作之前,必须先写进文件。这样不管 session 断几次,下次启动从文件就能重建出完整状态——哪些任务做完了,当前卡在哪,下一步干什么。
OpenAI 文章里的原话是:「从 Agent 的视角来看,任何不在仓库里的信息都不存在。」不是藏起来了,是字面意义上不存在。Slack 里讨论的设计决定、对话里说过的约束,如果没有写进文件,对下一个 AI 来说跟从没发生过一样。
两种保障手段:事前引导 + 事后检查
如果你只记一个概念,记这个。
mission 对 AI 的所有控制归结为两种:
事前引导——在 AI 动手之前告诉它该怎么做:
- 架构文档(系统长什么样)
- 约束边界(哪些东西不能碰)
- 服务清单(怎么跑测试、怎么启动服务)
- 任务规格(做完应该看到什么行为)
相当于新人入职的 onboarding 文档。减少犯错的概率。
事后检查——在 AI 做完之后检查做得对不对:
- 验收标准(每一条要验的行为)
- 自动验证器(工程检查 + 行为检查)
- 项目自带的 lint/test/typecheck
- 交接文件(做了什么、结果是什么)
相当于 CI 流水线 + Code Review。拦住已经犯的错。
事前引导减少出错概率,事后检查拦住出的错。两者配合就是 Harness 的核心。
每次任务发生变化,要问自己:我需要加一个事前引导,还是一个事后检查,还是两个都要?
一个反直觉的点:规则不是越多越好
mission 的设计文档里有一句话:
每一个 prompt 补丁、验证器、脚本的存在,都是因为模型在某件事上不可靠。
你加的每一条规则,背后都有一个假设:“AI 在这件事上会出错,所以我用这条规则兜底。“
但模型在进步。去年需要的护栏,今年可能多余了。设计文档建议:长任务结束后做一次简化审查——哪些验证器真的发现过问题?哪些门控从来没拦住过任何东西?能删就删。
最好的 Harness 是刚好够用的那个,不是最复杂的那个。
护栏太多,AI 反而花大量精力在满足规则上,而不是在解决问题上。跟软件工程里的过度设计一个道理。
怎么实际用起来
第一步:给项目搭骨架(每个项目做一次)
python scripts/mission_runtime.py bootstrap-repo --repo-root .
在项目里建一个 .agents/ 目录,放好架构文档、服务清单的模板。你需要把模板填成真实内容——系统怎么启动、测试怎么跑、环境变量有哪些。
第二步:创建一个 mission
python scripts/mission_runtime.py bootstrap \
--mission-root .agents/missions/my-task \
--goal "你要做的事情" \
--validation-contract contract.md \
--features features.json \
--repo-root .
第三步:写验收标准(先于任务拆分)
在 validation-contract.md 里定义每一条要验证的行为,写明用什么工具验、要什么证据。
第四步:拆任务
在 features.json 里把大目标拆成小任务,每个写清楚行为规格和依赖关系。
第五步:跑起来
# 检查就绪
python scripts/mission_runtime.py check-readiness \
--mission-root .agents/missions/my-task --repo-root .
# 开跑
python scripts/mission_runtime.py autopilot-loop \
--mission-root .agents/missions/my-task --repo-root .
autopilot-loop 自动循环:选任务 → 派 AI 去做 → 收结果 → 到里程碑自动验证 → 没过就自动修 → 直到全部完成或卡住。
随时可以中断,下次继续——状态在文件里,不会丢。
第六步:确认完成
python scripts/mission_runtime.py complete-gate \
--mission-root .agents/missions/my-task --repo-root .
什么时候用,什么时候不用
不用: 改一个 bug、重命名一个函数、修一个 typo。直接让 AI 做就行了。
可以用:
- 任务涉及多个文件、多个模块、有依赖顺序
- 你需要明确的”完成标准”来防止 AI 说完成但其实没完成
- 任务可能做到一半被中断,需要下次接着做
- 你想让不同的 AI 互相检查代码质量
一个简单的判断方法:如果这个任务最后你会说”完成了”,但你自己也不太确定是不是真的完成了——就适合用 mission,因为完成门控会替你把这个问题回答清楚。
回到本质
Harness、Mission、Orchestrator、Validator——这些词听着像新东西,但拆开看,就是软件工程里最基本的循环:
Plan:先定义什么叫完成,再拆怎么做。
Dev:按计划一个一个做,每次做完交作业。
Test:找另一个 AI 来检查,写代码的不能自己检查自己。
Review:过完成门控,所有标准 passed 才算结束。
跟人的区别只有三个:口头约定换成了文件,凭感觉换成了机械门控,自己测自己换成了强制隔离。
OpenAI 那篇 Harness Engineering 的核心经验,一百万行代码,三个工程师,说白了就一句话:
给 AI 搭好 Plan → Dev → Test → Review 的环境,比让 AI 更聪明更管用。
参考资料: