⚠️ Alpha内测版本警告:此为早期内部构建版本,尚不完整且可能存在错误,欢迎大家提Issue反馈问题或建议。
Skip to content

Harness Engineering

对于harness engineering 目前并没有一个确切的定义,本节将结合anthropic、langchain的几篇核心harness工程文章来介绍

面向长时间运行应用程序开发的harness设计

1.工程中的问题

工程师们先前已证明,框架设计对长期自主编码智能体的效能具有显著影响。 在早期实验中,他们使用初始化智能体将产品规格分解为任务列表,并由编码智能体逐项实现功能,同时通过消息传递中间件完成智能体之间的通信以保持上下文连贯。 更广泛的开发者社区已形成类似共识,例如采用"拉尔夫·维格姆"方法,通过钩子或脚本使智能体保持在持续迭代循环中。 但有些问题依然顽固存在。对于更复杂的任务,在长时间执行过程中,智能体会随着时间推移逐渐偏离正轨。

在剖析这一问题时,他们观察到智能体执行此类任务时存在两种常见的失效模式:

1.1.上下文内容过长问题

模型在长任务中随着上下文窗口填满容易失去连贯性。某些模型还会表现出 "上下文焦虑",即当接近其自认为的上下文容量极限时,会过早地开始收尾工作。 解决方法: 他们并没有采取上下文压缩的方式,而是一种更加激进的方式——上下文重置,完全清空上下文窗口并启动全新智能体,同时结合结构化交接流程来传递前序智能体状态与后续步骤。 为什么不采用压缩? 压缩是将对话的早期部分就地总结,以便同一智能体能够在缩短的历史记录中继续工作。虽然压缩保持了连续性,但它并没有给智能体一个全新的开始,这意味着上下文焦虑仍然可能存在。在他们早期的测试中发现, Claude Sonnet 4.5 表现出足够强烈的上下文焦虑,仅靠压缩不足以实现强大的长任务性能,因此上下文重置成为工具设计的关键。 代价: 交接工件需要包含足够的状态,以便下一个智能体能够清晰地接手工作。增加了每次工具运行的编排复杂性、token开销和延迟。

1.2.自我评估问题

当要求agent评估自己完成的工作时,智能体往往会自信地给予高度评价。这个问题在主观性任务(例如设计)中尤为突出,因为这类任务不存在类似可验证软件测试的二元判断标准。布局设计究竟显得精致还是平庸属于主观判断,而智能体在评估自身作品时总会倾向于给出积极评价。 甚至在可验证结果的任务上,智能体有时仍会表现出判断力不足,从而影响其任务完成的表现。 解决方法: 执行工作的智能体与评估工作的智能体分离开来,调整一个独立的Evaluator,编写提示词等方法,使其持怀疑态度。一旦有了这种外部反馈,Generator就有了具体可迭代改进的依据。

1.3评估方法问题

对于第二种失效模式,它又涉及另外一个问题——评估方法问题 怎么去评估agent产出的结果?对于带有主观性评估的问题,比如这个设计好不好,没有标准,因此需要一个标准来量化agent产出的质量,从而更好的作用于第二点

2.解决评估量化问题——前端设计:让主观质量可量化

工程师们从前端设计开始实验,因为自我评估问题在这里最为明显。在没有干预的情况下,Claude 通常会倾向于安全、可预测的布局,这些布局在技术上是可行的,但在视觉上并不出众。 虽然美学不能完全简化为一个分数——个人品味总是会有所不同——但可以通过编码设计原则和偏好的评分标准来改进。"这个设计漂亮吗?"很难一致地回答,但"这个设计是否遵循了我们的良好设计原则?"给了 Claude 一些具体的评分依据。其次,通过将前端生成与前端评分分开,创建一个反馈循环,推动Generator产生更强的输出。 考虑到这一点,工程师们写了四个评分标准,并在提示中同时提供给generator-agent和evaluator-agent:

  • 设计质量 (Design quality): 设计是否感觉像一个连贯的整体,而不是零散的部分的集合?在这方面表现出色意味着颜色、排版、布局、图像和其他细节相结合,创造出独特的氛围。
  • 原创性 (Originality): 是否存在定制决策的证据,还是仅仅使用了模板布局、库默认设置和 AI 生成的模式?一位人类设计师应当能够识别出有意识的创意选择。未经修改的现成组件——或者 AI 生成的典型迹象,比如白色卡片上的紫色渐变——在这方面是不合格的。
  • 工艺 (Craft): 技术执行:字体层次、间距一致性、色彩协调、对比度比例。这是一项能力检查而非创意检查。大多数合理的实现默认都能在此处表现良好;失败则意味着基础不牢。
  • 功能性 (Functionality): 可用性独立于美学。用户能否理解界面的作用,找到主要操作,并在无需猜测的情况下完成任务?

通过强调设计质量和原创性,而非工艺和功能性。Claude 在工艺和功能性方面已经默认表现出色,因为所需的技术能力往往自然而然地体现在模型中。但在设计和原创性方面,Claude 的输出往往平淡无奇。评估标准明确惩罚了高度通用的"AI 垃圾"模式,通过更重视设计和原创性,推动模型进行更具美学风险的尝试。

使用带有详细分数分解的少量示例来校准评估器,从而确保Evaluator的判断与工程师的偏好一致,并减少了迭代过程中的分数漂移。

anthropic的工程师在 Claude Agent SDK 上构建了这个循环,这使得整个编排过程保持简洁明了。一个generator agent首先根据用户提示创建 HTML/CSS/JS 前端。他们为评估器配备了 Playwright MCP,使其能够在评分每个标准并撰写详细评论之前,直接与实时页面进行交互。在实际操作中,评估器会自主浏览页面,截取屏幕截图并仔细研究实现细节,然后才生成评估报告。这些反馈会作为下一轮迭代的输入,回流给Generator。每代设计运行 5 到 15 次迭代,每次迭代通常都会推动Generator朝着更独特的方向发展,以响应评估器的批评。由于评估器是主动浏览页面,而不是对静态截图进行评分,每个周期还需要额外的时间。完整的运行过程可能长达四个小时。工程师明确指示generator在每次评估后做出战略决策:如果评分趋势良好,则继续优化当前方向;如果当前方法效果不佳,则转向完全不同的美学风格。

实验发现:

  1. 在多次运行中,Evaluator的判断随着迭代次数增加而提升,随后趋于稳定,但仍存在改进空间。部分生成结果实现了渐进式优化,而另一些则在迭代间发生了显著的审美转向。

  2. evaluator产出的评估意见(对generator的引导)以工程师完全预料之外的方式引导Generator。诸如"最佳设计应达到博物馆级品质"这类表述,将设计推向与上述量化标准趋同的方向,这表明与标准相关联的prompt直接塑造了输出结果的特性。

  3. 虽然评分总体上随迭代次数提升,但变化规律并非总是简单的线性增长。后期版本整体表现更优,但他们经常发现某些中间迭代版本比最终版本更符合偏好。随着迭代轮次增加,实现复杂度也呈上升趋势,Generator会根据Evaluator的反馈尝试更具特色和激进的解决方案。即使在首次迭代中,输出结果也明显优于完全无提示的基线水平,这表明评估标准及其相关表述本身就能引导模型摆脱通用默认模式,无需Evaluator反馈即可实现初步优化。

典型示例

工程师提示模型为一家荷兰艺术博物馆创建网站。到第九次迭代时,它已经为一个虚构的博物馆制作了一个简洁、深色主题的着陆页。页面视觉上很精致,但基本符合工程师的预期。然后,在第十轮中,它完全抛弃了之前的思路,将网站重新构想为一种空间体验:一个用 CSS 透视渲染的、带有棋盘格地板的 3D 房间,艺术品以自由形式悬挂在墙上,画廊房间之间通过门道导航,而不是滚动或点击。这是一种他们之前从未在单次生成中见过的创造性飞跃。

3.扩展到全栈编码

基于这些发现,工程师将这种受 GAN 启发的模式应用于全栈开发。将Generator-Evaluator这种循环范式泛化到软件开发生命周期中,比如其中代码审查和 QA 扮演着与设计评估器相同的结构性角色。

4.架构设计

在这项工作中,工程师以原始框架为基础构建了一个三智能体系统,该系统包含以下智能体角色:

  • 计划者 (Planner): 它只需接收一句至四句(1-4)的简单提示,就能将其扩展为一份完整的产品规格书。 工程师对该智能体的提示指令是:在规划范围上要具备前瞻性,且需聚焦产品业务上下文(Product Context)和高层技术设计,而非深入的技术实现细节。做出这一强调的原因在于,若规划器试图提前指定具体的技术细节并出现偏差,规格书中的错误将产生级联效应,传导至下游的执行环节。 更为合理的策略是,仅约束智能体最终需要产出的交付物(Deliverables),让它们在执行过程中自主探索具体的实现路径。同时,我也要求该智能体寻找机会,将 AI 功能深度融入(Weave into)产品规格书中。(详见文末附录中的示例。)
  • 生成器 (Generator): 早期测试工具采用的 "一次只开发一个功能" 的方法,在范围管理上效果很好。工程师在此处沿用了类似模式,指示生成器以迭代冲刺(Sprint)的方式工作,从规格说明书中每次选取一个功能进行开发。 每次迭代均基于 React + Vite + FastAPI + SQLite(后续替换为 PostgreSQL) 技术栈实现应用功能;并要求生成器在每次迭代结束后先进行自我评估,再交付给质量测试(QA)环节。
  • 评估器 (Evaluator): 早期测试工具生成的应用往往看起来效果不错,但实际使用时仍会存在真实 bug。为了发现这些问题,评估器使用 Playwright MCP,像真实用户一样对运行中的应用进行点击交互测试,验证 UI 功能、API 接口以及数据库状态。随后,评估器会根据发现的 bug,以及参照前端实验设计的一套评估标准,对每一轮迭代(sprint)进行打分。这套标准在这里被扩展为覆盖:产品深度、功能完整性、视觉设计、代码质量四个维度。每个评估项都设有严格阈值,只要任意一项不达标,本轮迭代即判定为失败,并且生成器会收到关于问题所在的详细反馈。

在每一轮开发冲刺开始前,生成器(Generator)与评估器(Evaluator)会协商一份冲刺契约(Sprint Contract):在编写任何代码之前,先就当前任务块的 **“完成标准(Definition of Done)”达成一致。 之所以设计这一步,是因为产品规格说明书是有意设计为高层级、非细节化的,我需要一个环节来弥合用户故事与可测试实现之间的差距。 由生成器提出它要构建的内容以及成功验证方式,再由评估器审核该提案,确保生成器正在构建正确的功能。二者会反复迭代,直至达成共识。

agent之间的消息传递方法: 通过文件进行,一个agent会写入文件,另一个agent读取该文件并通过同一文件或新建文件作出回应,再由前一个agent依次读取。随后,Generator依据已达成共识的契约进行构建,再将成果移交至质量保证环节。这种方式既确保工作忠实于规格要求,又避免了过早过度细化实施方案。

5.运行harness框架

提示词:

创建一个 2D 复古游戏制作工具,功能包括关卡编辑器、精灵编辑器、实体行为系统和可玩的测试模式。

下表显示了测试框架类型、运行时长和总成本。

框架时长成本
单次 (Solo)20 分钟$9
完整框架 (Full harness)6 小时$200

harness的成本高出 20 倍以上,但输出质量的明显较优。

solo run(单次运行):

  • 视觉与布局:初始应用看似符合预期,但实际体验粗糙。界面布局浪费空间,固定高度的面板导致大部分视口留白。

  • 用户体验(UX):工作流极其僵化。系统要求用户必须先创建精灵(Sprites)和实体(Entities)才能填充关卡,但 UI 界面上没有任何引导提示。

  • 核心功能表现: 产品处于不可用状态。虽然实体能显示在屏幕上,但完全不响应用户的输入。代码层面的检查显示,实体定义与游戏运行时(Runtime)之间的连接是断开的,且没有明显的错误提示。

full harness(完成harness运行):

  • 项目规划与扩展: Harness 中的“规划器(Planner)”将一句话的提示词扩展为分布在 10 个冲刺周期(Sprint)中的 16 项功能规范。除了核心功能,还自主添加了动画系统、行为模板、音效音乐、AI 辅助设计以及分享链接等高级特性。

  • 视觉与界面: 界面明显更加精致流畅,具有一致的视觉识别度。充分利用了屏幕视口,面板尺寸合理;精灵编辑器功能更丰富(包括清晰的工具调色板、优秀的拾色器和实用的缩放控制)。

  • 核心功能表现: 游戏真正可玩。角色可以移动并进行游戏互动。内置了 AI 集成,可以通过提示词加快部分游戏生成流程。

  • 质量保证(QA)机制: 生成器和评估器之间存在“合约谈判”。评估器(Evaluator)通过 Playwright 执行自动化测试,精准找出了多个代码级 Bug(如填充工具仅放置端点、快捷键逻辑判断缺失、API 路由解析冲突等)并强制修复。

  • 存在的瑕疵: 虽然功能完整,但物理引擎有粗糙感(跳跃会重叠),AI 构建的关卡有死角(无法跳过的墙壁);工作流缺乏引导的“产品直觉”问题依然存在;深层嵌套的隐藏 Bug 偶尔会漏掉。

结论:

1.方法有效: 工程化结构弥补了单次生成的不足: 单次运行容易产生代码断层(如 UI 与后端的失联),而 Harness 通过规划器、冲刺切分和合约机制,确保了大型项目的代码连贯性和功能完整性。实现了从“残次品”到“可用且功能丰富的产品”的质变。

翻阅日志时,可以清楚地看到Evaluator始终确保实现与规范保持一致。每个冲刺阶段,它都会逐条检查冲刺合约的测试标准,并通过 Playwright 对运行中的应用进行测试,一旦发现与预期行为不符之处便会提交缺陷报告。这些合约条款非常细致——仅冲刺 3 就包含了 27 项针对关卡编辑器的标准——而Evaluator的发现也足够具体,无需额外调查即可直接处理。

下表展示了Evaluator识别出的若干问题示例:

标准评估器发现
矩形填充工具允许通过点击拖动,用选定的图块填充一个矩形区域失败 — 工具仅在拖动起点/终点放置图块,而不是填充区域。fillRectangle 函数存在,但未能在 mouseUp 时正确触发。
用户可以选择并删除已放置的实体生成点失败LevelEditor.tsx:892 处的删除键处理程序要求同时设置 selectionselectedEntityId,但点击实体仅设置了 selectedEntityId。条件应为 `selection
用户可以通过 API 重新排序动画帧失败PUT /frames/reorder 路由定义在 /{frame_id} 路由之后。FastAPI 将 'reorder' 匹配为 frame_id 整数并返回 422:"无法将字符串解析为整数。"

2:harness范式是需要不断调整

这个系统开始时是一个糟糕的 QA agent。在早期运行中,工程师观察到它识别出合理的问题,然后说服自己认为这些问题无关紧要,最终仍然批准了工作。

它还倾向于进行表面测试,而不是深入探究边界情况,因此更细微的漏洞常常被忽略。

调整循环包括阅读评估器的日志,找出其判断与我的判断不一致的例子,并更新 QA 提示以解决这些问题。 经过几轮这样的开发循环后,评估器的评分方式才变得合理。 即便如此,测试框架的输出仍然显示了模型 QA 能力的局限性:小的布局问题、某些地方感觉不直观的交互,以及评估器未充分测试的更深层嵌套功能中未发现的漏洞。

因此,还有更多的验证空间可以挖掘。但与solo run相比,当时应用程序的核心功能根本无法工作,改进的效果是显而易见的。

6.那么如何去迭代harness呢?

初版 Harness 虽然有效,但存在臃肿、运行缓慢且成本高昂的问题。因此,下一步的合理目标是在不牺牲性能的前提下对其进行简化。

Harness 设计的核心原则: Harness 中的每一个组件,本质上都代表了对“模型自身能力不足”的一种假设。由于模型在不断发展,这些假设可能会过时或出错,因此必须对其进行压力测试。构建者应始终遵循 “寻找最简单的解决方案,仅在必要时才增加复杂性” 的原则。

1. 科学的迭代方法论: 激进地大面积删减组件会导致无法辨别哪些部分是真正的“承重墙”。在首次简化尝试中,工程师大幅削减了测试框架并尝试了几个创新想法,但未能复现原始版本的性能。更有效的方法是采取控制变量的系统性方法:每次仅移除一个组件,并仔细评估该操作对最终输出结果的具体影响。

2. 模型升级推动 Harness 瘦身: 底层模型的升级(如 Opus 4.6)是精简 Harness 的重要动力。当新模型在任务规划、长任务执行、大规模代码库处理、自我纠错以及长上下文检索等能力上获得显著提升时,原本为了弥补旧模型缺陷而搭建的复杂“脚手架(Scaffolding)”就可以被拆除。

7.anthropic在迭代过程的经验

拆除“冲刺(Sprint)”脚手架:能力替代结构

过去的 Harness 需要将大任务硬性拆解为多个冲刺周期(Sprint),是因为旧模型(如 4.5)无法在长上下文中保持连贯性。而随着新模型(如 Opus 4.6)原生处理复杂任务的能力提升,这种强制分解机制变得多余,可以直接移除,让模型全局统筹。

保留“规划器(Planner)”:对抗模型的“偷工减料”

尽管拆除了冲刺机制,但负责前置设计的规划器绝对不能省。实验证明,如果没有规划器给出的清晰规范(Spec),直接让模型写代码,模型会出现“范围缩水(Under-scoped)”的现象——它会本能地选择最简单的实现路径,导致最终产品的功能丰富度大幅下降。

“评估器(Evaluator)”的边界效用转移(核心内容,相当有深度的理解)

评估器的存在不是非黑即白的,它的价值取决于“任务难度”与“模型能力”之间的相对位置。

模型变强带来的“开销陷阱”: 旧模型写十行代码可能错三行,评估器抓虫的收益极高;但新模型已经能原生写对这些代码了,此时如果再让评估器去逐行测试,就变成了纯粹的成本浪费和不必要的开销(Overhead)。

刀刃向外: 评估器被调整为只在任务结束时进行单次测试。只有当任务难度触及当前模型能力的“边缘(Edge)”时,评估器才能发挥真正的杠杆价值。它是一笔需要精准计算的经济账。

提示词工程(Prompting)填补训练数据的时效性空白

在引导模型为应用构建内置的 AI 功能(如让 Agent 自行调用工具)时,Harness 遇到了模型训练数据的盲区——因为这类 Agent 技术太新了,导致 Claude 底层权重中的相关知识很单薄。这里的经验是:对于模型尚不熟悉的新兴技术范式,可以通过在 Harness 中加强特定提示词的迭代调优来强行“补课”。

8.harness结构更新后的结果

为了测试更新后的测试框架,工程师使用了以下提示来生成一个数字音频工作站(DAW),这是一个用于作曲、录音和混音的音乐制作程序: “使用 Web Audio API 在浏览器中构建功能齐全的数字音频工作站。”

运行过程仍然漫长且昂贵,花费了大约 4 个小时和 124 美元的 token 成本。

大部分时间花在了构建器上,它连贯运行了两个多小时,由于基模的提升,没有采用 Opus 4.5 所需的冲刺分解(任务拆分)。

智能体 & 阶段时长成本
计划者 (Planner)4.7 分钟$0.46
构建 (第1轮)2 小时 7 分钟$71.08
QA (第1轮)8.8 分钟$3.24
构建 (第2轮)1 小时 2 分钟$36.89
QA (第2轮)6.8 分钟$3.09
构建 (第3轮)10.9 分钟$5.88
QA (第3轮)9.6 分钟$4.06
整体 V2 框架3 小时 50 分钟$124.70

与之前的测试框架类似,Planner将单行提示扩展为完整规范。从日志中可以看出,生成模型在规划应用程序和代理设计、连接代理以及移交 QA 前进行测试方面都表现出色。

在generator第一轮反馈中,它指出:

这是一款功能强大的应用程序,具有出色的设计保真度、扎实的 AI 代理和良好的后端。主要不足之处在于功能完整性——虽然该应用看起来令人印象深刻,AI 集成也运行良好,但几个核心数字音频工作站功能仅为展示性质,缺乏交互深度:片段无法在时间轴上拖拽/移动,没有乐器 UI 面板(合成器旋钮、鼓垫),也没有视觉效果编辑器(均衡器曲线、压缩器仪表)。这些并非边缘情况——它们是使数字音频工作站可用的核心交互功能,而规格说明中已明确要求包含这些功能。

在其第二轮反馈中,它再次抓住了几个功能上的差距:

剩余漏洞:

  • 音频录制仍仅为存根(按钮可以切换但无法捕获麦克风)
  • 未实现通过拖动边缘调整剪辑大小和剪辑分割
  • 效果可视化是数字滑块,不是图形(没有 EQ 曲线)

Generator在自主运行时仍可能遗漏细节或功能存缺,而质量检测环节通过发现这些最终阶段问题供Generator修正,依然发挥着重要作用。

根据提示,工程师期待的是一个能创作旋律、和声与鼓点节奏,将其编排成曲,并在过程中获得集成智能体辅助的程序。

这款应用远非专业的音乐制作软件,智能体的歌曲创作能力显然还有很大提升空间。此外,Claude实际上不具备音频理解能力,这使得质量评估反馈在音乐品味方面的效果大打折扣。

但最终的应用程序具备了功能性音乐制作程序的所有核心部件:一个可运行在浏览器中的编曲视图、混音器和走带控制。除此之外,Claude 能够完全通过提示词拼接出一个简短的歌曲片段:智能体设置了速度和调号,铺下了旋律,构建了鼓轨,调整了混音器音量,并添加了混响。用于歌曲创作的核心原语都存在,智能体可以自主驱动它们,使用工具端到端地创建一个简单的作品。你可能会说它还不够完美——但它正在达到那个水平。

9.展望

随着模型性能持续提升,我们可以大致预期它们能够处理更长时间、更复杂的任务。在某些情况下,这意味着围绕模型构建的辅助框架会逐渐变得不那么重要,开发者可以等待下一代模型出现,看着某些问题自行解决。另一方面,模型越强大,就越有空间开发出能够完成超出模型基础能力的复杂任务的辅助系统。

基于这些思考,这项工作中有些经验值得延续。始终建议的做法是:针对您构建的模型进行实验,在实际问题上分析其运行轨迹,并调整性能以实现预期目标。处理更复杂的任务时,有时可以通过任务分解并为问题各方面配置专用智能体来提升空间。当新模型发布时,通常应重新审视评估框架,移除不再影响性能的冗余部分,并新增组件以实现以往难以达到的更强能力。

从这项工作中,工程师们坚信随着模型性能的提升,有趣的应用组合空间并不会缩小。相反,它会不断迁移,而 AI 工程师的有趣任务正是持续发掘下一个新颖的组合方式。

Managed Agents:实现大脑与执行器的解耦

在之前的工作中,工程师们发现 Claude Sonnet 4.5 会在感知到上下文限制接近时过早地结束任务——这种行为有时被称为“上下文焦虑”。他们通过在控制框架中添加上下文重置来解决这个问题。但当他们在 Claude Opus 4.5 上使用相同的控制框架时,他们发现这种行为已经消失了。重置机制变成了多余的负担。 随着基模能力的提升,对应的harness框架也需要进行调整,正如上面展望所说

  • 随着模型性能的提升,有趣的应用组合空间并不会缩小。相反,它会不断迁移,而 AI 工程师的有趣任务正是持续发掘下一个新颖的组合方式。

核心问题:Harness 具有“保质期”(基模提升带来的假设快速折旧)

Harness 的本质,是开发者为了弥补当前大模型能力的不足(如长文本处理弱、逻辑容易跑偏)而编写的“补丁”和假设。

但是模型进化的速度太快了。例如,在 Sonnet 4.5 时代,模型会有“上下文焦虑”(怕超出字数而草草收尾),开发者为此在 Harness 里写了“上下文重置”机制。但到了 Opus 4.5,模型自己克服了这个毛病,原来精心写的 Harness 代码瞬间变成了拖慢运行的“累赘(Dead weight)”。开发者陷入了必须频繁重写 Harness 的泥潭。

  1. 解决方法:借鉴操作系统的“抽象化”哲学 为了解决“系统总是为了适应新事物而不断重构”的老大难问题,Anthropic 借鉴了几十年前操作系统的设计智慧:虚拟化与抽象(Virtualization into abstractions)。

就像无论计算机底层插着的是 1970 年代的旧磁盘还是最新的固态硬盘(SSD),程序员在写代码时调用的 read() 读取指令永远是不变的。顶层接口保持绝对稳定,底层实现自由更迭。

  1. anthropic是怎么做的? Anthropic 将这种“系统级抽象”打包成了一个名为 Managed Agents 的云端托管服务。

核心:开发者通过极少数、极其稳定的 API 接口来运行长周期 Agent。至于底层“如何根据最新的 Claude 模型去优化 Harness 循环”这些脏活累活,全部由平台在后台静默完成。

大家可以借鉴这种分离的思想,应用在自己的agent中,不仅是为了harness的迭代,也可以帮助选定基模,anthropic只面对他们自家的模型,而我们在做实际任务中,面对不同模型需要做出选择

  1. 具体实现 为了让底层实现可以像换硬盘一样随时被替换(Swap),anthropic将复杂的 Agent 系统严格虚拟化为三个独立且解耦的组件:

Session(会话):系统的记忆体。记录所有已发生事件的“仅追加日志(append-only log)”。

Harness(基础设施循环):系统的路由器。负责调用 Claude 大脑,并将 Claude 发出的“工具调用请求”精准分发给对应的外部设施。

Sandbox(沙盒):系统的手脚。提供一个安全、隔离的执行环境,供 Claude 运行代码和修改文件。 Decouple.png

anthropic的优化过程

  1. 单体架构的“宠物(Pet)”陷阱 在最初的设计中,Anthropic 将 Session(状态日志)、Harness(控制循环)和 Sandbox(代码执行环境)全部塞进了一个容器里。

表面优势:文件修改直接走系统调用(syscalls),速度快,没有跨服务的网络开销。

致命缺陷:系统变成了一个碰不得的“宠物”。如果容器卡死,整个会话数据就会丢失;因为容器内混杂了用户隐私数据,工程师甚至无法登录进去排查 Bug;当企业客户要求在私有网络(VPC)中运行 Agent 时,这种强耦合架构导致部署极其困难。

  1. 解法:解耦“大脑”与“手脚” 为了解决上述问题,他们将系统进行了彻底的解耦,各自独立交互,互不依赖:

“大脑”(Brain):Claude 模型本身 + Harness(负责路由和调度)。

“手脚”(Hands):Sandbox(沙盒)和各种外部工具,专门负责执行动作。

“记忆”(Session):独立于两者的外部事件日志。

  1. 实现“牛群(Cattle)”化的高可用与容灾

通过解耦,系统中最脆弱的部分变成了可以随时丢弃和替换的“牛群”(即无状态化):

Harness 不再住在沙盒里:它通过 API(execute)被调用。如果沙盒崩溃,Harness 只会将其视为一次“工具调用失败”并告诉 Claude,随后系统会迅速拉起一个新沙盒继续工作,完全不需要人工干预。

Harness 的崩溃恢复:因为所有运行日志(Session)都存放在外部,Harness 本身也变成了无状态组件。如果 Harness 发生崩溃,系统可以直接重启一个新实例,读取外部日志,从上一次中断的地方无缝续跑。

Decouple_eg.png

  1. Session(会话 / 系统的记忆区)

    • 接口定义:它只需要能通过 getSession 读取历史,或者通过 emitEvent 写入新事件。
    • 含义:系统根本不在乎你的"记忆"存在哪里。只要它是一个"仅追加日志(append-only log)",无论你用的是企业级的 Postgres 数据库、轻量级的 SQLite,还是哪怕最简单的内存数组(in-memory array),都能完美充当 Session。
  2. Orchestration(调度编排 / 系统的唤醒者)

    • 接口定义:只有一个功能:wake(session_id)(唤醒某个会话)。
    • 含义:当 Harness崩溃或者需要重试时,需要有人把它叫醒。这个"唤醒者"可以是定时任务(cron job)、消息队列消费者,甚至是简单的 while 循环。它体现了我们在上一步分析的"Harness 崩溃恢复"机制。
  3. Harness(护栏与循环 / 系统的路由中枢)

    • 接口定义:产出效果(yield Effect)并返回结果。
    • 含义:Harness 不再是一个臃肿的单体程序,它被抽象成了一个纯粹的逻辑循环。它只负责思考下一步该干嘛(产生 Effect),并把进度写回到 Session 中。
  4. Sandbox(沙盒 / 系统的执行手脚)

    • 接口定义:提供资源(provision)并执行指令(execute)。
    • 含义:这正是"把服务器从宠物变成牛群"的具体体现!Harness 不管代码在哪里跑,它只管下达 execute 命令。至于底层实现,它可以是你电脑上的一个本地进程,也可以是云端的一个远程 Docker 容器。容器死了?重新 provision 一个就行。
  5. Resources(资源 / 系统的物资库)

    • 接口定义:知道从哪里拉取数据(source_ref)并挂载到哪里(mount_path)。
    • 深层含义:沙盒在启动时需要加载代码或文件。不管文件是存在 Google Cloud Storage、AWS S3 还是远端的 Git 仓库,系统统一将其抽象为一种可持久化挂载的"资源"。
  6. Tools(工具 / 系统的技能包)

    • 接口定义:只需要定义工具的名字、描述和输入格式(input_schema)。
    • 深层含义:任何能力只要能被描述为一个特定的"输入参数",就可以被 Agent 调用。它可以是 MCP(模型上下文协议)服务器,也可以是你自己写的某个 API 小脚本。
  7. 建立物理级的安全护栏(防御 Prompt 注入) 这是重构带来的最大安全收益。在旧架构下,Claude 生成的不可信代码与系统的敏感凭证(Tokens)处在同一个容器内。黑客只需通过“提示词注入(Prompt Injection)”骗 Claude 读取环境变量,就能盗取 Token 并生成恶意 Agent。

鉴权外部化:新架构下,敏感凭证永远不会进入执行代码的 Sandbox,Harness 也碰不到这些凭证。

代理模式:对于 Git 等工具,访问令牌在沙盒初始化时就直接绑定到了底层(比如配进 git remote),Agent 只能用,但看不到 Token 字符串。对于自定义工具,系统引入了 MCP(模型上下文协议)代理和安全金库(Vault)。Agent 只负责调用代理,由代理去金库取钥匙开门。这种物理隔离从根本上锁死了提示词注入窃取凭证的攻击路径。

会话并非 Claude 的上下文窗口

长时程任务常常超出 Claude 上下文窗口的长度,而解决这一问题的标准方法都涉及关于保留哪些内容的不可逆决策。我们在先前关于上下文工程的研究中探讨过这些技术。例如,压缩技术允许 Claude 保存其上下文窗口的摘要,而记忆工具则让 Claude 将上下文写入文件,从而实现跨会话学习。这可以与上下文修剪技术结合使用,后者会选择性地移除某些标记,例如旧的工具结果或思考区块。

但选择性保留或丢弃上下文的不可逆决策可能导致任务失败。我们很难预知未来轮次需要哪些标记。如果消息经过压缩步骤处理,控制框架会从 Claude 的上下文窗口中移除已压缩的消息,这些消息只有在被存储的情况下才能恢复。先前的研究探索了通过将上下文存储为存在于上下文窗口之外的对象来解决这一问题的方法。例如,上下文可以成为 REPL 中的一个对象,LLM 通过编写代码来过滤或切片它以进行程序化访问。

会话提供了同样的优势,它作为一个上下文对象存在于 Claude 的上下文窗口之外。但上下文并非存储在沙盒或 REPL 中,而是持久保存在会话日志里。接口 getEvents(), 允许大脑通过选择事件流的位置切片来查询上下文。该接口可以灵活使用,让大脑能够从上次停止阅读的地方继续,回溯到特定时刻之前的几个事件以查看前因,或在执行特定操作前重新阅读上下文。

任何获取到的事件在传递给 Claude 上下文窗口之前,也可以在控制框架中进行转换。这些转换可以是控制框架编码的任何内容,包括为实现高提示缓存命中率而进行的上下文组织以及上下文工程。我们将会话中可恢复的上下文存储与控制框架中任意的上下文管理分离开来,因为我们无法预测未来模型将需要什么样的具体上下文工程。接口将这种上下文管理推入控制框架,仅保证会话的持久性和可查询性。

session.png

Many brains, many hands

  1. Many brains :让成千上万个 Agent(大脑)同时高效且低成本地运行。

打破网络隔离墙(VPC 部署自由): 以前大脑和手脚绑在一个容器里,企业客户想把 Agent 连到他们内网,Anthropic 就必须搞复杂的网络打通。现在大脑脱离了容器,它只是云端的一个无状态逻辑流,可以纯通过 API 远程调用客户内网的“手脚”,部署变得极其轻量。

消灭“首字节延迟”(大幅降低 TTFT): 这是最显著的性能收益。过去,用户发一个任务,系统必须先去拉取代码仓库、配置环境、启动厚重的容器,然后 Claude 才能说出第一句话(这叫 TTFT,首字节响应时间)。现在,大脑和手脚解耦了,采用“按需懒加载(Lazy Loading)”模式。如果 Claude 一开始只需要做规划(不需要跑代码),它立刻就能开始思考并输出响应。

数据结果: 因为避免了不必要的容器冷启动,系统的 TTFT 中位数(p50)下降了 60%,长尾延迟(p95)更是暴降了 90% 以上。扩展大脑现在只意味着启动更多轻量级的 Harness,而不再是启动笨重的虚拟机。

  1. Many hands :每个聪明的大脑,如何同时操控无数个不同形态的外部工具和环境。

从“单体劳工”到“调度中心”: 早期大模型不够聪明,只能在一个固定的沙盒环境里干活。但现在的 Claude 足够聪明,它能理解并区分不同的执行环境(比如知道代码要在云端沙盒跑,数据库查询要走客户内网的 MCP 接口)。

绝对的环境不可知论(Agnostic): 所有的“手脚”都被统一抽象成了一个极其简单的 API 接口:execute(name, input) → string。这意味着,对于大脑来说,它根本不关心对面是一个 Docker 容器、一部真实的手机,还是一个用来玩游戏的老式模拟器。只要符合接口,万物皆可为“手脚”。

极强的容错与资源共享: 以前容器一崩,大脑连同所有工具状态全毁。现在,左手(比如某个 API 工具)断了,大脑完全不受影响,甚至可以让系统重新接一只手。更科幻的是,因为解耦,不同的 Agent 大脑之间甚至可以互相传递“手脚”(即共享某个沙盒或工具的控制权)。

“Many brains, many hands” 本质上是 Agent 基础设施从“单体应用时代(Monolithic)”走向了“微服务时代(Microservices)”。

将大脑与执行器解耦后,每个执行器都成为工具化的接口:输入名称和参数,返回字符串结果。这种接口设计支持任何自定义工具、MCP 服务器以及我们自研的工具。执行框架无需关心沙盒环境是容器、手机还是宝可梦模拟器。由于执行器不与特定大脑绑定,不同大脑之间可以互相传递执行器控制权。 manybh.png

结论

我们面临的挑战是一个老生常谈的问题:如何为“尚未构想出的程序”设计一个系统。操作系统之所以能历经数十年不衰,是因为它将硬件虚拟化为足够通用的抽象概念,从而能够兼容当时还不存在的程序。在 Managed Agents(托管智能体)上,我们致力于设计这样一个系统:它能够包容未来围绕 Claude 出现的任何新型 Harness、沙盒或其他组件。

Managed Agents 本质上是一个秉承同样精神的“元基础设施(Meta-harness)”。它不对 Claude 未来可能需要的特定 Harness 抱有成见(不强制绑定任何具体实现)。相反,它是一个拥有通用接口的系统,允许接入多种不同的 Harness。例如,Claude Code 是一个非常优秀的 Harness,我们在各种任务中广泛使用;此外,我们之前的研究也表明,针对特定任务的 Agent Harness 在垂直领域表现卓越。Managed Agents 能够兼容所有这些不同的 Harness,并随着时间的推移不断匹配 Claude 日益增长的智能。

“元基础设施(Meta-harness)”的设计意味着,我们对围绕 Claude 构建的接口有极其明确的坚持(opinionated):我们预期 Claude 一定需要操纵状态的能力(即 Session/会话),以及执行计算的能力(即 Sandbox/沙盒)。我们也预期 Claude 肯定需要能够扩展到“多个大脑(多 Agent)”和“多双手脚(多环境/工具)”的能力。我们所设计的这些接口,正是为了确保上述能力能在很长的时间跨度内安全、可靠地运行。但是,我们对 Claude 未来究竟需要多少个“大脑”或“手脚”,以及它们位于何处,不做任何预设和假设。

通过harness工程改进Deep Agents(langchain)

Harness Engineering的目标

Harness工程的目标,是将模型天生参差不齐的智能,塑造成能处理我们所关心任务的形态。它是一门关于系统的学问,我们需要围绕模型构建工具,以优化如任务性能、Token 效率、延迟等目标。设计决策包含了系统提示词、工具选择以及执行流程。

但是,如何修改框架来改进你的智能体(Agent)呢?

在 LangChain,他们使用 追踪(Traces) 来大规模地了解智能体的失败模式。

如今的模型大多是黑盒,其内部机制难以解释。但我们可以在文本空间中看到它们的输入与输出,并将其应用在我们的改进循环中。

他们采用了一个简单的方法,将 deepagents-cli(他们的编程智能体)在 Terminal Bench 2.0 上的表现,迭代地提升了 13.7 分,从 52.8 分提高到了 66.5 分。在这个过程中,他们仅仅微调了控制框架,而保持模型固定不变(使用了 gpt-5.2-codex)。 langchainboard.png

环境配置和harness的构件

实验设置与控制框架上的构件 他们使用了 Terminal Bench 2.0,这是目前用于评估智能体编程(agentic coding)能力的标准基准测试。它包含了 89 个任务,跨越机器学习、代码调试和生物学等领域。他们使用 Harbor 来编排测试的运行。它负责启动沙箱环境(Daytona),与他们的智能体循环(agent loop)进行交互,并执行验证与打分。 智能体的每一个动作都会被存储在 LangSmith 中。它还包含了延迟、Token 消耗量以及成本等指标。

可调整的构件 一个智能体的控制框架有很多“旋钮”(可调配置):系统提示词、工具、钩子/中间件、技能、子智能体委派、记忆系统等等。他们刻意压缩了优化的空间,将重点聚焦在三个方面:系统提示词(System Prompt)、工具(Tools)以及中间件(Middleware,这是他们对围绕模型与工具调用的钩子机制的称呼)。 他们从默认的提示词和标准的“工具+中间件”组合开始。在搭配 GPT-5.2-Codex 的情况下,得分为 52.8%。这是一个很扎实的成绩,刚好排在目前排行榜的前 30 名之外,但仍有提升的空间。

Trace Analyzer Skill

未来追踪分析能够重复进行,因此将其转化为一项智能体技能。这成为他们分析多次运行中的错误并改进测试框架的配方。流程如下:

  • 从 LangSmith 获取实验追踪记录
  • 并行启动错误分析代理 → 主代理综合发现结果与改进建议
  • 汇总反馈并对约束系统进行针对性调整。

这种方法类似于提升算法,专注于修正先前运行中的错误。在第三步中,人工参与(虽非必需)对验证和讨论拟议的修改非常有帮助。过度拟合特定任务的修改不利于泛化,并可能导致其他任务出现性能倒退。 trace_skills.png

提升智能体性能的关键因素

自动化轨迹分析使他们能够调试智能体出错的地方。问题包括推理错误、未遵循任务指令、缺少测试和验证、超时等。

自我验证使智能体能够在单次运行中通过反馈实现自我改进。然而,它们并没有自然倾向进入这种构建-验证循环。

最常见的失败模式是:智能体编写了一个解决方案,重新阅读自己的代码,确认看起来没问题,然后就停止了。测试是自主智能体编码的关键部分。它有助于测试整体正确性,同时为智能体提供信号,以便进行逐步优化

他们在系统提示中添加了关于如何解决问题的指导

  • 规划与发现: 阅读任务,扫描代码库,根据任务规范以及如何验证解决方案来制定初步计划。
  • 构建: 在实施计划时需考虑验证环节。若测试用例尚未建立,应创建测试并覆盖正常流程与边界情况。
  • 验证: 运行测试,仔细阅读完整输出,对照任务要求进行比对(而非对照您自己的代码)。
  • 修复: 分析所有错误,重新审视原始规范,并解决问题。

他们特别重视测试,因为它驱动着每一次迭代中的变更。他们发现,除了提示之外,确定性的上下文注入有助于智能体验证其工作。他们使用一种 PreCompletionChecklistMiddleware 机制,在智能体退出前拦截它,并提醒其根据任务规范运行验证流程。这类似于拉尔夫·维格姆循环,即通过钩子强制智能体在退出时继续执行,他们将其用于验证目的。

self-verification-loop.png

为智能体提供环境背景信息

线harness工程的一部分是为上下文工程构建良好的交付机制。终端基准任务附带目录结构、内置工具和严格的超时限制。

  • 目录上下文与工具配置:代理启动时运行 LocalContextMiddleware 来映射 cwd 及其他父级与子级目录。他们执行 bash 命令以查找如 Python 安装等工具。上下文发现与搜索容易出错,因此注入上下文可减少错误范围,并帮助代理快速适应其运行环境。
  • teaching agent编写可测试代码:智能体并不清楚其代码需要具备可测试性。他们通过提示告知它们,其工作成果将接受程序化测试的评估,类似于提交代码时的流程。例如,任务说明中提及的文件路径必须严格遵循,以确保解决方案能在自动化评分环节正常运行。强调边界情况的提示有助于智能体避免仅检查“理想路径”场景。强制模型遵循测试标准是防止“代码质量随时间滑坡”的有效策略。
  • 时间预算管理:他们引入时间预算警告机制,以促使智能体完成工作并转向验证阶段。众所周知,智能体在时间估算方面表现不佳,因此在这种环境中采用这种启发式方法很有帮助。现实世界的编程通常没有严格的时间限制,但如果不添加任何约束知识,智能体将无法在时间范围内工作。

智能体对其环境、约束条件和评估标准了解得越多,就越能自主地指导自身工作。

langchain提到:harness工程师的职责是准备并传递上下文,使智能体能够自主完成工作

鼓励智能体回退并重新审视计划

智能体一旦确定计划就可能变得短视,导致陷入"厄运循环",即对同一错误方法进行微小调整(在某些轨迹中重复 10 次以上)。

他们使用一个 LoopDetectionMiddleware ,通过工具调用钩子跟踪每个文件的编辑次数。在对同一文件进行 N 次编辑后,它会添加诸如“……考虑重新审视你的方法”等上下文。这有助于智能体从死循环中恢复,尽管如果模型认为自己是正确的,它仍可能继续沿着相同的路径前进。

重要说明。这是一种围绕当前感知到的模型问题而设计的启发式方法。随着模型的改进,这些防护措施可能将不再必要,但在当下有助于智能体正确且自主地执行任务。

如何分配推理资源(各agent使用什么推理模式-low-middle-high)

推理模型能够自主运行数小时,因此他们必须决定在每个子任务上投入多少计算资源。虽然可以为每项任务分配最大推理预算,但大多数工作都能通过优化推理计算开销而获益。

终端基准超时限制带来了一种权衡。更多的推理有助于智能体评估每个步骤,但可能消耗更多token/时间。 gpt-5.2-codex 提供四种推理模式: low 、 medium 、 high 和 xhigh 。

他们发现,推理有助于规划以全面理解问题,某些终端基准任务难度极高。良好的规划能帮助更快地找到可行的解决方案。

后期验证也受益于更多推理,以捕捉错误并提交解决方案。作为一种启发式方法,他们选择 xhigh-high-xhigh 的“推理三明治”作为基准。 the-reasoning-sandwich.png在规划和验证上投入更多推理计算资源 仅在 xhigh 运行时,由于智能体超时问题,在 53.9% 得分较低,甚至不如high:63.6%的表现。在不同推理预算分配下的试验运行中未发现显著差异,因此他们坚持原有方法,最终将得分提升至 66.5% 模型自然采用的方法是自适应推理,这在 Claude 和 Gemini 模型中可见,模型自行决定在推理上投入多少计算资源。 在多模型框架中,平衡推理预算可以表现为使用大型模型进行规划,然后交由小型模型执行实现。

构建Agent Harnesses的实用技巧

智能体的设计空间广阔。以下是langchain从实验和构建深度智能体过程中总结出的一些通用原则。

  • 为智能体进行上下文工程。 上下文组装对当今的智能体而言仍然困难重重,尤其是在未知环境中。通过引入包含目录结构、可用工具、编码最佳实践和问题解决策略等上下文信息来引导模型,有助于减少因搜索不当和规划中可避免错误所导致的失误面。

  • 帮助智能体自我验证其工作。 模型往往倾向于其首个看似合理的解决方案。通过运行测试和优化解决方案,积极引导它们验证自身工作。这在没有人工介入的自主编码系统中尤为重要。

  • 追踪feedback。 轨迹使智能体能够自我评估和调试。重要的是要同时调试工具和推理过程(例如:模型因缺乏工具或操作说明而走上错误路径)。

  • 短期内检测并修复不良模式。 当前的模型尚不完美。约束设计者的职责是围绕现有缺陷进行设计,同时为未来更智能的模型做好规划。盲目重试和不验证工作成果就是很好的例子。这些防护措施几乎肯定会随时间推移而逐渐消失,但为了构建稳健的智能体应用,它们仍是值得尝试的有用工具。

  • 为模型定制harness。 Codex 和 Claude 的提示指南表明,不同模型需要不同的提示方式。使用早期约束框架版本对 Claude Opus 4.6 进行测试时,其得分为 59.6% ,虽然具有竞争力但不如 Codex,因为他们未对 Claude 运行相同的改进循环。许多原则具有普适性,例如良好的上下文准备和注重验证,但针对具体任务进行几轮约束框架迭代,有助于最大化智能体在各类任务中的表现。