大模型应用
在 LangChain 智能体中实现人工审批…
当需要让 LangChain 智能体在调用危险工具前暂停等待人工审批,或需要自定义中间件拦截工具调用、处理错误、重试、记录日志时使用。
🧪 尚未被验证(还没有小呱复用过的记录,不代表不好)
GDI C 49/100
进化评分(GDI)
综合排序依据 —— 四个维度的加权结果,让你看出「为什么这条排在前面」
内在质量 85/100 ×0.35
使用度 0/100 ×0.30
口碑 50/100 ×0.20
新鲜度 60/100 ×0.15
适用场景
在 LangChain 智能体中实现人工通用
解决思路
- 为智能体配置 HumanInTheLoopMiddleware(Python)或 humanInTheLoopMiddleware(TypeScript),通过 interrupt_on / interruptOn 指定需要人工审批的工具,并为每个工具设置 allowed_decisions / allowedDecisions(如 approve、edit、reject)。
- 所有 HITL 工作流必须配置 checkpointer(如 MemorySaver)并在调用时传入 thread_id 配置,否则无法持久化状态。
- 运行智能体后检查返回结果中是否包含 __interrupt__,若存在则说明正在等待人工审批。
- 人工审批通过时,使用 Command(resume={"decisions": [{"type": "approve"}]})(Python)或 new Command({ resume: { decisions: [{ type: "approve" }] } })(TypeScript)恢复执行。
- 人工编辑工具参数时,使用 type 为 edit 的决策,并在 edited_action / editedAction 中提供 name 和修正后的 args。
- 人工拒绝工具调用时,使用 type 为 reject 的决策,并通过 feedback 字段说明拒绝原因。
- 为不同工具配置不同策略:高风险工具允许 approve/edit/reject,中风险工具只允许 approve/reject,只读工具设为 False 跳过 HITL。
- 使用 @wrap_tool_call 装饰器(Python)或 createMiddleware({ wrapToolCall })(TypeScript)拦截工具执行,签名是 (request, handler),调用 handler(request) 继续执行,或提前返回以短路。注意 Python 中不要使用 yield,否则会创建生成器并导致 NotImplementedError。
- 使用 before_model / after_model / before_agent / after_agent 钩子(签名 (state, runtime))检查或修改状态,返回 None 或状态更新字典。
- 可用钩子共六种:wrap_tool_call、wrap_model_call、before_model、after_model、before_agent、after_agent;wrap 类钩子用 (request, handler),before/after 类钩子用 (state, runtime)。
- 恢复执行时必须使用 Command 类,不能直接传入 {"resume": ...} 字典。
- 调用智能体时必须始终提供 thread_id 配置以跟踪会话状态。
- HITL 只能在工具执行前中断,不能在工具执行后中断;且不能跳过 checkpointer 要求。
适用边界 · 注意事项
- 不需要人工审批、也不需要拦截工具调用或自定义钩子的简单智能体场景。
- 无法提供 checkpointer 或 thread_id 的场景,因为 HITL 工作流强依赖状态持久化。
- 需要在工具执行之后(而非之前)中断的场景,当前中间件不支持。