想象一个很具体的场景:你让 AI Agent 帮你订一张机票。它已经搜索航班、比较价格、填写乘客信息,最后来到"支付 3280 元"这一步。
这时系统应该怎么办?
每一步都让你点确认,Agent 就退化成了一个不断弹窗的助手;完全不问你,直接付款,又很难让人放心。真正难的并不是"要不要 Human-in-the-Loop",而是:什么时候必须让人介入,以及人在介入时究竟拥有多大的控制权。
一个好用的 Agent,需要把 Human-in-the-Loop 设计成一套风险控制机制,而不是简单增加一个"确认"按钮。
支付为什么几乎一定需要单独处理
Agent 调用不同 Tool,风险完全不同。
"查询北京天气"和"向供应商支付 10 万元",虽然从系统角度看都只是一次 Tool Call,但对用户来说完全不是一回事。前者失败,大不了重新查询;后者执行错误,可能直接造成资金损失。
所以支付类操作不应该只判断"用户是否授权过这个 Tool",还要判断这一次交易本身。
例如:
订阅一个每月 20 元的软件,可以允许用户提前设置"100 元以内自动支付";购买一台 2 万元的服务器,则必须再次确认;如果收款账户还是第一次出现,风险等级还应该继续提高。
也就是说,审批对象最好不是"Tool",而是一次具体的 Action。
同一个支付 Tool,在不同金额、不同收款人、不同业务场景下,可以拥有完全不同的审批策略。
Risk Level 不该只是 Low、Medium、High 三个标签
很多系统做到这里,会设计三个等级:
Low 自动执行,Medium 请求确认,High 禁止执行。
思路没错,但真正有价值的是:Risk Level 到底根据什么计算。
至少可以考虑四类因素。
一类是影响范围。读取数据和修改数据不同,发一封邮件和删除整个数据库也不同。
一类是可逆性。创建草稿可以撤销,转账完成后却未必容易追回。越不可逆,越需要人工确认。
还有交易金额、外部对象是否可信,以及动作是否偏离用户最初的目标。
例如用户说"帮我找一个便宜的酒店",Agent 最后准备预订每晚 3000 元的房间。即使酒店预订本身是一个允许使用的 Tool,这次 Action 依然值得升级审批。
因此更合理的模型是:
Risk = Action Type × Impact × Reversibility × Context
系统根据最终风险决定:
低风险自动执行;中风险让用户确认;高风险除了确认,还可能要求二次验证;极高风险则直接禁止 Agent 自主完成。
这样 Human-in-the-Loop 才真正是动态的。
审批页面应该回答用户三个问题
很多审批体验的问题,不是审批太多,而是用户根本看不懂自己在批准什么。
一个好的审批界面,至少应该让用户在几秒钟内回答三个问题:
Agent 要做什么?为什么要做?做完会发生什么?
比如不要只显示:
execute_payment(amount=3280, merchant_id=83721)
普通用户无法判断风险。
更好的方式是展示:
"支付 3280 元给 XX 航空,用于购买上海至东京的机票。支付成功后将立即出票,该票不可免费退款。"
技术参数可以折叠展示,但关键业务含义必须优先出现。
如果系统认为这是高风险操作,还可以进一步解释触发审批的原因:
"这是一次超过你自动支付上限的交易。"
这样的提示比单纯显示一个红色"High Risk"有用得多。
Human-in-the-Loop 的目标并不是让用户承担 Agent 的责任,而是给用户足够的信息做决策。
Tool 参数能不能让用户修改?
答案不是简单的"可以"或者"不可以"。
关键要看:修改以后,Agent 原来的计划是否仍然成立。
例如 Agent 准备:
book_hotel(city="Tokyo", nights=3)
用户把 nights 从 3 改成 4,一般可以直接重新计算价格并再次确认。
但如果用户把 city 改成 Osaka,问题就不同了。原来的酒店搜索、交通规划、预算判断可能全部失效。此时系统不应该直接修改参数并执行,而应该把变更交回 Agent,让它重新规划。
因此可以把参数分为两类:
局部参数 允许直接编辑,例如数量、备注、时间等;
计划参数修改后触发 Re-plan,例如目的地、收款人、核心资源等。
更进一步,某些安全参数甚至不应该允许修改。
比如系统限定 Agent 单笔付款最多 5000 元,审批页面当然不能让用户把安全上限直接改成 50000 元并顺手确认。
用户可以修改 Action,但不能通过审批界面绕过 Policy。
Reject 不是流程失败,而是一条新的信息
用户点击 Reject 之后,最糟糕的设计是 Agent 再生成一个几乎一样的请求,然后继续让用户批准。
Reject 本身就是用户反馈。
Agent 应该理解:
刚才这个方案不被接受。
下一步可以有几种选择。
如果还有替代路径,就重新规划。例如用户拒绝 3280 元的机票,Agent 可以寻找更便宜的航班。
如果缺少信息,可以询问:"你是觉得价格太高,还是时间不合适?"
如果这个 Action 是完成任务的必要条件,则应该明确告诉用户:"不执行支付就无法完成订票,我可以保留搜索结果,但无法继续购买。"
如果用户拒绝的是安全敏感操作,Agent 更不应该偷偷换一种 Tool 达成同样效果。否则审批机制只是表面上的控制。
因此一个成熟的 Agent Loop 应该是:
Plan → Risk Check → Approval → Execute / Re-plan / Abort
而不是:
Plan → Approval → 用户不同意 → 再问一次。
Human-in-the-Loop 真正设计的是责任边界
Human-in-the-Loop 很容易被理解成"危险操作前弹一个确认框",但这只是最简单的一层。
真正成熟的系统,需要提前回答五个问题:哪些动作值得打断用户;风险如何动态计算;用户审批时需要看到哪些信息;哪些参数可以修改;拒绝之后 Agent 应该如何重新规划。
其中最重要的一条原则是:审批频率应该和风险相关,而不是和 Agent 的动作数量相关。
低风险操作越自动化,Agent 越有价值;高风险操作越透明,用户才越敢把更多任务交给 Agent。
所以设计 Human-in-the-Loop 时,与其问"这里要不要加一个确认按钮",不如换一个问题:
如果这一步执行错了,后果由谁承担?
当这个答案变得清晰,支付、Risk Level、参数修改和 Reject 之后的行为,通常也会跟着变得清晰。
