长话短说:Agent = 模型 + Harness。Harness 工程是我们如何围绕模型构建系统,将其转变为工作引擎。模型包含智能,而 Harness 则使这种智能变得有用。我们定义了什么是 Harness,并推导出当今和未来的 Agent 所需的核心组件。
Agent = 模型 + Harness
如果你不是模型,你就是 Harness。
Harness 是除了模型本身之外的每一段代码、配置和执行逻辑。一个原始模型不是一个 Agent。但当 Harness 赋予它状态、工具执行、反馈循环和可强制执行的约束时,它就成了一个 Agent。
具体来说,Harness 包括以下内容:
- 系统提示
- 工具、Skills、MCPs + 及其描述
- 捆绑的基础设施(文件系统、沙箱、浏览器)
- 编排逻辑(子 Agent 生成、交接、模型路由)
- 用于确定性执行的钩子/中间件(Compaction、延续、lint 检查)
在模型和 Harness 之间划分 Agent 系统边界的方式有很多种,而且很混乱。但在我看来,这是最清晰的定义,因为它迫使我们思考如何围绕模型智能来设计系统。
本文的其余部分将逐一介绍核心 Harness 组件,并从模型的核心原语出发,反向推导出每个部分存在的原因。
[](https://x.com/Vtrivedy10/article/2031408954517971368/media/2031389391680061440)
我们希望 Agent 能做一些模型开箱即用时无法做到的事情。这就是 Harness 发挥作用的地方。
模型(大多)接收文本、图像、音频、视频等数据,并输出文本。仅此而已。它们开箱即用时无法:
- 在多次交互中保持持久状态
- 执行代码
- 访问实时知识
- 设置环境并安装软件包以完成工作
这些都是 Harness 级别的功能。LLM 的结构需要某种机制来包装它们,以完成有用的工作。
例如,为了获得像“聊天”这样的产品用户体验,我们将模型包装在一个 while 循环中,以跟踪先前的消息并附加新的用户消息。读到这篇文章的每个人都已经使用过这种 Harness。其主要思想是,我们希望将期望的 Agent 行为转化为 Harness 中的实际功能。
Harness 工程帮助人类注入有用的先验知识来指导 Agent 的行为。随着模型变得越来越强大,Harness 已被用于精确地扩展和纠正模型,以完成以前不可能完成的任务。
我们不会详尽列出 Harness 的每一个功能。目标是从帮助模型完成有用工作的起点出发,推导出一系列功能。我们将遵循这样的模式:
我们想要(或想要修复)的行为 → 帮助模型实现这一目标的 Harness 设计。
[](https://x.com/Vtrivedy10/article/2031408954517971368/media/2031389459720163328)
我们希望 Agent 拥有持久化存储,以便与真实数据交互、卸载不适合上下文的信息,并在会话之间持久化工作。
模型只能直接操作其上下文窗口内的知识。在有文件系统之前,用户必须直接将内容复制/粘贴到模型中,这是一种笨拙的用户体验,并且不适用于自主 Agent。世界早已在使用文件系统来完成工作,因此模型很自然地在数十亿个关于如何使用文件系统的 token 上进行了训练。自然的解决方案变成了:
Harness 附带文件系统抽象和用于文件系统操作的工具。
文件系统可以说是最基础的 Harness 原语,因为它解锁了以下功能:
- Agent 获得一个工作区来读取数据、代码和文档。
- 工作可以增量添加和卸载,而无需将所有内容都保存在上下文中。Agent可以存储中间输出并维护能够跨越单个会话的状态。
- 文件系统是一个天然的协作界面。多个 Agent 和人类可以通过共享文件进行协调。像 Agent Teams 这样的架构就依赖于此。
Git 为文件系统添加了版本控制,因此 Agent 可以跟踪工作、回滚错误和分支实验。我们稍后会再次讨论文件系统,因为它被证明是我们需要其他功能的关键 Harness 原语。
我们希望 Agent 能够自主解决问题,而无需人类预先设计每一个工具。
今天主要的 Agent 执行模式是
,模型进行推理,通过工具调用采取行动,观察结果,然后在 while 循环中重复。但 Harness 只能执行它们拥有逻辑的工具。与其强迫用户为每个可能的操作构建工具,一个更好的解决方案是给 Agent 一个像 Bash 这样的通用工具。
Harness 附带一个 Bash 工具,这样模型就可以通过编写和执行代码来自主解决问题。
Bash + 代码执行是向模型提供一台计算机并让它们自主解决其余问题迈出的一大步。模型可以通过代码即时设计自己的工具,而不受限于一组固定的预配置工具。
Harness 仍然会附带其他工具,但代码执行已成为自主解决问题的默认通用策略。
Agent 需要一个具有正确默认设置的环境,以便它们可以安全地行动、观察结果并取得进展。
我们已经给了模型存储和执行代码的能力,但所有这些都需要在某个地方发生。在本地运行 Agent 生成的代码是有风险的,单个本地环境无法扩展到大型 Agent 工作负载。
沙箱为 Agent 提供了安全的操作环境。Harness 可以连接到沙箱来运行代码、检查文件、安装依赖项和完成任务,而不是在本地执行。这创建了安全、隔离的代码执行。为了更高的安全性,Harness 可以将命令列入白名单并强制执行网络隔离。沙箱还解锁了可扩展性,因为可以按需创建环境,分散到许多任务中,并在工作完成后拆除。
好的环境附带好的默认工具。Harness 负责配置工具,以便 Agent 可以完成有用的工作。这包括预安装语言运行时和包、用于 Git 和测试的 CLI、
用于 Web 交互和验证。
像浏览器、日志、屏幕截图和测试运行器这样的工具为 Agent 提供了一种观察和分析其工作的方式。这有助于它们创建自我验证循环,在循环中它们可以编写应用程序代码、运行测试、检查日志并修复错误。
模型不会开箱即用地配置自己的执行环境。决定 Agent 在哪里运行、有哪些可用工具、可以访问什么以及如何验证其工作,这些都是 Harness 级别的设计决策。
Agent 应该记住它们看到过的内容,并能访问在它们训练时不存在的信息。
模型除了其权重和当前上下文中的内容外,没有额外的知识。在无法编辑模型权重的情况下,“添加知识”的唯一方法是通过上下文注入。
对于内存,文件系统再次成为核心原语。Harness 支持像
这样的内存文件标准,这些文件在 Agent 启动时被注入到上下文中。当 Agent 添加和编辑此文件时,Harness 会将更新后的文件加载到上下文中。这是一种
的形式,Agent 在其中持久地存储一个会话中的知识,并将该知识注入到未来的会话中。
知识截止意味着模型无法直接访问新数据,比如更新的库版本,除非用户直接提供。对于最新的知识,Web 搜索和像
这样的 MCP 工具有助于 Agent 访问知识截止日期之后的信息,比如新的库版本或训练停止时不存在的当前数据。
Web 搜索和用于查询最新上下文的工具是集成到 Harness 中的有用原语。
Agent 的性能不应在工作过程中下降。
****描述了随着上下文窗口被填满,模型的推理和完成任务的能力如何变差。上下文是一种宝贵而稀缺的资源,因此 Harness 需要有策略地管理它。
如今的 Harness 在很大程度上是良好上下文工程的交付机制。
Compaction 解决了当上下文窗口接近满时该怎么办的问题。如果没有 Compaction,当对话超出上下文窗口时会发生什么?一种选择是 API 报错,这不好。Harness 必须对这种情况使用某种策略。因此,Compaction 会智能地卸载和总结现有的上下文窗口,以便 Agent 可以继续工作。
工具调用卸载有助于减少大型工具输出的影响,这些输出会嘈杂地弄乱上下文窗口,而没有提供有用的信息。Harness 会保留超过阈值 token 数量的工具输出的头部和尾部 token,并将完整的输出卸载到文件系统,以便模型在需要时可以访问它。
Skills 解决了在 Agent 启动时将太多工具或 MCP 服务器加载到上下文中导致性能下降的问题,这个问题在 Agent 开始工作之前就出现了。Skills 是一个 Harness 级别的原语,通过渐进式披露来解决这个问题。模型没有选择在启动时将 Skill 的前置信息加载到上下文中,但 Harness 可以支持这一点以保护模型免受上下文腐烂的影响。
我们希望 Agent 能够自主、正确地、在长时间跨度内完成复杂的工作。
自主软件创建是编码 Agent 的圣杯。但今天的模型存在提前停止、分解复杂问题困难以及在工作跨越多个上下文窗口时出现不连贯的问题。一个好的 Harness 必须围绕所有这些进行设计。
这就是早期 Harness 原语开始复合的地方。长周期的工作需要持久状态、规划、观察和验证,以便在多个上下文窗口中保持工作。
用于跨会话跟踪工作的文件系统和 Git。Agent 在一个长任务中会产生数百万个 token,因此文件系统可以持久地捕获工作以跟踪随时间推移的进度。添加 Git 允许新的 Agent 快速跟上项目的最新工作和历史。对于多个 Agent 协同工作,文件系统也充当了共享的工作分类账,Agent 可以在其中协作。
用于继续工作的 Ralph 循环。
是一种 Harness 模式,它通过一个钩子拦截模型的退出尝试,并在一个干净的上下文窗口中重新注入原始提示,迫使 Agent 继续朝着完成目标努力。文件系统使这成为可能,因为每次迭代都以全新的上下文开始,但从上一次迭代中读取状态。
用于保持正轨的规划和自我验证。规划是模型将一个目标分解为一系列步骤。Harness 通过良好的提示和注入关于如何在文件系统中使用计划文件的提醒来支持这一点。在完成每个步骤后,Agent 通过自我验证来检查其工作的正确性,从而受益。Harness 中的钩子可以运行预定义的测试套件,并在失败时将错误消息反馈给模型,或者可以提示模型独立地自我评估其代码。验证将解决方案建立在测试的基础上,并为自我改进创建了一个反馈信号。
今天的 Agent 产品,如 Claude Code 和 Codex,都是在模型和 Harness 参与的情况下进行后训练的。这有助于模型改进 Harness 设计者认为它们应该原生擅长的操作,如文件系统操作、Bash 执行、规划或与子 Agent 并行工作。
这创造了一个反馈循环。有用的原语被发现,添加到 Harness 中,然后在训练下一代模型时使用。随着这个循环的重复,模型在其被训练的 Harness 中变得更加强大。
但是这种共同进化对泛化能力有有趣的副作用。它表现在像更改工具逻辑会导致模型性能变差这样的方面。一个很好的例子在
中描述,其中 apply_patch 工具逻辑用于编辑文件。一个真正智能的模型在切换补丁方法时应该没有什么困难,但是在 Harness 参与的情况下进行训练会造成这种过拟合。
但这并不意味着最适合你任务的 Harness 就是模型经过后训练的那个。
就是一个很好的例子。在 Claude Code 中的 Opus 4.6 的得分远低于在其他 Harness 中的 Opus 4.6。
中,我们展示了如何通过仅更改 Harness,就将我们的编码 Agent 在 Terminal Bench 2.0 上的排名从前 30 名提升到前 5 名。为你的任务优化 Harness 还有很大的潜力可以挖掘。
[](https://x.com/Vtrivedy10/article/2031408954517971368/media/2031389533892218880)
随着模型变得越来越强大,今天存在于 Harness 中的一些东西将被吸收到模型中。模型将能更好地进行原生规划、自我验证和长周期连贯性,因此需要更少的上下文注入。
这表明随着时间的推移,Harness 的重要性应该会降低。但就像提示工程今天仍然很有价值一样,Harness 工程很可能将继续对构建好的 Agent 有用。
的确,今天的 Harness 弥补了模型的不足,但它们也围绕模型智能设计系统,使其更有效。一个配置良好的环境、正确的工具、持久的状态和验证循环,无论其基础智能如何,都能使任何模型更高效。
Harness 工程是一个非常活跃的研究领域,我们用它来改进我们在 LangChain 的 Harness 构建库
。以下是我们今天正在探索的一些开放且有趣的问题:
- 协调数百个 Agent 在共享代码库上并行工作
- Agent 分析自己的轨迹以识别和修复 Harness 级别的故障模式
- 能够为给定任务即时动态组装正确工具和上下文的 Harness,而不是预先配置
这篇博客文章旨在定义什么是 Harness,以及我们希望模型做的工作如何塑造了它。
模型包含智能,而 Harness 是使这种智能变得有用的系统。
致力于更多的 Harness 构建、更好的系统和更好的 Agent。