返回博客

Harness Engineering 入门

——“Agent = Model + Harness。当 AI 编程代理的可靠性取决于你围绕它构建的系统而非模型本身时,工程师的工作正在发生根本性变化。”

LangChain 在 Terminal Bench 2.0 上做了一个实验:同一个模型,只调整 harness,排名从第 30 名跳到了第 5 名。模型没换,代码能力没变,但输出质量有了质的飞跃。这个结果指向一个越来越清晰的结论:当我们用 AI 编程代理写代码时,瓶颈往往不在模型,而在模型周围的系统。

这篇文章梳理 Harness Engineering 的核心概念和实践框架。读完后,你会知道什么是 harness,如何用前馈和反馈两套控制机制提升 agent 可靠性,以及六个具体的配置层该怎么用。

模型不是瓶颈,系统才是

如果你用过 Claude Code、Cursor 或 Codex,大概有过这样的经历:agent 在简单任务上表现出色,但碰到稍微复杂的场景就开始忽略指令、绕圈子,或者生成一堆看起来合理但实际跑不通的代码。

第一反应通常是”等下一代模型就好了”。但 HumanLayer 团队在几十个项目、上百次 agent 会话后得出了不同的结论:这不是模型问题,是配置问题。更强的模型会解决一部分旧的失败模式,但因为我们会给它更难的任务,新的失败模式会持续出现。非确定性系统中的意外失败是根本性的。

LangChain 的 Terminal Bench 实验提供了最直接的证据。同一个 Opus 4.6 模型,在 Claude Code 的内置 harness 中排名第 33,放进一个优化过的 harness 后升到了前 5。换模型大约影响 10-15% 的输出质量;换 harness 决定的是系统能不能用。

这就是 Harness Engineering 要解决的问题。

什么是 Harness

”Harness”这个词来自马具——缰绳、马鞍、嚼子——一整套用来引导强壮但不可预测的动物朝正确方向前进的装备。在 AI agent 语境下,它的定义是:

Agent = Model + Harness

Harness 是 agent 中除了模型本身之外的一切:系统提示、工具编排、执行环境、反馈回路、可观测性基础设施。模型提供智能,harness 让智能变得可用。

LangChain 的 Vivek Trivedy 把这个定义推导得更具体:模型本身不能维持跨会话的状态,不能执行代码,不能访问实时信息,不能搭建环境。这些能力全部来自 harness。即便是最基本的”聊天”体验,本质上也是 harness 在一个 while 循环里追踪消息历史。

对于编程 agent,harness 还可以分成两层。Birgitta Böckeler 在 Martin Fowler 网站上的文章做了一个清晰的区分:

用户 Harness(你来配置)
AGENTS.md、Hooks、MCP Servers、Skills、Sub-agents
内置 Harness(Agent 厂商构建)
系统提示、工具路由、上下文检索、编排逻辑
Model
LLM 权重、推理能力、语言理解

Figure 1:Agent 的三层结构。你能直接工程化的是最外层的用户 harness。

内置 harness 是 Claude Code、Cursor、Codex 等工具的开发者已经构建好的:系统提示、代码检索机制、编排系统。用户 harness 是你根据自己的代码库和工作流定制的外层:AGENTS.md 文件、hooks、MCP 工具、skills。Harness engineering 主要关注的就是这个外层——你能控制的部分。

前馈与反馈:控制论视角

理解了 harness 是什么之后,下一个问题是:它该怎么工作?Böckeler 提出了一个借鉴控制论的框架,把 harness 的控制机制分成两类:

前馈引导(Feedforward Guides):在 agent 行动之前提供指导,提高第一次就做对的概率。比如 AGENTS.md 中的编码规范、参考文档 skill、架构描述文件。

反馈传感器(Feedback Sensors):在 agent 行动之后检测结果,让它有机会自我纠正。比如 lint 检查、测试套件、AI 代码审查。

只有前馈没有反馈,agent 会遵循规则但不知道规则是否起效。只有反馈没有前馈,agent 会反复犯同样的错误然后不断修复。两者配合才能形成有效的控制回路。

在每个方向上,控制手段又分为两种执行类型:

计算型(Computational):确定性的、快速的、CPU 执行的。类型检查器、linter、结构测试、依赖扫描。结果可靠,可以在每次提交时运行。

推理型(Inferential):语义层面的、较慢的、GPU 执行的。AI 代码审查、LLM-as-judge。结果有非确定性,但能捕获计算型手段无法触及的语义问题。

前馈引导 Guides
推理型
AGENTS.md · Skills
计算型
LSP · CLI · Codemods
Coding Agent
生成 → 执行 → 输出
harness 的目标不是替代判断,而是让这条回路更稳定、更可控。
反馈传感器 Sensors
计算型
ESLint · Tests · dep-cruiser
推理型
AI Code Review
人类工程师持续做的事
优化 guides,减少首轮跑偏;增加 sensors,尽早发现问题;让 agent 形成可重复的自我纠正回路。

Figure 2:Harness 的控制回路。前馈引导在左侧输入 agent,反馈传感器在右侧检测输出,人类工程师持续优化两套控制。

这个框架的实用价值在于它提供了一个系统性的思考方式:当 agent 出了问题,不是去调 prompt 碰运气,而是问自己,这个问题应该通过前馈预防还是通过反馈捕获?应该用确定性的计算型手段还是语义层面的推理型手段?

Böckeler 进一步指出,计算型传感器能可靠地捕获结构性问题,比如重复代码、圈复杂度、缺失测试覆盖、架构漂移。推理型传感器能部分解决需要语义判断的问题,比如语义重复、冗余测试、过度工程化,但代价更高且不确定。而一些高影响问题,比如误诊 bug 根因、添加不需要的功能、误解指令,目前两种类型都无法可靠捕获。这意味着人类审查在当前阶段仍然不可或缺,harness 的目标是减少审查负担而非消除它。

六个实用配置层

框架有了,接下来是具体怎么做。以下是当前编程 agent 中最重要的六个 harness 配置面:

配置层方向类型作用关键注意事项
AGENTS.md前馈推理型注入编码规范、项目结构、约束条件保持简洁(60 行以内);LLM 生成的版本反而降低性能
MCP Servers前馈计算型扩展 agent 工具能力工具描述会注入系统提示,连接过多会膨胀上下文
Hooks反馈计算型在生命周期事件上自动执行脚本类似 git hooks,提供确定性控制流
Skills前馈推理型渐进式披露知识,按需加载指令对抗 context rot 的关键手段
Sub-agents两者推理型在隔离 context window 中执行子任务充当”上下文防火墙”,维持长会话一致性
垃圾回收反馈两者定期清理架构漂移和冗余代码OpenAI 曾花 20% 时间手动清理,后编码为自动化流程

几个值得展开的细节:

AGENTS.md 的陷阱。OpenAI 的经验是把 AGENTS.md 当作目录而不是百科全书。巨大的指令文件会挤占上下文窗口中留给任务、代码和相关文档的空间。当所有东西都被标记为”重要”时,实际上没有任何东西是重要的。他们的做法是保持 AGENTS.md 在约 100 行左右,作为指向 docs/ 目录中结构化文档的索引。

Sub-agents 作为上下文防火墙。HumanLayer 发现,在复杂的棕地企业级代码库中工作时,sub-agents 是保持跨多个 context window 一致性的关键。每个子任务在隔离的 context window 中运行,中间过程的噪声不会累积到负责编排的父线程中。

自定义 linter 的妙用。OpenAI 的团队编写了自定义 lint 规则,并在错误消息中直接嵌入修复指令。这本质上是一种良性的 prompt injection——传感器检测到问题后,通过错误消息自动把修复方向注入 agent 的上下文。

上下文是稀缺资源

Harness engineering 的很多设计决策最终都回到一个核心约束:context window 是有限的,而且会随着使用而退化。

Context Rot 描述的是模型在 context window 逐渐填满后推理和任务完成能力下降的现象。这不是理论假设——在长时间运行的编程任务中,agent 在第 3 个小时的表现通常明显不如第 1 个小时。

未管理的 Context
任务指令
工具调用输出(膨胀)
旧对话历史(过时)
⚠️ 能力退化区
Harness 管理后
任务指令(完整)
压缩后的历史
按需加载的 Skill
✓ 可用空间充足
① Compaction 压缩
智能摘要旧上下文,保留关键信息。
② Tool Call Offloading
大输出卸载到文件系统,只保留摘要。
③ Skills 渐进披露
按需加载指令,不在启动时塞满上下文。

Figure 3:Context Rot 的问题与三种 harness 级别的应对策略。

OpenAI 的团队在实践中发现了一个相关原则:从 agent 的角度看,任何不在当前上下文中的东西就相当于不存在。Slack 讨论中达成的架构共识、Google Docs 里的设计文档、人们脑中的隐性知识——这些对 agent 来说都是不可见的。他们的应对方式是把越来越多的上下文推入代码仓库,让知识以版本化的 markdown 文件形式存在于 docs/ 目录中。

这也解释了为什么 AGENTS.md 不应该太大——它本身就是上下文的一部分,写太多会挤占留给实际任务的空间。

从写代码到设计环境

Harness engineering 代表的不只是一组技术实践,还是工程师角色的一次重新定义。OpenAI 的 Codex 实验中,工程师的主要工作是设计环境、指定意图、构建反馈回路。当 agent 失败时,修复方式几乎从来不是”再试一次”,而是问:缺了什么能力?如何让这个能力对 agent 来说既清晰可读又可执行?

这个转变的最大障碍不是技术性的,而是文化性的。习惯了通过手艺来解决问题的工程师,需要适应一种委托型思维:你的工作不是把事情做完,而是构建让 agent 能把事情做完的系统。

但这并不意味着技术要求降低了。Harness engineering 需要更深的架构思维——你在设计一个必须在没有持续人工干预的情况下正常运行的系统。系统思维、架构设计、规约写作、可观测性、快速迭代——这些能力在 harness engineering 的语境下变得比具体的编码技巧更重要。

随着模型能力的持续提升,今天 harness 中的一些组件会被吸收进模型本身。但就像 prompt engineering 在模型变强之后依然有价值一样,harness engineering 很可能会持续存在。你不会因为马更聪明了就扔掉缰绳。