跳到主要内容

Harness:控制 Agent 的执行过程

模型说“运行 npm test”,这句话本身不会让任何测试跑起来。真正去跑的,是包在模型外面的那层软件:Harness(控制层)。假设一个 Harness 这样处理这条请求:先查 npm test 在不在允许运行的命令清单里,再把它放进一个限时 5 分钟的子进程;跑完以后,把退出码和最后 200 行输出交回模型,同时写进日志。如果进程中途崩溃,下次就从日志里这条记录接着来。

这一步里,模型只提出了下一步动作,Harness 则让这个动作真的能执行、不越界、事后查得到、出了错能接着做。所以 Harness 不只是聊天界面,它把模型、代码仓库、终端、权限和验证流程连在了一起。

Harness 至少要管八件事​

下表把八项职责都落在同一个 npm test 请求上。

层级职责在 npm test 这一步做什么
循环 (Loop)交替处理模型回合、工具调用、结果反馈及停止条件把测试结果交回模型,让它决定下一步;测试通过或步数用完时停下
上下文 (Context)筛选指令、历史对话、文件内容及检索到的证据只把最后 200 行输出放进上下文,不把整份日志塞给模型
工具 (Tools)校验参数、执行调用并返回结构化结果确认命令和工作目录合法,返回退出码和输出;子进程会继承父进程的环境变量和已打开资源(见进程、地址空间与内存),所以要先定好它能带走哪些
策略 (Policy)强制执行范围、权限、审批、预算及安全边界查允许清单:npm test 可以直接跑,删除目录或推送代码的命令要先停下来问人
状态 (State)保存任务进度、产物及可恢复的检查点记下这一步跑过测试、结果是什么,进程崩了也能从这里接着来
可靠性 (Reliability)处理超时、重试、幂等性、取消及失败情况5 分钟一到就结束进程;重跑测试不改变任何东西,可以放心重试
可观测性 (Observability)保留追踪记录、日志、Token/成本数据及工具证据日志里留下命令、耗时和退出码,事后能查清什么时候跑过什么
评估 (Evaluation)在代表性任务上测试结果,而非仅评判文本质量看测试是否真的通过,而不是看模型说得像不像完成了

模型说“测试都过了”不算数:可靠的 Harness 自己去看 npm test 的退出码,再决定停不停。怎样把这种外部验收接进循环,见有界 Agent 循环。

设计 Harness 时按这个顺序来​

  1. 定义结果和外部成功检查,比如“npm test 退出码为 0”。
  2. 暴露最小的有用工具集。本地小模型更离不开这一步:迭代要短,工具要少,返回的输出要有长度上限。
  3. 将只读操作与写入和不可逆操作分开。
  4. 在对话记录之外保存产物和证据。
  5. 添加时间、Token、重试和并发限制;停止条件和断路器的细节见有界 Agent 循环。
  6. 在保护敏感数据的前提下追踪模型回合与工具调用。
  7. 更改默认模型、Harness 或推理级别前,先重放有代表性的任务。

判断结果能不能交付的检查,比如测试、权限和端到端验收,属于 Harness 和工作流;模型则可以换。变化快的模型与定价信息放在模型与 API 选型雷达,公开测试结果和各工具的故障模式记在挑选 AI 编码 Agent。更强的模型也许能减少重试,但证据、权限和端到端检查一样都省不掉。

这些控制在 Claude Code、Codex 和 Pi 里放在哪​

买来的编码 Agent 已经替你实现了上面大部分职责,要调的是它们的开关。下表按 2026-10-29 的官方文档整理;Pi 按 1.4.0。

控制Claude CodeCodexPi
项目指令CLAUDE.md,也能读仓库里的 AGENTS.mdAGENTS.md:先读 ~/.codex/AGENTS.md,再从仓库根往下逐层读AGENTS.md、CLAUDE.md 不受项目信任限制,总会加载(安全文档)
权限与审批/permissions,或 settings.json 里的 permissions.allow / ask / deny,按拒绝 → 询问 → 允许生效approval_policy(如 on-request、never)和 /permissions;approvals_reviewer = "auto_review" 把审批交给审查 Agent工具调用前不询问;--approve / --no-approve 只决定是否加载项目里的设置和扩展
沙箱默认关闭,用 /sandbox 或 sandbox.enabled 打开;只包住 shell 命令sandbox_mode:read-only、workspace-write、danger-full-access;workspace-write 默认不联网没有内置沙箱,把整个 Pi 放进容器或虚拟机
Skills 目录.claude/skills/<name>/SKILL.md,个人的在 ~/.claude/skills/.agents/skills,从当前目录到仓库根逐层扫描;个人的在 $HOME/.agents/skills.agents/skills/、~/.agents/skills/,以及 .pi/skills
MCP 配置claude mcp add;要和团队共享,写进项目根的 .mcp.jsoncodex mcp add,或 ~/.codex/config.toml 里的 [mcp_servers.<name>]pi mcp add;~/.pi/agent/mcp.json,项目的 .pi/mcp.json
Hookssettings.json 里的 hooks,例如 PreToolUse 能拦下一次工具调用~/.codex/hooks.json 或 config.toml 里的 [hooks];项目的 .codex/ 要先受信任没有单独的 hook 配置;扩展用 pi.on("tool_call", …) 拦截或改写调用
无人值守运行claude -p "…"codex exec "…",默认在只读沙箱里跑pi -p "…",或 --mode json、--mode rpc
恢复会话claude -c 接最近一次,claude -r <ID 或名字> 接指定会话codex resume --last;非交互的用 codex exec resume --lastpi -c 接最近一次,pi -r 打开会话列表

同一个“沙箱”在三者里管的范围不同,例如 Claude Code 的沙箱打开后仍能读 ~/.ssh。动手前先看 Agent 安全里的对照和起步配置。

探索关联打开关联网络