coding agent 一次能跑的时间越来越长。从几分钟扩展到小时、过夜、数天。这条时间轴的远端,一个老问题以新形式回到了桌面:人退出控制回路之后,回路里原来由人做的那几件判断,是谁接走的。
这篇文章从一个前提开始:Human-in-the-loop 里的 H,不是非「人」不可。它是控制回路里 verifier 这个角色,人只是它最早的实现。 过去两年 coding agent 的演化,很大程度上就是 harness 逐步接管这个角色的过程。
下面从五个维度展开:HITL 到底包含几件独立的判断,harness 怎么一件件接过去,/goal 如何将验证变成软件行为,人从回路角色中退出之后停在哪个位置,以及哪些判断至今交不出去。
HITL 里的那个「H」,从来不是绑在「人」身上的。它是一个位置——回路里那个 verifier。人,只是最早坐进去的那个。
HITL 是一个位置,不是一个角色
「Human-in-the-loop」听上去是一件事,其实是多个独立判断集中在一个人身上:
- 启动下一轮 — 这步干完,还接着干嘛?你要说出来。
- 权限审批 — 这条命令、这次写文件,能不能让它动手?你得批准。
- 纠偏 — 方向跑偏了,得把它拽回来。
- 验证 — 这轮算不算成了?你得检查。
- 担责 — 真出了岔子,谁来负责。
这几个职能的控制论分档早已有之。盯着每一步、步步确认,叫 in-the-loop;不盯每一步,只在边上看着、出错才介入,叫 on-the-loop;连看都不看、只认最后交出来的结果,叫 out-of-the-loop。人沿着这条线往后退——从逐步确认,退到只看最终结果。
看起来这五件该由同一个人来完成。但它们本来就是五件独立的事。一旦承认这一点,问题就出现了:它们能不能拆开?能不能几件交给软件,几件留给自己?
HITL 之所以感觉像「一个角色」,只因为这五件事恰好落在同一个人身上。一旦拆开,哪些能交给软件、哪些必须留在人手里,就是一道明确的工程问题。
工具形态的变化,只是把这条路修通了。早期的补全光标把人限制在最内层:光标停在哪,注意力就得跟到哪,无法离开。只有当 agent 变成终端里一个独立运行的进程,你才能抽出身,往后退一步。Cursor 这种从 IDE 出身的产品,也在 2026 年 1 月把 agent 移进了终端(Cursor CLI)。形态往终端收,不是因为谁喜欢命令行——是因为只有「进程」这个形态,才接得住人往后撤。
这一段「从光标到进程」的形态史不是本文的主角。它只是背景:形态就位之后,真正要追问的是——那五件事,一件一件被谁接管了。
harness 就是来接管这个位置的
写完上一篇之后回顾,把 harness 描述为「模型外面的那圈循环」没错,但忽略了它真正在做的事:它是一个容器,专门用来逐个接管那五件原本归人的判断。
先明确 harness 的定义。一个 coding agent 真正运行的,是一个循环:读上下文 → 想下一步 → 调工具(读文件、改文件、跑命令、查资料)→ 看结果 → 再想下一步。这个循环,再加上外面那圈管上下文、管权限、管子 agent、管错误恢复、管「到底算没算完」的逻辑,合起来才是 harness。你在命令行里敲的那个 CLI,只是这圈循环的一个入口,不是循环本身。
关键的对应关系是:这圈循环里的每个组件,都对应着人原来干的某件事;而且接管的顺序,是按「这件事能不能写成一条可自动检查的规则」来排的——
| 人原来干的事 | harness 怎么接管 | 成熟度 |
|---|---|---|
| 启动下一轮 | Agent Loop:自动续跑、自动 break | 高 |
| 权限审批 | Permissions 系统(allow/deny/ask)+ auto 模式 | 中 |
| 纠偏 | Plan mode、AGENTS.md / CLAUDE.md、pre-commit/pre-push hooks | 低 · 在追 |
| 验证 | /goal、Stop hooks、prompt-based evaluator → 本文重点 | 中高 |
| 担责 | 无 | 无 · 永远归人 |
这张表本身就是一份「在 harness 上该在哪里投入」的地图。AGENTS.md、CLAUDE.md、plan 预审、权限边界、MCP、子 agent——这些不是零散的配置项,它们合起来在回答同一个问题:那五件事,你打算把哪几件交给 harness。
选择 agent,选的不只是模型,更是 harness。你决定的不是一圈循环,而是「人和软件那条分工线,划在哪儿」。
这也给上一篇《Brain ≠ Hands》补充了一个观察。当时讲模型是「脑子」,harness 是「手」加调度。现在看,harness 接走的不只是执行,还有验证——它的边界已经延伸到了原来由模型(「脑子」)承担的任务。
/goal:把验证变成软件行为
那五件事里,验证接管得最早、也最彻底。/goal 就是这一步骤的产品名称。
但 /goal 不是凭空出现的。它前面有一段权限模式的演化,从时间线来看,方向很清楚。
最早,想让 agent 不用每一步都等人确认,只有一条路:完全跳过审批。Claude Code 给了 --dangerously-skip-permissions,Codex 给了 --dangerously-bypass-approvals-and-sandbox(后来叫 Full Access)。两个名字里都带着「dangerous」,因为在真实开发机上,带着 SSH key、环境变量和 git credential,不加护栏地运行一个自主进程,风险不可控。日常开发没人敢开,只在一次性容器里用。
2026 年 3 月,Claude Code 上线了 auto 模式:一个独立的 AI classifier 跑在后台,主 agent 每想调一个工具,classifier 先过一遍——安全的直接放行,有破坏性的阻止,并告诉主 agent 为什么不能做。同一时期,Codex 推出了 auto-review:一个独立的 reviewer agent 坐在 sandbox 边界上,主 agent 试图越过边界,reviewer 先批。config.toml 里一行 approvals_reviewer = "auto_review",就把审批权从人移交给了另一个模型。
两家的做法不同,但做的是同一件事:把「这步能不能跑」从人换成了另一个模型。
这一步走通之后,下一个问题就自然出现了:既然另一个模型能判「能不能跑」,能不能判「做没做完」?
/goal 就是这个问题被回答的那个版本。
在 /goal 之前,一个回合跑完,agent 默认就停下,把控制权交还。换句话说,每一轮都得人回到 verifier 的位置确认一次。/goal 做的是把这个确认替换为软件。
Claude Code:把 verifier 写成一个独立的评估器。 Claude Code 在 2.1.139(2026 年 5 月 12 日)加入了 /goal。你给它一个完成条件,每一轮跑完,由配置里的小模型(默认 Haiku)去判:条件满足了没?没满足,它自己开下一轮。评估器不调工具、不跑命令,只能判对话记录里已经出现的事实——所以条件必须写成可以被记录验证的形式,比如「npm test 全绿」比「代码写好了」有效。那个小模型占的,正是你以前每轮都要回到的位置。这是 HITL 里「验证」这一格,第一次有软件明确地替代上去。
Codex:把 verifier 写进一个可审计的合约。 Codex 在 0.128.0 加入了 Goals。它跟 Claude Code 的 /goal 目标一样——设好完成条件,自动跨轮续跑——但路线不同。Claude Code 靠一个独立的 Haiku 做评估器,每轮结束用它判条件成没成。Codex 没有独立评估器:它把 outcome、verification surface、constraints 都写进同一个合约,让主模型自己对照证据回答「做没做完」——不是「我觉得做完了」,而是「文件改了、测试过了、benchmark 数据对上了」。合约定义了完成的标准,模型每轮对照可审计的证据下结论。跟 Claude Code 一样,Goal 能暂停、恢复、清除,session 重连后自动恢复。
验证这一格一旦交出去,人就从盯着每一轮,退到了从旁监控。不再一轮一轮确认,而是把条件设好、保持观察,只在出问题的时候才介入。两家正好各走了一条路线:
Claude Code /goal | Codex Goals | |
|---|---|---|
| 评估器 | 独立小模型(Haiku),每轮结束判定 | 无独立评估器,主模型对照证据自检 |
| 判的依据 | 对话记录里已出现的事实 | 文件、测试、benchmark 等可审计证据 |
| 生命周期 | 设条件、自动续跑、/goal clear 提前停 | /goal pause / resume / clear,同线程持久化 |
| 共同点 | 都从「每轮等确认」升级为「设好条件、对照证据、自动续跑」 | 同左 |
两家的差别在评估机制——一个拆成独立模型,一个写成主模型的自检合约。但共通点更关键:验证这个位置,第一次有了一段明确的软件行为,而不是一段模糊的「我看看」或「我觉得行了」。
怎么造一个靠得住的 verifier
既然 verifier 这个位置要交出去,所有可参考的做法就收成同一件事:你交出去的这个实现,到底靠不靠得住。
写不出 check 的判断,根本交不出去。 /goal 的第一关,是这个目标能不能落成一盏绿灯:迁到新接口,直到所有调用点编译、测试通过;照设计文档实现,直到验收条件全部满足;拆大文件,直到每个都低于指定行数;清 issue queue,直到队列见底。反过来说,「把代码写得更漂亮点」这类写不出判定条件的任务,交给 /goal 等于让它自循环,无法收敛。
验证有多可靠,你就能退多远。 正确的顺序是:先有一个失败的测试、一段验收脚本、一条能跑的检查命令,再开 /goal。你给 verifier 做的实现有多可靠,就直接决定了你敢离它多远。实现粗糙,你就只能保守推进;实现可靠,你才敢真的走开。从 HITL 到 VITL(Verifier-in-the-loop),本质上就是这个逻辑。
让它自己跑的范围,别超过你的验证能覆盖的范围。 自动开下一轮需要谨慎使用:方向对,它能一路跑到底;方向错,一个早期的小问题也会一轮轮放大成大面积返工。所以越是验证覆盖不全、越要跑得久的任务,越得在开跑前设置好护栏——通过 plan 锁定方向,通过权限边界限制范围,通过 checkpoint 保留回退点。
跑得久,最终会触及 verifier 的上下文保持能力。 一个跑好几天的 /goal,一定会触发上下文压缩。压缩不是把历史截短,是选择性保留有用事实、丢弃噪音。压缩质量差,它第三天就忘了第一天定下的验收标准——verifier 失忆,等同于 verifier 失效。这块在《从 Cursor 的 Self-Compaction 看 Agent 上下文压缩》里详细分析过。
HITL 到 VITL,只隔一件事:你有没有把一个判断,写成了能自动验证的 check。写出来,那一步你就退出回路了。写不出来,你还在里面。
人退出来之后,是停在回路边上,还是干脆走开
verifier 交出去之后,人在回路里的角色就空了。接下来的选择是:你站在哪儿。两条远程方案,正好是这条线上的两个落点,分岔就在一个问题上——workspace 归谁。
干脆走开:把任务发到云端。 Cursor Cloud Agents、Devin、Claude Code on the web(claude.ai/code)都是这条路。开一台干净的云端机器,把仓库克隆进去,在一个单独的分支上执行,完成后生成一个待审的 PR。你既不在每一轮里,也不在边上看,只在最后对那个 PR 负责。收益明确:环境隔离、可并行、结果可复现。代价也明确——那不是你的环境。本地工具链、改了一半的工作树、未提交的改动、私有依赖、跑起来才暴露的环境差异,它一概看不见。
留在边上:把自己的机器当 workspace。 Claude Code 的 Remote Control(2026 年 2 月 24 日,v2.1.51 以上)和 Codex 的 Remote Connections(2026 年 5 月,嵌入 ChatGPT 手机 app)走的是另一条。agent 始终跑在你自己的机器上,远端那台设备只是一块控制面板:Remote Control 只往外发 HTTPS、不开任何入站端口,手机和浏览器通过 Anthropic 的 relay 接入同一个本地 session;Codex 通过 codex app-server 让手机、平板或另一台电脑连过来。你没有离开,只是站到了回路外侧——而那个窗口的意义,正是让你随时能切回去接管。
| 发去云端 | 留在边上 | |
|---|---|---|
| workspace | 一台临时的云端虚拟机 | 你自己那台 |
| 环境够不够真 | 干净,但陌生 | 真,连 dirty state 都在 |
| 你所处的位置 | out-of-the-loop · 只看 PR | on-the-loop · 随时切回去 |
| 谁家的 | Cursor Cloud、Devin、Claude Code on the web | Remote Control、Codex Remote Connections |
交不出去的,才是真正的 Human-in-the-loop
这条线走到头,有一个该讲清的判断:能移出回路的,恰好就是那些能写成 check 的。剩下交不出去的,正好是写不成 check 的三件事——开放世界里的判断(verifier 判得了「测试过了」,判不了「这个目标本身就定错了」)、到底什么值得做(品味和取舍)、还有担责(真出了事,法律上、人情上,总得有人负责)。
所以 human-in-the-loop 不会消失,它只是缩到了「眼下还写不成验证器的那一小块」。这里可以下一个可被推翻的判断:人留在回路里的那条边界,会精准地跟着「能把多少判断写成 check」往外挪。
最后回到本文开头:coding agent 跑得越来越长,不是因为人越来越不重要,而是因为 verifier 这个位置,正在交给一个你亲手构造的、靠得住的软件。而你自己,退到了它覆盖不到的地方——决定什么值得做,以及为做出来的东西负责。
能从回路里交出去的,恰好就是能写成 check 的那部分。所以可参考的做法只有一条:尽量把判断写成能自动验证的 check,给 verifier 一个可靠的实现,然后想清楚——交不出去的那件事,才是你该待的地方。HITL 的 H 正在从 Human 变成 Harness;但有一个 H,永远是你。
参考
- Anthropic,「Keep Claude working toward a goal」(
/goal文档),https://code.claude.com/docs/en/goal - Claude Code 2.1.139 release(2026-05-12):引入
/goal - OpenAI Codex CLI:Goals(
/goal,自 Codex 0.128.0 起正式可用):thread-scoped completion contract,主模型对照可审计证据自检 - Cursor CLI(2026-01-16):https://cursor.com/cli
- Anthropic,「Continue local sessions with Remote Control」(2026-02-24),https://code.claude.com/docs/en/remote-control
- OpenAI Codex Remote Connections(2026-05):嵌入 ChatGPT 手机 app,通过 app-server 远程连入本地 session,https://developers.openai.com/codex/remote-connections
- Anthropic,「How we built Claude Code auto mode」(2026-03-24),https://www.anthropic.com/engineering/claude-code-auto-mode
- OpenAI,「Auto-review of agent actions without synchronous human oversight」(2026),https://alignment.openai.com/auto-review/