跳转到内容

人类中断(HITL):Agent 执行中的人类审批

人类中断(HITL):Agent 执行中的人类审批

学习目标

理解 CopilotKit 的 HITL 实现:

  • LangGraph Interrupt 事件的协议定义和传输
  • 前端如何接收和渲染中断事件
  • 用户审批后的恢复流程
  • HITL 场景下的线程锁管理

前置知识

本章涉及护栏系统和事件驱动架构的通用原理,建议先阅读:

下文假设你已理解上述概念,直接聚焦 CopilotKit 的 HITL 实现。

项目实践

Interrupt 事件协议

当 LangGraph Agent 执行到 interrupt() 节点时,通过 AG-UI 的 MetaEvent 通知前端。CopilotKit 定义了三种中断相关事件:

事件类型方向说明
LangGraphInterruptEventAgent → 前端Agent 暂停,携带中断信息
LangGraphInterruptResumeEvent前端 → Agent用户审批完成,携带恢复数据
CopilotKitLangGraphInterruptEventAgent → 前端增强版,携带完整消息历史和工具调用

事件载荷结构(源码验证):

LangGraphInterruptEvent:
{
type: "MetaEvent",
name: "LangGraphInterruptEvent",
value: "中断信息(字符串)"
}
CopilotKitLangGraphInterruptEvent:
{
type: "MetaEvent",
name: "CopilotKitLangGraphInterruptEvent",
data: {
value: "中断信息",
messages: [TextMessage | ActionExecutionMessage | ResultMessage]
}
}

前端中断处理

React hook useLangGraphInterrupt 接收和处理中断事件:

const {
interrupt, // 当前中断事件(或 null)
setInterruptResponse // 设置用户审批结果,触发恢复
} = useLangGraphInterrupt();
if (interrupt) {
// 渲染审批 UI
return (
<ApprovalDialog
message={interrupt.value}
onApprove={() => setInterruptResponse("approved")}
onReject={() => setInterruptResponse("rejected")}
/>
);
}

QueuedInterruptEvent 队列管理(源码验证):

当 Agent 可能连续触发多个中断时,前端通过队列管理:

  1. 第一个中断事件到达 → 渲染审批 UI
  2. 用户审批 → setInterruptResponse 将结果传回 Agent
  3. Agent 继续执行,可能触发下一个中断
  4. 新的中断事件进入队列,等待下一个审批

中断恢复流程

用户审批后,恢复流程:

关键细节

  • 恢复请求通过 interruptResume API 发送
  • 响应体包含用户审批结果(任意 JSON 值)
  • Agent 接收到恢复数据后,从断点处继续执行

线程锁管理

在 HITL 场景中,Agent 的执行被暂停,但线程锁仍然有效。CopilotKit 的 Intelligence 模式通过以下机制管理:

参数默认值最大值说明
lockTtlSeconds20s3600s(1 小时)锁的过期时间
lockHeartbeatIntervalSeconds15s3000s(50 分钟)心跳续约间隔
lockKeyPrefix默认自定义Redis key 前缀

防泄漏设计

  • 即使用户永久不响应,锁最终会因 TTL 过期而自动释放
  • 在用户审批期间,心跳续约保持锁有效
  • 最大 TTL 限制为 1 小时,防止无限期锁定

问题与规避

问题规避策略
中断事件在 SSE 流中的时序问题中间件通过 middleware-sse-parser 解析 SSE 消息边界,确保中断事件完整到达
用户拒绝后的 Agent 行为Agent 需要处理中断响应为”拒绝”的情况(如回退到安全操作或终止 run)
中断超时Intelligence 模式的 Redis 锁 TTL 是最终保障;前端可额外实现超时提示
多个中断的串行处理QueuedInterruptEvent 确保一次只处理一个中断,后续中断排队

设计取舍

HITL vs Guardrails

维度HITLGuardrails
触发方式Agent 主动请求自动规则匹配
决策主体人类代码逻辑
适用场景高风险操作(删除数据、发送消息)内容安全、格式校验
恢复方式审批结果注入 Agent,Agent 继续推理直接阻断或替换输出

组合使用:Guardrails 做自动的初级过滤,HITL 做人类的高级决策。

同步中断 vs 异步中断

同步中断(LangGraph 默认)

  • Agent 执行到 interrupt() 时完全暂停
  • 必须等待人类响应才能继续
  • 适合:必须人类确认的操作

异步中断(自定义 MetaEvent)

  • Agent 继续执行,同时通知前端
  • 前端可选择是否干预
  • 适合:信息通知类场景

参考来源

  • packages/react-core/src/hooks/use-langgraph-interrupt.ts
  • packages/runtime/src/service-adapters/events.ts(RuntimeEventTypes.MetaEvent)
  • LangGraph 人类中断文档