青蛙小白

Harness Engineering(驾驭工程)

驾驭工程(Harness Engineering) 是将包裹 LLM 的 基础设施层(agent harness / execution harness) 视为独立工程面的系统方法论。名称源自 “harness” 的驾驭含义:不是限制模型能力,而是把能力引导到正确方向。

区别于Prompt Engineering(提示工程)(优化模型输入)和Context Engineering(上下文工程)(优化模型每步看到什么),驾驭工程优化的是模型如何运行——执行环境、工具接口、上下文管理、生命周期编排、可观测性、验证与治理等基础设施层的总体质量。

OpenAI 对 Codex CLI harness 的拆解给出了一个具体例子:Codex harness 负责构造包含指令、工具 schema、权限说明、项目文档、技能元数据和环境上下文的输入,通过 Responses API(响应 API)驱动 Agent Loop(智能体循环),再执行工具调用、转发流式事件、管理上下文窗口和缓存命中。

OpenAI 2025 年 3 月发布的 Agent 工具栈展示了另一种平台化方向:Responses API(响应 API)提供内置 Web search、File search 和 Computer use 工具,OpenAI Agents SDK提供 Agent、handoff、guardrail 和 tracing 原语。也就是说,一部分 harness 能力正在从应用代码下沉到平台层,但业务权限、风险分级、验证标准和人工确认仍然必须由应用侧定义。

OpenAI 2026 年 4 月 15 日对 Agents SDK 的更新把这个平台化方向推进到执行层:SDK harness 不只管理 Agent、handoff 和 trace,还开始标准化文件检查、命令执行、代码编辑、沙箱运行、工作区 Manifest、snapshot 与 rehydration。它说明“harness”正在从应用内部的手写循环,演化成模型提供商和沙箱生态共同提供的一层标准基础设施。

这里要区分对象和方法论:agent harness 指那套非模型基础设施本身;harness engineering 指设计、评估和演进这套基础设施的方法论。为了避免词条碎片化,本库不单独拆出 “Agent Harness” 词条,而是在本页统一讨论。

Viv Trivedy 在《The Anatomy of an Agent Harness》中把这条边界压缩成一个便于检查的公式:Agent = Model + Harness。模型负责推理与决策;除此之外,系统提示、工具与 Skill(技能)、文件系统、Agent Sandbox(Agent 沙箱)、浏览器、子 Agent 编排、上下文压缩、继续执行 hook 和 lint 检查,都属于 harness。这个定义不是说模型不重要,而是提醒工程师:凡是模型原生做不到、但产品又要求 Agent 稳定做到的行为,都必须在模型外找到可执行的实现位置。

文章的第一张架构图把 harness 归纳为围绕模型的五类接口:

flowchart TB
    C["上下文注入\nprompt / memory / skills / conversation"] --> M["模型\n推理与决策"]
    K["控制\ncompaction / orchestration / Ralph loop"] --> M
    M --> A["行动\nbash / tools / MCP"]
    A -.->|"结果回到上下文"| M
    M --> P["持久化\nfilesystem / git / progress files"]
    P -.->|"读取状态"| M
    M --> V["观察与验证\nbrowser / screenshots / tests / logs"]
    V -.->|"反馈"| M

这五类接口对应的不是一张静态组件清单,而是一组从期望行为反推外部机制的设计关系:

期望 Agent 做到什么Harness 增加什么
持久处理真实数据文件系统 + Git
自主编写并执行代码Bash + 代码执行
在安全且开箱可用的环境工作沙箱 + 默认工具链
记住旧信息并访问新知识Memory 文件 + Web 搜索 + MCP
长上下文中维持性能压缩 + 工具结果清除 + Skill 渐进披露
完成长时任务Ralph Loop + 规划 + 验证

这里最值得保留的设计方法是:先写清楚模型缺失的行为,再决定 harness 原语;不要先堆工具,再期待模型自己发现这些工具为何存在。

这里的 工具结果清除(Tool Result Clearing,原文也称 Tool Call Offloading) 不是停止工具,也不是销毁结果,而是把大体积工具输出移出模型的活跃上下文视图。关键实现是把“完整事件存储”与“下一次请求发给模型的消息列表”分开:Harness 可以永久保存原始结果,但每次调用模型前重新投影一份精简消息列表。保存到磁盘本身不会省 token;只有下一次请求不再携带原文,卸载才真正发生。

常见实现有两个时间点:

  1. 模型读取前截断:测试命令产生 20,000 行日志后,Harness 立即把完整结果写入 /tmp/test.log,只把头尾片段、错误摘要和路径作为 tool 消息发给模型。模型从未一次性看到全部日志,需要细节时再调用 greptail 或分段读取工具。
  2. 模型读取后清除:如果某次模型调用确实读过完整日志,那么这一次调用的 token 成本已经发生,无法追回。但在再下一次调用前,Harness 可以把历史中的那条巨大 tool 消息替换成“日志路径 + 已确认结论 + 关键错误”,不再原样重放 20,000 行。

还有一种相邻但更彻底的方案是 Subagent(子智能体)上下文隔离:主 Agent 不读取完整日志,只把“分析 /tmp/test.log,返回失败用例、根因、证据行号和建议动作”委派给独立上下文的子 Agent。搜索、分段读取和推理轨迹都留在子线程,主线程只接收结构化结论。它减少的是主 Agent 的上下文污染,但不会让成本凭空消失——子 Agent 仍要消耗 token;如果它也一次性吞入 20,000 行,同样可能发生 Context Rot。更好的组合是让子 Agent 通过 grepsedtail 等工具按需读取,再返回带文件路径和行号的短报告。

第二种方式之所以可行,是因为多数 Agent Loop 并不是让模型自己保存对话,而是由 Harness 组装每次 API 请求。概念上,它维护两份表示:

完整存储:tool_call_17 -> 20,000 行原始日志或文件引用
模型视图:tool_call_17 -> 失败用例 A/B/C;完整日志见 /tmp/test.log

如果使用的服务端会话 API 会自动、不可变地续接全部历史,仅把日志另存到文件并不能卸载;Harness 还必须使用该平台的 tool-result clearing、compaction,或从精简状态开启新的分支/会话。它与上下文压缩的区别在于:工具结果清除针对单个工具输出持续、局部地替换;上下文压缩通常对整段历史做全局摘要。两者都通过减少实际发送给模型的 token 来缓解 Context Rot(上下文腐烂)

文章的第三张图还提出一个重要的模型—Harness 共同演化回路:工程团队先发现有效原语,把它标准化进产品 harness,再让下一代模型在这套 harness 中接受后训练;模型因此更擅长使用这些原语,而新的使用经验又会催生下一轮 harness 设计。

flowchart LR
    D["发现有效原语\nskills / compaction / Ralph loops"] --> H["加入 Harness\n标准化进产品"]
    H --> T["训练下一代模型\n将 Harness 放进训练回路"]
    T --> I["模型更擅长使用 Harness"]
    I --> D

共同演化同时会带来接口耦合:模型可能对训练时见过的工具名称、参数形状或编辑协议形成偏好,替换一个语义相近的工具仍可能使表现下降。因此不能把 harness 当成对模型透明的包装层;工具接口变更需要像模型升级一样经过 Evals(评估)和回归测试。另一方面,“原厂 harness”也不必然对所有任务最优,特定任务仍可能从有针对性的工具、上下文和验证设计中获得更大收益。

绑定约束论题(Binding Constraint Thesis)

驾驭工程的核心主张:真实世界 Agent 可靠性的绑定约束是 harness,而非模型本身。

三个近期实证印证(均来自 2025–2026 年):

  • 仅修改工具格式与 harness 配置,无需改动模型权重,在 15 个模型的编程 benchmark 上提升高达 10×
  • 通过系统 prompt 重构、中间件上下文注入、自验证 hook,在 Terminal-Bench 2.0 从 52.8% 提升至 66.5%(+13.7pp),完全来自基础设施变更
  • 自动化 harness 优化(Meta-Harness)在 Terminal-Bench-2 达到 76.4%,超越所有手工调优方案且未修改模型权重

这些增益超过同一 benchmark 上模型升级通常带来的 2–4pp 改进。OpenAI 在 2026 年 2 月明确将 harness engineering 定义为一门独立学科;Anthropic 的工程博客从多个方向得出相同结论;Martin Fowler 网站将其描述为围绕 LLM 形成 控制论调速器(cybernetic governors) 的工程方法。

三阶段工程演进

工程杠杆点随 Agent 能力成熟而上移:

阶段时期核心问题工程范围
Prompt Engineering(提示工程)2022–2024如何有效地问 AI优化单次文本输入
Context Engineering(上下文工程)2025模型每步应看到什么多步上下文管理
驾驭工程2026整个系统如何可靠运行七层基础设施全栈

三阶段是包含关系,不是替代关系:驾驭工程包含上下文工程,上下文工程包含提示工程。Loop 里的每次 Agent 调用仍然需要好的 Prompt、充足的 Context;驾驭工程只是把杠杆点向上移动了一层,优化模型运行所在的系统,而非模型本身的输入。

生产 Harness 的组成

从 Anthropic、OpenAI、LangChain 等实践中可以把生产 Agent harness 归纳为一组相互耦合的部件:

  • 编排循环:组装输入、调用模型、解析输出、执行工具、把观察结果追加回上下文,再重复直到停止;这是 Agent Loop(智能体循环)的运行核心。
  • 工具层:管理工具 schema、注册、参数校验、权限检查、沙箱执行、结果捕获和错误包装;工具越多,能力越大,选择错误率和上下文成本也越高。
  • 记忆与状态:把短期会话历史、长期 Agent Memory(Agent 记忆)、checkpoint、progress file、数据库记录或 git commit 组合起来,使任务可恢复、可审计、可续接。
  • 上下文管理:通过压缩、观察遮蔽、按需检索和子 Agent 摘要控制 Context Rot(上下文腐烂),只把当前步骤最需要的高信号 token 放进窗口。
  • Prompt 构造与输出解析:按优先级组织系统指令、开发者指令、项目规则、工具定义和用户请求;用原生 tool calling 或结构化输出区分最终回答、工具调用、handoff 与格式错误。
  • 错误处理:把瞬时错误、模型可恢复错误、用户可修复错误和意外异常分开处理;可恢复错误应作为结构化观察返回给模型,而不是静默吞掉。
  • 护栏、权限与沙箱:把“模型想做什么”和“系统允许做什么”分开,由工具层、权限系统、Agent Guardrails(Agent 护栏)Agent Sandbox(Agent 沙箱)决定动作是否能执行。
  • 验证与终止:用测试、lint、类型检查、截图、独立 reviewer 或 Evals(评估)判断进展,并设置最大 turn、token、成本、连续失败次数、人工审批和安全拒绝等停止条件。
  • 子 Agent 编排:在工具集过载、任务域分离或需要独立审查时,把子任务交给专门 Agent;多 Agent 并行通常需要 Agent Worktree(Agent 工作树)隔离状态。

这组部件说明:harness 的复杂性不在”写一个 while 循环”,而在循环周围如何管理上下文、权限、错误、状态、成本和验证信号。

Deep Agents把这组部件产品化为四个控制面:执行环境(工具、虚拟文件系统、权限、sandbox / interpreter)、上下文管理(Skill、memory、摘要、卸载、prompt caching)、委派(todo 规划与 subagent)和 steering(人工中断)。这个例子进一步说明 agent framework 与 agent harness 的差别:前者可以只提供模型—工具循环,后者还要为真实长任务提供状态、隔离和控制。

OpenAI 的 Codex Prompting Guide 进一步说明,coding-agent harness 的效果会被很多“看似实现细节”的接口形状影响:shell 工具是否强制 workdir、文件修改是否有 apply_patch、计划工具是否有稳定状态枚举、并行工具调用是否被显式鼓励、工具输出是否按固定规则截断、assistant preamble 是否带 phase 元数据。这些都不是模型之外的杂务,而是模型实际工作的操作界面。

数据研发实践中的三层六支柱

曹亚龙在阿里云开发者文章《数据研发 Multi-Agent 架构的 Harness 工程实践》中,按一次任务的生命周期把 harness 归纳成身份层、执行层、进化层。这是作者基于数仓研发系统总结的落地框架,并非行业统一标准;它的价值在于把上面的组件清单重新组织成“执行前定边界、执行中保可靠、执行后把错误工程化”的闭环。

flowchart TB
    I["身份层:Identity\n角色 / 工具能力 / 行为约束"] --> X["执行层\nOrchestration / Context / Gate / Recovery"]
    X --> E["进化层:Evolution\n违规记录 / 经验加载 / 约束迭代"]
    E -->|"更精确的身份与约束"| I
    X -->|"质量结果与失败样本"| E

六个支柱分别消除一类系统性失效:

支柱要回答的问题数据研发案例中的实现
Identity谁负责什么,什么绝对不能做?协调者只调度、审查和汇报;需求、方案、SQL、测试由 specialist 分工;约束分为红线、错误记录、操作规则
Orchestration按什么路径和顺序执行?全链路、快案、快码与单点模式共用同一能力;有依赖串行、无依赖并行;修改按轻量、中等、重大匹配不同流程
Context每一步能看到什么?按阶段加载指令;阶段结束生成 checkpoint 摘要;规范渐进加载;Agent 之间通过结构化 Spec 文件而非完整对话交接
Gate产出是否达标?工具可用性、上游产物、SQL 语法和阶段切换均设检查点;强制检查不能由 Agent 自行豁免;生成者与评估者分离
Recovery当前在哪,失败后从哪继续?状态机和中间文件持久化;失败分为自动重试、回退到稳定点、停止并请求人工介入
Evolution一次错误怎样减少再次发生?错误实时结构化记录并在后续任务中加载;反复出现的错误升级为红线、自动检查或流程门禁

这套划分也揭示了两个容易混淆的边界。Identity 的约束属于前馈控制,Gate 的验收属于反馈控制,两者不能互相替代;Evolution 也不等于让模型“记住教训”,而是把教训转成下一轮可执行的规则、检查或编排变化。后者与Agent Memory(Agent 记忆)有关,但最终落点仍是可版本化、可评估的 harness 机制。

Evaluation Harness 与 Agent Harness

Anthropic 在 Agent eval 实践里明确区分两类 harness:

  • Agent harness / scaffold:让模型作为 Agent 行动的执行系统,负责输入组织、工具调用、状态更新和终止。
  • Evaluation harness:运行评估的外部系统,负责分发 task、创建干净环境、并发运行 trial、记录 trajectory、调用 grader、聚合指标。

这一区分很关键:评估一个 Agent 时,被测对象不是模型本身,而是模型 + agent harness + 工具 + 环境 的组合。Evaluation harness 则是测量系统,必须尽量避免把自身噪声混进结果。

一个可靠 evaluation harness 至少要满足四点:

  • 环境隔离:每个 trial 从干净状态启动,避免文件残留、缓存、git history 或共享数据库让后续 trial 获得不公平优势。
  • 轨迹完整:记录消息、工具调用、推理摘要、工具输出、环境更新、token、延迟和错误,方便人工读 transcript 判断 grader 是否公平。
  • 结果优先:优先检查最终环境状态和产物,而不是强制 Agent 走某条工具调用路径;路径检查只用于必要约束。
  • 可复跑基线:同一 suite 能在模型升级、prompt 改动、工具接口变化和 harness 改动后重复运行,形成 baseline 与 regression gate。

这也解释了为什么 Agent Sandbox(Agent 沙箱)不仅是安全组件,也是评估组件:没有可重置、可隔离、可观测的执行环境,Agent eval 的 trial 之间就不是独立样本。

长时 Agent Harness

Anthropic 的 Long-running Agent Harness 案例展示了 harness 在跨多个上下文窗口时的另一条边界:compaction 不等于连续性。即使模型能自动压缩上下文,后一轮 Agent 仍可能拿不到足够清楚的交接信息,结果要么在半成品上猜测,要么看到部分进展后过早宣布完成。

可工作的长时 harness 需要把连续性外化到环境里:第一次运行由 initializer agent 生成 feature_list.jsoninit.shclaude-progress.txt 和初始 git commit;后续 coding agent 每轮只做一个功能,启动时读进度和 git log,先跑基础端到端测试,结束时提交增量并更新进度。这里的 git、progress file、feature list 共同构成 Agent Memory(Agent 记忆),浏览器自动化和 passes 字段则构成 Evals(评估)

这个模式把 harness 从“一次执行的工具壳”扩展为“跨班次工作的接力制度”。它不替代 Durable Execution(持久执行):前者让新上下文窗口知道任务状态,后者让运行时在崩溃后从正确步骤恢复。

Harness 与 compute 分离

OpenAI 的 Agents SDK 更新明确提出一个生产边界:把可信 harness 与不可信 compute 分开。Harness 保留 agent loop、工具编排、memory、凭证与状态;sandbox/compute 只执行模型生成的文件操作、shell 命令、代码运行和依赖安装。这样设计的直接收益有三类:

  • 安全:凭证和内部 API 不进入模型生成代码所在的沙箱,prompt injection 即使影响了执行命令,也更难直接读到密钥。
  • 持久性:Agent 状态外置到 harness,沙箱容器失败或过期后,可以用 snapshot 和 rehydration 在新容器中恢复运行。
  • 扩展性:一个 run 可以按需调用一个或多个沙箱,也可以把 Subagent(子智能体)路由到隔离环境,并行处理文件、测试或数据任务。
flowchart LR
    H["可信 harness\nagent loop / memory / secrets / tools"] -->|"受控命令与文件操作"| C["非可信 sandbox / compute\nshell / code / filesystem"]
    H -->|"直接访问"| D["数据库 / API / Web"]
    C -->|"产物与日志"| H
    H -->|"snapshot / rehydrate"| R["恢复后的新 sandbox"]

这个分离强化了 harness engineering 的核心观点:可靠 Agent 系统不是“模型 + 容器”就够了。真正的控制面在 harness:它决定哪些状态被保存、哪些动作进入沙箱、哪些凭证永不下放、失败后从哪里恢复。

Anthropic 的 Claude Managed Agents 把同一条边界推进成托管平台抽象:session、orchestration、harness、sandbox、resources、tools 都有稳定接口,具体实现可以替换。session 是 append-only 事件日志,harness 通过 getEvents() 选择性读取并用 emitEvent() 追加进展;sandbox 只通过 provision({resources})execute(name, input) -> String 被调用。这样容器失败只是一次工具错误,而不是整个 Agent 失联。

flowchart LR
    S["Session\nappend-only log"] <--> H["Harness\nClaude + loop"]
    H <--> B["Sandbox\nexecute / provision"]
    H <--> T["Tools / MCP"]
    O["Orchestration\nwake(session_id)"] <--> H

这也是 meta-harness 的设计方式:对接口有强约束,对接口背后的 harness、sandbox、调度器和工具实现保持可替换。它解决的不是“今天这个模型需要什么脚手架”,而是“模型能力继续变化时,哪些边界不该跟着重写”。

Claude Managed Agents 的早期反例是把 session、harness 和 sandbox 都放进同一个容器:文件编辑可以直接走 syscall,服务边界也少,但容器会变成不可丢失的状态实体。容器崩溃会丢 session,容器卡死时只剩 WebSocket 事件流可观察;客户接入自有 VPC 时,还会迫使 harness 跟执行环境同处一地。拆开之后,“脑”可以留在托管控制面,“手”可以是云 sandbox、自托管 sandbox、MCP 工具或其他执行环境。

工具不是越多越好

Harness 的工具层容易被误解成"能力越多越强"。实际设计里,工具数量增加会同时增加三种成本:工具说明占用上下文、模型选择动作的分支数变多、错误路径更难诊断。

Vercel 的 text-to-SQL 案例提供了一个反例:起初为 Agent 配置大量专用工具,后来删掉大部分专用工具,只保留 grep、cat、find、ls 等基础文件工具,让模型直接读取 schema 文件再生成 SQL,成功率和效率反而提升。它说明好的 harness 不是把所有 API 都暴露给模型,而是给模型一组足够稳定、可组合、低歧义的操作原语。

工具层的目标是降低不确定性,而不是展示能力清单。每新增一个工具,都应该回答:它是否显著减少任务步骤?是否比基础工具更不容易误用?失败时是否容易被 Evals(评估)捕捉?如果答案不清楚,少工具往往更稳。

Writer-Checker 子 Agent 分离

多 Agent 场景下最有价值的结构是写作者(Writer)与检查者(Checker)分离:主 Agent 生成输出,独立的 Reviewer 子 Agent 用干净的上下文窗口校验。同一模型审查自己的输出,天然宽松——它太了解自己的”意图”了;独立 Reviewer 才能抓住写作者说服自己接受的错误。这正是让 Loop Engineering(循环工程)在无人值守时依然可信的技术基础。规则:生成者不宣布完成。

Dynamic Workflows(动态工作流)把这些部件集中暴露为 Workflow Runtime:模型负责按目标生成编排脚本,Runtime 负责调度 subagent、管理中间状态、控制并发、记录日志、处理失败并触发验证节点。没有这层 Runtime,所谓“动态编排”很容易只是一个更长的 prompt,而不是可审计、可恢复、可复跑的执行系统。

Claude Code Harness 目录布局

以 Claude Code 为参照,整个 harness 住在一个目录里——.claude/。理解这套布局可以在几秒内读懂任何人的 harness 配置:

.claude/
├─ CLAUDE.md          # 常驻事实——每次会话都读
├─ settings.json      # 权限、模型选择、hooks
├─ .mcp.json          # 外部工具连接(MCP 服务器)
├─ rules/             # 路径范围限定的行为规则
│  ├─ tests.md
│  └─ python-types.md
├─ agents/            # 子 Agent 定义(每个约 30 行)
│  ├─ reviewer.md
│  └─ eval-runner.md
├─ skills/            # 可复用工作流
│  └─ pr-checklist/
│     └─ SKILL.md
└─ agent-memory/      # 在会话间存活的状态
   └─ STATE.md

这套结构体现了 harness 的四件事分工:常驻事实(CLAUDE.md)、权限与约束(settings.json + hooks)、工具接入(.mcp.json)、可复用知识(rules/ + skills/ + agents/)、跨轮状态(agent-memory/)。

判断 harness 是否健康的粗略规则:能不能用一句话解释这个目录下每个文件存在的理由?解释不了的,删掉。

Settings.json:权限一次设好

默认 harness 对每个有风险的操作都弹出确认。settings.json 是把安全操作预批准、危险操作永久拒绝的地方——避免循环在无人值守时卡在权限弹窗上:

{
  "model": "claude-sonnet-4-6",
  "permissions": {
    "autoApprove": [
      "Read(*)", "Grep(*)",
      "Bash(npm test)", "Bash(git status)"
    ],
    "deny": [
      "Bash(rm -rf*)", "Bash(git push*)",
      "Edit(.env*)", "Edit(secrets/*)"
    ]
  }
}

判断原则:这个操作出错后撤销成本低吗?低 → 预批准;高(强推、删文件、改密钥)→ 永久拒绝或弹窗确认。

Hooks:不依赖模型理解的确定性约束

Hook 是在 Agent 生命周期固定时间点执行的 shell 命令,退出码可以阻断动作——H1-H4 护栏是判断,Hook 是确定性执行,模型无法绕过。

几乎每个 harness 都值得配的两个 hook:

"hooks": {
  "PreToolUse": [{
    "matcher": "Bash",
    "command": "./.claude/hooks/block-dangerous.sh"
  }],
  "PostToolUse": [{
    "matcher": "Edit|Write",
    "command": "prettier --write \"$CLAUDE_FILE_PATH\""
  }]
}
  • PreToolUse:在危险命令执行前拦截,exit 2 即阻断。模型说不上话。
  • PostToolUse:每次文件修改后自动格式化,Agent 永远不会提交未格式化代码。

Hook 用于必须发生或绝不能发生的事——安全、格式化、审计日志。判断、权衡是模型的工作,不是 hook 的工作。好的 harness 有一两个锋利的 hook,不是二十个没人能解释的 hook。

打包与复用

一个在一个项目上有效的 harness 是资产。把 skills、agents、rules 打包成插件(Plugin),团队一步安装,获得相同的约定、相同的安全 hook、相同的 Reviewer。Harness 从个人配置变成共享基础设施。

打包前要扫描:泄露的密钥和过宽的权限会随插件传播给所有安装者。deny 规则尤其要在打包前仔细确认。

ETCLOVG:七层结构

ETCLOVG Taxonomy(ETCLOVG 分类法) 将 Agent harness 分为七层(170+ 开源项目的实证映射):

结构核心

控制平面

  • O — 可观测性与运维:trace 收集、成本追踪、故障诊断(Langfuse、OpenTelemetry)
  • V — 验证与评估:五阶段任务到反馈生命周期;评估分数是模型-harness 对的属性
  • G — 治理与安全:权限模型、生命周期 hook、组件加固、声明式宪法、审计基础设施

V 层里的 Evals(评估)不是一个附属报表,而是控制循环的判定器:它决定改动是否保留、循环是否继续、是否需要回滚或升级给人类。没有 Evals,harness 只能执行 Agent 动作;有 Evals,harness 才能把动作变成可改进、可停止、可审计的反馈系统。

Harness 作为控制系统

Harness 的实质是把 Agent 从"随机输出机器"变成可控反馈系统。G 层的四个 hook 点形成围绕 LLM 的控制环路:

flowchart LR
    I["输入"] --> H1["H1 输入护栏"] --> LLM["LLM"] --> H2["H2 动作护栏"] --> T["工具执行"]
    T --> H3["H3 信息流控制"] --> R["结果返回"] --> LLM
    H2 -.->|"关键动作"| H4["H4 人工审批"]
    H4 --> T
  • H1 输入护栏:检测 prompt injection(PromptShield、DataSentinel)
  • H2 动作护栏:在工具执行前验证 LLM 提出的动作(ShieldAgent、ControlValve)
  • H3 信息流控制:工具结果返回上下文前的污点追踪(CaMeL:每个数据值携带溯源元数据标签)
  • H4 人工审批:Codex、Gemini CLI、OpenHands 对破坏性或超出范围的动作要求人工确认

OpenAI 的 Agent guide 给这套控制系统补了一个实用清单:相关性分类器、安全分类器、PII 过滤、Moderation、工具风险分级、规则型保护和输出校验。它们可以由模型、分类器、确定性规则和人工审批共同组成,不要求全部塞进同一个 prompt。

同一种闭环,三次上移

George 在《Harness Engineering Is Cybernetics》中把驾驭工程放进一条更长的控制论演进线:18 世纪的离心调速器把蒸汽机转速闭环,2010 年代的 Kubernetes controller 把集群状态闭环,编码 Agent 则尝试把代码质量闭环。三者都把人的工作从直接操作对象,推向定义目标、设计控制器和校准反馈。

制造业,1780s

flowchart LR
    MS["目标转速"] --> MG["离心调速器"] --> ME["蒸汽机"] --> MO["实际转速"]
    MO -->|"反馈"| MG

基础设施,2010s

flowchart LR
    KS["期望状态"] --> KC["Kubernetes controller"] --> KL["集群"] --> KO["实际状态"]
    KO -->|"协调反馈"| KC

代码库,Agent 时代

flowchart LR
    CS["约定 / 架构约束"] --> CL["LLM + 工具"] --> CB["代码库"] --> CQ["质量信号"]
    CQ -->|"验证反馈"| CL

这张类比的关键不是“LLM 就是 Kubernetes controller”,而是反馈回路闭合的层级上移了。编译器早已能检查语法,测试能检查部分行为,linter 能检查风格;但“改动是否符合架构”“抽象是否会随规模增长而恶化”过去缺少同时具备语义感知与修改能力的传感器和执行器。LLM 让这类高层闭环第一次部分可行。

但“能感知、能修改”只是必要条件,不是充分条件。转速是相对清晰的标量,集群也有明确的期望状态;代码质量却是多维、含语境且经常互相冲突的目标。因此 Agent 闭环更依赖校准:把真实分层和依赖方向写进架构文档,把修复建议写进自定义 linter,把团队判断沉淀为黄金原则,并让测试、CI 和错误输出对 Agent 可运行、可解析、可行动。否则,Agent 不会从重复运行中自动“耳濡目染”,只会以更高速度重复同一种架构漂移。

这也解释了工程师角色为何从“亲手修每个结果”转向“让判断可机器执行”:定义什么叫正确、识别偏离、决定方向,比逐行实现更稀缺。原文借生成—验证不对称说明这一点;它适合作为工程直觉,而不是把软件质量验证简单等同于复杂度理论里的 P vs NP。

编码 Agent 的质量调控(前馈与反馈)

Birgitta Böckeler(Thoughtworks)将编码 Agent 的 Harness 框架为围绕 LLM 形成的控制论调速器(cybernetic governors),并提出两种互补的控制机制:

  • Guides(引导)/ 前馈控制(feedforward):在 Agent 行动前介入,提高初始输出正确的概率。典型形式:CLAUDE.md 架构文档、技能规范、测试要求、性能指标,以及技术栈约定。
  • Sensors(传感)/ 反馈控制(feedback):在 Agent 行动后观察结果,触发自我修正。典型形式:测试运行器、lint 工具、类型检查器、架构合规检查器、独立 Review Agent。反馈控制在优化为 LLM 解读时最有效(清晰的错误信息 > 模糊的退出码)。

传感器按执行方式分为两类:

类型执行方式速度可靠性适合捕捉
计算型(Computational)确定性,CPU毫秒~秒极高结构性问题(重复、复杂度、覆盖率、风格)
推理型(Inferential)AI 语义分析,GPU/NPU秒~分钟中等语义性问题(冗余逻辑、过度设计、意图偏差)

三类质量调控维度

编码 Agent 的 Harness 可按质量维度分为三个相互独立的调控域:

可维护性(Maintainability):目前最成熟。现有工具链可直接复用——计算型传感器可靠捕捉重复代码、圈复杂度、覆盖率缺口、风格违规;推理型传感器可部分识别冗余逻辑和过度设计。剩余盲区:诊断错误、不必要功能、指令理解偏差,依然需要人类判断。

架构合规(Architecture Fitness):将「架构适应性函数(Fitness Functions)」编码为可测量约束——前馈侧把性能要求和可观测性标准(日志格式、trace 规范)写进 Skill;反馈侧用性能测试和调试指令让 Agent 自行反思架构问题。

行为验证(Behaviour):目前最不成熟。多数团队仅靠功能规格(前馈)+ AI 生成测试套件 + 人工测试(反馈),提供的信心不足以支持自主部署。新兴模式是「批准夹具(approved fixtures)」——预置经人工验证的场景集,用于自动化行为验收。

Keep Quality Left(质量左移)

质量检查的时序原则:越快、越轻量的检查越靠前,越重的检查异步或延后

阶段检查内容
集成前Language Server、架构文档引导、快速 lint、基础 Review Agent
集成后 Pipeline变异测试、完整代码 Review Agent、更广泛架构分析
持续监控漂移检测(死代码、覆盖质量、依赖演化)、运行时反馈(SLO 降级、输出质量采样)

Agent 生成代码的速度远超人工审查能力,及早捕获问题使修复成本接近零。这与 Harness 的绑定约束论题一致:将更多约束力前置到引导层,而非依赖事后修复。

Harnessability(可驾驭性)

可驾驭性(Harnessability) 是代码库的一种结构属性,描述它对 Agent 控制的天然友好程度——“环境本身使 Agent 能够读懂、能够导航、能够有效处理的结构性前提”。

高可驾驭性代码库的典型特征:强类型系统(减少 Agent 猜测空间)、明确的模块边界(变更影响可推断)、确立的框架约定(减少设计决策负担)。Greenfield 项目可在早期嵌入可驾驭性;遗留代码库的改造成本更高,引入 Agent 前先提升可驾驭性是合理投资。

与 Ashby 必要变种定律的关系:将 Agent 限定在固定服务拓扑(CRUD 服务、事件处理器、仪表盘)会收缩 Agent 的输出变种空间,使全面调控变得可行。拓扑定义是一种"变种收缩动作(variety-reduction move)"。

Harness 模板

一个新兴模式是将常见服务拓扑的 Guides 和 Sensors 捆绑为可实例化的 Harness 模板——类似于服务模板,团队可版本化、复用、治理。Harness 本身成为可管理的资产,而非散落在各处的配置脚本。

常见约束形式(G 层实践)

行为护栏(Behavioral Rails)

明确规定 Agent 不能做什么:

  • 不能删除测试
  • 不能修改 public API
  • 不能直接向 main 分支提交
  • 不能在未审查情况下执行数据库迁移

权限边界(Permission Scope)

最小权限原则:Agent 只获得完成当前任务的最小权限集。生产环境、账单系统、用户数据相关操作必须人工审批。

工具权限还应按风险分级:只读、可逆、局部影响的工具可以自动执行;不可逆、涉及资金、隐私或生产系统的工具应触发 Agent Guardrails(Agent 护栏)中的额外检查或人工审批。这个分级比简单的 allow/deny 更贴近生产场景。

声明式宪法(Declarative Constitutions)

将治理规则外化到声明式配置文件(YAML、DSL)而非硬编码到应用逻辑:

  • 训练时宪法(Anthropic Constitutional AI):四层优先级——安全 > 伦理 > 合规 > 有用性
  • 部署时 YAML(AutoHarness):pipeline 模式、风险分类、allowed/denied tool 模式、token 预算、审计日志目标
  • 编程策略 DSL(Progent):布尔谓词+量词,运行时最小权限策略

停止条件(Stop Conditions)

  • 连续失败 N 次后停止,而非无限重试
  • 检测到高风险操作时暂停等待人工确认
  • 上下文窗口接近上限时主动压缩或归档状态

跨层工程挑战

Harness 的层不是独立的——三个跨层问题无法在单层内解决:

成本-质量-速度三元悖论:更强沙箱 + 更深评估 + 更严治理增加延迟和成本。生产系统必须显式决定哪些检查同步、哪些异步、哪些放入回归套件。

能力-控制权衡:每次扩展工具菜单或放宽沙箱权限都增大控制问题。这是设计轴而非独立变量——工具菜单扩大 = 选择错误率上升 + prompt injection 攻击面扩大。

Harness 耦合问题:本地优化可能产生全局回退。Prompt 改动影响 token 消耗和 cache 命中率;工具描述变更既消耗上下文预算又改变模型行为;评估分数因此无法干净地归因于模型——harness 变更(tool schema、verifier、recovery loop)同样会改变测量到的行为。

Codex 的工程实践也说明,harness 变更会直接影响成本:工具列表顺序、模型特定 instructions、沙箱配置、审批模式和当前工作目录都会改变 prompt 前缀,进而影响Prompt Caching(提示缓存)命中率。性能优化因此不是 API 调用层的小细节,而是 harness 结构设计的一部分。

Harness 假设原则

每个 harness 组件都编码了一条关于模型不能自主完成什么的假设;随着模型改进,这些假设会变得陈旧。(Anthropic, 2026c)

Anthropic 在实践中验证了这一点:为 Opus 4.5 设计的上下文重置在 Opus 4.6 上变得多余,移除后在维持输出质量的同时将成本从 $200 削减至 $125。这意味着 harness 本身需要随模型能力改进而持续简化,而不是单调地增加脚手架。

Agent-First 开发的实证

OpenAI 于 2025 年 8 月启动了一项"零手写代码"实验:用 Codex 完整构建一个内部产品,任何应用代码、测试、CI 配置、文档均由 Agent 生成,人类只负责方向和验收。五个月后的结果:

  • 仓库规模约 100 万行代码(含应用逻辑、基础设施、文档)
  • 约 1,500 个 PR 合并,团队规模从 3 人扩展到 7 人
  • 平均吞吐 3.5 PR/工程师/天,且随团队增长吞吐持续提升
  • 估计约为手写代码速度的 10 倍

这个实验给 harness engineering 带来几个关键洞见:

三层控制面

把这套实践压缩来看,支撑 Agent-first 代码库的 Harness 可以归纳为三个相互咬合的控制面:

控制面要解决的问题典型实现
上下文工程Agent 此刻是否看见正确的信息仓库内文档、按需检索、上下文压缩、文件系统与 Git 持久状态
架构约束Agent 是否沿着团队认可的结构扩展系统固定分层、依赖方向、自定义 linter、测试与可行动的错误信息
熵控制大量生成之后,局部妥协是否持续污染代码库黄金原则、定期扫描、文档园丁与清理 Agent、小步偿还技术债

三层缺一不可:只给上下文,Agent 能找到代码却仍可能复制坏模式;只有架构规则,没有反馈检查,规则只是愿望;只做事后清理,则会把高吞吐变成更快积累技术债。真正的 Harness 是把信息供给、行动约束、偏差纠正闭合成持续运转的回路。

这也解释了许多 Agent 失败为什么不是“模型不够聪明”:所谓“好代码是什么样”“哪些依赖方向值得奖励”“何时算真正完成”,往往仍锁在工程师脑中。Agent 不会仅凭长期待在仓库里就自动吸收这些判断;若它们没有被外部化为文档、linter、测试、日志和停止条件,第 100 次运行仍可能重复第 1 次的错误。

工程师角色重新定义。当代码由 Agent 生成,工程师不再主要写代码,而是设计环境(design environments)、规定意图(specify intent)、构建反馈循环(build feedback loops)。核心范式:"人类掌舵,Agent 执行(Humans steer, agents execute)"。

当遇到失败时,正确反应几乎从不是"更努力地提示",而是定位缺失的能力并问:“这个能力如何对 Agent 变得可读、可执行?”

吞吐量改变合并哲学。当 Agent 产出速度远超人工 Review 能力,纠错很便宜、等待却很昂贵。与低吞吐环境相反,许多常规工程规范(强阻塞合并门禁、等待 flaky 测试稳定)反而成为瓶颈。短生命周期 PR + 跟进修复 + Agent-to-Agent Review 替代了人工强 Review 流程。

架构约束是速度的前提。刚性分层架构(每个业务域有固定的 Types → Config → Repo → Service → Runtime → UI 依赖方向)通常被推迟到有数百名工程师时才实施。但在 Agent-first 仓库里,这些约束必须尽早建立——约束是不让速度衰减的机制。自动 linter 强制执行这些规则,且 linter 错误信息本身被设计成注入 Agent 上下文的修复指令。

知识可读性与熵控制

Agent 可读性原则

Harness 的知识层遵循一个核心原则——Agent 可读性(Agent Legibility)Agent 在运行时无法访问的任何信息,对它等同于不存在。

Slack 讨论、Google Docs、口头决策、人的记忆——这些都在 Agent 的可见范围之外。每一条重要决策和约定,都必须以版本化 Markdown 的形式落入仓库,才能对 Agent 产生效果。这要求把 AGENTS.md 设计为"目录"而非"百科全书"(约 100 行,指向 docs/ 各专题文档),并用 linter + CI 机械验证知识库的新鲜度。

黄金原则与熵控制

Agent 会复制仓库中已有的模式——包括不完善的模式。随时间积累,这会产生漂移(drift),早期团队称之为"AI slop",每周需花费 20% 时间手工清理。

这不可持续。解决方案是"黄金原则(golden principles)"+ 递归清理

  • 将质量标准和设计偏好编码为仓库内的可机械检查规则(“优先用共享 utility 包而非自造 helpers”、“在边界解析数据 shape 而非假设类型”)
  • 定期运行"文档园丁(doc-gardening)“Agent:扫描过期文档、违反黄金原则的代码,开修复 PR(大多数不到一分钟就能 review 并自动合并)
  • 技术债是高息贷款"——持续小步偿还远优于让其复利后集中处理

结果:人的判断和品味被捕获一次,然后持续作用在每一行 Agent 生成的代码上。这是 harness 把技术债纳入可控反馈系统的机制。

跨会话任务连续性(Multi-Session Continuity)

长时间编码任务的一个特有挑战:任务所需工作量远超单个上下文窗口。每个新会话的 Agent 和换班工程师一样,对上一班发生了什么一无所知。

Anthropic 在用 Claude Opus 4.5 构建 claude.ai 克隆的实验中给出了一套具体模式:初始化者-执行者分工(Initializer-Coder Split)

初始化者 Agent(Initializer Agent)

第一个会话不做功能开发,只建立后续所有会话共享的基础设施:

  • init.sh:可重现的环境启动脚本,后续每个会话开始时运行,确保一致的起始状态
  • claude-progress.txt:工作历史文档,记录已完成内容、已知问题、下一步入口;每次会话结束后更新
  • 功能列表 JSON:200+ 条粒度化需求,每条包含 categorydescription、操作步骤和 passes 布尔字段

功能列表是防止"提前完成"失效的核心机制——让后续任何 Agent 会话都能精确知道哪些功能通过、哪些未完成,不会因为看到"进展不错"就宣布完工。关键约束:不允许删除或修改测试——这会导致功能遗漏或 bug 被掩盖。

执行者 Agent(Coding Agent)的标准化启动流程

1. 验证工作目录(pwd)
2. 读取 git 日志与 claude-progress.txt
3. 从功能列表选出最高优先级的未完成项
4. 执行 init.sh,恢复运行环境
5. 运行基础端到端测试
6. 专注开发单个功能直至完成

每次会话结束时:把代码置于"merge-ready"状态、提交含描述的 commit、更新 claude-progress.txt。

四类失效与对应方案

失效模式表现Harness 应对
过度野心(Over-Ambition)试图一次会话完成整个应用,上下文中途耗尽强制单次会话只做一个功能
提前完成(Premature Completion)后续 Agent 看到进展后宣布项目完成详细功能列表防止误判完成状态
测试不充分Agent 改了代码但没做端到端验证集成 Puppeteer MCP,进行浏览器自动化测试
文档缺口Agent 离开时环境残缺或无文档强制 git commit + 进度摘要 + 会话开始时健康检查

浏览器自动化作为 Harness 组件

传统单元测试无法捕捉完整用户路径的问题;本模式把浏览器自动化作为 harness 的标准组件:通过 Puppeteer MCP 在真实浏览器环境执行测试,与人工测试等价。Anthropic 观察到:一旦明确提示 Agent 使用浏览器自动化工具,端到端验证质量显著提升。这与"传感器(Sensors)“的前馈/反馈思路一致——不靠 Agent 自我判断,而是给它确定性的验证工具。

当前局限:模型视觉能力尚不能识别某些 UI bug(如浏览器原生 modal alert);单 Agent 与专职多 Agent 团队(测试 Agent、QA Agent、清理 Agent)的最优架构仍是开放问题。

常见 Harness 错误

以下是让每个 Loop 都变差的 harness 反模式:

错误症状纠正方式
跑在默认 harness 上Agent 每次重新推断项目、重复问相同权限写 CLAUDE.md + settings.json
CLAUDE.md 膨胀常驻上下文里塞满流程,真正的规则被挤走流程移入 Skills,路径规则移入 rules/
约束写进 CLAUDE.md 而不是 hooksAgent 偶尔忽略规则把必须/绝不能发生的事写进 PreToolUse hook
写作者自我评分Agent 审查自己的输出,天然宽松加独立 Reviewer 子 Agent(Writer-Checker 分离)
没有状态文件每次循环重新理解世界,无法续接建 agent-memory/STATE.md
把循环套在烂 harness 上循环加速产出垃圾先让单次执行可靠,再加循环
二十个 hooks没人能解释每个 hook 的作用一两个锋利的 hook,其余删掉
打包前不扫描泄露密钥和过宽权限随插件传播发布前审查 deny 规则和 secrets

口诀:先让一次执行可靠,再加循环;先有约束,再给自由。

Harness 持续改进循环

Harness 不是"设计一次、永久运行"的静态配置——它需要随运行证据持续演进。OpenAI 的 Agent Improvement Loop Cookbook 展示了一套具体的改进飞轮:先用 OpenAI Agents SDK 跑出真实 trace,再让人类和模型解释这些 trace,把反馈转成可复跑的 Evals(评估),用 Promptfoo 作为 gate 验证当前行为,最后交给 HALO(层次化 Agent 循环优化) 排序改进建议,并生成 Codex 可执行的 handoff。

它不是一个新的基础模型能力,而是 Harness Engineering 的闭环操作化:把一次运行中学到的东西沉淀为下一轮 harness 修改、回归测试和自动化交接,而不是停留在零散评论里。

flowchart LR
    T["SDK traces\n观察到的真实行为"] --> F["Human + LLM feedback\n解释 trace 中什么重要"]
    F --> E["Promptfoo evals\n生成并验证回归条件"]
    E --> H["HALO diagnosis\n诊断并排序 harness 改动"]
    H --> C["Codex handoff\n把证据交给代码实现"]
    C --> U["Harness update\nPR + validation"]
    U --> T

    A["Automation + heartbeat\n发现新 handoff 并触发 Codex"] -.-> C

这张飞轮图的关键信息是:人类判断不是只在最后审批一次,而是先通过 feedback 进入系统,之后每一轮都会通过 eval、HALO 建议和 handoff 继续复利化。自动化的 heartbeat 可以观察新 handoff 并触发 Codex,但是否全自动合并取决于 gate 可信度和团队策略。

飞轮的五个阶段:

1. Traces — 收集真实执行记录。 Agent 每次运行产生 OpenTelemetry 格式 JSONL,记录模型调用、工具使用、输出产物和 token 消耗。这是改进的原始证据,不是假想的失败场景。

2. Feedback — 人工与 LLM 双轨批注。 领域专家读 trace,指出哪些失败真正重要(“不应把未验证的 NRR 当官方指标”)、哪些正确行为应固化(required observations)、哪些表述需要禁止(prohibited claims)。同一批 trace 再通过模型批注补充人工遗漏的模式。两者分开保存——人工判断是第一性证据,模型洞察是覆盖扩展。

3. Evals — 把反馈固化为可复跑测试。 LLM 将 trace + feedback 转为 Evals(评估)定义(本例中用 Promptfoo),每条测试包含:期望行为描述(rubric)、确定性断言(contains/not-contains)和 llm-rubric judge(阈值 0.8)。这一步使"本次发现的问题"变成"所有未来版本都要跑的回归门”。

4. HALO — 分析全部信号,生成排名建议。 HALO(层次化 Agent 循环优化) 接收 traces + feedback + evals + gate 结果 + 当前 harness config,将故障分类为三类(规则缺失 / 规则存在但未可靠执行 / 实现缺陷),并按影响力排序输出 codex_handoff.md,包含 Executive Summary、Top 3 改动、证据、分章节详细建议和机器可读的 top_priorities JSON。

5. Codex — 实施改进,重启飞轮。 开发者(或 Codex 自动化)依据 handoff 文档实施变更,跑 eval gate 验证通过后合并,产生新版 harness;新版 harness 再运行 → 新 trace → 下一轮。

HALO 输入上下文

Cookbook 把不同来源统一包装成 HALO 可分析的上下文,而不是让优化器只看失败文本:

输入信号数量作用
当前 harness config1系统 prompt、模型设置、工具策略和 eval 元数据
SDK execution traces5Agent 步骤、工具调用和最终输出
Human feedback5专家认为必须出现或不得出现的观测
LLM feedback5模型补充的失败模式和 caveat
Generated eval definitions5从反馈生成的期望行为、rubric、正反例
Promptfoo row results5每条 eval 的通过/失败和解释
Promptfoo gate summary1整个 suite 的总览结果

这种做法的价值在于让 HALO 同时看到“发生了什么”“为什么重要”“哪些要求已经被固化成 gate”“当前 gate 是否通过”。如果只给它 trace,它容易把个别失败当成全部问题;如果只给它 eval 结果,它又看不到行为路径和上下文。

飞轮的工程意义

飞轮的价值在于把"单次观察"转为"持久改进路径”:没有飞轮时,trace 是孤立日志、feedback 是一次性评论,改进靠工程师的个人判断拼接;有飞轮时,每次发现的问题直接进入 eval suite,每次 eval 失败直接进入 HALO 排序,每次 HALO 建议直接对应可实施的 diff。信号不再消失在对话记录里。

从 Harness Engineering 的"绑定约束论题"看,这个飞轮的假设前提也相同:改进 harness 基础设施比调整模型权重带来更大、更可控的实际提升,因为改进对象明确(具体 policy 规则、工具校验脚本、输出合约),改进结果可验证(eval gate),改进路径可复跑(codex_handoff.md 是可版本化的文档)。

Feedback-derived Evals(反馈驱动的测试生成)

这套流程里最值得关注的工程环节是 Feedback → Evals 转换:

  • 人工 feedback 格式:{ summary, required_observations: [...], prohibited_claims: [...] }
  • LLM feedback 格式:{ observations: [...] }
  • 转换后的 eval 包含:rubric(llm-rubric judge 用)+ deterministic_assertions(contains/not-contains)+ pass/fail 示例

这种结构使 eval 既能捕捉字面要求(确定性断言),又能检查语义质量(rubric judge),而且由 trace 中的真实失败案例生成,不是凭空构想的假设场景。

Evaluator-Optimizer(评估器-优化器)的区别在于时态:Evaluator-Optimizer 是运行时在线评估(边执行边判断);Feedback-derived Evals 是离线生成可复跑测试(把观察固化成未来的判断标准)。

示例中的 generated evals 不只是“让 LLM 再评价一次”。每条 eval 都来自 trace 和 feedback,包含 rubric、确定性断言、建议通过样例和失败样例。Promptfoo 再用自定义 provider 重放 trace 输出,检查当前 harness 是否满足这些条件。

这个结构适合把专家反馈转成长期回归:例如财务尽调场景里,人工反馈指出 ARR 必须使用 finance-controlled source of truth、客户集中度必须 roll up 到 parent account、SOC 2 Type I 和 Type II 不能混淆、没有支撑的 NRR 和 CAC payback 必须拒答。生成 eval 后,这些要求不再只是一次 review 里的评论,而会在未来 harness 修改后继续运行。

风险也很明确:generated eval 首轮仍需要人类审查。模型可以把反馈翻译得太宽、太窄,或只检查表面词句。Cookbook 的第二张图把“Eval review”列为可插入的人类 gate,原因正是 eval gate 一旦变成自动合并依据,错误的 gate 会长期塑造系统行为。

人类 gate 的放置点

Cookbook 的 human-gates 图强调,同一个 loop 支持不同自动化程度:可以全自动,也可以在若干关键点人工卡口。

flowchart LR
    R["Trace review\n补充领域反馈"] --> E["Eval review\n收紧 gate"]
    E --> P["PR review\n检查 Codex diff"]
    P --> M["Merge approval\n按策略部署"]
    M --> A["Autonomous path\n高置信时由策略驱动"]

这比“human-in-the-loop”更具体:人类可以在 trace review 阶段定义什么算错,在 eval review 阶段校准自动验收标准,在 PR review 阶段检查实现,在 merge approval 阶段控制发布风险。随着 eval suite 和 harness 变可信,某些 gate 可以从人工批准变成策略驱动。

与 Loop Engineering 的关系

Loop Engineering(循环工程) 关心的是长期系统如何触发、验证、记录状态并决定下一步。Agent improvement loop 是其中一种更窄的模式:它不直接处理“明天要做什么任务”,而处理“这个 Agent harness 如何从真实运行中持续变好”。

可以把它看成三层反馈的中间层:

层级反馈对象周期
Agent run单次回答、工具调用和 artifact分钟级
Agent improvement loopprompt、工具策略、验证器、输出契约和 trace 采集小时到天
产品/组织 loop任务定义、业务指标、风险政策和发布节奏周到月

这个分层避免把所有问题都塞给单次 Agent run。单次 run 应该尽力完成任务;改进 loop 负责把 run 中暴露的问题变成 harness 修改;产品 loop 决定哪些行为值得优化、哪些风险必须保留人工判断。

与相邻概念的关系

参考来源
  1. 1. https://www.anthropic.com/engineering/effective-harnesses-for-long-running-agents
  2. 2. https://openreview.net/forum?id=3hXEPbG0dh
  3. 3. https://openreview.net/pdf?id=3hXEPbG0dh
  4. 4. https://github.com/Picrew/awesome-agent-harness
  5. 5. https://openai.com/index/unrolling-the-codex-agent-loop/
  6. 6. https://x.com/akshay_pachaar/status/2041146899319971922
  7. 7. https://openai.com/index/harness-engineering/
  8. 8. https://martinfowler.com/articles/harness-engineering.html
  9. 9. https://x.com/0xCodez/status/2066867539305459732
  10. 10. https://developers.openai.com/cookbook/examples/agents_sdk/agent_improvement_loop
  11. 11. https://openai.com/business/guides-and-resources/a-practical-guide-to-building-ai-agents/
  12. 12. https://openai.com/index/new-tools-for-building-agents/
  13. 13. https://openai.com/index/the-next-evolution-of-the-agents-sdk/
  14. 14. https://developers.openai.com/api/docs/guides/function-calling
  15. 15. https://developers.openai.com/cookbook/examples/gpt-5/codex_prompting_guide
  16. 16. https://www.anthropic.com/engineering/demystifying-evals-for-ai-agents
  17. 17. https://www.anthropic.com/engineering/managed-agents
  18. 18. https://x.com/odysseus0z/status/2030416758138634583
  19. 19. https://kubernetes.io/docs/concepts/architecture/controller/
  20. 20. https://www.anthropic.com/engineering/building-c-compiler
  21. 21. https://github.com/anthropics/claudes-c-compiler/commit/a28ff299
  22. 22. https://arxiv.org/abs/2110.14168
  23. 23. https://x.com/Vtrivedy10/status/2031408954517971368
  24. 24. https://docs.langchain.com/oss/python/deepagents/overview
  25. 25. https://github.com/earendil-works/pi
  26. 26. https://mp.weixin.qq.com/s/9ikvuGaAJSPyGYidbAdC7g
评论