Google Cloud AI 总监 Addy Osmani 发布了一篇讨论 Agent Harness 的文章,他的核心观点:
“如果你不是模型,你就是 harness。”
过去两年,行业一直在争论模型:哪个最聪明,哪个写 React 最干净,哪个幻觉最少。这个对话固然重要,但它忽略了系统的另一半——Agent = Model + Harness。
好模型加好 harness 的组合,始终战胜好模型加差 harness 的组合。当前行业最有价值的工程工作不是选模型,而是设计模型周围的脚手架。
Harness 包含什么#
Harness 涵盖了模型本身之外的所有代码、配置和执行逻辑。原始模型不是 agent,只有当 harness 为它提供状态、工具执行、反馈循环和可执行约束时,它才成为 agent。
具体来说,harness 包括:
- 系统提示词:CLAUDE.md、AGENTS.md、skill files 和子代理指令
- 工具系统:Tools、skills、MCP servers 及其技术描述
- 基础设施:文件系统、沙箱和 headless browsers
- 编排逻辑:生成子代理、处理交接和路由模型
- 约束层:钩子和中间件用于确定性执行,如 lint 检查或上下文压缩
- 可观测性:日志、追踪、成本和延迟计量
Agent 的核心是一个运行工具循环以实现目标的系统。真正的技能在于同时设计工具和那个循环。
重新审视”技能问题”#
常见的情况是,工程师在 agent 做出荒唐事情时责备模型,通常把问题归档为”等下一个版本修复”。
harness engineering 思维拒绝这种默认做法。失败通常是可以理解的:
- 如果 agent 忽略了一个约定,把它加到 AGENTS.md 里
- 如果它运行了破坏性命令,写一个 hook 来阻止它
- 如果它在 40 步任务中迷失了,把架构拆分为 planner 和 executor
- 如果它总是以损坏的代码结束,在循环中接入类型检查反向压力信号
正如 HumanLayer 所说:“这不是模型问题,这是配置问题。”
考虑性能基准:一个领先模型在现成框架中运行,往往得分远低于在同一模型在定制化、高度调优的 harness 中运行。把模型移入一个有更好 codebase 工具、更严格提示词和更清晰反向压力的环境,可以解锁原设置遗留的能力。
今天模型理论上能做的和你实际看到它们做的之间的差距,很大程度上是 harness 的差距。
棘轮原则:每次错误都变成规则#
harness engineering 中最重要的习惯是把 agent 错误当作永久信号来对待,而不是侥幸重试后忘记的一次性事件。
示例:如果 agent 提交了一个被合并的带注释测试的 PR,那就是一个输入。
- AGENTS.md 必须说明:“不要注释测试;删除或修复它们”
- pre-commit hook 应该自动标记 diff 中的
.skip( - reviewer 子代理必须更新以阻止带注释的测试
约束原则:
- 约束只在观察到真实失败时才添加
- 只在有能力的模型使其多余时才移除
- 好的系统提示词中的每一行都应该能追溯到一个具体的、历史性的失败
正因为如此,harness engineering 不是一刀切的框架,而是一门学科。一个特定代码库的正确答案完全由其独特的失败历史塑造。
从行为倒推#
设计 harness 最有效的方法是从期望的行为开始,构建提供该行为的组件。
工具选择规则:
- harness 的每个部分都必须有明确的工作。如果无法为某个组件命名它的特定功能,它就应该被移除
- 一份位于仓库根目录的平面 markdown 文件仍然是最高杠杆的配置点
- 十个高度专注的工具总是优于五十个重叠的工具
核心组件#
文件和 Git 是持久状态
- 文件系统是基础,提供读取数据的工作空间、卸载中间工作的场所,以及多个 agent 协调的表面
- Git 提供免费版本控制,允许 agent 追踪进度、分支实验和回滚错误
Bash 和代码执行是通用工具
- 大多数 agent 在 ReAct 循环中运行:通过工具调用推理、行动、观察、重复
- Agent 通常擅长 shell 命令,使 bash 和代码执行成为自主解决问题的默认策略
Bash 只有在安全运行时才有用
- 沙箱为 agent 提供隔离环境来运行代码、检查文件和验证工作
- 良好的沙箱带有强大的默认设置:预装语言运行时、测试 CLI 和 headless browsers
Memory 和 Search:持续学习
- 模型除了训练权重和当前上下文外没有其他知识
- Harness 使用内存文件(如 AGENTS.md)弥合这一差距
- 对于实时信息(如新库版本或实时数据),web search 和 MCP tools 直接内置在 harness 中
与上下文腐化作斗争
模型在上下文窗口填满时推理能力会下降。Harness 使用三种主要技术管理这种稀缺:
- 压缩:智能总结并将较旧的上下文卸载以防止 API 错误
- 工具调用卸载:将大量工具输出存储在文件系统中,而只在上下文中保留必要的头部和尾部
- 渐进式披露:只在任务明确需要时才揭示指令和工具,而不是在启动时加载所有内容
长期执行
自主的长期运行工作存在早期停止和问题分解不佳的问题。Harness 通过结构设计来应对:
- 循环:拦截模型退出尝试,迫使其在新的上下文窗口中继续对抗完成目标
- 规划:强迫模型将目标分解为逐步计划文件,在每步后通过自验证 hook 检查其工作
- 分离:将生成和评估分离到不同的 agent 中,防止模型在评估自己作品时固有的正向偏差
Hooks 是你的执行层
- Hooks 弥合了请求行动和执行行动之间的差距
- 它们在特定生命周期运行:工具调用之前、文件编辑之后或提交之前
- Hooks 阻止破坏性命令、强制自动格式化以节省 token,以及运行测试套件
理想情况下,成功是沉默的,失败是冗长的。如果类型检查通过,agent 听不到任何声音;如果失败,错误直接注入回循环中进行自纠正。
行业趋势#
行业正从构建 LLM API(提供补全)转向构建 Harness API(提供运行时)。SDK 现在开箱即提供循环、工具、上下文管理、hooks 和沙箱。
看今天的顶级 coding agent,它们彼此之间看起来比底层模型更相似。模型不同,但 harness 模式正在收敛。
Harness 不会缩小,只会转移#
随着模型改进,对 harness 的需求不会消失——它会转移。
- 模型改进时,过时的脚手架应该被移除
- 新脚手架必须为下一个 horizon 构建
- Harness 的每个组件都编码了一个关于模型无法自行完成的假设
训练循环#
当前 harness 设计和模型训练之间存在一个主动反馈循环。今天的模型通常在特定 harness 在环中的情况下进行后训练,产生一定程度的过拟合。
这使得 harness 成为一个活系统,而不是静态配置文件,并证明”最好”的 harness 是针对你独特任务和工作流程优化的那个。
未来方向#
最具前景的开放问题正在超越单一 agent:
- 编排多个 agent 并行工作
- 使 agent 能够分析自己的追踪以修复 harness 级别的失败
- 构建动态组装工具的环境
最终,harness 将停止成为静态配置文件,开始像编译器一样运作。