Human-in-the-loop 中断机制
Human-in-the-loop 中断机制
学习目标
读完本章后,你将能够:
- 理解 Human-in-the-loop 在 Agent 系统中的核心作用
- 设计基于中断点的人类审核工作流
- 掌握中断的持久化与恢复机制
- 评估不同中断模式的适用场景与风险
1. 概念定义
Human-in-the-loop(HITL) 指在 Agent 自动执行的过程中,在关键节点主动暂停,等待人类审核、确认或注入数据后再继续执行的机制。
在 AI Agent 场景中,HITL 解决的核心问题是控制权边界:哪些决策可以全自动,哪些需要人类把关?
2. 中断的四种响应类型
| 类型 | 行为 | 适用场景 |
|---|---|---|
| accept | 人类确认当前状态,无需修改 | 审批流程、操作确认 |
| ignore | 人类跳过当前步骤 | 可选项审核、低优先级检查 |
| response | 人类提供文本反馈 | 代码审查、内容审核 |
| edit | 人类修改当前状态/内容 | 工具调用参数修正、决策修正 |
3. 中断配置
中断机制需要配置人类可执行的操作范围:
- allow_accept:是否允许人类直接确认
- allow_respond:是否允许人类提供文本反馈
- allow_edit:是否允许人类修改当前状态
- allow_ignore:是否允许人类跳过
配置决定了中断界面展示的交互选项,避免人类在不该修改的地方误操作。
4. 中断与 Checkpoint 的协同
中断不是简单的”暂停”,而是与持久化系统深度集成:
- 执行到中断点:Agent 执行
interrupt()函数 - 保存 checkpoint:当前状态、执行位置、中断上下文被持久化
- 抛出中断异常:执行暂停,向调用方返回中断信息
- 人类审核:外部系统展示当前状态,等待人类决策
- 恢复执行:人类通过
Command(resume=数据)提交决策 - 加载 checkpoint:从持久化存储恢复之前的状态
- 注入数据:将人类决策注入状态
- 继续执行:从中断点之后的节点继续
5. 中断 vs 异常的区别
| 维度 | 中断(Interrupt) | 异常(Exception) |
|---|---|---|
| 触发方 | 代码主动调用 interrupt() | 运行时错误、超时 |
| 预期性 | 预期内的控制流 | 预期外的错误 |
| 恢复方式 | 通过 Command(resume=...) 注入数据 | 通过重试策略或错误处理节点 |
| 状态保存 | checkpoint 包含中断上下文 | checkpoint 可能包含不完整状态 |
| 人类参与 | 必须有人类审核 | 可选 |
6. 陷阱与对策
陷阱 1:中断前未 checkpoint
问题:如果中断发生在 checkpoint 之前,中断后的状态变更可能丢失。
对策:确保中断点之前有明确的 checkpoint 时机。在配置中设置 Durability 为 sync 确保每次写入都先持久化。
陷阱 2:thread_id 不匹配
问题:恢复时必须使用与中断时相同的 thread_id,否则加载的是错误的 checkpoint。
对策:中断时将 thread_id 和 checkpoint_id 返回给调用方,恢复时原样传入。
陷阱 3:中断后状态膨胀
问题:中断时保存的 checkpoint 包含完整状态,如果状态中包含大文件、图片等数据,checkpoint 体积会急剧增长。
对策:在中断前清理状态中的大对象,或引用外部存储路径而非内联数据。
7. 设计取舍
优势
- 可控性:关键决策点有人类把关,降低自动化风险
- 可审计:每次中断和恢复都有 checkpoint 记录
- 灵活性:支持多种人类响应类型,适应不同审核场景
代价
- 延迟:人类审核时间不可控,可能长达数小时
- 复杂性:需要外部系统管理中断状态和人类交互界面
- 状态一致性:中断期间外部依赖(API、数据库)可能已变化
替代方案
- 全自动化 + 事后审核:适合低风险场景,审核在完成后进行
- 沙箱预览:在沙箱中执行并展示结果,人类确认后再应用到生产环境
- 分级授权:根据操作风险等级决定是否需要人类介入
8. 参考来源
- 文档: LangGraph Interrupts, https://docs.langchain.com/oss/python/langgraph/interrupts
- 论文: Pregel: A System for Large-Scale Graph Processing, Google, 2010
9. PydanticAI 的 Deferred Tool 审批实践
PydanticAI 不采用中断点(interrupt)模式,而是通过**延迟工具(deferred tool)**协议实现 Human-in-the-Loop:
审批流程
与 LangGraph Interrupt 的对比
| 维度 | LangGraph Interrupt | PydanticAI Deferred Tool |
|---|---|---|
| 触发点 | 节点执行中途 interrupt() | 工具执行后 ApprovalRequired |
| 暂停机制 | 保存 checkpoint 后抛出异常 | 异常被捕获,不中断整个 run |
| 恢复方式 | Command(resume=...) | HandleDeferredToolCalls 内联处理 |
| 适用范围 | 任意节点 | 仅限工具调用 |
| 参数修改 | 通过 edit 修改状态 | 通过 override_args 修改工具参数 |
| 持久化 | 依赖外部 checkpoint | 通过消息历史(ToolReturnPart)保持 |
两种审批注册方式
- 工具级:
Tool(requires_approval=True)— 所有调用都需要审批 - Toolset 级:
ApprovalRequiredToolset+ 谓词 — 动态决定是否需要审批(基于参数、历史、偏好)