Harness 层:OpenAI、Anthropic、Stripe、DeepSeek 四家 Agent 工程范式拆解(2026)
目录
- 1 为什么 harness 值得单独成为一层
- 2 Harness 的解剖学:五个维度
- 3 官方一手实践:四家公司给出的四种 harness 范式
- 4 四个范式对照:什么该抄,什么不该抄
- 5 用户侧的外层 harness:guides 与 sensors
- 6 五层 harness 配置机制(开源侧的实证)
- 7 Harness 与模型训练的耦合(这是 2026 年的新认识)
Harness 层:2026 年的工程主战场
地基之上,2026 年真正的工程战场是"模型外面那一层"。这一层在 2 月到 4 月被反复命名、拆解、争论,到 5 月已经成为共识。
1 为什么 harness 值得单独成为一层
有一个数据在 2026 年被反复引用:在模型完全不变的前提下,只替换 harness,基准分数可以摆动 7 到 26 分,通常大于换一代模型带来的提升。另一个公开榜单上,同一个模型在 8 个不同 harness 里跑出了 13 分的跨度。
最著名的单一案例是 Terminal-Bench 2.0:Claude Opus 4.6 在 Claude Code 里跑,分数远低于同一个模型在定制 harness 里的成绩。LangChain 团队仅通过改 harness,把他们的 coding agent 从 Top 30 推到 Top 5。
这解释了为什么"harness 工程"会在 2026 年上半年突然成为显学。但要注意一个诚实的分寸:那篇广为流传的"harness 决定了 70% 性能"的说法,其作者自己承认 70% 是个记忆性的框架数字,不是任何单一研究的结论。真正被测量到的是 7–26 分这个区间。
2 Harness 的解剖学:五个维度
综合 LangChain、Addy Osmani、Future AGI 和后续多篇综述,一个 harness 可以被拆成五个可独立设计的维度:
| 维度 | 要解决的问题 |
|---|---|
| 子 agent 编排(subagent orchestration) | 工作怎么在多个 agent 之间拆分、handoff、以及谁来决定下一步 |
| 上下文管理(context management) | 每一轮模型看到什么。长任务里这一维权重最高 |
| 工具设计(tool design) | 动作面(action surface)的形状与 schema。十个聚焦的工具胜过五十个重叠的 |
| 安全与权限(safety & permissions) | agent 被允许做什么。这是团队最容易跳过的一维 |
| 循环编排(loop orchestration) | 什么时候行动、什么时候重试、什么时候停 |
这五个维度的关系是相乘而非相加,所以"只优化一个维度"往往看不到效果。原文的建议顺序是:先上下文管理和工具设计(权重最大),再收紧安全和循环编排。
3 官方一手实践:四家公司给出的四种 harness 范式
这一小节是全篇最有"证据密度"的部分。四家公司的写法刚好代表了四种不同的取舍,而第四种直到 8 月才出现。
(1) OpenAI:把仓库变成 agent 能读懂的知识库
OpenAI 内部团队做了一件极端的事:五个月,零行手写代码,约一百万行代码,1500 个 PR,最初只有 3 个工程师(后来扩到 7 人),平均每人每天 3.5 个 PR,而且吞吐量随着团队扩大反而上升。估算开发时间约为手写的十分之一。
他们的核心结论只有一句,但非常硬:
“我们现在最困难的挑战,集中在设计环境、反馈循环和控制系统上,以帮助 agent 达成我们的目标:大规模地构建和维护复杂可靠的软件。”
注意这句话的份量——说出这句话的是训练模型的那家公司。他们等于公开承认:瓶颈不在模型。
他们踩过并明确否定的做法,比正面经验更值得记:
-
"一个大 AGENTS.md"必然失败,原因有四条:上下文是稀缺资源,巨型指令文件会挤掉任务本身;什么都"重要"就等于没有重点; monolithic 手册会瞬间腐烂成过时规则的坟场;而且它无法被机械校验。所以他们把 AGENTS.md 缩到约 100 行,只当目录用,真正的知识库放在结构化的 docs/ 目录里,做渐进披露(progressive disclosure)。
-
规则要能用 linter 强制。他们用自定义 linter 和结构化测试来钉死架构:每个业务域只能沿固定层次"向前"依赖(Types → Config → Repo → Service → Runtime → UI),横切关注点(鉴权、连接器、遥测、开关)只能通过单一 Provider 接口进入。违反即报错,而且错误信息里直接写入修复指令,注入 agent 上下文。
-
把应用本身变成 agent 可读的。他们让每个 git worktree 都能独立启动应用实例,接入 Chrome DevTools Protocol,为 agent 提供 DOM 快照、截图、导航技能;再搭一套临时的本地可观测栈(VictoriaLogs/Metrics/Traces + LogQL/PromQL/TraceQL)。于是"确保启动在 800ms 内完成""这四条关键用户路径没有 span 超过 2 秒"这类 prompt 才真的可执行。
-
熵与垃圾回收。他们曾经每周五花 20% 的时间清理"AI slop",不可扩展。后来改成把"金科玉律"编码进仓库,用后台 agent 任务定期扫描偏移、更新质量评分、开小范围重构 PR,多数一分钟内可评审并自动合并。
一个可直接引用的数据点:他们说单次 agent 运行经常在单个任务上连续工作六小时以上,通常是在人睡觉的时候。
(2) Anthropic:从 initializer/coding 双 agent,到 planner/generator/evaluator 三 agent
Anthropic 的 harness 演进有清晰的三个阶段,而且每个阶段都在做减法——这条线索本身就是理解 harness 生命周期的关键。
阶段一(2025 年 11 月):双 agent 解决"跨上下文窗口的一致性"
他们先把问题定义得很准:长任务的本质困难是 agent 必须在离散的会话里工作,每个新会话开始时对之前发生的事毫无记忆。就像一支项目团队按班次轮换,每个接班的工程师都不记得上一班发生了什么。
观察到的两个失败模式:
- 想一把梭。agent 试图一次性完成整个应用,结果在实现中途耗尽上下文,留下半成品和没写文档的功能,下一班只能靠猜。
- 过早宣布完工。后来的 agent 实例看到"已经有进展了",就宣布任务完成。
解法是 initializer agent + coding agent:第一个会话用专门的 prompt 搭环境——写 init.sh、写 claude-progress.txt 进度日志、做第一次 git commit;后续每个会话只做一件事,然后留下结构化更新。
几个细节很值得记:他们把功能清单写成 JSON 而不是 Markdown,因为模型更不容易乱改 JSON;每个功能带 passes: false 字段,且明确禁止"删测试";每个会话开场先跑 pwd、读进度文件、读 git log、跑一次基础端到端测试,确认没把环境搞坏再动手。
阶段二(2026 年 3 月):三 agent + 上下文重置
阶段一撞到了天花板,暴露出两个新问题:
- 上下文焦虑(context anxiety):某些模型在接近它以为的上下文上限时,会开始草率收尾。
- 自我评估失灵:让 agent 评价自己产出的东西,它会自信地夸奖,哪怕在人看来明显平庸。这在设计这类主观任务上尤其严重。
两个关键判断:
上下文重置 ≠ compaction。 compaction 是就地摘要、同一个 agent 继续;重置是清空上下文、换一个全新 agent,靠结构化交接物传递状态。重置能给干净的白板,代价是要有足够好的 handoff 文件。
生成与评判必须分离。 他们借了 GAN 的思路——生成器与评估器对抗。把评估器调成"挑剔"远比让生成器"自我批判"可行;一旦有了外部反馈,生成器就有了对抗的具体对象。
于是有了 planner / generator / evaluator 三角色,以及两个我认为最有迁移价值的机制:
- 把主观质量变成可打分的准则。他们给"这个设计好不好"拆成四项:设计质量、原创性、工艺、功能性。并明确把设计质量和原创性权重调高,因为 Claude 在工艺和功能上默认就及格,而在品味上容易滑向"紫渐变+白卡片"式的 AI 味。评估器用 few-shot 加详细评分拆解来校准,减少跨轮次的分数漂移。
- Sprint 契约(sprint contract)。每个 sprint 开始前,生成器和评估器先协商"什么叫做完"——生成器提出要建什么、如何验证,评估器审这个提案,来回迭代到一致,再开始写代码。这一条解决了"规格太高层、用户故事和可测实现之间有断层"的问题。
代价也很真实:同一个"2D 复古游戏编辑器"的 prompt,单 agent 跑 20 分钟花 9 美元,完整 harness 跑 6 小时花 200 美元——贵 20 倍以上,但产出质量的差距一眼可见(单 agent 版本的游戏根本跑不起来,实体定义和运行时的接线断了)。
阶段三:模型变强之后,主动拆掉脚手架
这段是整篇文章里我最想让读者记住的部分,因为它展示了一种罕见的工程纪律。
Opus 4.6 发布后,他们开始逐个移除组件、观察影响,而不是一把重写(他们试过激进砍,结果无法复现性能,也搞不清哪些部件是承重的)。结果:
- sprint 结构被完全移除——4.6 原生就能连贯工作两小时以上
- 上下文重置被移除——4.6 基本消除了上下文焦虑
- planner 保留——没有它,生成器会低估范围、不先做规格就开始写
- evaluator 保留但降级——从每 sprint 一次改为最后单次;而且他们明确指出评估器不是固定的是非题,而是一笔成本收益判断:只有当任务超出当前模型能稳定独立完成的范围时才值得
由此得出一句被广泛引用的话,也解释了"harness 不会消失,只会移动":
“harness 里的每一个组件,都编码了一个关于’模型自己做不到什么’的假设。当模型变强,这个组件就不再承重,应该被拿掉;当模型解锁了新能力,就需要新的脚手架去够到新的天花板。”
(3) Stripe:把 harness 焊进公司已有的工程基础设施
Stripe 的 Minions 给出的启发完全不同——它讲的是在超大遗留代码库里怎么让 harness 活下来。
规模:每周有一千多个合并的 PR 完全由 minion 产出,虽然有人工评审,但不含任何人类写的代码。代码库是数亿行 Ruby(非 Rails)+ Sorbet,大量自研库,对 LLM 天生不熟;而且这段代码每年驱动超过一万亿美元的支付量。
几个设计决策非常值得借鉴:
- “对人类工程师好的东西,对 LLM 也好”。他们没有为 agent 单独造一套工具,而是复用已有的开发基础设施——源码管理、环境、代码生成、CI。
- devbox 而不是 git worktree。每次运行起一个预热好的隔离开发机(10 秒内就绪,预载代码和服务),与生产资源和互联网隔离,因此无需人工权限审批就能跑。他们明确说 worktree 在 Stripe 这个规模上无法扩展。
- agent 循环与确定性代码交织。核心循环 fork 自 Block 的 goose,但编排是"有主见地"改过的——git 操作、linter、测试这些必须完成的步骤由确定性代码保证,创造性交给 agent。
- 规则按子目录条件生效,而不是全局无条件规则(后者在这个规模下不可行)。
- 400+ MCP 工具的中央服务器 Toolshed。而且他们在 minion 启动之前就确定性地跑一批相关 MCP 工具去"预热上下文"。
- 反馈左移 + CI 最多两轮。第一道防线是本地可执行文件,用启发式在每次 git push 时跑选定 lint,5 秒内完成。CI 有三百多万个测试,很多带自动修复。他们明确限制:最多两轮 CI,因为让 LLM 反复跑完整 CI 循环的边际收益递减。
(4) DeepSeek:把 harness 做成一个可替换的内核
前两家在回答「harness 该往里加什么」,DeepSeek 问的是另一个问题:如果 harness 的每一部分都可以被替换,包括主循环本身,它会变成什么。它的答案(dsh,2026-08-13,MIT)是把整个运行时做成插件树,跑在 Cordis 这个插件元框架上。官方架构文档的说法很干脆:没有需要打补丁的特权内核——扩展的方式是「在别的插件旁边挂一个插件」,而注册动作是 effect,插件卸载时自动回退。
这个主张在包结构上可以逐条验证。核心包各占一个 ctx 键:core/session 拥有只追加的 SessionEvent 日志;core/system-prompt 负责提示词分段与工具 schema 装配;core/tools 是带作用域的工具注册表与受保护执行管线;core/agent 定义 Agent 接口与注册表;而 core/agent-loop 只是实现该接口的默认驱动器。最后这一句是「连 loop 都能换」的工程依据,也是它区别于 Codex 与 Claude Code 的地方——后两者的编排逻辑内建在核心里,要换得改源码。
代价落在组合语义上。运行中的 dsh 是一棵启动时按有序层组合出的插件树,层序是 profile 的有序 bundle、该 profile 的 cordis.patch.yml、home patch、–patch 覆盖层。关键语义是:patch 按行 id 定位,然后整行替换掉它的全部配置,或者插入新行——行级替换,不是深度合并。于是两个插件争用同一个界面挂载点或同一行时,结果不是合并,而是后者整行盖掉前者。官方把这个语义写进了文档,说明预见到了冲突,但没有提供任何检测工具。
把四家的扩展机制并排,会出现一条很干净的光谱。Stripe 是内建式:不为 agent 单独造工具,复用已有的开发基础设施(源码管理、环境、代码生成、CI),规则按子目录条件生效。Codex 是声明式的:插件本质上就是磁盘上的文件夹,即 Markdown skill、MCP 配置、shell 脚本,改配置重启两三秒,门槛接近零,代价是插件不进进程、改不了执行逻辑。Claude Code 是半声明式的:Skills 是纯文本、不含可执行代码,Hooks 是 shell 脚本、26 个生命周期事件,两者被明确分层,用户可以按风险档位挑。dsh 是进程内的命令式:插件带着状态跑在 harness 进程内、互相注册,为支持运行时热替换必须处理悬空引用、后台任务终止、依赖链协同、崩溃回滚,仅管理插件生命周期的核心模块就有 750 行。
这条光谱的实践含义是:扩展深度与扩展安全性是一根轴的两端,不是两个可以分别优化的指标。声明式插件风险面小,因为安装单元是可读的文本;进程内插件能力上限最高,但它同时拿到了宿主进程的全部权限,因此必须用签名、审核、权限声明把治理补回来。dsh 三样都没有,这一点在第十章展开。
还有一个数字值得记,它说明「最独特的能力」未必是「最多人用的能力」:社区普查 2,143 个可装插件里,真正替换主循环的只有两个,而换模型的插件有 69 个、头部周下载约六千。用最重的运行时换来的那层自由度,恰好是生态最少人碰的一层。
4 四个范式对照:什么该抄,什么不该抄
| 维度 | OpenAI | Anthropic | Stripe | DeepSeek |
|---|---|---|---|---|
| 核心赌注 | 环境即产品:把仓库、应用、可观测性全变成 agent 可读 | 结构即质量:用角色分离和契约把主观质量工程化 | 复用即杠杆:不给 agent 另造一套基础设施 | 内核即接口:连主循环都做成可替换插件 |
| 上下文策略 | 渐进披露 + 知识库分片 + 机械校验新鲜度 | compaction 为主,必要时上下文重置;后期随模型变强而简化 | 启动前确定性预热 MCP 工具,把相关上下文先灌进去 | 做成独立插件:先裁超预算的工具结果,撑不住再生成摘要节点替换一段历史 |
| 质量保证 | 自定义 linter + 结构化测试 + 后台"垃圾回收" agent | 生成器/评估器分离 + 可打分准则 + sprint 契约 | 确定性代码守住 git、linter、测试,创造性交给 agent;CI 最多两轮 | 靠生态与用户:官方不做测试与 eval,只提供一个 GitHub 标签做发现 |
| 扩展机制 | 声明式:插件是文件夹,不进进程 | 半声明式:文本 skill 与可执行 hook 明确分层 | 内建式:只按子目录条件加载规则 | 命令式:带状态跑在进程内,可替换主循环 |
| 最适合抄的场景 | 长期维护的单体仓库、需要架构不漂移 | 交付物质量主观、需要可验证的"做完"定义 | 超大遗留代码库、已有成熟工程基础设施 | 要自研或改造 agent 平台、需要在多模型间路由 |
| 最大风险 | 前期环境投入极重,短期看不到回报 | 成本可能高一个数量级,且评估器本身要调很久 | 强绑定既有基础设施,换公司就带不走 | 插件即全权限进程内代码,边界与治理一起外包给了用户 |
5 用户侧的外层 harness:guides 与 sensors
Thoughtworks 的 Birgitta Böckeler 提供了一个我认为最实用的思维模型,它把 harness 分成内层(模型厂商内置的,比如系统提示、代码检索机制)和外层(用户自己搭的,比如指令文件、MCP server、自定义 skill)。然后给出两个正交的分类轴:
方向轴:
- Guides(前馈)——在 agent 动手之前引导它,提高一次做对的概率。例:AGENTS.md、Skills、代码修改脚本。
- Sensors(反馈)——在 agent 动手之后观察结果,让它自我纠正。特别有效的是为 LLM 消费而优化的信号,比如自定义 linter 的错误信息里直接写修复指令——一种"正向的提示注入"。
执行类型轴:
- 计算型(computational)——确定、快、CPU 跑:测试、linter、类型检查、结构分析。毫秒到秒级,结果可靠。
- 推断型(inferential)——语义判断、AI code review、LLM as judge。慢、贵、不确定,但能做语义层判断。
关键的洞察是:只有前馈会变成"写了规则但永远不知道有没有用";只有反馈会变成"反复犯同样的错"。两者必须成对出现。
她还提出了一个概念(来自同事 Ned Letcher):ambient affordances(环境可供性)——环境本身的结构属性,使它对 agent 更易读、可导航、可处理。强类型语言的代码库天然自带类型检查这个 sensor;边界清晰的模块天然支持架构约束;Spring 这类框架屏蔽掉细节,本身就提高了 agent 成功率。没有这些属性,这些控制手段就造不出来。
这条洞察很有用:要提升 agent 在某个代码库上的表现,改 prompt 是低杠杆动作;先看这个代码库的"可 harness 性"——有没有类型系统、有没有边界、有没有可执行的测试——才是高杠杆的。她还引用了 Ashby 的必要多样性定律:调节器必须具备至少和被调节系统一样多的多样性,而且只能调节它有模型的部分——所以给 agent 限定技术拓扑(topology),本质上是在削减多样性、让 harness 变得完备。
6 五层 harness 配置机制(开源侧的实证)
2026 年有一项针对 2,853 个开源仓库的探索性研究(Galster 等),把 agentic coding 工具的配置机制归为八类:上下文文件、settings、skills、subagents、commands、hooks、rules、MCP server。
结论有点扫兴但很有价值:开发者压倒性地采用静态上下文文件,很少使用可执行机制。作者的原话是"今天开源界的 harness 工程……大体上还是上下文工程"。
这也解释了另一组矛盾的研究结果:一项研究发现 AGENTS.md 的存在与更低的运行时和更少的输出 token 相关;另一项研究发现任务成功率并没有提升,但推理成本高了 20% 以上。这两个结论并不冲突——上下文文件降低的是"摸索成本",不是"任务难度"。
7 Harness 与模型训练的耦合(这是 2026 年的新认识)
今天所有 agent 产品都是把 harness 放进训练回路里后训练的。模型会专门变得更擅长 harness 设计者认为它该擅长的事:文件系统操作、bash 执行、规划、subagent 并行。
这形成了一个反馈回路:harness 里发现了有用的原语 → 标准化进产品 → 用于训练下一代模型 → 模型在该 harness 里更强。
副作用是过拟合。最典型的例子是 apply_patch 的风格:一个真正通用的模型不应该在意你用 patch 还是 str_replace,但 co-training 制造了这种依赖。Drew Breunig 给这个现象起了个名字:“对抗权重”(fighting the weights)——模型不按你说的做,是因为你在跟它的训练倾向较劲。
他还给了一个极好的诊断技巧:当你翻开一个 prompt 看到大量重复和大写,八成是在对抗权重。Claude Code 的系统提示里"你可以在单次响应中调用多个工具"这句话重复了七次,"如果工具之间没有依赖请并行调用"又重复了四次——因为模型的训练环境长期是串行的,需要反复对抗。
但这也带来一个重要的反直觉结论:对模型最好的 harness 不一定是你任务最好的 harness。 迁移到别的 harness 时,模型可能表现更好也可能更差。Terminal-Bench 的榜单就是证据。
更多推荐


所有评论(0)