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 应用在真实生产环境中的安全性与可靠性。

本月热点