编码智能体是模型加上围绕它构建的一切。Harness 工程将这种脚手架视为真正的产物,每当智能体出错时,它就会收紧。
大致意思是:每当发现智能体犯错,你就花时间设计解决方案,让它再也不会犯同样的错误。
过去两年,我们一直在争论模型。哪个最聪明、哪个写的 React 最干净、哪个幻觉更少。这种讨论本身没问题,但它忽略了系统的另一半。模型只是运行中智能体的一个输入。其余的是 harness:提示词、工具、上下文策略、钩子、沙箱、子智能体、反馈循环和恢复路径——所有包裹在模型周围、让它真正能完成任务的组件。
一个不错的模型配上优秀的 harness,胜过优秀的模型配上糟糕的 harness。 我在自己的工作中反复见证这一点。而且越来越明显的是,有趣的工程不在于挑选模型,而在于设计围绕它的脚手架。
这门学科现在有了名字。Viv Trivedy 创造了 harness 工程 这个术语,他的《智能体 Harness 解剖》一文最清晰地推导了 harness 究竟是什么、以及每个部分为何存在。Dex Horthy 一直在追踪这一模式的出现。HumanLayer 将大多数智能体失败归结为"技能问题",根源在于配置而非模型权重。Anthropic 的工程团队 发表了我认为关于如何为长时运行任务设计 harness 的最佳公开解析。而 Birgitta Böckeler 从用户角度对这一切做了很好的概述。
本文是我尝试将这些线索串联起来的努力。
Viv 的一句话道出了核心:
智能体 = 模型 + Harness。如果你不是模型,你就是 harness。
Harness 是每一段代码、配置和执行逻辑,只要不是模型本身。原始模型不是智能体。只有当 harness 赋予它状态、工具执行、反馈循环和可强制执行的约束时,它才成为智能体。

具体而言,harness 包括:
系统提示词、CLAUDE.md、AGENTS.md、技能文件和子智能体提示词
工具、技能、MCP 服务器及其描述
捆绑的基础设施(文件系统、沙箱、浏览器)
编排逻辑(子智能体生成、交接、模型路由)
用于确定性执行的钩子和中间件(压缩、续接、代码检查)
可观测性(日志、追踪、成本和延迟计量)
Simon Willison 将循环部分提炼到本质:智能体是一个"循环运行工具以实现目标的系统"。技能在于工具设计和循环设计两者。
如果这听起来涉及面很广,确实如此。而且这是你的涉及面,不是模型提供商的。Claude Code、Cursor、Codex、Aider、Cline:这些都是 harness。底层的模型有时相同,但你体验到的行为主要由 harness 决定。
coding agent=AI model(s)+harness
这个由 Viv 提出、HumanLayer 呼应的等式,才是实际工作所在。关于等式左边的争论很热闹。但大多数实际杠杆点在右边。
我观察到一个工程师们容易陷入的模式。智能体做了蠢事,工程师责怪模型,然后把责任归结为"等下个版本"。
Harness 工程的思维方式拒绝这种默认。失败通常是可解读的。智能体不知道某个约定,你就把它加进 AGENTS.md。智能体运行了破坏性命令,你就加个钩子阻止它。智能体在 40 步任务中迷失,你就把它拆成规划器和执行器。智能体不断"完成"有问题的代码,你就把类型检查的回压信号接入循环。
HumanLayer 说:"这不是模型问题,是配置问题。" Harness 工程就是当你认真对待这句话时发生的事。
Viv 的文章和 HumanLayer 都提到了一个引人注目的数据点。在 Terminal Bench 2.0 上,Claude Opus 4.6 在 Claude Code 内部运行的得分远低于在定制 harness 中运行的同一模型。Viv 的团队仅通过改变 harness,就将编码智能体从 Top 30 提升到 Top 5。模型在训练后会与训练时使用的 harness 耦合。将它们移入不同的 harness——配备更适合你代码库的工具、更紧的提示词和更锐利的回压——可以释放出原始 harness 未能利用的能力。
这与"就等 GPT-6"的叙事相反。今天的模型能做什么与你看到它们做什么之间的差距,很大程度上是 harness 的差距。
Harness 工程中最重要的习惯,是将智能体的错误视为永久信号。不是一笑而过的轶事,不是重试的"坏运行"。是信号。
如果智能体提交了一个带有注释掉测试的 PR,而我意外合并了,这就是一个输入。下一版我的 AGENTS.md 会写"永远不要注释掉测试;要么删除要么修复"。下一版我的预提交钩子会在 diff 中搜索 .skip( 和 xit(。下一版我的审查子智能体会将注释掉的测试标记为阻塞项。
只有见过真实失败,你才添加约束。只有有能力的模型让它们变得多余,你才移除它们。好的 AGENTS.md 中的每一行都应该能追溯到某个具体出错的事情。
这也是 harness 工程是一门学科而非框架的原因。适合你代码库的 harness 由你的失败历史塑造。你无法下载它。
当我实际设计 harness 时,Viv 的框定最有用:从你想要的行为出发,推导出实现它的 harness 部件。他的模式是:我们想要的行为(或想要修复的)→ 帮助模型实现这一点的 harness 设计。

这样推导的好处在于,每个 harness 组件都有明确的职责。如果你说不出某个组件存在是为了交付什么行为,它可能就不该存在。
本节其余部分大致按 Viv 的顺序 walk 过这些部件,附带我发现值得借鉴的具体模式。
文件系统是最基础的基元,它往往被低估,因为它很无聊。模型只能直接操作能放入上下文的内容。没有文件系统,你就是在聊天窗口里复制粘贴,这不是工作流。
有了文件系统,智能体就有了读取数据、代码和文档的工作空间;有了卸载中间工作的地方,而不是把它留在上下文里;有了多个智能体和人类可以通过共享文件协调的表面。加上 Git,你就免费获得了版本控制,智能体可以跟踪进度、回滚错误、分支实验。
大多数其他 harness 基元最终都会指向文件系统获取某些东西。
今天的主智能体循环是 ReAct 循环:模型推理、通过工具调用采取行动、观察结果、重复。但 harness 只能执行它有逻辑的工具。你可以尝试为每个可能的动作预建工具,或者给智能体 bash,让它按需即时构建需要的工具。
Willison 对此的看法是,智能体已经擅长 shell 命令;大多数任务归结为几个精心挑选的 CLI 调用。Harness 仍会提供专注的工具,但 bash 加代码执行已成为自主问题解决的默认通用策略。这就像教某人使用单一厨房小工具与交给他整个厨房的区别。
Bash 只有在安全的地方运行才有用。在笔记本上运行智能体生成的代码有风险,单一本地环境无法扩展到多个并行智能体。
沙箱给智能体提供隔离的操作环境。Harness 不本地执行,而是连接到沙箱来运行代码、检查文件、安装依赖、验证工作。你可以允许列表命令、强制网络隔离、按需启动新环境、任务完成后销毁它们。
好的沙箱配备好的默认值:预装语言运行时和包、Git 和测试 CLI、用于网页交互的无头浏览器。浏览器、日志、截图和测试运行器让智能体能观察自己的工作,闭合自我验证循环。
模型不配置自己的执行环境。决定智能体在哪里运行、有什么可用、如何验证输出,都是 harness 层面的决策。
模型除了权重和当前上下文中的内容外,没有额外知识。无法编辑权重的情况下,添加知识的唯一方式是通过上下文注入。
文件系统再次成为基元。Harness 支持记忆文件标准如 AGENTS.md,每次启动时注入。智能体编辑该文件时,harness 重新加载它,一个会话的知识带入下一个。这是一种粗糙但有效的持续学习形式。
对于训练时不存在的知识(新版本库、当前文档、今日数据),网页搜索和 Context7 等 MCP 工具弥合了截止点。这些是值得归进 harness 而非留给用户的基元。
上下文衰减是指随着上下文窗口填满,模型推理和完成任务的能力下降。上下文稀缺,harness 很大程度上是良好上下文工程的交付机制。
三种技术反复出现:
压缩。 当窗口接近满时,必须有所舍弃。让 API 报错对生产 harness 不是选项,因此 harness 智能地总结和卸载旧上下文,让智能体能继续工作。
工具调用卸载。 大型工具输出(比如 2000 行日志文件) 集群上下文而不增加多少信号。Harness 保留阈值以上的首尾 token,将完整输出卸载到文件系统,智能体可以按需读取。
渐进披露的技能。 启动时就把每个工具和 MCP 加载进上下文,会在智能体采取任何动作前就降低性能。技能让 harness 只在任务实际需要时才揭示指令和工具。
Anthropic 的 harness 文章为真正长时任务添加了另一种技术:完整上下文重置,harness 拆除会话并从紧凑的交接文件重建。他们明确表示仅压缩不足以应对长任务;有时你需要带着结构化简报重新开始。这更接近人类 onboarding 新工程师的方式,而非我们通常理解的"记忆"。
自主长时程工作是圣杯,也是最难做对的事。今天的模型遭受过早停止、复杂问题分解不佳、以及工作跨越多个上下文窗口时的不连贯。Harness 必须围绕这一切进行设计。
我以前在自我改进智能体和2026 趋势文章中写过 Ralph 循环等自主编码循环,但值得在此框定下重述:钩子拦截模型的退出尝试,将原始提示词重新注入新鲜上下文窗口,强制智能体针对完成目标继续。每次迭代干净开始,但通过文件系统读取前一状态。这是一个将单会话智能体变成多会话智能体的惊人简单技巧,是那种你永远不会从"就用更聪明的模型"推导出的基元。
规划是模型将目标分解为步骤序列,通常写入磁盘上的规划文件。Harness 通过提示词和提醒如何使用规划文件来支持这一点。每一步后,智能体通过自我验证检查工作:钩子运行预定义测试套件,将失败循环回模型并附带错误文本,或模型根据明确标准审查自己的输出。
规划器/生成器/评估器分离。 Anthropic 的长时运行 harness 工作明确表示,将生成与评估分离到不同智能体优于自我评估,因为智能体给自己的工作打分时总是偏向正面。这是文本的 GAN。相关模式是冲刺契约,生成器和评估器在写代码前就"完成"意味着什么进行协商。在我自己的工作流中,开始前写下完成条件,比任何提示词更改都更能捕捉范围漂移。
钩子是区分"我告诉智能体做 X"和"系统强制执行 X"的东西。
钩子是运行在特定生命周期点的脚本:工具调用前、文件编辑后、提交前、会话启动时。它们是智能体永远不该忘记但经常忘记的事情的合适位置。每次编辑后运行类型检查、代码检查和测试并暴露失败。阻止破坏性 bash(rm -rf、git push --force、DROP TABLE)。打开 PR 或推送到 main 前需要批准。写入时自动格式化,让智能体不浪费 token 在空白字符上。
HumanLayer 强调、我也逐渐认同的原则是:成功静默,失败啰嗦。 如果类型检查通过,智能体听不到任何声音。如果失败,错误文本注入循环,智能体自我纠正。这让反馈循环在常见情况下几乎无成本,在出错时直接可行动。
仓库根目录的扁平 markdown 规则手册仍然是单一最高杠杆的配置点,因为它每轮都进入系统提示词。约定放在这里:包管理器、测试框架、格式化、"永远不要碰 /legacy"、"总是使用我们的日志记录器"。两个来之不易的教训:
保持简短。HumanLayer 的保持在 60 行以内。每行都在争夺注意力,更多规则让每个规则的重要性降低。飞行员检查单,不是风格指南。
每行都要有价值。规则应追溯到具体过去的失败或硬外部约束。如果不是,就是噪音。棘轮;不要头脑风暴。
同样的纪律适用于工具。每个工具的名称、描述和模式都压入每次请求的提示词。十个专注的工具胜过五十个重叠的,因为模型能在脑中记住菜单。HumanLayer 还指出了真正的安全问题:工具描述填充提示词,所以你安装的任何 MCP 服务器都是智能体在你说任何话之前就会读取的受信任文本。一个草率或恶意的 MCP 可以在你打字之前就提示注入你的智能体。
我见过的最清晰的成熟 harness 公开图景是 Fareed Khan(估算)对 Claude Code 架构的拆解,值得对着图表坐一会儿。

前几节几乎每个概念都以命名组件的形式出现在这张图上。上下文注入是知识层。循环状态存在于记忆存储和工作树隔离器中。破坏性动作钩子位于权限门后。子智能体上下文防火墙是整个多智能体层。工具调度注册表是 MCP 服务器和 bash 都插入的地方。Khan 的论点与 Viv 相同,只是通过一个已发布产品推演:Claude Code 的发展轨迹至少与底层模型一样关乎 harness。
Anthropic 文章中的一个更好观察是,随着模型改进,有趣的 harness 组合空间不会缩小。它会移动。
天真的故事是更好的模型让 harness 过时。如果模型能规划,就不需要规划器。如果模型在长时程上连贯,就不需要上下文重置。是的,Opus 4.6 很大程度上杀死了上下文焦虑失败模式(Sonnet 4.5 过去会在接近它认为的上下文限制时过早结束工作),这意味着我六个月前写的一整类焦虑缓解脚手架现在成了死代码。
但天花板随模型一起移动。以前够不到的任务现在可以做了,它们有自己的失败模式。焦虑脚手架消失,取而代之的是你需要多日记忆策略,或协调三个专业智能体的 harness,或生成 UI 中设计质量的评估器。假设转变,编码它们的脚手架也随之转变。
Anthropic 说得干脆:"harness 中的每个组件都编码了一个关于模型自身不能做什么的假设。" 当模型在某方面变得更好,该组件就不再承载任何负载,应该移除。当模型解锁新东西,就需要新的脚手架来够到新的天花板。
另一件正在发生的事,Viv 明确命名,是 harness 设计与模型训练之间的反馈循环。

今天的智能体产品在 harness 参与下进行后训练。模型专门针对 harness 设计者认为它应该擅长的事情变得更好:文件系统操作、bash、规划、子智能体调度。这就是为什么 Opus 4.6 在 Claude Code 内部与在别人 harness 中感觉不同,也是为什么改变工具逻辑有时会导致奇怪的回归。一个真正通用的模型不会在乎你用 apply_patch 还是 str_replace,但联合训练造成了过拟合。
实际影响有两方面。Harness 是活的系统,不是你一次性设置的配置文件。 而且"最佳"harness 不一定是模型训练时所在的那个;它是为你的任务设计的那个。Viv 从 Top 30 到 Top 5 的 Terminal Bench 跃升是我见过的最清晰证明点。
Viv 的另一贡献是 HaaS 框定:Harness-as-a-Service。观察是我们正从构建于 LLM API(给你补全)转向构建于 harness API(给你运行时)。Claude Agent SDK、Codex SDK 和 OpenAI Agents SDK 都指向同一方向。你开箱即得循环、工具、上下文管理、钩子和沙箱基元,然后定制它们。
这种转变很重要,因为以前的默认路径是:构建自己的循环、连接自己的工具调用、处理自己的对话状态、发明自己的审批流。现在的默认路径是:挑选 harness 框架,沿四大支柱(系统提示词、工具、上下文、子智能体)配置它,把其余精力投入领域特定的提示词和工具设计。
这让"技能问题"变得可处理。你不是每次出错都从零开始重建智能体。你是在调整一个已经良好分解的配置表面。
Viv 对此的说法也是支持从凌乱开始的最佳论据:"好的智能体构建是迭代的练习。如果你没有 v0.1,就无法迭代。"
并排看顶级编码智能体(Claude Code、Cursor、Codex、Aider、Cline),它们彼此之间的相似度超过与底层模型的相似度。 模型不同。Harness 模式在收敛。我不认为这是偶然。这是行业慢慢找到将生成模型变成能交付东西所需的承重脚手架部件。
Viv 对开放问题的框定最让我兴奋:编排多个智能体并行工作在共享代码库上;分析自己追踪以识别和修复 harness 级失败模式的智能体;为给定任务动态组装正确工具和上下文的 harness,而非启动时预配置。
最后一点尤其感觉像 harness 停止成为静态配置、开始变得更接近编译器的地方。