Skip to content

HITL 的 H,正在从 Human 变成 Harness

MasakiMu319 ·

coding agent 一次能跑的时间越来越长。从几分钟扩展到小时、过夜、数天。这条时间轴的远端,一个老问题以新形式回到了桌面:人退出控制回路之后,回路里原来由人做的那几件判断,是谁接走的。

这篇文章从一个前提开始:Human-in-the-loop 里的 H,不是非「人」不可。它是控制回路里 verifier 这个角色,人只是它最早的实现。 过去两年 coding agent 的演化,很大程度上就是 harness 逐步接管这个角色的过程。

下面从五个维度展开:HITL 到底包含几件独立的判断,harness 怎么一件件接过去,/goal 如何将验证变成软件行为,人从回路角色中退出之后停在哪个位置,以及哪些判断至今交不出去。

HITL 里的那个「H」,从来不是绑在「人」身上的。它是一个位置——回路里那个 verifier。人,只是最早坐进去的那个。


HITL 是一个位置,不是一个角色

「Human-in-the-loop」听上去是一件事,其实是多个独立判断集中在一个人身上:

  1. 启动下一轮 — 这步干完,还接着干嘛?你要说出来。
  2. 权限审批 — 这条命令、这次写文件,能不能让它动手?你得批准。
  3. 纠偏 — 方向跑偏了,得把它拽回来。
  4. 验证 — 这轮算不算成了?你得检查。
  5. 担责 — 真出了岔子,谁来负责。

这几个职能的控制论分档早已有之。盯着每一步、步步确认,叫 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.mdCLAUDE.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 /goalCodex 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 · 只看 PRon-the-loop · 随时切回去
谁家的Cursor Cloud、Devin、Claude Code on the webRemote 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,永远是你。


参考


Next 人类作为弱监督者:从 AAR 看对齐的可行性与边界