人在回路总览 (Human-in-the-loop overview)
深入解析智能体如何暂停工具调用等待人工审批,以及逐调用中断(Per-call)与批量中断(Batched)的核心架构差异。
人在回路(Human-in-the-loop,HITL)能够在敏感工具调用实际执行前主动挂起智能体,等待人类进行审查确认。审批人可以执行原样批准(approve)、修改参数(edit)、驳回并附带反馈(reject),或直接代替工具提供人工回复(respond)。该机制广泛用于难以撤销或需要强合规审计的高危操作,例如删除数据库记录、对外发送正式邮件或直接修改生产环境文件。
在 LangChain 中可通过 humanInTheLoopMiddleware 接入审查;在 Deep Agents 中可通过 interruptOn 参数配置。中间件支持两种中断审批模式:
- 逐调用中断 (Per-call):每个需要审核的工具调用单独产生一次精准中断挂起。
- 按轮次批量中断 (Batched):每个大模型交互轮次统一产生一次批量中断,覆盖本轮发起的所有受控工具调用(当前默认模式)。
从暂停到恢复的全流程 (Follow an approval from pause to resume)
无论采用哪种模式,人工审批的标准流转均遵循以下五个阶段:
- 模型提议调用:大语言模型根据推理生成一个或多个工具调用意图。
- 策略拦截挂起:中间件依据配置的
interruptOn安全策略进行比对。命中敏感规则的调用通过interrupt()触发流程挂起。 - 检查点状态保存:检查点持久化机制 (Checkpointer)自动保存当前状态快照,使得运行流程安全停顿,即便进程重启或跨天亦可随时断点恢复。
- 人工审核决策:宿主应用将挂起的工具调用呈现给审核人员,并收集每一项决定的操作结果。
- 恢复执行流:调用方传入
new Command({ resume })唤醒智能体。中间件应用人类决策,智能体继续向下流转。
系统支持四种标准决策类型:
| 决策类型 | 行为说明 | 典型业务场景 |
|---|---|---|
✅ approve | 批准:直接以模型提议的原始参数执行该工具。 | 邮件草稿内容完全符合要求,直接发送 |
✏️ edit | 编辑:在工具实际执行前人为修订其入参。 | 调整邮件收件人地址或补充关键参数后发送 |
❌ reject | 驳回:完全跳过该工具的执行,并将人类驳回原因反馈给智能体。 | 拒绝删除生产数据表,并说明安全阻断理由 |
💬 respond | 代答:跳过工具执行,直接将人类输入的回复作为工具执行结果灌回模型。 | 智能体调用“询问用户”类交互工具时直接给出答复 |
逐调用单独审核 (Review each tool call separately, Per-call)
在 Per-call 模式下,每个需要审批的工具调用在即将启动时独立触发中断:
每个中断对象都精准描述一个工具调用,并附带用于前端动态渲染表单的 response_schema(JSON Schema),客户端无需硬编码审批逻辑即可自动渲染操作表单。
恢复时,严格按中断的唯一 ID 精确传递决策结果:
ts
new Command({
resume: {
[writeFileInterrupt.id]: { type: "approve" },
[executeSqlInterrupt.id]: { type: "reject", message: "删除订单前必须先归档。" },
},
});按轮次整批审核 (Review a whole turn at once, Batched)
在 Batched 批量模式下,中间件在模型输出本轮回复后、任何工具实际执行前统一产生一次全局中断。即便是不需要审批的普通工具(如 read_data),也会被迫一并等待审批。
客户端必须以数组形式按位置顺序依次提交决策列表:
ts
new Command({
resume: {
decisions: [
{ type: "approve" },
{ type: "reject", message: "删除订单前必须先归档。" },
],
},
});两种模式的核心差异与问题对比
| 场景问题 | 批量模式 (Batched) | 逐调用模式 (Per-call) |
|---|---|---|
| 决策匹配机制 | 依靠数组下标严格按位置对齐。若前端传错顺序(如 [reject, approve]),错误会被张冠李戴应用到错误工具上。 | 每个决策与工具调用的 Interrupt ID 强绑定,杜绝位置错位风险。 |
| 表单渲染协议 | 审核规则分散在 reviewConfigs 数组中,前端必须自行解析并硬编码交互按钮。 | 每个中断原生下发 response_schema,前端可直接基于 Schema 自动生成动态表单组件。 |
| 格式校验时机 | 状态持久化写入后才做校验。若决策数量不匹配直接抛出致命异常,导致会话永久死锁卡死。 | 状态持久化前先做 Schema 校验,校验不通过允许用户修改后再次重试。 |
| 部分驳回影响 | 一损俱损:本轮只要有一个工具被 reject,其余被批准的工具乃至非受控只读工具都会被一并取消。 | 细粒度隔离:被批准的工具正常执行,被驳回的工具单独返回拒绝原因给模型重构思路。 |
中断模式选型指引
| 评估维度 | 逐调用模式 (Per-call,推荐) | 批量模式 (Batched) |
|---|---|---|
| 中断发生时机 | 每个敏感工具即将执行时单独挂起 | 模型本轮推理结束后、任何工具运行前挂起 |
| 非受控工具行为 | 立即放行并并行执行 | 被迫与受控工具一同停滞等待 |
| 状态回填方式 | 强类型 Map,基于 Interrupt ID 索引 | 数组形式,依赖位置顺序匹配 |
| 推荐适用场景 | 所有新建智能体项目,卡片式独立审批 UI,面向未来规范 | 维护现有的老旧审批 UI(如适配旧版 actionRequests 数据结构) |
