"If you're not the model, you're the harness."
中文大意:一个 agent 系统里,除了模型,剩下的全部都是 harness。模型只是被插进来的一个部件。
— Addy Osmani《Agent Harness Engineering》;LangChain《The Anatomy of an Agent Harness》独立给出同一两层模型
Field Guide · 挽具工程
Agent = Model + Harness。模型只是 agent 的一个输入;其余一切——prompts、工具、上下文策略、hooks、沙箱、子 agent、反馈与恢复回路——都是 harness。你已有的三页讲了内层(模型自己转的圈)和外层(谁来推这个圈),这一页专攻此前没有一页系统解剖过的中间那层:模型与循环之间的全部工程。
这里把 2026 年中爆发的 “harness engineering” 讨论收成一张地图——这个词怎么来的、harness 由哪五大件组成、Böckeler 的前馈/反馈双控制、长时 agent 怎么搭跨会话的记忆桥、单线程还是多 agent——最后 12 题验证你真的学会了。一条主线贯穿:配置差距,常常大于模型差距。
主要一手来源:Anthropic 工程博客系列(Building Effective Agents / Writing Tools / Context Engineering / Effective Harnesses / Harness Design / Demystifying Evals / Claude Code Best Practices)· Addy Osmani《Agent Harness Engineering》 · Birgitta Böckeler《Harness Engineering》 · LangChain《The Anatomy of an Agent Harness》 · Latent Space《Extreme Harness Engineering》 · Thorsten Ball / Simon Willison / Armin Ronacher / Geoffrey Huntley / Cognition · 本地 LLM-WIKI 概念群。
先立一句能扛住整页的骨架。裸模型不是 agent——只有当 harness 赋予它状态、工具执行、反馈回路与可强制的约束后,它才成为 agent。
"If you're not the model, you're the harness."
中文大意:一个 agent 系统里,除了模型,剩下的全部都是 harness。模型只是被插进来的一个部件。
— Addy Osmani《Agent Harness Engineering》;LangChain《The Anatomy of an Agent Harness》独立给出同一两层模型
AGENTS.md / pre-commit hook / 一个 review 子 agent。配套口味:hooks 要「静默成功、响亮失败(quiet success, loud failure)」。(Addy)这一页的全部内容,都是在回答一个问题:模型之外那层工程,到底该搭些什么、怎么搭得让 agent 转得稳。
最容易混的三个「循环/工程」其实是套在一起的三层。分清谁负责哪层,才知道这一页在讲哪一块。中层高亮的就是本页主场。
收集上下文 → 行动(调工具)→ 验证 → 重复(Anthropic 概括 gather context → take action → verify work → repeat),即 ReAct 回路。Claude Code、Codex、Amp 都内置这一层。
一句话记边界:内层是「模型自己转的圈」(产品给你的);外层是「谁来推这个圈、多久推一次」(你设计的系统,已在 loop-engineering 页讲透);中层 harness 是「这个圈能不能转得稳」的全部工程——这是本页独占的地盘。Böckeler 还把 coding agent 语境下的 harness 再分成内建 harness(产品自带)与你自加的 outer harness(Guides/Sensors),本页主要讲后者。
“harness engineering” 不是一天冒出来的。先有「agent = LLM harness」的心智,再由 Anthropic 官方系列把各面逐一工程化,最后在 2026 年中被正式命名、解剖,成为行业术语。诚实标注:命名爆发期几篇只有抓取日期,确切发表日未标注,故不硬排先后。
一句话谱系:agent = LLM harness(2024–2025 建立心智)→ Anthropic 官方系列把工具/上下文/长时/eval 逐面工程化(2025 秋–2026 春)→ 2026 年中 Addy 命名公式、Böckeler 给框架、LangChain 做解剖,“harness engineering” 成词 → 循环工程在其上接棒。
把 LangChain 的组件清单、Addy 的核心组件、Böckeler 的控制分类、Anthropic 各面官方文,收敛成一张部件图——五件。记忆口诀:上下文(知道什么)· 工具(能做什么)· 验收(做对没有)· 运行时反馈(正在发生什么)· 编排恢复(多轮/多手怎么协同兜底)。
make dev)+ 种子数据(测试账号/订单)+ 关键路径冒烟测试(零 flaky)+ 结构化日志(JSON + request id)。以前是加分项,现在是 agent 能否自主工作的前提——旧工程债直接变成 AI 债。反馈信号是放大器(Willison);构建回路要短——保持 <1 分钟是规模化的关键加速器(Latent Space);充分日志作为执行副产物,让 agent 自我诊断恢复(Ronacher)。对齐中文圈最早的命名:dolphin07 的「三类供给」= 件 1(上下文)+ 件 3(验收)+ 件 4(运行时反馈)。本页在其上补齐件 2 工具与件 5 编排,合成完整五件——这是把散在五六篇里的拆法收成一张图,全站首次。
最严谨的 harness 拆法。外层 harness = 两类控制,每类再按「确定性计算 / LLM 推断」分成计算式与推断式 → 四象限。价值:把人类隐性经验外部化为显式、可复用的控制,减少 review toil、少浪费 token。
| 计算式(确定性、快) | 推断式(LLM 语义判断) | |
|---|---|---|
| Guides · 前馈(事前) | linter / 类型系统 / 模板生成 / codemod / pre-commit 规则 / AGENTS.md·CLAUDE.md 约定 / 权限 allow deny | 规划阶段的 spec 澄清 / skill·SOP 里的领域指令 / prompt 里的 few-shot 示范 |
| Sensors · 反馈(事后) | LSP 诊断 / 测试退出码 / 构建·CI 状态 / 脚本断言 / 静态分析 | review agent 对抗式复核 / generator+evaluator 的 evaluator / 语义 diff 检查 |
分布原则 “Keep quality left”:按成本与速度把控制铺到开发生命周期上——快检查放 pre-commit,昂贵的推断式检查放集成之后。从三个维度治理质量:可维护性 / 架构适配度 / 行为。(Böckeler,Thoughtworks)
要知道 harness 该补什么,先看清产品替你内置的内层长什么样。Thorsten Ball 把它摊开:一个 agent = 一个 LLM + 一个循环 + 足够的 token,约 300 行。"The Emperor Has No Clothes."
"An agent is an LLM with access to tools that let it modify things beyond its own context window."
中文大意:所谓 agent,就是一个能调用工具、从而改变自身上下文窗口之外事物的 LLM。工具四要素:name + 给模型的 description + 输入 JSON schema + 本地执行函数。
— Thorsten Ball《How to Build an Agent》(Amp / Sourcegraph)
tools = register([read_file, list_files, edit_file, bash, search]) # 五原语
conversation = [ system_prompt ] # 系统提示定义可用工具与期望行为(可数百行)
conversation += [ user_task ]
while True:
response = model.infer(conversation, tools) # 1) 发给模型
conversation += [ response ]
if response.has_tool_calls(): # 2) 模型请求调用工具?
for call in response.tool_calls:
result = tools[call.name].run(call.args) # 3) harness 本地执行
conversation += [ tool_result(result) ] # 4) 结果回灌进对话
continue # 5) 带新观察再推理
if is_done(response): # 完成信号/停止条件
break关键点 模型自主决定何时调哪个工具;harness 负责提取工具请求、执行、把结果回灌进下一轮。上下文纪律:活动之间清空/隔离 context,防 death spiral。
根本困难:长任务必须在离散会话中工作,每个新会话对之前毫无记忆。仅靠 compaction 不够——前沿模型在循环里会「一口气想做太多」或「看到有进展就宣布完工」。Anthropic 两篇给出两套机制。
feature_checklist.json(每项含 pass/fail 状态)、建立「环境校验仪式」脚本。机理旁证(Ghuntley):Claude 3.7 名义 200k,输出质量在 147k–152k 就开始 clip,tool-call 到 tool-call 开始失败——这正是「为什么要 reset / 隔离而不是硬撑」的物理原因。
这是件 5 编排里最贵的一个选择。两派各有硬论据与硬数字——不是「多 agent 更酷」,而是一道成本/收益的架构题。(多 agent 数字的批判性对冲另见 正本清源页。)
共识(双方都同意):多 agent 适合 breadth-first、可并行探索、子任务弱依赖的场景;不适合紧耦合、需连续决策的任务。而且 Anthropic 官方另一处主张——能用单 agent 别上多 agent,能用 workflow 别上 agent:从最简单方案起步,只在确有收益时加复杂度。任一问 No → 退回单线程线性 agent 或 workflow。
7 个模板 + 1 个微模板,对应五大件与两大架构决策。功能性内容保留英文/结构原文(是拿来用的,不是拿来读的),说明用中文。从上到下,覆盖 harness 的搭建全链。
用在:为 agent 新增/审查一个工具时,逼齐四要素 + 高信号返回。
name: <verb_noun, e.g. search_orders>
description: |
<一句话说清"什么时候该用它",给模型看,不是给人看。
写清副作用、返回什么、何时别用。>
input_schema: # JSON schema, 每个字段带 description
query: {type: string, description: "..."}
returns: # 高信号: 语义化标识 + concise/detailed 两档 + 分页
format: concise | detailed
on_error: "<actionable message: 告诉 agent 下一步怎么办>"纪律 能合并成一次高层调用就别拆成多次往返;工具总数宁少勿多;错误信息必须可操作。(Anthropic《Writing Tools》)
用在:写项目约定或知识库时,做到「分层 + 保鲜」。
# 组织红线(继承,所有项目共享,最高优先) - <合规 / 安全 / 不可承诺项> # 项目约束(覆写组织默认) - 构建/测试命令: <agent 猜不到的> - 架构决策: <项目特有> # 知识条目(每条必带三元信息,否则不许进库) - fact: <内容> provenance: <出处链接/来源> owner: <谁维护> expires_when: <失效条件, 如 "v3 发布后作废">
纪律 注入越多未必越好(注意力稀释);过期知识比没有知识更危险。(EngineeringHarness)
用在:交付前的独立验收门禁(生成者不能批改自己的试卷)。
闸门① 验收覆盖率: [ ] 需求逐条有对应用例 [ ] shallow 命名匹配 [ ] deep 语义比对 闸门② Spec 漂移: [ ] 结构层(接口/字段未擅改) [ ] 语义层(行为未偏离 spec) 闸门③ 失败熔断: [ ] 有限重试 N=___ [ ] 超限 → 暂停 [ ] 暂停 → 回滚/转人工 起步: 从真实失败 case 取 20–50 条建 eval; grader = 代码型 + 模型型 + 人评校准
出处 EngineeringHarness / dolphin07;Anthropic《Demystifying Evals》。generator 与 evaluator 拆成两个 agent。
用在:搭 harness 时自查「前馈/反馈 × 计算式/推断式」四格是否都有覆盖。
计算式(确定性快) 推断式(LLM 语义)
Guides 前馈 [ ] linter/类型/模板 [ ] spec 澄清 / skill 指令 / few-shot
[ ] 权限 allow/deny [ ]
Sensors 反馈 [ ] 测试退出码/CI/LSP [ ] review agent 对抗复核 / evaluator
[ ] 静态分析 [ ]
分布: 快检查放 pre-commit, 昂贵推断式放集成之后 (Keep quality left)出处 Birgitta Böckeler《Harness Engineering》。四格都空的那一列/行,就是你 harness 的盲区。
用在:想理解/自建内层循环时的起点。五工具原语 read/list/edit/bash/search + while 回灌循环,完整骨架见 §6。约 300 行即可跑起来。
while True:
response = model.infer(conversation, tools)
if response.has_tool_calls():
for call in response.tool_calls:
conversation += [ tool_result(tools[call.name].run(call.args)) ]
continue
if is_done(response): break出处 Thorsten Ball / Ghuntley。模型决定调什么工具,harness 执行并回灌——这就是 agent 的全部魔法。
用在:任务跨多个上下文窗口时。initializer 只跑一次,generator 每会话推进,evaluator 独立打分。
# 会话 0: initializer agent —— 只跑一次 - 搭好环境, 写 feature_checklist.json (每项含 pass/fail) - 建立"环境校验仪式"脚本 (verify_env.sh) # 会话 N: generator agent —— 每次会话 1. 先跑 verify_env.sh (环境校验仪式) 2. 读 git log + progress.md + feature_checklist.json 恢复记忆 3. 只推进"下一个未完成 feature" (别一口气想做太多) 4. 端到端测试(含浏览器) 必须过 5. 描述性 commit + 更新 progress.md (clean state) 交下一会话 # evaluator agent —— 独立于 generator - 按显式"契约(done 的定义)"打分; 不达标打回 - 长任务用 context reset 而非 compaction
出处 Anthropic《Effective Harnesses…》《Harness Design…》。记忆桥 = git 历史 + 进度日志 + checklist。
用在:决定该不该上多 agent。四问全 Yes 才上,任一 No 退回单线程。
[ ] breadth-first 可并行? [ ] 子任务弱依赖 / 无需连续共享决策? [ ] 价值撑得起 ≈15× token? [ ] 能共享完整 context+traces, 避免看不见彼此假设? → 全 Yes: orchestrator-worker 多 agent (Anthropic: +90.2% / ~15× token) → 任一 No: 单线程线性 agent 或 workflow (Cognition: 单线程优先)
出处 Cognition / Anthropic。默认单线程,多 agent 是需要论证才配得上的例外。
{ AGENTS.md 约束 | pre-commit hook | 一个 review subagent } → 让同类错误永不复发。你的 harness 就是一部「踩坑史」的物化。按 5 组分类。想深挖某一件事就顺着链接回一手来源。诚实标注:partial 的两篇正文在订阅墙后,只用了可见开篇;命名爆发期几篇确切发表日未标注。
while :; do cat PROMPT.md | agent; done,文件系统/git 当记忆绕过 context rot;$297 造出 CURSED 语言。specs/,规格是可复用单一真相源,代码可反复重生。.cursor/rules/*.mdc 规则当标准库沉淀组合;「you can program LLM outcomes」。--max-iterations 是首要安全阀。12 道题,覆盖公式、三层区分、五大件、双控制、长时 agent、单 vs 多 agent、工具与上下文。选错会立刻告诉你为什么错,并给出「重读 §X →」锚点。全对才算通关,未过可重置重考。