Human-in-the-loop:审批、暂停、修改与恢复

# Human-in-the-loop:审批、暂停、修改与恢复

本篇目标

把人工介入设计成系统状态和产品流程,而不是临时弹窗;掌握审批绑定、暂停恢复、超时和幂等。

识别介入时机设计审批契约安全恢复执行改善用户体验

# 先记住一句话

Human-in-the-loop(HITL,人在回路中)是 Agent 在需要判断、补充信息或执行敏感动作时进入可持久化的暂停状态,由人审批、修改或拒绝后从同一任务继续。

# 四类人工介入

  1. Clarification:目标或关键信息不足,请用户补充;
  2. Approval:转账、发邮件、删除、发布等动作执行前确认;
  3. Review/Edit:人检查草稿,可以修改参数后再执行;
  4. Escalation:系统无法可靠判断,将任务交给专家处理。

# 审批不是一个布尔值

审批必须绑定具体动作和参数:

type ApprovalRequest = {
  taskId: string // 本次审批属于哪个任务
  actionId: string // 待执行动作的唯一标识,用于追踪并防止审批被挪用
  tool: string // 审批通过后准备调用的具体工具
  argsHash: string // 工具参数的哈希;参数改变后,原审批自动失效
  preview: string // 展示给审批人的动作内容、参数和影响摘要
  risk: 'medium' | 'high' // 风险等级,用于决定审批策略和警示方式
  expiresAt: string // 审批的失效时间,通常使用 ISO 8601 时间字符串
  requestedBy: string // 发起审批请求的 Agent 或系统组件
}
1
2
3
4
5
6
7
8
9
10

这段代码只是审批请求的数据契约,通常定义在后端或 Agent Runtime 中。一个常见的目录划分是:

src/
├── agent/
│   ├── approvals/
│   │   ├── types.ts               # 定义 ApprovalRequest 等审批数据结构
│   │   └── service.ts             # 创建、保存、批准和拒绝审批
│   └── runtime.ts                 # 遇到审批时暂停,审批完成后恢复 Agent
└── api/
    └── approvals.ts               # 向前端提供查询、批准和拒绝接口
1
2
3
4
5
6
7
8

类型定义可以由前后端共享,但前端只负责展示 preview 和收集用户决定。审批记录的保存、身份与权限校验以及工具执行必须留在可信的后端或 Agent Runtime,不能把前端弹窗当成安全边界。

用户批准后,如果工具参数发生变化,旧审批立即失效。恢复时还要重新校验身份、权限、过期时间和幂等状态,防止 “批准 A,实际执行 B”。

# 暂停和恢复流程

Agent 产生敏感 tool call
  ↓
服务端校验并生成操作预览
  ↓
保存 checkpoint,状态改为 requires_action
  ↓
前端展示影响范围、参数和风险
  ↓
用户批准 / 修改 / 拒绝
  ↓
后端再次校验 → 幂等执行 → 写入 observation → 继续循环
1
2
3
4
5
6
7
8
9
10
11

暂停可能持续数分钟甚至数天,所以不能依赖内存中的 Promise。需要持久化任务和 checkpoint,并允许审批超时、撤销和重新请求。

# 哪些动作默认需要批准

  • 财务、链上交易和购买;
  • 对外发送消息、邮件或发布内容;
  • 删除、覆盖和大范围修改;
  • 提升权限、连接新数据源;
  • 使用敏感个人信息;
  • 任何不可逆或难补偿的操作。

低风险只读操作可以自动执行,但仍要遵循权限和速率限制。

# 贯穿项目怎样落地

笔记助手读取和检索笔记可自动执行;新增学习记录可以展示预览后确认;批量改写或删除原笔记必须列出文件和 diff,用户确认后才执行。若用户长时间未响应,任务保持 requires_action 或过期为 cancelled,不应在后台自动继续。

# 高频面试题与回答

回答顺序:先说结论,再解释原因,最后补一个例子或工程边界。不要逐字背诵,记住这条表达主线即可。

1. 30 秒回答:如何设计 Agent 审批参考答案

我会在服务端拦截高风险调用,而不是只在前端弹一个确认框。系统先生成审批单,展示要调用的工具、具体参数、影响范围和过期时间,同时保存 Checkpoint。审批要绑定这一次动作和参数;用户同意后,服务端再次检查身份、权限和参数,再用幂等方式执行。参数变了、审批过期或用户拒绝,都不能沿用旧审批。

2. 为什么不能只在前端做确认弹窗?参考答案

因为前端请求可以被绕过或篡改,弹窗只能改善交互,不能成为安全边界。前端负责展示操作和收集决定;服务端必须保存审批记录,把审批绑定到具体动作和参数,并在真正执行前重新检查用户身份和权限。

3. 用户修改参数后还能使用原审批吗?参考答案

不能直接沿用。审批同意的是某一次具体操作,例如给谁转多少钱,而不是笼统同意 “可以转账”。系统应把审批绑定到规范化后的参数哈希;金额、收件人等关键内容一旦变化,就要重新展示并确认。

4. 怎样恢复一个暂停数小时的任务?参考答案

要从持久化 Checkpoint 恢复,不能依赖原进程还活着。继续前重新检查审批是否过期、用户是否仍有权限、外部条件是否变化,以及写操作是否已经执行。所有检查通过后,再从明确的下一步继续。

# 接下来学什么

下一篇学习 Agent 安全,重点理解怎样围绕提示注入、越权、数据泄露和危险副作用建立纵深防御。

# 参考资料

上次更新时间: 2026年09月10日 00:05:23