Harness Engineering 实战:模型是 AI Agent 里最不重要的部分(60 天管线复盘)
60 天跑 Claude Code 博客管线,换模型只升 5%,重写 Harness 端到端降本 60%。讲透 Agent = 模型 + Harness 公式、引导器+传感器架构、Sub-Agent 路由策略、和你今天就能用的 ROI 决策表。
Harness EngineeringAI AgentsAI EngineeringClaude CodeAI Coding ToolsSub-AgentContext Engineering
924  字
2026-03-30

这是 Harness Engineering 系列第 1 篇。第 2 篇 拆 CLAUDE.md 最佳实践,第 3 篇 讲 Sub-Agent 架构。
我过去 60 天在跑一个 Claude Code 驱动的博客管线:选题、调研、写作、配图、SEO、分发,全部交给 Agent。跑下来最反直觉的一条经验是——模型是这套系统里最不重要的部分。
这不是口号。我切过 Opus、Sonnet、又切回 Opus,挨个对比产出质量和执行稳定性,端到端变化一直在 5% 以内。真正把成本打下来的那一刀,是我重写了 Harness(外围系统):把调度层从 Opus 降到 Sonnet,把写作留给 Opus,把搜索和粗筛交给 Haiku——同样产出同样质量,每月 token 成本从 400 美金降到 160 美金左右,直接砍掉 60%。
这篇要讲的 Harness Engineering(线束工程),就是决定一个 AI Agent 能不能在生产里真正跑起来的东西。它不是新概念,但在 2026 年成了 AI 工程里 ROI 最高的那笔投资。
三次进化:提示词、上下文、线束
AI 工程在过去三年翻过三座山,每过一座,工程师要设计的东西就扩大一圈。
第一阶段:Prompt Engineering
关注点是写出一条完美的指令。
你是一个资深 Python 开发者。写干净、有注释的代码。
使用类型提示。遵循 PEP 8。逐步思考。
这在模型是无状态工具的 2023 年管用——发一条指令,得一条回复。工程挑战全在你选的词上。类比是给承包商写一封措辞完美的邮件。
第二阶段:Context Engineering
一条指令远远不够。模型要看到的是一个动态组装的上下文:相关文档、对话历史、工具签名、RAG 检索结果、当前文件内容。RAG 管道、向量库、上下文窗口压缩这些话题都从这里爆发出来。
这是 2025 年的主旋律。类比从一封邮件变成一个完整的简报包——组织架构、项目文档、过往沟通记录,都塞进去。
第三阶段:Harness Engineering
Context Engineering 的潜在假设是 Agent 做一次决策,人类评估一次输出。但现代 Agent 是自主跑的——一次任务发起几百次工具调用、编辑几十个文件、反复跑测试、失败重试。Harness 就是管理整个生命周期的那一层。
它至少包含工作流编排、工具访问策略、验证系统、反馈循环、记忆持久化、护栏约束、可观测性、升级规则。类比再变一次:现在你不是写邮件,也不是准备简报,你在设计整间办公室——文件归档、审批流程、安全制度、绩效考核、什么时候叫老板进来。
三层的包含关系
下面这张图把三层的从属关系画清楚。外层不替代内层,只是把内层包在更大的运行系统里。
graph TB
subgraph Harness["Harness Engineering"]
subgraph Context["Context Engineering"]
Prompt["Prompt Engineering
写干净的 Python 代码"]
end
Context -.-> Tools["+ 文档、历史、工具、RAG"]
end
Harness -.-> Lifecycle["+ 工作流、护栏、反馈、生命周期"]
你依然要写好提示词、管好上下文——这两层没有被废,只是不够了。Harness Engineering 把工程师的工作从"调一次模型"升级成"设计一整套能让模型在真实任务里稳定工作的系统"。
核心公式:Agent = Model + Harness
这是整个学科的一个公式。Model 提供原始推理能力,Harness 提供其他一切。
| 维度 | Model | Harness |
|---|---|---|
| 类比 | CPU | 操作系统 |
| 做什么 | 思考、生成、推理 | 管理、约束、验证 |
| 怎么升级 | 等下一代发布 | 今天就能工程化 |
| 差异化空间 | 同质化,性能差距很小 | 独特的,是你的竞争优势 |
打个比方——CPU 没有操作系统就是废铁,操作系统没有 CPU 跑不起来。但普通人买电脑的时候,操作系统对体验的影响远远大于具体的 CPU 型号。AI Agent 同理。Opus 4.6、GPT-5、Gemini 3 推理能力都不差,真正决定你家 Agent 是稳定交付还是制造混乱的,是你围绕它构建的 Harness。
这里要澄清一个我反复看到的误区——“换更强的模型 Agent 就更强”。这句话对,但增量远小于你想象。LangChain 在 TerminalBench 2.0 上的跃迁是最硬的反例:不换模型,只重写 Harness,就从第 30 名跳到第 5 名,分数从 52.8% 提到 66.5%,相当于把那一代开源模型的推理能力多榨出了 13 个百分点。这 13 个点不是从模型里来的,是从引导它、约束它、验证它的那些代码里挤出来的。
我跑了 60 天,得出的三个反直觉结论
纸上推导不如真跑。我用自己这套博客管线(每周产出 3-5 篇中英双语深度文 + 自动配图 + SEO 优化 + 分发)挨个验证下来,三个结论:
结论一:换模型的边际收益早就被榨干了
我做过两轮 A/B。第一轮把写作 Agent 从 Sonnet 换成 Opus,文章质量指标(GA 停留时长、完读率、SEO 打分)提升 4-6%,token 成本翻倍多;第二轮把调研 Agent 从 Opus 降到 Sonnet,再把搜索粗筛降到 Haiku,综合指标只降了不到 2%,成本却降到原来的 40%。
当前模型之间的差距已经进入一个很窄的区间——这不是未来会发生的趋势,是我账单上每个月都在印证的事实。如果你的 Agent 表现不好,90% 的概率问题不在模型,在你怎么用它。
结论二:Harness 的复杂度要和任务严格匹配
我踩过最贵的一次坑,是试图用"朴素多 Agent 架构"来写长文——调度 Agent 把任务切成 6 份丢给 6 个写作 Sub-Agent 并行,最后合并。跑出来的文章风格撕裂、论点自相矛盾、互相打架。我翻 Cognition 团队关于 Devin 的公开复盘才反应过来,他们给出的一条核心结论就是——朴素的多 Agent 架构在真实任务上不 work,宁可用一个大上下文窗口的单 Agent 也别用松散 swarm,除非交接契约写得比 API 文档还死。
我最后的妥协方案:单 Agent 写作,上下文窗口塞满;只把"搜资料"、“查事实”、“生成配图"这几件边界清晰、输出结构化的事情拆出去给 Sub-Agent。质量立刻回来。这个教训在第 3 篇 Sub-Agent 架构里会完整展开。
结论三:CLAUDE.md 写太长,是我犯过最隐蔽的错
早期我把所有能想到的约定都塞进 CLAUDE.md,一路写到 90 行。表现开始不稳——Agent 有时候忽然忘记项目约定,产出莫名其妙的代码风格。我一度以为是模型的问题。后来看到苏黎世联邦理工的一项研究:CLAUDE.md 超过 60 行会让 Agent 表现下降约 20%,人写的简洁版本反而比 LLM 生成的冗长版本更强。我把我的 CLAUDE.md 砍到 40 行,把其余细节挪到 Skills(按需加载)和 Hooks(自动触发),Agent 的稳定性当天就回来了。
这条反直觉到什么程度——给 Agent 更少的指令,它反而更听话。详细拆解看第 2 篇 CLAUDE.md 最佳实践。
核心组件:引导器与传感器
Martin Fowler 把 Harness 的组件分成两大类,这是我见过最干净的划分。一类在生成前引导行为,一类在生成后发现错误。缺一不可。
引导器(Guides)—— 前馈控制
引导器在 Agent 动手之前就把可能的错误压缩掉,提高一次做对的概率。它们的共同点是:把约束编码进系统,而不是写成一句话指令。
| 引导器 | 类型 | 举例 |
|---|---|---|
| 架构文档 | 推理型 | CLAUDE.md 描述仓库结构和约定 |
| 编码规范 | 计算型 | ESLint/Prettier 强制输出格式 |
| 启动脚本 | 计算型 | 项目脚手架创建正确的文件结构 |
| 类型定义 | 计算型 | TypeScript 类型收窄解题空间 |
| 示例模式 | 推理型 | “正确做法"的参考代码片段 |
在 Claude Code 里,你手头的引导器至少包括——CLAUDE.md 和 AGENTS.md(约定与约束)、MCP Server 配置(可用工具)、Skills(按需加载的能力包)。挑选原则是计算型优先、推理型兜底:一条拦截循环引用的 lint 规则比一句"不要创建循环引用"的提示词可靠一万倍。
传感器(Sensors)—— 反馈控制
传感器在 Agent 动手之后帮它发现错误、自我纠正。它们的关键不是"能不能发现错”,而是"发现之后能不能以 LLM 能理解的形式把信号喂回去”。
| 传感器 | 类型 | 能发现什么 |
|---|---|---|
| 单元测试 | 计算型 | 行为正确性 |
| 类型检查 | 计算型 | 类型错误、接口不匹配 |
| 代码检查 | 计算型 | 风格违规、常见 bug |
| AI 代码审查 | 推理型 | 语义问题、设计缺陷 |
| 集成测试 | 计算型 | 跨组件故障 |
在 Claude Code 里你用的传感器就是——Hooks(PreToolUse、PostToolUse)、自动跑的测试套件、类型检查(tsc、mypy)。一个关键细节:传感器的输出要为 LLM 优化。比如 lint 错误写成 Error: unused variable 'x' on line 42 就比一个裸的错误码有用得多,写成纠错指令(“移除第 42 行未使用的变量 x”)效果最好。
为什么必须两个都要
只有引导器——Agent 按模式写,但从不验证,错误以最安静的方式发生,直到生产爆炸你才知道。只有传感器——Agent 犯错、发现、修复、再犯同一个错,慢得折磨人,贵得离谱。只有两者组合,Agent 才能通常一次做对、偶尔出错也能自动收敛。
真实案例:别人跑出来的证据
OpenAI Codex:100 万行代码,零行人写
OpenAI Codex 团队在五个月内生产了超过 100 万行代码和 1,500 个 PR,没有一行是人类工程师写的。七个人全力投入 Harness Engineering:分层架构通过自定义 lint 规则强制(不是写进提示词)、结构性测试验证模块边界、定期扫描架构漂移、仓库作为唯一真相源。
这里最值钱的一句话是他们的总结——把约束编码进系统,而不是写进提示词。这句话顺带打脸一个常见误区:“AI 写代码不可信”。不是 AI 不可信,是缺了约束系统的 AI 不可信。给它对的护栏,它写的 100 万行可以比很多团队的人写代码更一致。
LangChain:不换模型从第 30 升到第 5
前面提过一次,再精确写一遍——LangChain 的编程 Agent 在 TerminalBench 2.0 上完全不换模型,仅优化 Harness:更好的工具定义、更聪明的上下文管理、更完善的错误恢复循环。结果从 52.8% 跳到 66.5%,从第 30 名升到第 5 名。这是"模型不如 Harness"这个命题最干净的对照实验。
Stripe Minions:每周 1300 个 PR
Stripe 的自主 Agent 系统每周合并 1300+ 个 PR。他们的 Harness 里有一条非常克制、我认为被严重低估的规则——同一个问题失败两次,就升级给人,不无限重试。这是成熟系统的味道:知道 Agent 什么时候不该继续,比让它一直转更重要。Push 前的 Hook 自动选相关 lint 规则,Blueprint 编排把确定性节点和 Agent 节点分开。简单,但每一条都在真刀真枪地兜底。
我自己:端到端降本 60%
把我 60 天跑下来的账单摊开写一下,因为我没看到几个人把这个写清楚过。
原版管线:调度 Opus + 全员 Opus 执行。每月 token 成本 ~400 美金,质量不错,但调度这种琐碎决策也烧 Opus 太浪费。
重写后:调度 Sonnet + 写作 Opus + 搜索/粗筛 Haiku。原因——调度需要的是可靠遵循规则、成本敏感,Sonnet 足够;写作需要推理深度和风格把控,必须 Opus;搜索粗筛是高吞吐低智力密度,Haiku 够用还快。同样的产出、同样的 GA 指标,每月 token 成本 ~160 美金,降幅约 60%。
如果你只能记住这篇文章一件事,记这个——Sub-Agent 按任务性质路由模型,是 2026 年最朴素、ROI 最高的 Harness 优化。
实操指南:从零搭建 Harness
第一层:最小可行配置
一个 60 行以内的 CLAUDE.md,讲清楚三件事——项目是什么、遵循什么约定、怎么验证。
# CLAUDE.md(控制在 60 行以内)
## 项目
- TypeScript monorepo,pnpm workspaces
- React 前端,Express 后端
## 约定
- 优先组合而非继承
- 所有 API 响应使用共享的 Result<T> 类型
- 测试文件与源码同目录:foo.ts → foo.test.ts
## 命令
- pnpm test —— 跑全部测试
- pnpm lint —— ESLint + Prettier
- pnpm typecheck —— TypeScript 严格模式
不要一开始就堆满。Harness 和代码一样——你猜不准 Agent 会在哪里犯错,先跑再补。
第二层:反馈循环(Hooks)
文件改完自动跑类型检查。错误立刻暴露,不会在改了 50 个文件后才发现。
{
"hooks": {
"PostToolUse": [
{
"matcher": "Write|Edit",
"command": "pnpm typecheck --quiet",
"description": "文件修改后自动类型检查"
}
]
}
}
实操建议:别跑完整测试套件,跑相关子集就好。完整套件放 CI。否则 5 分钟一次的反馈循环会让 Agent 的迭代速度变成负数。更完整的 Hook 模式见 Claude Code Hooks 完全指南。
第三层:按需加载(Skills)
别把所有专项知识塞进 CLAUDE.md。用 Skills 在需要的时候加载。
# .claude/skills/database-migration.md
---
name: database-migration
description: 创建或修改数据库迁移时使用
---
## 迁移规则
- 必须创建可逆迁移(up + down)
- DDL 变更使用事务
- 迁移前在生产 schema 副本上测试
- 永远不要修改已有迁移,创建新的
只有做迁移时才加载这段上下文,其他时候不占窗口、不污染注意力。完整用法见 Claude Code Skills 完全指南。
第四层:Sub-Agent 路由
这是我上面降本 60% 的核心机制。一句话概括——按任务性质选模型,而不是一律用最强的。
父 Agent(调度,用 Sonnet)负责任务拆解和关键决策。子 Agent 按任务类型路由——需要推理的写作任务用 Opus,高吞吐低智力密度的搜索粗筛用 Haiku,每个子 Agent 返回精简结果加文件/行号引用,不把原始上下文带回父 Agent。这样父 Agent 的窗口保持干净,同时每一类任务用的都是最合适的模型。
详细的路由策略、交接契约、failure mode 分析在第 3 篇 Sub-Agent 架构。
第五层:架构约束(适应度函数)
把架构规则写成可自动验证的测试,这样不管漂移来自人类还是 Agent 都兜得住。
// architecture.test.ts
describe('架构适应度', () => {
it('后端模块不引用前端', () => {
const violations = findImports('src/backend/**', 'src/frontend/**');
expect(violations).toHaveLength(0);
});
it('API 处理器使用共享 Result 类型', () => {
const handlers = findFiles('src/api/handlers/**/*.ts');
handlers.forEach(file => {
expect(file.content).toContain('Result<');
});
});
});
这类测试在 CI 里跑,是传感器的终极形态——不依赖 Agent 自觉,不依赖人类 review,直接用代码守住架构边界。
三个真实会翻车的错误
上一版的"6 行常见错误表格"信息密度太低,我挑三个我自己踩过、代价最大的展开讲。
错误一:一开始就设计完美 Harness
现象:你花两周搭了一套你自以为完备的 Harness,Agent 跑起来还是翻车——它犯的错都不在你预想的列表里。
为什么错:Harness 是要贴着真实 failure 长出来的。你预想的错误大概率不是 Agent 实际会犯的错误。提前设计 = 提前浪费。
怎么改:从最小配置开始(一个 60 行 CLAUDE.md + 类型检查),跑真实任务,每次 Agent 翻车就补一条——是规则漏了就补规则,是验证漏了就补 Hook,是知识缺了就加 Skill。三周后你的 Harness 会贴合真实 failure 分布,精确得多。
错误二:CLAUDE.md 越写越长
现象:你不断往 CLAUDE.md 里加规则,越加越详细,以为越清楚 Agent 越听话。结果 Agent 开始表现得像注意力涣散——简单任务反而忘记基础约定。
为什么错:模型的上下文预算是稀缺资源,每一条不常用的规则都在稀释高优先级信号的注意力。苏黎世联邦理工的数据是 >60 行降 20% 表现,我自己在 90 行的时候明显感受到 Agent “糊"了。
怎么改:核心约束(10-20 条)进 CLAUDE.md,专项知识进 Skills 按需加载,具体流程进 Hooks 自动执行。三层各司其职,上下文窗口永远干净。
错误三:把约束写在提示词里
现象:你在提示词里反复强调"不要创建循环引用”、“所有 API 必须有错误处理”、“不要修改已有迁移文件”——Agent 偶尔记得,偶尔忘了,你开始怀疑人生。
为什么错:提示词是建议,lint 是强制执行。模型可以忘、可以绕,但 lint 规则/类型系统/pre-commit hook 不会。
怎么改:每一次你想在提示词里加一条规则,先问一句——能不能用 lint 规则、类型定义、或者 Hook 实现?能的话绝不进提示词。计算型约束 > 推理型约束是 Harness 设计的铁律。
什么时候不该投 Harness Engineering(ROI 边界)
Harness 不是万金油。投错场景等于用大炮打蚊子。三种情况别投:
情况一:一次性脚本。如果这段代码你明天就扔,Harness 的建设成本完全无法摊薄。直接跟 Agent 口头讲清楚、手动验证一次就收工。
情况二:团队 < 3 人且代码库 < 1 万行。这个规模下你手写比教 Agent 快,Harness 的 ROI 要在"重复执行 + 多人协作 + 长期维护"三个条件同时满足时才出来。
情况三:没有类型系统 + 测试基础设施。传感器层建不起来,Harness 只剩引导器,相当于只有前馈没有反馈——跟闭着眼睛开车差不多。这种情况下先把类型和测试补上,再谈 Harness。
下面是一个更实操的决策表,你可以对着自己的场景打勾:
| 场景特征 | 投 Harness | 不投 |
|---|---|---|
| 任务会重复执行(周级以上) | 是 | |
| 团队 ≥ 3 人协作 | 是 | |
| 代码库 ≥ 2 万行 | 是 | |
| 已有类型系统 + 测试 | 是 | |
| Agent 每月 token 成本 ≥ 200 美金 | 强烈建议 | |
| 一次性脚本/原型 | 是 | |
| 无测试基础设施 | 先补 infra | |
| 团队都是非技术背景 | 太早 |
Ashby 定律:为什么约束反而提升产出
这是一个看起来反直觉但其实有严格数学支撑的结论——给 Agent 更少的选项,它更高效。
这来自 Ashby 必要多样性定律——调节器的复杂度必须不低于被调节系统的复杂度。LLM 能生成几乎任何东西,解题空间是无限的。为无限空间构建完备 Harness 是不可能的。但如果你把解题空间主动缩小——“所有 API 端点长这个样”、“所有数据访问走这一层”、“所有状态管理用这个模式”——你就把空间压到 Harness 能全面覆盖的范围。
约束不是限制,约束是可靠自主运行的前提。这句话放在这里可能有点抽象,但我自己每次在管线里犹豫"要不要再给 Agent 多一点自由度"的时候,都会回来默念一遍。
三个我愿意押钱的预测
不写"未来展望"这种虚话,写三个我愿意在自己管线上押钱、两年内会被验证或证伪的预测。
预测一:Harness 模板会出现并且快速商品化。针对常见模式(CRUD 服务、数据管道、事件处理器、博客管线)的预制"引导器+传感器"包会在 GitHub 上泛滥。押注理由——这类模板边际复制成本几乎为零,而每个团队从零搭建 Harness 要两到三周。模板会先开源、再 SaaS 化。
预测二:Harness 质量指标会成为招聘时的考察项。类似代码覆盖率,会出现 Harness 成熟度评估——引导器覆盖面、传感器召回率、升级规则完备度、模型路由合理性。押注理由——Harness 一旦被证明是 Agent 生产稳定性的关键,它的质量必然被量化,再被放进简历和面试题。
预测三:模型厂商会开始发布"Harness 感知"训练版本。未来的模型会基于真实 Harness 失败轨迹的数据来训练,学会在特定 Harness 下工作得更好。押注理由——Harness 是 Agent 生产性能的瓶颈,模型厂商迟早会意识到"训练一个通用强模型"的回报已经饱和,“训练一个在主流 Harness 下跑得更好的模型"回报更高。
延伸阅读
- Harness Engineering 系列第 2 篇:CLAUDE.md 最佳实践 —— 写好引导器文件,60 行陷阱怎么绕开
- Harness Engineering 系列第 3 篇:Sub-Agent 架构 —— 按任务路由模型,降本 60% 的完整拆解
- Claude Code Hooks 完全指南 —— Harness 的传感器层实操
- Claude Code Skills 完全指南 —— 按需加载的引导器能力包
- Context Engineering 指南 —— Harness Engineering 的上一代
- 2026 AI 开发方法论对比 —— Harness Engineering 在更大图景里的位置
- Martin Fowler 的 Harness Engineering 原文 —— 概念起源
- Cognition 团队 Devin 的公开复盘 —— 朴素多 Agent 为什么不 work
- Ashby 必要多样性定律 —— 约束为什么等于能力
Comments
Join the discussion — requires a GitHub account