第 5 课:干预与操控:打断、转向、人在环
学习目标:
- 说清为什么自主循环需要人在环,把「过度授权」和「循环越自主越要留人工闸」这条因果讲明白
- 区分打断、转向、审批三种介入手段,各自在循环的哪一步插进去、改变了什么
- 判断一个高影响操作的人工审批点该放在执行之前还是之后,并说明「不可逆之前」这条位置原则
前置要求:读过第 3、4 课,知道循环有停止条件、也知道死循环和空转要怎么兜底;理解 harness 是模型之外那层控制代码 | 上一课 第 4 课 << | 下一课 第 6 课 >>
前四课都在管「循环自己怎么转」,这一课把人放进来
到这里,你手里的循环已经能转、能停、能兜底了。第 3 课给它设了显式停止条件,第 4 课教它认出死循环和空转、别把预算烧光。但这些控制有个共同点:它们全是 harness 自己在跟循环较劲,从头到尾没有人插手。
可真实的 Agent 很少能一路无人值守地跑到底。任务跑到一半,你可能想直接叫停——方向整个错了,别再烧钱了;也可能想不停机地换个目标——「先别管重构了,先把那个线上 bug 修了」;还可能是某一步太危险,你想在它真动手之前先看一眼、点个头再放行。这三件事,模型自己决定不了,第 3、4 课那套自动化的停止与兜底也覆盖不到——它们是人从循环外面伸手进来的动作。这一课就讲这层:人怎么在循环中途介入,以及这层介入的代码该往哪儿插。
为什么循环越自主,越要给人留一道闸
先想清楚一件事:既然前面费了那么大劲让循环自动跑,为什么还要把人塞回去?
答案藏在「自主」这个词的另一面。Agent 是让模型在循环里自己动态决定下一步做什么、用什么工具的系统,这份自主正是它有用的地方——但也正是它危险的地方。安全社区把这类风险起了个名字叫「过度授权」(excessive agency):当一个 LLM 的输出出现异常、有歧义、或者被人为操纵时,如果它背后连着能真正动手的权限,这些不对劲的输出就足以触发破坏性的动作,而且不管模型是因为什么原因出的岔子,结果都一样1。
把这句话摊到循环里看就很具体了。模型某一轮可能读错了工具返回的内容、可能把用户一句含糊的话理解偏了、也可能被某个网页里嵌的恶意指令带跑——第 4 课讲的失控里,坏的是循环的「节奏」(停不下来、原地打转);这里坏的是循环的「动作」(它真去干了一件不该干的事)。而循环给的权限越大、越自主,模型一次判断失误能造成的破坏就越重。所以除了 harness 自己那套自动闸(停止条件、兜底),在那些「一旦做错就收不回来」的关键点上,还得再留一道人工闸——让一个人在动作真正落地之前,有机会说「等一下」。
这不是不信任自动化,而是承认:模型可能连续跑很多轮,你得对它的决策有一定程度的信任才敢让它跑2,但「信任」不等于「全程放手」。信任让它在大部分步骤上自己走,人工闸负责守住少数几个一旦走错就无法挽回的路口。
三种介入:打断、转向、审批
人伸手进循环,不是只有「叫停」一种姿势。按「介入之后循环怎么走」,可以分成三种,各自插在循环的不同位置、改变的东西也不同。
打断(interrupt)——叫停整个循环。 这是最干脆的一种:不管模型这一轮想干什么,直接让循环终止,不再发下一次请求。它和第 3 课的停止条件像,区别在触发者:停止条件是 harness 按预设规则自动收手,打断是人在循环外临时按下的那个「停」。用在你已经看出方向彻底错了、继续跑只是白烧 token 的时候。打断之后循环就结束了,没有「然后呢」。
转向(steer)——改目标或给新指令,然后接着跑。 这一种不终止循环,而是往对话里塞一条新的人类消息,改变模型接下来要朝哪使劲,循环带着这条新指令继续转。比如 Agent 正在吭哧吭哧重构一个模块,你突然发现线上有个更紧急的 bug,就可以不重启进程,直接插一句「暂停重构,先定位并修复登录接口那个 500」。转向改的是循环的「目标」,不是循环的「生死」。
审批(approve)——单步放行,不放行就不做。 前两种都是针对整个循环的,审批则是针对某一个具体动作的:循环转到某个高影响操作跟前先停下,把「我打算做什么」摊给人看,人点头才执行,人摇头就跳过或取消。它其实就是一种非常克制的暂停——Agent 可以在检查点、或者遇到阻碍时暂停下来等人反馈2,审批就是把这种检查点精准地钉在那些危险动作前面。审批放行之后,循环回到正常节奏继续转;这也是三种里最常态化、最适合长期挂着的一种。
一句话记住区别:打断动的是循环的存亡,转向动的是循环的方向,审批动的是单个动作的放行与否。第 6 课那个最小 harness 会把审批这一种真正写进代码里。
把审批阀写进循环:停在动作落地之前
三种介入里,审批是最需要落到 harness 代码里的一种——因为打断和转向往往可以靠「人在终端里敲一下」触发,而审批必须由 harness 主动在对的位置停下来等人,漏了它循环就直接把危险动作干了。
OWASP 给过度授权开的缓解药方里,就有这么一条:对高影响操作引入人在环控制,要求必须有一个人先批准,动作才能执行1。注意这句话的时序——是 approve before they are taken,先批准、后执行,不是先执行、再找人补个签。这道审批阀具体放在哪一层,规范里说得很宽松:既可以放在下游系统里(在 LLM 应用范围之外),也可以嵌在 Agent 扩展本身1。落到我们这个循环上,最自然的位置就是工具分发这一步——在真正调用某个被标为「高影响」的工具之前插一个停顿。
代码上,它就是在执行工具那行前面加一道岔路:
三个地方值得盯一眼。第一,判断放在 executeTool 之前——停顿必须发生在动作落地前,等人的这段时间里,那个危险操作还没真的执行。第二,被拒绝时不是静默跳过,而是回一个 is_error 的 tool_result(还记得第 2 课那个字段吗),让模型知道「这条路被人堵了」,好去想别的办法,而不是下一轮又提议一模一样的动作。第三,isHighImpact 只挑高影响的操作卡,读文件、查日志这类无害动作照常放行——不然每一步都要人点头,Agent 就退化成一个昂贵的手动工具了。
闸门放在哪:动作变得不可逆之前,而不是之后
上面那道审批阀之所以有用,全靠它站对了位置。这一节把这条位置原则单独拎出来,因为它是这一课最容易记反、也最要命的一点。
原则一句话:审批停顿要放在动作变得不可逆之前,而不是之后。 你在更早那门讲工具调用的课里已经见过这个思路——一个操作的「爆炸半径」越大、越收不回来,确认点就该越靠前。这里把它落到循环上:判断卡在 executeTool 那行的前面,等人的那段时间里破坏性动作尚未发生;一旦挪到后面,等你反应过来,表已经删了、邮件已经群发了、生产配置已经改了,再精确的日志也只是给这场事故拍了张遗照。
怎么认「不可逆」?给自己一个反事实测试:假设这个动作执行错了,我还能不能一步撤销回来?能低成本回滚的(比如写一个临时文件、发一条内部草稿),闸门可以不设或设得很松;收不回来的、或者收回代价极高的(删库、转账、对外发布、改线上配置),闸门必须靠前、且必须是「先批准才做」。这也正好和第 4 课接上:那一课讲怎么防循环把资源烧光,这一课讲怎么防循环把一件收不回的事给做了——前者是节奏失控,后者是动作失控,都得在「已经太晚」之前就设好闸。
还有个常被忽略的细节:闸门要卡在最靠近「真正落地」的那一步。假设删表这个动作要经过「模型提议 → harness 分发 → 调用 drop_table」几道手,审批不能设在「模型提议」那一步就放心了——模型提议本身没有任何杀伤力(第 1 课就说过,模型只提议、从不执行3);真正有杀伤力的是最后那次 executeTool 调用。把闸门尽量往执行那一端推,中间哪怕模型反复改主意、换参数,都还在闸门这一侧,伤不到人。
这三种介入,第 6 课怎么收进一个循环里
把这一课和前几课并排放,harness 的控制手段就凑齐了:第 3 课的停止条件(该收手时自动收手)、第 4 课的失控兜底(认出死循环空转、别烧穿预算)、这一课的人在环审批(危险动作落地前留一道人工闸)。三者不是三选一,而是叠在同一个循环上的三层防护——停止条件管「转多久」,兜底管「转歪了怎么办」,审批管「这一下能不能真的动手」。
第 6 课就是把这三层一起焊进一个可运行的最小 harness:一个带轮次上限、带空转检测、带高影响操作审批阀的 while 循环。到那时你会看到,这一课的 isHighImpact 岔路、第 3 课的计数器、第 4 课的进展检测,是怎么在同一段循环体里各占一个位置、互不打架的。这一课你只要先把「三种介入分别改变什么」和「审批闸门必须站在不可逆之前」这两点攥住就够了。
小结
- 循环越自主,越要在关键处留人工闸:过度授权意味着模型异常、有歧义或被操纵的输出,可能触发收不回的破坏性动作1;信任模型能连续跑很多轮2 不等于全程放手,人工闸负责守住少数几个走错就无法挽回的路口
- 三种介入各管一层:打断动循环的存亡(人从外面叫停整个循环)、转向动循环的方向(塞一条新指令改目标后继续)、审批动单个动作的放行(危险操作前暂停等人点头);后者正是把「检查点暂停等人反馈」2 钉在高影响动作前面
- 人在环审批的铁律是「先批准、后执行」:对高影响操作必须要求一个人先批准、动作才能执行1,审批阀既可放在下游系统、也可嵌在 Agent 扩展本身1
- 闸门要放在动作变得不可逆之前,而不是之后:卡在
executeTool 前,等人时破坏性动作尚未发生;挪到执行之后,再精确的日志也只是事后追溯,拦不住已经落地的动作。用反事实测试认「不可逆」——执行错了还能不能一步撤销回来
- 这一课的审批、第 3 课的停止条件、第 4 课的失控兜底,是叠在同一个循环上的三层防护,第 6 课会把它们一起焊进一个可运行的最小 harness
>> 第 6 课:实战:手写一个带控制的 Agent Harness