Agent Harness Engineering

Agent Harness Engineering

@addyosmani
英语4天前 · 2026年5月09日

AI 功能

798K
3.2K
458
77
7.8K

TL;DR

Harness Engineering 将 AI 模型周围的架构视为一种动态产物。通过将每一次 Agent 的失败转化为永久的规则或工具调整,开发者能够构建出远超原始模型性能的系统。

一个编码 Agent 是模型加上围绕它构建的一切。框架工程(Harness Engineering)将这种支撑结构视为一个活的工件,每次 Agent 犯错时都会对其进行收紧。

简单来说:每当 Agent 失败时,你就设计一个永久性的解决方案,让它永远不会再犯同样的错误。

过去两年,行业一直在争论模型:哪个最聪明,哪个能写出最干净的 React,或者哪个幻觉最少。虽然这种讨论很重要,但它忽略了系统的另一半。

模型只是运行中 Agent 的一个输入。其余部分是框架:提示词、工具、上下文策略、钩子、沙箱、子 Agent、反馈循环和恢复路径,这些围绕模型构建,使其能够实际完成任务。

一个不错的模型加上优秀的框架,始终能击败一个优秀的模型加上糟糕的框架。越来越多地,最有趣的工程工作不在于选择模型,而在于设计围绕它的支撑结构。

这门学科现在有了名字。@Vtrivedy10 创造了“框架工程”这个术语,清晰地分解了框架到底是什么以及每个部分存在的原因。其他行业声音如 @dexhorthy 追踪新兴模式,HumanLayer 将 Agent 失败视为配置“技能问题”,Anthropic 的工程团队发布关于长时间运行应用设计的指南,以及 Birgitta Böckeler 探索用户端体验——所有这些都大致汇聚到同一个想法上。

这篇文章将这些线索整合在一起。

框架到底是什么?

Trivedy 的核心定义完成了大部分重活:

Agent = 模型 + 框架。如果你不是模型,你就是框架。

框架包含了模型本身之外的所有代码、配置和执行逻辑。一个原始模型不是 Agent。只有当框架为其提供状态、工具执行、反馈循环和可强制执行的约束时,它才成为 Agent。

Addy Osmani - inline image

具体来说,框架包括:

  • 系统提示词、CLAUDE.md、AGENTS.md、技能文件和子 Agent 指令。
  • 工具、技能、MCP 服务器及其技术描述。
  • 捆绑的基础设施,如文件系统、沙箱和无头浏览器。
  • 用于生成子 Agent、处理交接和路由模型的编排逻辑。
  • 用于确定性执行的钩子和中间件,如 lint 检查或上下文压缩。
  • 用于日志、追踪、成本和延迟测量的可观测性工具。

核心而言,Agent 是一个在循环中运行工具以实现目标的系统。真正的技能在于设计工具和那个循环。

虽然这代表了巨大的表面积,但这是你的表面积,而不是模型提供商的。Claude Code、Cursor、Codex、Aider 和 Cline 都是框架。底层模型可能跨平台相同,但你体验到的行为主要由框架决定。

让我们重新定义“技能问题”

当 Agent 做出荒谬的事情时,工程师们通常归咎于模型,往往将问题归档为“等待下一个版本”修复。

框架工程思维拒绝这种默认。失败通常是可理解的。如果 Agent 忽略了某个约定,将其添加到 AGENTS.md。如果它运行了破坏性命令,编写一个钩子来阻止它。如果它在 40 步任务中迷失了方向,将架构拆分为规划器和执行器。如果它总是以损坏的代码结束,在循环中接入类型检查的反向压力信号。

正如 HumanLayer 所说:“这不是模型问题。这是配置问题。”考虑性能基准:一个领先模型在现成框架中运行时,得分通常远低于同一个模型在定制的高度优化框架中运行。将模型迁移到具有更好代码库工具、更精确提示词和更强反向压力的环境中,可以释放原始设置未能发挥的能力。

当今模型理论上能做的与你实际看到它们能做的之间的差距,很大程度上是框架差距。

棘轮:每个错误都变成一条规则

框架工程中最关键的习惯是将 Agent 错误视为永久信号——而不是一次性偶然事件,重试后忘记。

如果 Agent 提交了一个带有被注释掉的测试的 PR,并且意外合并了,那就是一个输入。AGENTS.md 的下一次迭代必须声明:“永远不要注释掉测试;删除或修复它们。”下一个预提交钩子应该自动标记 diff 中的 .skip(。审查子 Agent 必须更新以阻止注释掉的测试。

约束只应在观察到实际失败时添加,并且只在有能力的模型使其冗余时移除。一个好的系统提示词中的每一行都应该追溯到特定的历史失败。

因此,框架工程是一门学科,而不是一刀切的框架。特定代码库的正确框架完全由其独特的失败历史塑造。

从行为反向设计

设计框架最有效的方法是从期望的行为开始,然后构建实现它的组件:期望的行为 → 实现它的框架设计。

框架的每个部分都必须有明确的工作。如果你不能说出某个组件存在的具体行为,就应该移除它。

Addy Osmani - inline image

文件系统和 Git —— 持久状态

文件系统是基础。模型只能操作适合其上下文窗口的内容。文件系统提供了读取数据的工作空间、卸载中间工作的地方以及多个 Agent 协调的表面。

添加 Git 提供了免费版本控制,允许 Agent 跟踪进度、分支实验和回滚错误。

Bash 和代码执行:通用工具

大多数 Agent 运行在 ReAct 循环上:推理、通过工具调用行动、观察、重复。与其为每个可能的动作预先构建工具,不如让 Agent 访问 bash,使其能够即时构建所需内容。

Agent 通常擅长 shell 命令,使 bash 和代码执行成为自主解决问题的默认策略。

沙箱和默认工具

Bash 只有在安全运行时才有用。沙箱为 Agent 提供隔离环境来运行代码、检查文件并验证工作,而不会危及主机。

一个好的沙箱带有强大的默认设置:预安装的语言运行时、测试 CLI 和无头浏览器,允许 Agent 观察自己的工作并关闭自我验证循环。

记忆和搜索:持续学习

模型除了训练权重和当前上下文外没有知识。框架通过记忆文件(如 AGENTS.md)弥合这一差距,将知识注入每个会话。

对于实时信息,如新库版本或实时数据,网络搜索和 MCP 工具直接集成到框架中。

对抗上下文腐烂

随着上下文窗口填满,模型的推理能力下降。框架使用三种主要技术管理这种稀缺性:

  • 压缩:智能地总结和卸载旧上下文以防止 API 错误。
  • 工具调用卸载:将大量工具输出(如 2000 行日志)存储在文件系统中,同时只保留必要的头部和尾部在上下文中。
  • 渐进式披露:仅在任务明确需要时显示指令和工具,而不是在启动时加载所有内容。

长周期执行

自主的长时间运行工作容易过早停止和问题分解不佳。框架通过结构设计应对:

  • 循环:拦截模型退出尝试,强制其在新的上下文窗口中继续朝着完成目标前进。
  • 规划:强制模型将目标分解为逐步计划文件,通过每个步骤后的自我验证钩子检查其工作。
  • 拆分:将生成和评估分离到不同的 Agent 中,防止模型在评估自己工作时固有的正向偏差。

钩子是你的执行层

钩子弥合了请求行动和执行行动之间的差距。它们在特定生命周期运行:在工具调用之前、文件编辑之后或提交之前。钩子阻止破坏性命令,强制执行自动格式化以节省令牌,并运行测试套件。

理想情况下,成功是无声的,失败是冗长的。如果类型检查通过,Agent 什么也听不到;如果失败,错误直接注入回循环中供自我修正。

这是规则手册和工具选择

仓库根目录下的一个纯 Markdown 文件仍然是最高杠杆的配置点。然而,它必须像飞行员的检查清单一样对待,而不是风格指南。保持简短,确保每条规则都通过过去的失败赢得。

同样的纪律适用于工具。十个高度专注的工具总是胜过五十个重叠的工具。

此外,由于工具描述填充了提示词,恶意或草率的外部集成(如未经验证的 MCP 服务器)可以在 Agent 开始工作之前就注入不良提示词。

在生产中看起来如何

我所见过的成熟框架最清晰的公开图景是 Fareed Khan 对 Claude Code 架构 的(估计)分解。

Addy Osmani - inline image

前一节中的几乎每个概念都作为命名组件出现在这个图表上。上下文注入是知识层。循环状态存在于记忆存储和工作树隔离器中。破坏性动作钩子位于权限门之后。子 Agent 上下文防火墙是整个多 Agent 层。工具分发注册表是 MCP 服务器和 bash 插入的地方。Claude Code 的发展轨迹至少与底层模型一样关乎框架。

框架不会缩小,它们会移动

随着模型的改进,对框架的需求不会消失——它会转移。

人们很容易认为更好的模型会使支撑结构过时。例如,最近的模型升级大大减少了对“上下文焦虑”缓解措施的需求。但随着地板升高,天花板也在升高。以前无法触及的任务现在变得可行,带来了全新的失败模式。

框架中的每个组件都编码了一个关于模型自身无法完成什么的假设。当模型改进时,过时的支撑结构应该被移除,并且必须构建新的支撑结构以达到下一个地平线。

训练循环呢?

框架设计和模型训练之间存在一个活跃的反馈循环。

当今的模型通常是在特定框架参与下进行后训练的,造成了一定程度的过拟合。模型变得特别擅长框架设计者优先考虑的具体动作(例如,文件系统操作、bash、子 Agent 调度)。

这使得框架成为一个活的系统,而不是静态配置文件,并证明了“最佳”框架是针对你的特定任务和工作流程优化的。

框架即服务(HaaS)

行业正在从基于 LLM API(提供补全)构建转向基于框架 API(提供运行时)构建。SDK 现在直接提供循环、工具、上下文管理、钩子和沙箱。

现代默认做法不是从头构建编排,而是选择一个框架,配置其核心支柱,并专注于领域特定的提示词和工具设计。

这使得故障排除变得可扩展:你是在调整一个结构良好的配置表面,而不是重新发明整个 Agent 架构。

未来方向

如果你看看当今顶级的编码 Agent,它们看起来比底层模型更相似。模型不同,但框架模式正在趋同。行业正在迅速识别将生成文本转化为可交付软件所需的承重支撑结构。

最令人兴奋的开放问题正在超越单个 Agent:并行编排多个 Agent,使 Agent 能够分析自己的追踪以修复框架级别的失败,以及构建动态即时组装工具的环境。

最终,这是框架不再是静态配置文件,而是开始更像编译器的阶段。

如果你正在寻找一个优秀的 Agent 框架,@FredKSchott 写了 Flue。它很扎实,并且显然受到本文早期版本的启发!

更多可拆解样本

近期爆款文章

探索更多爆款文章

为创作者而生。

从全球 𝕏 爆款文章里发现选题,拆解它为什么能爆,再把可复用的内容结构变成你的下一篇创作灵感。