LangChain 中间件实战:HumanInTheLoopMiddleware 实现高危操作人工审核
1. 引言在构建基于大语言模型LLM的智能体Agent时我们常常需要让 Agent 执行一些具有潜在风险的操作例如直接操作数据库、调用外部 API 或执行系统命令。为了确保安全性和可控性引入人工审核环节至关重要。LangChain 提供了强大的中间件Middleware机制其中HumanInTheLoopMiddleware便是实现“人在回路”Human-in-the-loop审核的利器。本文将深入解析HumanInTheLoopMiddleware的工作原理并通过一个完整的代码示例演示如何拦截 Agent 对数据库的高危写操作如INSERT、UPDATE、DELETE在人工确认、拒绝或修改后才继续执行。2. 核心概念与依赖2.1 什么是中间件Middleware在 LangChain 的 Agent 执行流程中中间件是一种可插拔的组件它能够在 Agent 调用工具Tool之前或之后介入实现诸如日志记录、权限检查、结果修改或本文重点人工中断等功能。2.2 HumanInTheLoopMiddlewareHumanInTheLoopMiddleware是langchain.agents.middleware模块提供的一个中间件。它的核心功能是根据预定义的规则interrupt_on在特定工具被调用时暂停 Agent 执行等待外部例如用户、审批系统输入决策然后根据决策结果恢复执行。2.3 关键依赖安装确保已安装以下库pipinstalllangchain langchain-core langgraph本文示例还假设你有一个可用的 LLM 模型。示例中使用了一个名为get_deepseek_model的工厂函数来获取模型你可以替换为 OpenAI、Azure OpenAI 或本地模型。3. 代码实现详解3.1 导入与初始化fromlangchain.agentsimportcreate_agentfromlangchain.agents.middlewareimportHumanInTheLoopMiddleware,InterruptOnConfigfromlangchain_core.messagesimportHumanMessagefromlangchain_core.toolsimporttoolfromlanggraph.checkpoint.memoryimportInMemorySaverfromlanggraph.typesimportCommandfrommethod.model_factoryimportget_deepseek_model# 获取模型实例modelget_deepseek_model()3.2 定义高危工具我们定义一个模拟的数据库写操作工具。在实际应用中这里应连接真实的数据库。tooldefdangerous_write(sql)-str:对数据库执行风险操作插入/更新/删除。当请求涉及数据库写操作或出现以‘SQL’开头的指令时必须调用本工具returnf[模拟执行]{sql}关键点工具的description非常重要它引导 LLM 在何时调用此工具。这里明确要求“当请求涉及数据库写操作或出现以‘SQL’开头的指令时必须调用本工具”。3.3 配置人工审核中间件hitlHumanInTheLoopMiddleware(interrupt_on{dangerous_write:InterruptOnConfig(allowed_decisions[approve,reject,edit],description请确认是否执行此高危操作)})interrupt_on: 一个字典指定哪些工具的调用需要中断。键是工具名dangerous_write值是InterruptOnConfig配置对象。allowed_decisions: 定义人工可以做出的决策类型。通常包括approve: 批准执行。reject: 拒绝执行。edit: 修改工具调用的参数后再执行。description: 中断时显示给人工审核者的提示信息。3.4 创建带中间件的 Agentagentcreate_agent(modelmodel,middleware[hitl],# 将中间件加入执行链tools[dangerous_write],system_prompt 只用一句极短中文回答≤20字。 凡是涉及数据库写操作或消息以“SQL”开头时必须调用工具dangerous_write不得直接回答 ,checkpointerInMemorySaver()# 用于保存中断状态便于恢复)CFG{configurable:{thread_id:test-hitl}}# 会话配置system_prompt进一步强化了 LLM 的行为约束确保其严格遵守工具调用规则。3.5 实现中断处理逻辑当中间件触发中断后Agent 的invoke方法会返回一个包含__interrupt__键的状态。我们需要编写处理函数来获取人工决策并使用Command(resume...)来恢复 Agent 执行。state{messages:[]}defhandle_interrupt(result):处理HITL中断从命令行读取决策并用Command(resume...)恢复。interruptresult.get(__interrupt__)print(interrupt)print(开始人工干预)decisioninput(请输入决策approve,reject,edit\n).strip().lower()ifdecisionapprove:returnagent.invoke(Command(resume{decisions:[{type:approve}]}),configCFG)elifdecisionreject:returnagent.invoke(Command(resume{decisions:[{type:reject,override:{content:[操作已被人工拒绝]}}]}),configCFG)elifdecisionedit:new_sqlinput(请输入您的新sql语句)returnagent.invoke(Command(resume{decisions:[{type:edit,edited_action:{name:dangerous_write,args:{sql:new_sql}}}]}),configCFG)else:print(输入的指令有问题采用reject方案)returnagent.invoke(Command(resume{decisions:[{type:reject,override:{content:[操作已被人工拒绝]}}]}),configCFG)决策恢复机制approve: 决策类型为approveAgent 将使用原参数继续调用工具。reject: 决策类型为reject并提供一个override内容。Agent 不会调用工具而是直接将此内容作为工具调用的结果返回给 LLM。edit: 决策类型为edit并提供edited_action指定新的工具名和参数。Agent 将使用新参数调用工具。3.6 模拟多轮对话conversation[你是谁,SQL: INSERT INTO logs(content) VALUES (hello);,继续,SQL: DELETE FROM orders WHERE created_at date(now,-7 days);]fori,questioninenumerate(conversation,start1):print(f\n第{i}轮)print(fQ:{question})humanMessageHumanMessage(contentf{question})stateagent.invoke({messages:[humanMessage]},configCFG)# 检查是否被中间件中断ifstate.get(__interrupt__):statehandle_interrupt(state)print(type(state).__name__)print(state)answerstate[messages][-1].contentprint(fA:{answer})4. 执行流程与输出分析运行上述代码你将看到类似以下的交互过程第1轮普通问答:Q: 你是谁 A: [LLM的简短自我介绍例如“我是AI助手。”]说明第一轮不涉及 SQLLLM 直接根据系统提示简短回答。第2轮触发中断:Q: SQL: INSERT INTO logs(content) VALUES (hello);此时LLM 识别到“SQL:”开头决定调用dangerous_write工具。中间件检测到对该工具的调用触发中断。控制台打印中断信息并等待输入开始人工干预 请输入决策approve,reject,edit假设用户输入approveAgent 恢复执行工具被调用返回[模拟执行]INSERT INTO logs(content) VALUES (hello);LLM 最终输出该结果。第3轮不触发:Q: 继续 A: [LLM的简短回答]第4轮再次触发中断:Q: SQL: DELETE FROM orders WHERE created_at date(now,-7 days);再次触发中断。此时用户可以尝试reject或edit决策。如果输入reject最终回答将是[操作已被人工拒绝]。如果输入edit程序会提示输入新的 SQL例如改为SELECT * FROM orders WHERE ...然后 Agent 会用新 SQL 调用工具。5. 总结与扩展5.1 核心价值HumanInTheLoopMiddleware为 AI Agent 系统提供了关键的安全护栏。它将自动化流程与人类判断相结合特别适用于数据库写操作防止误删、误更新。金融交易支付、转账前的二次确认。内容发布敏感信息发布前的审核。系统控制重启服务器、修改配置等危险命令。5.2 扩展思路图形化界面将命令行输入替换为 Web 界面或聊天机器人按钮提升用户体验。多级审批根据操作风险等级设计串联多个审批节点的中间件。超时与默认策略为中断设置超时超时后自动执行预设策略如拒绝。审计日志在中间件中记录所有中断事件、决策人、决策结果和时间戳便于追溯。通过本文的示例你应该已经掌握了使用HumanInTheLoopMiddleware为你的 LangChain Agent 添加人工审核能力的基本方法。合理利用此机制可以极大增强 AI 应用在真实生产环境中的安全性与可靠性。

相关新闻

超辐射发光二极管(SLD)原理、应用与选型全解析

超辐射发光二极管(SLD)原理、应用与选型全解析

1. 项目概述:从“配角”到“主角”的超辐射光源在光电子领域,提到光源,大家首先想到的往往是激光器(LD)和发光二极管(LED)。前者方向性好、亮度高,后者成本低、寿命长。但你是否遇到…

2026/10/2 10:47:28 阅读更多 →
JavaScript:ES6 + 高级语法、模块化、元编程

JavaScript:ES6 + 高级语法、模块化、元编程

第十一阶段:ES6 高级语法、模块化、元编程 11.1模块化系统「ES6」 ES Module 模块标准 import /export 默认导出 export default、具名导出 export 默认导出:一个模块只能有一个默认导出,使用 export default 关键字。例如,在 ma…

2026/9/29 3:21:39 阅读更多 →
STM32内部FLASH存储与显示图片:资源优化与RGB565转换实战

STM32内部FLASH存储与显示图片:资源优化与RGB565转换实战

1. 项目缘起:为什么要在STM32内部FLASH里存图片?最近在做一个基于STM32F103的便携式设备,需要显示一个公司的Logo和一些简单的状态图标。一开始,我理所当然地想到了用SD卡或者外置SPI FLASH来存储这些图片资源,毕竟现在…

2026/10/12 23:23:36 阅读更多 →

最新新闻

拼多多商家自研接口申请教程(2026最新版):从注册到调通API全流程踩坑记录

拼多多商家自研接口申请教程(2026最新版):从注册到调通API全流程踩坑记录

关键词:拼多多开放平台 商家自研 ERP对接 API申请 pdd接口 最近公司要把拼多多店铺的订单、库存、物流全部收到自研ERP里统一管理,研究了一圈拼多多开放平台,发现"商家自研"这条路其实门槛不高,但官方文档写得比较散,中…

2026/10/13 10:29:05 阅读更多 →
Spring Boot + MyBatis 整合实践:从自动装配到事务与连接池调优

Spring Boot + MyBatis 整合实践:从自动装配到事务与连接池调优

简介:这套Spring Boot与MyBatis的整合模板,面向需要快速搭建后端数据接口的Java工程师,也适合作为项目开发的基础骨架。项目利用Spring Boot的自动配置简化依赖管理与启动流程,将MyBatis作为持久层框架,通过Mapper接口…

2026/10/13 10:29:05 阅读更多 →
Spring Boot + MyBatis 数据访问层实战:配置、踩坑与性能优化

Spring Boot + MyBatis 数据访问层实战:配置、踩坑与性能优化

简介:面向Java Web后端开发者,这是一套SpringBoot与MyBatis整合的项目示例,围绕高效微服务开发场景,引入Druid连接池与Swagger接口文档工具,可降低项目初期配置成本,统一数据持久层访问,并为API…

2026/10/13 10:29:05 阅读更多 →
64位PowerShell避坑指南:从32位进程架构到内存溢出与注册表重定向

64位PowerShell避坑指南:从32位进程架构到内存溢出与注册表重定向

简介:面向仍在使用Windows Server 2003等旧版64位系统的运维人员与开发者,这是一份难得的Windows PowerShell 64位安装包。该压缩包恰好补足了微软官方不再为这些老系统提供下载的缺口,共包含2个文件:PowerShell_Setup_amd64.msi安…

2026/10/13 10:29:05 阅读更多 →
C# WinForms+SQLite设备管理系统开发:台账、维修与报表全攻略

C# WinForms+SQLite设备管理系统开发:台账、维修与报表全攻略

简介:这是一套基于C#与ASP.NET的Web设备管理系统完整源码工程,主要面向C#初中级学习者、高校软件相关专业学生以及需要快速搭建设备管理后台的开发者。系统覆盖设备档案维护、借用归还登记、维修工单处理和报表统计等典型管理环节,源码中充分…

2026/10/13 10:29:05 阅读更多 →
Oracle rownum与rowid底层原理与实战避坑指南

Oracle rownum与rowid底层原理与实战避坑指南

1. 为什么刚学Oracle的人总在rownum上栽跟头?刚接触Oracle的开发者,十有八九会在rownum上卡住至少三天。我见过某高校数据库课程的期末项目里,A同学用SELECT * FROM emp WHERE rownum > 5想跳过前5条查后面的数据,结果返回空集…

2026/10/13 10:28:04 阅读更多 →

日新闻

物联网系统集成避坑指南:从选型到验收的关键要点

物联网系统集成避坑指南:从选型到验收的关键要点

做了这么多年物联网系统集成的项目,我最大的感受是,大部分坑不是出在技术前沿,而是出在一些看起来很平常的地方。设备选了便宜的、协议没问清楚、现场没摸透、验收标准写得含糊——这些细枝末节,最后都会变成延期、超支和扯皮的大…

2026/10/13 0:00:57 阅读更多 →
ESP32舵机控制全攻略:从PWM原理到高级玩法与常见故障排查

ESP32舵机控制全攻略:从PWM原理到高级玩法与常见故障排查

如果你玩ESP32有一阵子了,很难不碰到舵机控制这道坎。做智能小车要转方向,做机械臂要抬关节,做云台要偏航俯仰,背后都是同一个东西在干活:舵机。而我见过太多人卡在“代码能编译、舵机就是不听话”这个阶段&#xff0c…

2026/10/13 0:00:57 阅读更多 →
CAN总线原理与STM32实战:抗干扰、仲裁、错误处理全解析

CAN总线原理与STM32实战:抗干扰、仲裁、错误处理全解析

1. 为什么CAN总线至今仍是工业现场的“硬通货”?——从汽车底盘到智能温室的真实需求你有没有拆过一辆老款燃油车的中控台?或者调试过某高校实验室里那台跑着Modbus协议却频频丢帧的PLC控制柜?又或者,在某个农业物联网项目里&…

2026/10/13 0:00:57 阅读更多 →

周新闻

流感时间序列预测实战:ARIMA/LSTM全流程拆解与避坑指南

流感时间序列预测实战:ARIMA/LSTM全流程拆解与避坑指南

简介:基于 ARIMA、LSTM、Transformer 等模型的流感时间序列预测 Python 源码,面向计算机相关专业课程设计与期末大作业学生,以及项目实战学习者。内容覆盖预处理、平稳性检验、定阶、残差分析、多模型对比预测的完整时序建模流程,…

2026/10/13 2:54:56 阅读更多 →
影刀RPA新手教程:键盘模拟输入实战——输入文本与模拟按键的区别

影刀RPA新手教程:键盘模拟输入实战——输入文本与模拟按键的区别

影刀RPA新手教程:键盘模拟输入实战——输入文本与模拟按键的区别 做影刀RPA自动化,十个新手有八个栽在"往输入框里填东西"这件事上:要么填不进去,要么填了一半,要么直接把原来内容追加在后面。这背后的根因&…

2026/10/12 0:16:38 阅读更多 →
影刀RPA新手教程:阅文起点小说数据采集实战——书籍信息与章节内容

影刀RPA新手教程:阅文起点小说数据采集实战——书籍信息与章节内容

影刀RPA新手教程:阅文起点小说数据采集实战——书籍信息与章节内容 1. 认识影刀:什么场景该用RPA采小说数据 起点中文网的页面结构相对稳定——分类榜单、书籍详情、章节内容三块独立页面,跳转链路清晰。这种场景非常适合影刀自动化&#x…

2026/10/13 1:58:08 阅读更多 →

月新闻

我发现了一个新思路:用 Remotion + Claude Code 像写代码一样自动化生成短视频

我发现了一个新思路:用 Remotion + Claude Code 像写代码一样自动化生成短视频

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/12 21:05:09 阅读更多 →
Windows下 Codex 中 Chrome 和 Computer Use 插件不可用问题排查及解决参考方式:TaoToken 统一 Key 配置与验证

Windows下 Codex 中 Chrome 和 Computer Use 插件不可用问题排查及解决参考方式:TaoToken 统一 Key 配置与验证

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/12 14:48:49 阅读更多 →
黑夜航拍船只数据集训练YOLOV5模型全流程解析

黑夜航拍船只数据集训练YOLOV5模型全流程解析

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/12 18:11:17 阅读更多 →