Agent 的上限是 Harness 的上限:OpenAI、Anthropic、Factory 三种答案
我去年花了很多时间在想一个问题:为什么同样的模型,有些人跑出来的 Agent 能真正干活,有些人的永远在兜圈子?
差别不在模型。差别在 Harness。
这个结论听起来不新鲜,但真正理解它需要一些具体的证据。 OpenAI 的文章,五个月、一百万行代码、0 行手写代码,三个工程师,平均每人每天 3.5 个 PR。Anthropic 也发了一篇,三种不同架构的 Agent,跑了将近四小时,造出来一个能跑的 DAW(数字音频工作站)。Factory 把 Mission 做成了产品功能。我自己也照着这些想法,实现了一个 mission skill。
这篇文章是我把这些拼在一起之后的理解。
前情提要:上一篇《从 OpenAI Harness Engineering 蒸馏出四个 Skill,Agent 跑了 25 小时》讲的是 worker 层——如何把 OpenAI 的 Harness 方法论落地成四个可复用的 Skill:
harness(持久执行)、closed-loop-testing(闭环测试)、architecture-guardrails(架构约束)、harness-marathon(运行策略)。这篇讲的是更上面一层:Mission 作为编排层,负责拆分目标、调度 worker、在里程碑边界做验证。两篇可以独立阅读,但放在一起看更完整。
Harness 是什么
Harness 这个词最近突然出现在很多工程师的讨论里。字面意思是"驾驭",但在 Agent 工程里它的意思是:模型之外的所有东西。
一个 Agent = 模型 + Harness。
你能调教的只有 Harness,模型是固定的(或者说变化不由你控制)。Harness 包括:给 Agent 的指令、上下文管理方式、工具集合、验证逻辑、持久化状态、反馈机制。每一个设计决定都在告诉 Agent:"这个,你自己搞不定,我来帮你。"
问题是:很多人的"Harness"就是一个很长的 system prompt,然后期待模型自己脑补出所有细节。
不行的。不是因为模型不够聪明,是因为你没给它足够的结构。
OpenAI 的数据:规模是靠约束换来的
OpenAI 的那篇文章叫 Harness Engineering。他们的核心实验很简单:从空仓库开始,不写任何手动代码,只用 Codex 驱动所有 PR,看能走多远。
结果是:五个月,约一百万行代码,1500 个 PR,三名工程师。
但这不是重点。重点是他们怎么做到的,以及为什么早期比预期慢。
他们的原话:"早期进展比预期慢,不是因为模型能力不够,是因为环境缺少规格化(underspecified)。"
Agent 缺的不是智能,是可以操作的结构。他们的解法走了两个方向:
一是把知识库搬进仓库。Slack 讨论、架构决定、设计规范,全部转化成 markdown,存在 docs/ 下。从 Agent 的视角来看,任何不在仓库里的信息都不存在——不是隐藏了,是字面意义上不存在。Google Docs 里的设计讨论、Slack 里的对齐记录,跟从没发生过是等价的。
二是把架构约束机械化,不是写文档说"不要这么做",是写 linter 说"这么做会报错",而且报错信息里直接附上修复指引,Agent 读报错就能知道怎么改。
我觉得这里最反直觉的一点是:他们允许技术债走垃圾回收逻辑,而不是堵死它。每周有专门的 "doc-gardening" Agent 扫描过时文档,开修复 PR。代码里的 AI slop 也通过定期 cleanup 任务清理,而不是每次生成时都把质量要求逼得很高。
这很像 GC:与其手动管内存,不如设计一个可以自动回收的系统。
一个额外的发现:严格的架构约束(类型化依赖层级、强制 lint、layer 之间的单向依赖)实际上让 Codex 跑得更快,因为它不需要在每个决策点重新想"该怎么做"。约束本身就是现成的答案。这个结论在他们文章里提到了,说通常要等你有几百个工程师才会引入的那种架构规范,在 Agent 环境里是早期就要上的东西。
Anthropic 的三层架构:不能让自己给自己打分
Anthropic 的那篇文章更偏实验性,他们拿同一个任务跑了不同架构的 Agent,直接比较输出质量。
他们发现了两个会让 Agent 退化的问题:
第一个是上下文窗口降解。 Agent 跑得越久,输出越模糊,有些甚至会提前收摊,因为感觉"快满了"。他们叫这个 "context anxiety"。解法不是压缩,是重置——给它一个干净的上下文,把必要的状态通过结构化的 handoff 文件传递。
第二个是自评偏差。 让 Agent 审自己写的代码,它会说很好,即使代码明显有问题。Anthropic 的原话:"confident praise even when the quality is obviously mediocre(质量明显很差,但还是自信地夸自己)。"
他们的解法是三层:Planner(把模糊需求扩展成详细规格)→ Generator(按规格实现功能)→ Evaluator(独立跑,用 Playwright 实际操作应用来验收)。
其中 Evaluator 是独立跑的,拿着双方之前谈好的 sprint contract,用 Playwright 实际点击应用,而不是读代码猜行为。Sprint contract 是 Generator 和 Evaluator 在动工之前协商出来的,说清楚"完成"长什么样子——比协议不清楚要好得多,虽然有时候谈合同本身也要花时间。
这个 Generator/Evaluator 分离的设计,我觉得是整篇文章最有价值的部分。不是因为它新鲜,软件工程里早就有"不能 review 自己的 PR"这个规则,而是因为在 Agent 系统里很多人会图省事跳过它。
跳过的代价很明显:单 Agent 和三层架构的输出质量差距,体现在游戏能不能实际跑起来。他们对比的 retro game maker 任务,完整三层架构生成的游戏有 working physics,单 Agent 版本的游戏"看起来还行,但玩不了"。
代价是成本。一次 DAW 任务跑了 3 小时 50 分钟,花了 $124.70。不便宜。但产出是一个有 working timeline、mixer、transport controls 的浏览器 DAW,这个比价还说得过去——前提是你不需要每天跑这种任务。
Factory 的 Mission:Planning Phase 才是关键
Factory.ai 把类似的思想做成了产品功能,叫 Missions。
核心流程:/enter-mission 进入规划对话,先把功能、里程碑、成功标准都搞清楚,然后交给 Mission Control 编排执行。配置继承也处理了——MCP integrations、custom skills、hooks、conventions 全部带进 mission 执行上下文。
他们说得很直接:"planning phase matters most。"不是说规划比实现重要,是说规划不扎实,实现就是随机漫步。这个我深有体会:给 Agent 一个模糊目标,它不会拒绝,它会干,但干的方向可能完全不是你想要的。
有意思的是他们对 Mission 的定位:不是"按下开始然后等结果",而是"你是项目经理,Agent 是执行者"。这个心智模型挺准确的——Mission 模式下你的工作不是写代码,是判断优先级、处理卡点、决定是否需要 replan。
他们还在 research preview 阶段,自己承认有几个问题没想清楚:要不要并行?怎么最大化正确率?成本和质量怎么权衡?我觉得这些问题本身就说明这个领域还很早期。没有标准答案,每个项目的权衡都不一样。
我自己实现的 mission skill
用了 Factory.ai 的 Missions 之后,我想做一个类似的东西,可以在其他 Agent 里直接 /mission 调用。
这里有个层级关系值得说清楚:Mission 是编排层,不是执行层。上一篇文章里的 harness、closed-loop-testing、architecture-guardrails 是 worker skill——每个负责干一件具体的事。Mission 的工作是决定先干什么、把任务派给哪个 worker、验收结果、处理失败。Mission 本身从不写一行业务代码,写代码的永远是它派出去的 subagent,带着相应的 worker skill 跑。
核心设计理念直接从 OpenAI 和 Anthropic 的文章里借来的。主要是这几条:
文件驱动,不靠聊天记忆
所有状态都落文件。Mission 的进度、每个 feature 的 assignment、subagent 的 handoff、validator 的 synthesis,全部是 JSON 或 markdown,存在 .agents/missions/<mission-name>/ 下。Orchestrator 被打断之后可以重启,从磁盘重建状态,不依赖对话历史。
这解决了一个实际问题:长任务的上下文会被清理。靠记忆的 Agent 系统,一旦上下文重置就相当于失忆了。
.agents/missions/ship-auth/
├── mission.md
├── validation-contract.md
├── validation-state.json
├── features.json
└── handoffs/
├── feature-001/
│ ├── assignment.json
│ └── handoff.json
└── feature-002/
└── assignment.json
Generator 和 Evaluator 是不同的 subagent run
这是从 Anthropic 直接学来的。Feature 实现由一个 subagent 完成,验证由另一个独立跑。Skill 里甚至把这个规则写进了 runtime check:如果你尝试手动创建 scrutiny-validator 或 user-testing-validator 的 feature,runtime 会拒绝。这两个 validator 是里程碑边界时自动注入的,不允许绕过。
AGENTS.md 是目录,不是百科全书
这是 OpenAI 文章里我最认同的一点。他们试过"一个大 AGENTS.md",失败了。原因是:上下文是稀缺资源,一个几千行的指令文件只会让 Agent 要么读不完,要么记不住重要的部分。太多的指引等于没有指引。
我的实现里,AGENTS.md 控制在约 100 行,主要是指针:这个模块的文档在哪、服务配置在哪、校验合约在哪。实际内容分散在 .agents/library/*.md 下,Agent 需要时才去读。
垃圾回收是设计的一部分
长时间跑的 Mission 会积累漂移——文档和代码不一致、AI slop 扩散、架构约束慢慢被绕过。Skill 里有一个 gc-* milestone 的约定:周期性调度一个清理任务,扫 .agents/library/ 和代码的不一致,清理 lint 问题,重新评估架构文档。
这是跟 OpenAI 的"doc-gardening agent"学的,但把它显式化为 milestone 更好控制。
Orchestrator 从不实现功能
这条规则执行起来比想象中难。Skill 里写了:如果 Orchestrator 发现自己在写实现代码,停下来,派一个 subagent。Context 花在实现上就是从整体 mission 里偷走的。
Orchestrator 保留的职责只有:需求跟踪、里程碑边界决策、feature 排序、验证结果判断、replan。其他全部委托。
Mission 模式的实际效果
用下来的感受是:主要提升在于减少了人的介入次数,而不是单个任务的质量。
单个 feature 的实现质量,Claude 本身就不错,Mission 模式加不了太多。但如果你有一个需要 20 个 feature 才能完成的目标,没有 Mission 模式你大概要:
- 手动跟踪哪些做完了哪些没做
- 每次都要重新给 Agent 灌一遍上下文
- 手动判断哪个 feature 失败了,要不要重试
- 最后无法确定整个目标是否真的完成了
Mission 模式把这些结构化了。任务列表在文件里,依赖关系明确,validation contract 说清楚什么叫"完成",失败了自动生成 remediation feature。
Completion gate 是我觉得最有价值的部分——它不让你在有未通过断言的情况下宣布完成,必须:所有 assertion 都 pass、文档更新、synthesis 文件合法、README.md 反映最终状态。没有这个,长任务很容易在最后一公里自欺欺人。
两个明显的限制,说实话
第一,初始规划成本高。 Planning phase 要花时间,而且规划不好后面会很痛苦。对于真正简单的任务,用 Mission 模式是负担。Skill 的 SKILL.md 里也写了:单文件改动、重命名、typo fix,直接执行,别用 mission。
第二,多 Agent 协调的调试很难。 当一个 subagent 写了错误的 handoff,或者 validator 的判断有问题,排查路径比单 Agent 复杂很多。日志量大,责任链长,有时候你得跟着读好几个 JSON 文件才能找到问题在哪。这个体验还不够好,我还在想怎么改善。
综合来看
从这三篇文章和自己的实现来看,我觉得以下几件事是确定的:
你设计的不是 Agent,是环境。 Agent 的行为是环境的函数。不可预期的输出通常是环境缺了某个结构,而不是模型不够强。
状态必须外化。 任何只存在于上下文里的信息都是临时的。长任务必须把关键状态落文件,这不是习惯问题,是工程必要条件。
不能自己审自己的代码。 在人的工程实践里是常识,但在 Agent 系统里很容易偷懒省掉。
每个 harness 组件都在告诉你模型哪里不行。 Anthropic 说:每加一个 guard,背后是某个模型行为不可靠。随着模型能力提升,旧的 guard 可以删掉。最好的 harness 是刚好够用的,不是最复杂的。
用 Mission 模式工作几周之后,我对 Agent 工程的看法从"怎么写好 prompt"转移到了"怎么设计 feedback loop"。这个转变挺大的。
Prompt 写得再好,上下文满了就失忆;Agent 跑得再快,没有验证就是在赌。真正稳定的 Agent 工作流,需要把人的直觉和判断转化成系统里的结构,然后把那些结构变成可运行的代码。
Factory 的 Mission 是产品化的解法,OpenAI 的文章是工程化的经验,Anthropic 的是实验性的设计。我自己的实现是把这三个角度合在一起,在 Codex 上跑起来。
还有很多没解决的:Mission 间的知识怎么传递?什么时候该 replan 什么时候该死扛?大规模并行 feature 的调试路径?这些我还在摸索。
但比起一年前,我现在至少知道问题出在哪了。
参考资料: