最近社区里有个话题热度很高:Prompt 工程过时了,Context 工程也过时了,现在只要学好 Harness 工程就够了。短短一个月,Harness Engineering 从一个博客概念变成了人工智能领域的高频词。
在 AI 智能体编程中,最终效果好坏的关键,往往不取决于模型有多聪明,而在于模型之外那套由状态、工具、环境和反馈回路构成的系统。如果 AI 将成为软件开发流程中的长期协作者,那么软件工程体系本身也需要进化。
LangChain 作者 Vivek Trivedy 所写的《The Anatomy of an Agent Harness》[1] 一文,恰好解答了一个行业里常说但定义模糊的核心概念:Harness。
什么是 Harness?
Agent = Model + Harness
如果你不是模型,那你就属于 Harness。
这句话虽然有点绝对,但精准地划清了界限。Harness 的本质就是模型之外的一切:代码、配置以及各类执行逻辑。模型本身只是一个能力源,只有当 Harness 将状态管理、工具调用、反馈循环和约束机制串联起来时,它才真正成为一个能工作的 Agent。
具体来看,一个 Harness 通常包含以下部分:
- 系统提示词:定义模型的角色和目标。
- 工具、技能、MCP:模型可以调用的外部能力接口。
- 基础设施:文件系统、沙箱环境、浏览器等运行时支撑。
- 编排逻辑:子任务拆分、多 Agent 协作、模型路由等。
- 钩子/中间件:上下文压缩、续写、代码检查等确定性处理流程。
为什么用「模型 vs Harness」来划分系统?因为这能提供更清晰的边界。很多关于 Agent 的讨论容易陷入概念模糊,但这种划分方式迫使你回答一个根本问题:模型负责什么?剩下的系统能力又该由谁来补足?
接下来,我们就从这个定义出发,逐一拆解 Harness 的核心组件,并从「模型能做什么」反向推导「为什么需要这些设计」。

为什么需要 Harness?
原因很直接:有些事我们希望 Agent 能做到,但模型本身无法实现。
这听起来像句废话,但关键在于先明确模型的边界。大多数模型的输入是文本、图像或音频,输出也是文本。本质上,模型只是一个 输入 → 输出的函数。
它自身无法完成以下操作:
- 在多轮交互中记住状态。
- 执行代码。
- 获取实时信息。
- 操作物理环境(例如安装依赖、运行程序)。
所有这些能力,都不在模型内部,而需要外部系统来补充。这个外部系统就是——Harness。
举个最常见的例子:聊天。看似自然的“聊天”体验,模型本身是无法提供的。要实现它,你至少需要做几件事:维护一段对话历史;每次请求时将历史记录拼接到上下文;持续循环接收用户输入并返回模型输出。本质上,这就是一个将模型包裹起来的简单循环。
因此,核心观点是:你希望 Agent 表现出的所有能力,最终都需要通过 Harness 来实现。 这也是 Harness Engineering 的核心思路:不要总想着“调教模型让它能做到”,而是换个方向——先明确你想要什么能力,再把这些能力逐一设计到 Harness 中。

文件系统:持久化存储和上下文管理
我们对 Agent 的期望很实际:能处理真实数据、能管理放不下的内容、还能把工作成果保存下来。
模型只能处理其上下文窗口内的内容。如果没有文件系统,用户只能反复复制粘贴信息喂给模型——这对人类来说都很繁琐,更别提让 Agent 自主工作了。
现实世界中,我们依靠文件系统来组织一切工作。模型在大量数据训练中也早已“学会”了这一点。因此,一个自然的结论是:Harness 需要提供文件系统抽象,以及对应的读写操作(fs-ops)。
有了文件系统,多项关键能力才得以实现:
- Agent 拥有了自己的工作空间,可以读写数据、代码和文档。
- 信息可以按需加载,而非一次性全部塞入上下文。
- 中间结果可以落盘,任务状态能够跨会话保留。
- 文件本身成为协作接口:人类与多个 Agent 可以围绕同一份内容协同工作。
如果再进一步,集成版本控制(如 Git),整个工作流将更加完整:
- 记录每一步代码或配置的改动。
- 出现问题时可以快速回滚。
- 可以创建分支进行不同的尝试。
从这个角度看,文件系统并非一个“附加功能”,而是最基础的 Harness 原语之一。后续的许多能力,如状态管理、多 Agent 协作、复杂任务拆分,都将依赖它。
Bash + 代码执行:通用问题解决工具
我们真正想要的,是让 Agent 能自己动手解决问题,而不是为它的每一步都预先设计好专用工具。
但现实是,大多数 Agent 仍遵循固定的“思考-行动-观察”循环:推理一步,调用一个预设工具,观察结果,然后继续。问题在于:它只能使用你预先提供的那些工具。 这带来了一个现实限制——你不可能提前穷举所有可能的工具。
因此,更直接的解决方案是:不要给出一长串工具列表,而是直接提供一台“能干活的机器”。 也就是:在 Harness 中集成 Bash + 代码执行能力。
一旦具备这个能力,局面将彻底改变:
- 模型可以自主编写脚本来解决特定问题。
- 可以临时“创造工具”,而非依赖预先定义的接口。
- 能够组合现有能力,拼装出新的工作流程。
本质上,你不再是在“设计工具库”,而是在提供一个通用的执行环境。当然,Harness 中仍然可以包含各种现成工具,但在许多场景下,代码执行将成为默认的问题解决策略。
沙箱环境和工具:安全执行与工作验证
给了 Agent“能存”和“能执行”的能力还不够——它还需要一个能放心干活且能验证结果的地方。
代码总需要在某个环境中运行。如果直接在本地执行模型生成的代码,风险极高;同时,本地环境也难以支撑多任务、高并发的 Agent 工作流。
更合理的做法是:将代码执行放进沙箱中。
沙箱主要解决两个核心问题:
1. 安全性
- 隔离执行环境,避免影响宿主机系统。
- 可以限制命令、禁用网络、控制文件权限。
- 即使代码出错,影响范围也被限制在沙箱内部。
2. 可扩展性
- 可以按需快速创建和销毁环境。
- 支持多个任务并行执行。
- 用完即焚,不留存状态污染。
但光有“环境”还不够,还要让它开箱即用。这就是 Harness 的另一项职责:准备一套合理的默认工具集。 例如:
- 常见语言的运行时和基础依赖库。
- Git、测试框架等命令行工具。
- 浏览器(用于页面交互与结果验证)。
这些工具的价值不仅在于“能用”,更在于让 Agent 能够观察并验证自己的工作成果:
- 查看运行日志。
- 执行单元测试。
- 对操作界面进行截图。
- 检查程序输出。
一旦具备了这些能力,就能形成一个关键的闭环:写代码 → 运行 → 观察 → 修复 → 再运行,也就是一个简单但有效的自我验证循环。
所以,这里的重点不是“提供一个运行环境”,而是:决定 Agent 在什么环境里工作、能使用什么工具、能看到什么反馈,以及如何判断自己是否做对了。 这些,全部都是 Harness 的职责所在。
记忆与搜索:持续学习能力
我们希望 Agent 不只是“当下聪明”,还要能记住经验、查询新信息。
但模型本身做不到这一点。它的知识仅来源于两部分:训练时学到的内容(固化在权重中),以及当前上下文里提供的信息。除此之外,模型没有“记忆”,也无法主动更新知识。
因此,问题就转化为:如何将“新知识”提供给模型? 答案只有一个:通过上下文注入。 在这件事上,文件系统再次成为关键基础设施。
一种常见做法是让 Harness 维护一些“记忆文件”(例如 AGENTS.md):
- Agent 在运行过程中可以将重要信息写入该文件。
- 下次启动时,文件内容会被重新加载进上下文。
- 文件更新了,上下文知识也随之更新。
这本质上是一种朴素的“学习”方式:写下来 → 保存 → 下次继续用。虽然没有改变模型权重,但已经能实现跨会话的经验积累。
然而还有一个问题:模型不知道“现在正在发生什么”。例如新发布的库版本、最新的 API 变动、实时市场数据等,这些都不在训练数据里。
这时就需要另一类能力:搜索与外部知识获取。例如 Web 搜索,或者像 Context7 这样的上下文查询工具(MCP)。它们的作用非常直接:把模型“看不见”的实时信息,拉取到当前上下文中。
对抗上下文衰减:智能压缩策略
我们不希望 Agent 工作时间越长,就变得越“笨”。
但现实是,随着上下文长度不断增加,模型的表现往往会下降。这就是所谓的“上下文衰减”(Context Rot):信息总量增加,但有效信息比例下降;关键线索被淹没;模型的推理能力开始变得不稳定。
本质原因很简单:上下文是有限的资源,且极易被浪费。 所以问题变成:如何让 Agent 在长时间工作中,始终使用“干净高效”的上下文? 这正是 Harness 需要解决的工程问题。你可以把现代的很多 Harness 理解为一套 “上下文管理”的工程化系统。
最核心的应对手段包括:
1. 压缩(Compaction)
当上下文即将填满时,不能只是继续堆叠,必须对已有内容进行处理。常见做法是:对历史对话进行总结,保留关键决策和信息,将细节内容移出上下文。这样,Agent 就能在不丢失主线信息的前提下继续工作。
工具调用产生的输出往往是占用上下文的“大户”:日志很长、返回结果杂乱,但真正有用的信息可能很少。一种更合理的策略是:只保留输出的开头和结尾(关键信号),将完整内容写入文件系统,需要时再按需读取。 其本质就是:不要让“噪音”占据宝贵的上下文空间。
3. 技能(Skills)与延迟加载
另一个常见问题是:Agent 一启动,就把所有工具的说明文档、MCP 的描述全部塞进上下文。结果任务还没开始,上下文已经被污染了。更好的方式是 按需加载(渐进式披露):先提供最必要的初始信息;当 Agent 需要某个特定能力时,再将相关的工具描述和用法引入上下文。可以将 Skills 理解为对工具和能力的 “懒加载机制”。
长期自主执行
我们真正想要的,是让 Agent 能把一件复杂的任务从头到尾独立完成。
但现实还有差距。当前模型常见的问题是:容易提前结束(认为任务“差不多”就停了)、不擅长拆解复杂任务、一旦工作跨越多个上下文窗口,连贯性就开始变差。
所以,问题不在于“它会不会写代码”,而在于:它能不能把一项工作持续地推进下去。 这正是 Harness 要解决的核心问题之一:如何让工作能够跨时间、跨上下文持续进行。 这不是单一能力,而是一组能力叠加产生的结果。
文件系统 + Git:把过程“记下来”
长周期任务必然产生大量中间结果,不可能全靠上下文窗口来承载。因此,必须将工作外部化:
- 文件系统记录当前工作状态。
- Git 记录历史修改和版本变化。
- 新的 Agent 实例可以快速接手已有的工作进度。
当多个 Agent 协作时,这套机制本质上就是一个 共享的协作笔记本。
Ralph 循环:防止“做一半就停”
模型很容易在“看起来差不多了”的时候宣布任务结束。Ralph 循环的思路很直接:拦截“我要结束”的信号,为模型提供一个重置后的干净上下文,并驱使它继续朝最终目标推进。关键在于:上下文可以重置,但工作状态(保存在文件系统中)不能丢失。 这也再次说明了文件系统是这一机制的前提。
规划 + 自我验证:让过程不跑偏
能持续执行还不够,还要 做对。这里有两个关键机制:
1. 规划(Planning)
- 将总体目标拆解为具体步骤。
- 将规划写入文件。
- 根据执行进度持续更新规划。
这样,每一步操作都有“参照物”,不容易偏离方向。
2. 自我验证(Self-Verification)
每完成一步,就进行检查:
- 运行相关测试。
- 查看执行日志。
- 验证程序输出。
如果验证失败,则将错误信息反馈给模型,让它继续修复。这就形成了一个稳定的质量闭环:执行 → 检查 → 反馈 → 修正。
Harness 与模型的共同进化
如今我们所见的强大 Agent 产品,如 Claude Code,正是模型与 Harness 协同进化的结果。在训练过程中,模型不仅学习生成文本,还被特意训练以更好地使用 Harness 提供的工具和流程,例如文件系统操作、Bash 执行、任务规划、与子 Agent 并行工作等。
这形成了一个 反馈循环:
- Harness 提供基础操作原语和能力。
- 模型学习如何使用这些原语。
- 训练成果被反馈并融入下一代模型。
- 新一代模型在相同的 Harness 环境中表现更出色。
这种共同进化虽然让模型在特定 Harness 下能力更强,但也有其副作用:模型可能对特定的工具调用逻辑或环境产生“过拟合”,当切换到不同的 Harness 环境时,性能可能出现下降。
一个例子来自某些模型的提示指南:用于编辑文件的 apply_patch 工具,如果模型在训练中只接触过一种补丁应用逻辑,那么在切换到其他补丁方法时可能出现问题。这也说明了一个道理:最适合你手头任务的 Harness, 未必是模型在训练时使用的那个。
例如,在 Terminal Bench 2.0 基准测试中,Claude Code 中的 Opus 4.6 模型得分远低于其他 Harness 环境中的同版本模型。而通过优化 Agent 的运行环境(如文档结构、验证回路、追踪系统),LangChain 的编码智能体在同一基准下的排名从全球第 30 位跃升至第 5 位,得分从 52.8% 提升到了 66.5%。

结语
随着模型能力越来越强,今天由 Harness 承担的部分功能(如基础规划、简单验证)未来可能会被模型自身吸收。模型在长时程任务中保持连贯性的能力会更强,对上下文注入的依赖也会减少。
这是否意味着 Harness 会变得不重要?就像提示工程在今天依然有其价值一样,Harness Engineering 很可能将继续在构建高效、可靠的 AI 智能体系统中扮演关键角色。
原因在于:
- Harness 不仅弥补模型的固有不足。
- 它更是一种系统工程的设计范式,旨在让模型能够最高效、最安全地完成任务。
- 一个配置精良的环境、合适的工具集、持久化的状态管理和严谨的验证循环,能让任何模型都发挥出最大效能。
可以将其比作舞台与演员的关系:
- Harness 是舞台、灯光、音响和幕后控制系统。
- Agent 是舞台上的演员。
无论演员多么天赋异禀,如果没有一个设计良好的舞台和一套清晰的演出规则,他们也难以呈现完美的表演。深入理解 Harness Engineering,正是为 AI 智能体搭建那个能让其大放异彩的“舞台”。
引用链接
[1] The Anatomy of an Agent Harness: https://blog.langchain.com/the-anatomy-of-an-agent-harness