← 学习笔记

学习笔记 · 2026-10-08 · 基础

智能体 Harness:把模型变成能干活的系统的设计指南

Harness 是智能体中除模型以外的全部,由系统提示词、工具、执行环境、上下文管理、钩子、子智能体和验证机制组成。本文以官方工程文章和 SWE-agent 研究为依据,整理组成部分、设计原则、在编程智能体中的应用步骤、面向长任务的 Harness 以及检查清单。

目录
要点
  • Harness 指“智能体 = 模型 + Harness”这一公式中模型以外的全部代码、配置和执行逻辑;即便是同一个模型,性能也会因 Harness 不同而有很大差异。
  • 上下文是有限的资源,因此与其提供一份庞大的指南,不如采用简短的导航地图加按需查阅文档的结构,效果更好。
  • 好的 Harness 同时具备事先指明方向的引导(feedforward)和检查结果、促使自行修正的传感器(feedback)。
  • 在跨越多个会话的长任务中,仅靠压缩是不够的,还需要功能清单、进度记录、git 提交这类下一个会话能直接读取的痕迹。
  • 当同样的错误反复出现时,人的职责不是把提示词写得更强硬,而是追问“缺少了什么能力”,并补强 Harness。

什么是 Harness,为什么需要它

LangChain 文章(w1)将智能体定义为“模型 + Harness”。Harness 是模型本身以外的所有代码、配置和执行逻辑。该文总结说“不是模型,就是 Harness”,并解释说,原始模型并不是智能体,只有当 Harness 提供状态保存、工具执行、反馈循环和可强制执行的约束时,它才成为智能体。

原因很简单。模型只是接收文本、图像等输入并输出文本。据同一篇文章(w1),模型在默认状态下无法跨对话保持状态、执行代码、访问实时信息,也无法搭建工作环境或安装软件包。我们日常使用的“聊天”,其实也是最简单的 Harness:用一个循环包裹模型,记住之前的消息并追加新消息。

Harness 的效果也得到了研究的证实。SWE-agent(paper)没有改动模型权重,只设计了模型操作计算机的接口(作者称之为 ACI,Agent-Computer Interface),就提升了性能。它基于 GPT-4 Turbo 解决了 SWE-bench 测试任务中的 12.47%,大幅超过此前最佳的非交互式检索增强方法的 3.8%。这说明 Harness 设计与模型选择同样重要。

在编程智能体中,区分两层会比较方便。Martin Fowler 网站上的文章(w4)区分了系统提示词、代码检索方式这类产品中已内置的部分,以及用户根据自己的代码仓库和用途叠加上去的“外层 Harness(outer harness)”。本指南的应用步骤主要涉及这一外层 Harness。

组成部分:Harness 由什么构成

LangChain 文章(w1)列出的 Harness 组成如下:系统提示词,工具、技能、MCP 及其说明,随附的基础设施(文件系统、沙箱、浏览器),编排逻辑(创建子智能体、移交任务、模型路由),以及确定性执行的钩子和中间件(上下文压缩、任务接续、lint 检查)。在此基础上,本指南将检查结果的验证机制单独列出来看。

在执行环境方面,同一篇文章(w1)把文件系统视为最基础的要素。因为它是智能体读取数据、代码和文档的工作空间,可以存放上下文装不下的内容,并保存会话结束后仍保留的状态。再加上 git,就可以追踪工作和回滚。作为通用工具,提供 bash 和代码执行已成为基本策略;为了安全运行生成的代码,会使用沙箱(隔离的执行环境),并可以加上命令允许列表和网络隔离。

上下文管理和记忆也是 Harness 的工作。上下文窗口填满后推理能力下降的现象被称为 Context Rot,Harness 通过压缩(compaction)对已有内容进行摘要或转移,使工作得以继续(w1)。AGENTS.md 这类记忆文件会在智能体启动时注入上下文,在会话之间延续知识。

子智能体是一种让独立的子任务各自在隔离的上下文中并行处理的机制(w1)。Anthropic 构建智能体的文章(w5)中的 orchestrator-workers 模式也是同样的结构:由中心 LLM 拆分任务并交给工作者 LLM,再汇总结果;文章说明这适合无法事先知道要改多少个文件的编程任务。

Harness 的组成部分系统提示词 → 模型; 工具、技能、MCP → 模型; 执行环境 → 模型; 上下文管理 → 模型; 模型 → 钩子、中间件(执行前后); 模型 → 子智能体(委派); 模型 → 验证机制(结果检查)提供给模型的内容包裹执行的机制系统提示词AGENTS.md 等指令工具、技能、MCPbash、文件编辑、说明执行环境文件系统、沙箱、浏览器上下文管理压缩、记忆文件模型唯一不属于 Harness 的部分钩子、中间件lint 检查、任务接续子智能体隔离的上下文验证机制测试、linter、浏览器执行前后委派结果检查
Harness 的组成部分 除中间的模型外,所有方框都是 Harness。上方是输入模型的内容和环境,下方是包裹并检查执行的机制。

设计原则:各来源的共同观点

第一,从简单开始。Anthropic 构建智能体的文章(w5)建议寻找最简单的解决方案,只在必要时增加复杂度。框架让起步更容易,但可能遮蔽实际的提示词和响应,使调试变难,因此文章建议先直接使用 LLM API,如果使用框架,则要理解其内部工作方式。

第二,上下文是需要节约使用的资源。Anthropic 上下文工程文章(w6)建议找到能最大化获得预期结果可能性的“最小高信号 token 集合”。系统提示词应写在脆弱的 if-else 式硬编码与空泛的一般原则之间的“合适高度”;文章建议先用好的模型测试最简提示词,再根据失败案例补充指令和示例。同一篇文章还建议,与其密密麻麻地罗列例外情况,不如挑选多样而有代表性的示例。

第三,把工具设计成面向模型的接口。SWE-agent(paper)没有提供有几十个选项的 bash 命令,而是提供了查看文件、搜索、编辑等少数简单命令,并加入防止常见错误的护栏以及每一轮简短而具体的反馈。它还指出,人可以忽略不必要的信息,但对模型来说所有内容都是成本。Anthropic 工具编写文章(w7)和上下文文章(w6)也强调功能不重叠的最少工具、清晰的命名区分(namespacing)、token 高效的响应和精心打磨的工具说明,并指出“如果人类工程师都无法确定该用哪个工具,智能体也做不到”。

第四,同时设置引导和传感器。Martin Fowler 网站上的文章(w4)区分了在行动前指明方向的引导(feedforward)和在行动后观察、促使自行修正的传感器(feedback)。只有反馈会反复犯同样的错误,只有引导则始终无法知道规则是否奏效。文章还总结说,测试、linter、类型检查这类计算型(computational)机制快速且确定,适合每次变更时运行;AI 代码审查或 LLM-as-a-Judge 这类推理型(inferential)机制较慢且不确定,但能补充语义判断。

系统提示词的“合适高度”

← 脆弱的硬编码空泛的一般原则 →
123
  1. 罗列 if-else 式规则
  2. 最简提示词 + 用失败案例补充挑选多样而有代表性的示例
  3. 空泛的指令
本图把 Anthropic 上下文工程文章的建议放在同一条轴上。位置表示相对程度。

在编程智能体中应用 Harness 的步骤

第 1 步是从最小配置开始。用好的模型、简短的系统提示词以及 bash、文件编辑等基础工具,交给它几个实际任务,并记录它在哪里卡住(w5, w6)。不要一开始就写一大堆规则。

第 2 步是在代码仓库中建立“地图”。OpenAI 文章(w2)表示,一个庞大的 AGENTS.md 失败了,因为它侵占上下文,一切都重要时就什么都不重要,很快过时,而且难以机械地验证。取而代之的做法是,把约 100 行的 AGENTS.md 作为目录,把设计文档、执行计划和产品规格放在结构化的 docs/ 目录中,作为“记录的来源”。这是一种渐进式披露(progressive disclosure)方式,让智能体从一个小入口出发,学会下一步该看哪里。

第 3 步是接入验证机制。让智能体能自己运行测试、linter 和类型检查,并先铺设计算型传感器,例如用提交前钩子检查模块边界违规(w4)。同一篇文章还建议,在 linter 错误信息中写明修复方法,模型就能直接读取并修正。如果是 Web 应用,则让它用浏览器自动化工具像人一样从头到尾进行确认(w3)。

第 4 步是隔离执行环境并使其可观测。OpenAI 文章(w2)让每个 git worktree 都能启动应用,并让智能体可以直接查询 Chrome DevTools Protocol 以及日志、指标和追踪,把缺陷复现和修复验证交给智能体。第 5 步是通过评估来打磨工具。Anthropic 工具编写文章(w7)建议设计接近实际使用的多步骤评估任务,在准确率之外还收集工具调用次数、token 用量和工具错误,以此改进。

第 6 步是把反复出现的错误反馈回 Harness。Martin Fowler 网站上的文章(w4)把“转向循环(steering loop)”视为人的工作:当同一问题多次出现时,修改引导和传感器,使其难以再次发生。OpenAI 文章(w2)也表示,失败时的解决办法几乎从来不是“再努力试试”,而是追问“缺少了什么能力,如何让它变得智能体可读、可强制执行”。

Harness 应用六步

  1. 1
    从最小配置开始用简短提示词和基础工具记录卡住的地方
  2. 2
    在代码仓库中建立“地图”目录式 AGENTS.md + docs/
  3. 3
    接入验证机制测试·Linter·类型检查、提交前钩子
  4. 4
    环境隔离·可观测每个 worktree 一个应用,由智能体查询日志·指标
  5. 5
    边评估边打磨工具准确率·调用次数·token·错误
  6. 6
    把反复出现的错误写进 Harness修改指引·传感器,避免再次发生
前一阶段到位,下一阶段才能见效。第 6 阶段不是终点,而是持续运转的循环。

面向长任务的 Harness

耗时数小时到数天的任务需要跨越多个上下文窗口,而新会话启动时没有之前的记忆。Anthropic 长时运行 Harness 文章(w3)把这比作轮班工程师完全不记得上一班做过的工作。该文表示,即使有压缩功能也不够。失败表现为两种形式:一是想一次做太多,实现中途上下文耗尽,留下做了一半的功能;二是后来的会话看到已有进展,就过早宣布工作已完成。

解决方法是两个角色不同的提示词。第一个会话中的初始化智能体(initializer agent)会创建启动开发服务器的 init.sh、记录工作的进度文件(claude-progress.txt)以及首个 git 提交。它还会编写一份展开用户请求的功能清单;在复刻 claude.ai 的示例中,200 多个功能全部被标为“失败”状态。之后的智能体只能修改是否通过的字段;文章称之所以选择 JSON,是因为模型对 JSON 的随意改动比 Markdown 少(w3)。

之后会话中的编程智能体按固定顺序了解情况:确认工作目录,读取 git 日志和进度文件,从功能清单中选出一个尚未完成、优先级最高的功能。先用 init.sh 启动服务器,运行基本的端到端(E2E)测试,然后再实现;完成后留下带说明的提交信息和进度摘要,以“干净状态”交接(w3)。由于有 git,还可以回滚错误的变更。

OpenAI 文章(w2)也是同样的方向。复杂任务以包含进度和决策记录的执行计划文件留在代码仓库中,进行中和已完成的计划以及技术债务一同进行版本管理,使智能体无需外部背景信息也能工作。该文表示,一次 Codex 运行持续处理一项任务超过 6 小时的情况很常见。

跨多个会话的任务结构初始化智能体 → 功能清单 JSON(编写); 初始化智能体 → 了解情况(下一个会话); 了解情况 → 实现一个功能; 实现一个功能 → E2E 测试; E2E 测试 → 提交、记录; 功能清单 JSON → 实现一个功能(选择); init.sh → 提交、记录; 提交、记录 → 了解情况(下一个会话)第一个会话留下的内容每个会话重复初始化智能体仅第一个会话功能清单 JSON全部以“失败”开始进度记录、gitclaude-progress.txtinit.sh启动开发服务器了解情况读取日志和进度文件实现一个功能E2E 测试浏览器自动化提交、记录以干净状态交接编写下一个会话选择下一个会话
跨多个会话的任务结构 第一个会话中的初始化智能体留下文件,之后的会话读取这些文件,逐个实现、测试并提交功能,再交接给下一个会话。

检查清单

配置检查:系统提示词是否处于过度硬编码与空泛一般原则之间(w6)?工具数量是否最少、功能不重叠,并且人能确定在什么情况下用哪个工具(w6, w7)?工具响应是否在节约 token 的同时返回有意义的信息(w7)?智能体代码是否在沙箱中运行,必要时是否设置了命令允许列表和网络隔离(w1)?

上下文检查:AGENTS.md 是否起到目录而非百科全书的作用,是否用 linter 和 CI 捕捉过时文档(w2)?上下文快满时,是否有压缩或转存到文件的策略(w1)?交给子智能体的独立任务是否在隔离的上下文中运行(w1)?

验证检查:智能体能否自己运行测试、linter 和类型检查并读取结果(w1, w4)?是否把快速检查放在提交前、把昂贵检查放在集成之后(w4)?如果是 Web 功能,是否用浏览器自动化从头到尾进行确认(w3)?错误信息是否连修复方法也一并给出(w4)?

长任务检查:是否留下下一个会话可读取的进度记录、功能清单和提交历史,是否每个会话只处理一个功能,是否阻止了未经测试就标记完成(w3)?最后,是否存在让反复出现的错误转化为 Harness 改进的循环(w4)?

Harness 检查清单

构成

  • 提示词是否介于硬编码与泛泛而谈之间
  • 工具是否精简且互不重叠
  • 是否有沙箱·命令允许列表

上下文

  • AGENTS.md 是否起到目录作用
  • 是否有压缩·转存到文件的策略
  • 独立任务是否拆给子智能体

验证

  • 是否自行运行测试·Linter
  • 快速检查是否放在提交前
  • 错误信息是否说明修复方法

长任务

  • 是否留下进度记录·功能列表·提交
  • 是否一个会话只做一个功能
  • 是否禁止未经测试就标记完成

常见错误与局限

最常见的错误是放入过多的指令和工具。庞大的指令文件会挤占任务所需的上下文,而且很快过时(w2)。功能宽泛、边界模糊的工具集合是 Anthropic 上下文文章(w6)列出的典型失败。反过来,也有警告指出,在不理解的情况下层层堆叠 Harness 框架,很容易看不清内部发生了什么(w5)。

第二个错误是把验证交给模型自己判断。在 Anthropic 长时运行 Harness 文章(w3)中,Claude 在没有明确指示时只做单元测试或 curl 检查,没有发现功能在端到端层面无法运行。提供浏览器自动化工具后情况大为改善,但对于浏览器原生提示框这类工具看不到的部分,仍然有很多缺陷。

Harness 也有局限。Martin Fowler 网站上的文章(w4)指出,计算型传感器能稳定发现重复代码、复杂度、测试覆盖率、结构偏离这类结构性问题,但对于问题误诊、过度设计与不必要的功能、误解指令这类更大的问题,无论计算型还是推理型机制,都无法稳定到足以减少监督的程度。归根结底,Harness 只能减轻人工审查的负担,无法消除它。

另一个争议点是评估设计。Anthropic 工具编写文章(w7)建议避免过于简单的评估环境,也要避免因格式差异等小事就拒绝正确答案的过严验证器。由于通往正确答案的路径可能有多条,不要过拟合于特定的工具调用顺序。

延伸学习

想先掌握概念,就从 LangChain 文章(w1)读起。它从模型做不到的事反向出发,逐一推导出为什么需要文件系统、bash、沙箱、记忆和压缩。接着可以通过 Anthropic 构建智能体的文章(w5)了解工作流与智能体的区别,以及 prompt chaining、routing、orchestrator-workers 等基本模式。

想深入了解设计原则,可以把 Anthropic 上下文工程文章(w6)和工具编写文章(w7)一起读。前者从上下文预算的角度讨论系统提示词、工具和示例,后者展示了先做出工具原型、再通过评估打磨的流程。如果需要研究依据,可以在 SWE-agent(paper)中看到接口设计对性能的影响。

在实际应用方面,三篇文章互为补充。Martin Fowler 网站上的文章(w4)提供引导与传感器、计算型与推理型机制的思考框架;OpenAI 文章(w2)提供代码仓库知识结构和可观测执行环境的案例;Anthropic 长时运行 Harness 文章(w3)则给出跨多个会话任务的具体文件配置和会话启动流程。

相关术语

Harness 系统提示词 沙箱 子智能体 技能 上下文工程 编程智能体 MCP

参考资料

延伸阅读(官方文档与技术博客)

奠基论文

视频与课程

视频未被用作正文的依据,仅供想进一步学习的读者参考。

由 AI 根据所列参考资料撰写并经过审核。详情请查看原始资料。