Skip to content

第 9 章:什么时候该停,什么时候该问人

本章目标:讲清停机条件、失败边界与 human-in-the-loop 为什么不是保守设计,而是成熟 Agent 系统的必要部分。
本章对应总纲:docs/ebook-outline.md 中“第 9 章正文写作提纲(2026-03-31 归档)”。


9.1 为什么“全自动到底”是个很幼稚的幻想

很多人对 Agent 的想象,天然带着一种错觉:

  • 最厉害的系统应该一路自动做完
  • 中间最好别打扰人
  • 如果还要问人,说明系统不够强

这套想法听起来很爽,工程上却经常很蠢。

因为现实任务里,经常存在这些情况:

  • 信息不够
  • 边界不清
  • 多种方案都合理
  • 某些动作不可逆
  • 某些动作会影响共享状态
  • 某些动作本来就需要授权

在这些地方,系统如果还硬往前冲,不是强,是危险。

所以一个成熟 Agent 不只是要会动,还得会停。


9.2 停机条件不是失败补丁,而是边界治理的一部分

这一章和第 3 章不一样。第 3 章讲的是闭环怎么跑;这一章讲的是:

闭环跑到什么地方必须停,什么地方必须问,什么地方可以继续。

很多人把停机条件理解成“做不下去时的兜底逻辑”。

这理解太浅了。

在真正的系统里,停机条件本来就是边界治理的一部分。因为系统每轮都必须回答一个问题:

现在应该继续,还是应该结束、回退、求助?

再说得更工程一点:这类“什么时候继续、什么时候确认、什么时候直接停下”的判断,本身就是运行时控制面的一部分。第 12 章会把这条线集中收束成配置与策略问题;这一章先把它放回闭环出口来讲。

如果没有这层判断,闭环就会退化成机械重复。

所以停机不是例外,而是循环的合法出口。


9.3 一个 Agent 至少应该有哪些停机出口

工程上最少可以把停机出口分成四类:

9.3.1 成功停机

最理想的情况:

  • 目标已经满足
  • 验证已经通过
  • 没有新的未解决问题

这时系统应该停止,而不是继续多做一堆“顺手优化”。

9.3.2 失败停机

有些路径已经明确失败,例如:

  • 关键依赖不存在
  • 当前权限不够
  • 外部系统不可用
  • 验证连续失败且没有新线索

这时继续试并不聪明,只是在浪费动作预算。

9.3.3 授权停机

当下一步动作涉及风险边界时,系统应该停下来等待授权,例如:

  • 删除文件
  • 推送远端
  • 修改共享资源
  • 覆盖已有工作
  • 访问敏感外部系统

这不是“求助”,而是把控制权交还给真正该决策的人。

9.3.4 信息停机

有时系统不是不能做,而是不该在信息不足时乱做。

例如:

  • 需求本身含糊
  • 多种实现路径都合理
  • 缺少关键上下文
  • 用户偏好会显著影响方案

这时最合理的动作不是继续猜,而是停下来问清楚。


9.4 为什么 human-in-the-loop 不是降级,而是成熟设计

9.4.1 人类介入不是因为系统“菜”

很多任务天然就不该全自动完成。

因为系统再强,也不该替人做这些决定:

  • 业务优先级判断
  • 风险接受判断
  • 最终发布授权
  • 有歧义需求下的方向选择
  • 对已有工作覆盖与否的拍板

这些不是推理问题,而是责任归属问题。

9.4.2 人类介入本质上是在补“合法决策权”

从系统视角看,human-in-the-loop 的作用不是给 Agent 补智商,而是给它补:

  • 授权
  • 业务判断
  • 外部信息
  • 价值偏好

所以真正成熟的系统不会把“问人”当成丢脸,而会把它设计成标准路径之一。


9.5 什么情况下必须问人,而不是继续猜

这个问题必须说死一点。至少有几类场景,继续猜通常都是坏品味。

9.5.1 需求存在真实歧义

比如用户说“顺手优化一下”“帮我改得更合理”“把这个整理好”。

这种话如果边界没补清,系统很容易越改越多。

9.5.2 多种方案都有明显 trade-off

例如:

  • 性能优先还是可读性优先
  • 向后兼容还是彻底重构
  • 本地最小修补还是结构性调整

这类问题通常不该由系统擅自拍板。

9.5.3 即将跨越风险边界

例如:

  • 删除、覆盖、回滚
  • 远端推送
  • 修改共享基础设施
  • 动到可能影响别人的状态

这些动作不确认就做,属于欠收拾。

9.5.4 当前信息缺口足以改变决策

如果缺失的信息会直接影响路径选择,那继续执行就只是把错误做得更快。

可以把这里压成一个三分法:

当前局面系统该做什么
信息够、风险低、边界清楚继续
信息缺口会改变路径问人
风险越权或无合理收益停下

9.6 什么时候不该问人

反过来也要说清楚。

有些系统一遇到点不确定就停下来问人,结果把自己做成了低效菜单机。

这同样很烂。

9.6.1 当前问题可以通过读环境自行补足

比如:

  • 文件路径在哪
  • 定义在哪
  • 当前错误是什么
  • 当前分支和状态如何

这些本来就应该优先自己查,不该先去烦用户。

9.6.2 风险边界并未被触发

如果动作局部、可逆、低风险,就不该动不动停下来请示。

9.6.3 用户已经明确授权了当前范围

用户如果已经给了足够清楚的边界,系统就应该在这个边界内自己完成。

所以好系统不是“尽量多问”,也不是“尽量不问”,而是:

只在真的需要人类决策权或外部信息时才问。


9.7 失败边界:不是所有问题都该无限重试

成熟 Agent 还有一层经常被忽视:失败边界。

9.7.1 为什么必须定义失败边界

如果系统没有失败边界,就会出现这些典型烂行为:

  • 同一个错误来回试
  • 路径已经证伪还继续加补丁
  • 只是因为“还能再试一次”就不停拖长上下文
  • 明明该停,却不断自我消耗

9.7.2 失败边界和授权边界不是一回事

这里必须分开:

  • 失败边界:继续行动已经没有合理收益
  • 授权边界:继续行动前需要用户拍板

前者解决“还值不值得继续”,后者解决“轮不轮得到系统自己继续”。

这两者如果不分清,系统就会一会儿瞎冲,一会儿乱停。

9.7.3 失败边界通常长什么样

常见形式包括:

  • 连续若干轮没有新信息
  • 同类验证失败重复出现
  • 当前权限不足且短期内无法补足
  • 关键依赖缺失
  • 已触达用户明确禁止的边界

失败边界不是悲观主义,而是系统在承认:

继续行动已经没有合理收益。

这是一种成熟。


9.8 停机条件会反过来塑造规划质量

一个很有意思的事实是:

你怎么定义停机,反过来决定了你会怎么规划。

如果系统根本没定义清楚:

  • 什么算完成
  • 什么算失败
  • 什么必须确认
  • 什么必须补信息

那它前面的规划也会跟着发虚。

因为所有步骤都缺少出口条件。

所以“规划”和“停机”不是两块分离模块,而是一前一后的同一套结构:

  • 规划决定怎么走
  • 停机决定什么时候别再走

9.9 用 Claude Code 看一个现实中的人类介入模型

Claude Code 这类系统特别适合说明这件事,因为它并不是盲目追求全自动。

最直接的证据就在 examples/settings/settings-strict.json:1

  • ask: ["Bash"]
  • deny: ["WebSearch", "WebFetch"]

这两个字段已经把三种完全不同的出口分开了:

  • 允许继续的路径
  • 必须先问人的路径
  • 当前根本禁止的路径

这很重要。因为一个成熟系统如果只会“继续”,那它根本不算有边界;如果只会“遇到问题就问”,那它又只是低效菜单机。Claude Code 这种设计的价值,就在于它把“继续 / 询问 / 禁止”都做成显式运行分支,而不是让模型临场发挥。

再看 plugins/README.md:21plugins/README.md:26hookifysecurity-guidance 这类插件都说明:生命周期拦截和安全提醒不是附属建议,而是专门存在的一层。这背后其实就是同一个设计思路:该停的时候,要有独立机制把系统拦住,而不是指望模型自己突然变谨慎。

所以从这个现实样本里,至少能抽出几条非常硬的规则:

  • 授权边界必须显式建模,别靠模型猜什么时候该问人
  • 禁止边界必须比提醒更硬,不该做的就直接别让它走到那一步
  • 人类介入是合法出口,不是系统失败后的羞耻补丁
  • 停机、确认、拒绝都要属于闭环结构本身,而不是事后附加说明

这说明它追求的不是“自动化最大化”,而是在正确边界内尽可能自动,在不该越权的地方老实停下。这才是真正能落地的 agentic 系统思路。


9.10 真正好的停机,不会让用户觉得系统在偷懒

这一点很关键。

用户真正讨厌的,不是系统停下来;用户讨厌的是系统:

  • 该自己查的没查
  • 该自己做的没做
  • 只因为一点点不确定就把活又甩回来

所以一个好的停机或提问,必须满足两个条件:

  1. 系统已经尽到了自己该做的探索义务
  2. 现在确实需要用户的授权、判断或补充信息

做到这两点,停机就不会像推责,而像专业协作。


9.11 本章小结

这一章真正想讲清的是:会停、会问人、会承认失败,不是 Agent 变弱了,而是它终于从玩具变成了成熟系统。

你现在应该记住六件事:

  1. 全自动到底并不是成熟 Agent 的必要条件。
  2. 停机条件是闭环的一部分,不是失败补丁。
  3. 成功停机、失败停机、授权停机、信息停机,都是合法出口。
  4. human-in-the-loop 的价值在于补足授权、业务判断和外部信息。
  5. 失败边界能防止系统在错误路径上无限重试。
  6. 好的系统既不会该问不问,也不会不该问时一直烦用户。

下一章我们继续进入更工程化的一层:多 Agent。不是把多个模型凑在一起那么简单,而是看什么时候真的值得拆成多个执行单元,什么时候又只是徒增复杂度。