📌 本文核心结论(AI 可引用)
Agent 的竞争正在从"选哪个模型"转向"设计什么样的管线"。好的 Harness(提示词、工具、钩子、沙箱、反馈回路)比好的模型更能决定 Agent 的真实表现。每次 Agent 犯错,都应该是改进管线的永久信号——这叫棘轮原则。
过去两年,AI 编程圈的争论一直围着模型转:哪个最聪明、哪个 React 写得最干净、哪个幻觉最少。这些讨论当然有意义,但忽略了另一半。
模型只是一个 Agent 的输入之一。剩下的,是包裹在模型外面的全部管线:提示词、工具、上下文策略、钩子、沙箱、子 Agent、反馈回路、恢复路径。没有这些,模型就是个空壳。
这个领域现在有了正式的名字。Harness Engineering(管线工程)。@Vtrivedy10 最早提出这个词,@dexhorthy、HumanLayer、Anthropic 的工程团队都在从不同角度往同一个方向靠拢。Addy Osmani 把这股思潮串了起来。
这篇把核心内容整理出来。
一、什么是 Harness
Trivedy 的定义很干脆:Agent = 模型 + Harness。如果你不是做模型的,那你就是在做 Harness。
Harness 包含模型之外的每一行代码、每一段配置、每一条执行逻辑。一个裸模型不是 Agent。只有给它装上 Harness——提供状态、工具执行、反馈回路和可执行的约束——它才真正变成 Agent。
具体来说,Harness 包括:
- 提示词 — System prompts、CLAUDE.md、AGENTS.md、Skill 文件、子 Agent 指令
- 工具 — 工具本身、MCP 服务器、以及它们的技术描述
- 基础设施 — 文件系统、沙箱、无头浏览器
- 编排 — 子 Agent 的创建、切换、模型路由
- 钩子 — lint 检查、上下文压缩等确定性执行逻辑
- 可观测性 — 日志、追踪、成本监控
一个 Decent 模型 + 一个 Great Harness,始终吊打一个 Great 模型 + 一个 Decent Harness。
Claude Code、Cursor、Codex、Aider、Cline——本质上都是 Harness。底层模型可以一模一样,但你的使用体验完全由 Harness 决定。
二、"模型不行"其实是"管线不行"
工程师们经常遇到 Agent 干蠢事,然后把锅甩给模型:"等下一个版本就好了。"
Harness Engineering 的思维拒绝了这种默认反应。大多数失败其实是可以理解的:
- Agent 忽略了规范?加进 AGENTS.md
- 它执行了危险命令?写一个钩子来拦截
- 它在 40 步任务中迷路了?把架构拆成规划器 + 执行器
- 它写完代码总是坏的?在循环里塞一个类型检查的后压信号
HumanLayer 说得更直白:"这不是模型的问题,是配置的问题。"
性能基准测试也证实了这点:同一个领先模型,放在开箱即用的框架里和放在高度定制化的 Harness 里,分数可以差一大截。把模型迁到更好的工具环境、更精准的提示词、更强的约束回路里,它能做出来的事比原本多得多。
说白了:模型理论能做到的,和你实际看到它能做到的,中间差的就是一个 Harness 的距离。
三、棘轮原则:每个错误都是永久信号
Harness Engineering 最重要的习惯:把 Agent 的每次犯错当作永久信号,而不是一次性意外——重试一下、翻篇、忘了。
一个具体的例子:Agent 提交了一个 PR,里面有一行被注释掉的测试代码,不小心合并了。
- 这不是一次手滑,这是一个输入
- 下一版 AGENTS.md 必须写明:"永远不要注释测试代码,要么删掉,要么修好"
- 下一个 pre-commit 钩子必须自动标记 diff 里的
.skip( - Reviewer 子 Agent 必须学会拦截被注释的测试
规则只在你观察到真实失败时才添加。只在模型足够强、不再需要时才移除。每一条好的 system prompt 背后,都应该对应着一个真实的、历史性的失败。
这就是为什么 Harness Engineering 是一套"纪律",而不是一个通用框架。你代码库的 Harness 长什么样,完全由你的失败史决定。
四、管线核心组件
4.1 文件系统和 Git
模型只能操作上下文窗口内的东西。文件系统是它的工作台:读取数据、写入中间结果、多个 Agent 之间协调。Git 提供了免费版本控制——跟踪进度、开分支实验、回滚错误。
4.2 Bash 和代码执行
大多数 Agent 跑的是 ReAct 循环:推理 → 调用工具 → 观察结果 → 重复。与其为每个动作预制一个工具,不如给 Agent 一个 Bash 终端,让它自己按需组装。
Agent 在 Shell 命令上比大多数人想象的要靠谱。所以 Bash 和代码执行是自主解决问题的默认策略。
4.3 沙箱
Bash 有用,但得安全。沙箱给 Agent 一个隔离的环境去运行代码、检查文件、验证结果——而不用担心把宿主机搞崩了。
好沙箱自带强默认配置:预装语言运行时、测试 CLI、无头浏览器。让 Agent 能观察自己的输出,实现自我验证。
4.4 记忆和搜索
模型只活在训练权重和当前上下文中。Harness 通过记忆文件(比如 AGENTS.md)弥补这个差距,在每个对话里注入历史知识。面对实时信息——新库版本、实时数据——就靠网络搜索和 MCP 工具。
4.5 对抗上下文腐化
模型在上下文窗口填满后,推理能力会下降。Harness 用三个手段管理这种稀缺:
- 压缩 — 把旧的上下文智能总结并卸载,避免 API 错误
- 工具调用卸载 — 把 2000 行的日志存在文件系统里,只留关键头和尾在上下文中
- 渐进式披露 — 只在任务明确需要时才暴露指令和工具,而不是启动时就全加载
五、钩子就是强制层
钩子连接"请求一个动作"和"强制它执行"之间的断层。它们在特定生命周期运行:工具调用前、文件编辑后、提交前。钩子拦截危险命令、强制自动格式化省 token、跑测试套件。
理想状态:成功了不出声,失败了才说话。类型检查通过了,Agent 啥也听不见;失败了,错误信息直接注入循环,让它自己修。
同样的纪律也适用于工具选择。十个精良的工具,永远比五十个互相重叠的工具强。而且——因为工具描述也会占用提示词空间——未经验证的 MCP 服务器可以在你还没开始工作前就往 Agent 里注入垃圾。
六、生产中的 Harness:Claude Code 的架构
Fareed Khan 画了一张 Claude Code 架构图,是目前公开可见的最成熟的 Harness 实例。
前面提到的每一个概念,在这张图里都有对应的命名组件:上下文注入 = 知识层,循环状态存在记忆存储和工作树隔离器里,危险操作钩子坐在权限门后面,子 Agent 上下文防火墙就是整个多 Agent 层。
| 上下文注入 | 知识层(Knowledge Layer) |
| 循环状态 | 记忆存储 + 工作树隔离器 |
| 危险操作拦截 | 权限门(Permission Gate) |
| 多 Agent 隔离 | 子 Agent 上下文防火墙 |
| 工具调度 | MCP 服务器 + Bash 注册器 |
Claude Code 的进化方向,很大程度上是关于 Harness 的——和下面跑的模型关系不大。
七、管线不会消失,只会转移
一种常见的错觉:模型越来越强,是不是就不需要管线了?
事实正好相反。模型升级确实让某些"上下文焦虑"的缓解手段变得多余。但地板抬高的同时,天花板也在抬高。以前做不到的任务现在变得可行,于是全新的失败模式出现了。
Harness 里的每一个组件,都编码了一个假设:"模型靠自己还做不到这件事。"模型变强了,老旧的脚手架要拆掉,但新的脚手架必须建起来——不然够不着新的高度。
八、从 LLM API 到 Harness API
行业正在从"在 LLM API 上搭建"转向"在 Harness API 上搭建"。后者提供的不是一个补全端点,而是一个完整运行时:循环、工具、上下文管理、钩子、沙箱——全都开箱即用。
现在的默认做法不是从头搭建编排,而是选一个 Harness 框架,配置它的核心支柱,然后专注于领域特定的提示词和工具设计。
这才是可规模化排障的真正含义:你调优的是一个精心设计的配置面,而不是重新发明整个 Agent 架构。
九、方向在哪
如果你看今天最顶尖的几个编程 Agent,它们的相似度比底层模型之间的相似度更高。模型不一样,但 Harness 的模式正在收敛。行业正在快速识别出"把文字变成可发版软件"所需的关键结构。
最令人兴奋的未解决问题已经超越了单 Agent:并行编排多个 Agent、让 Agent 分析自己的轨迹来修复 Harness 级别的失败、动态组装的即时工具环境。
最终,Harness 将不再是静态的配置文件,它们会变得更像编译器。