[LangGraph]Human-in-the-loop示例之人工干预shell命令执行
[LangGraph] Human-in-the-loop示例之人工干预shell命令执行引言在现代AI应用中智能体Agent自主执行shell命令的能力越来越常见例如自动化运维、代码生成与执行、数据分析等场景。然而完全自主的shell执行存在巨大的安全风险删除文件、修改系统配置、执行恶意命令等操作一旦失控后果不堪设想。因此Human-in-the-loop人机协同模式成为解决这一问题的关键方案。LangGraph是LangChain生态中专注于构建有状态、多步骤、图结构智能体的框架。它天然支持状态持久化和“中断-恢复”机制非常适合实现人工审核与干预的场景。本文将深入剖析LangGraph中Human-in-the-loop的原理并通过一个可运行的示例展示如何让智能体在执行shell命令前等待人工确认或修改。## Human-in-the-loop的核心机制在LangGraph中Human-in-the-loop的底层实现依赖于两个关键概念1.节点函数Node Function与中断Interrupt每个节点可以调用interrupt()函数挂起当前图的执行等待外部输入。执行状态会被持久化到存储后端如内存、数据库。2.状态更新与恢复外部系统如用户界面可以获取当前状态并提交更新。LangGraph会从断点处继续执行注入新的输入。这种设计使得我们可以在任意节点插入人工审核逻辑而不需要修改整个图的拓扑结构。## 示例人工干预shell命令执行假设我们有一个智能体它可以根据用户的需求生成并执行shell命令。我们希望在命令执行前让用户审查命令内容同意执行、修改命令、或拒绝执行。### 系统架构我们将构建一个简单的LangGraph图包含三个节点-parse_input解析用户输入生成shell命令。-human_review中断点等待人工审核。用户通过输入“Y”、“N”或修改后的命令来响应。-execute_command根据审核结果执行或跳过命令。### 代码示例1定义状态与节点函数pythonfrom typing import TypedDict, Optionalfrom langgraph.graph import StateGraph, ENDfrom langgraph.checkpoint.memory import MemorySaverfrom langgraph.constants import interrupt # 关键中断函数# 定义状态类型class AgentState(TypedDict): user_input: str # 用户原始输入 generated_command: Optional[str] # 生成的shell命令 human_decision: Optional[str] # 人工决策Y表示执行N表示拒绝其他字符串视为修改后的命令 execution_result: Optional[str] # 命令执行结果# 节点1解析输入生成shell命令def parse_input_node(state: AgentState) - AgentState: 根据用户输入生成shell命令模拟 user_input state[user_input] # 这里简化处理直接根据关键词生成命令 if list in user_input.lower(): command ls -la elif disk in user_input.lower(): command df -h else: command fecho Unknown command for: {user_input} print(f[Agent] 生成命令: {command}) return {generated_command: command}# 节点2人工审核节点中断点def human_review_node(state: AgentState) - AgentState: 等待人工输入返回决策结果 command state[generated_command] # 中断等待外部输入 # interrupt() 会挂起图执行并等待用户通过外部接口提交数据 user_response interrupt( f请审核即将执行的命令:\n{command}\n输入 Y 执行N 拒绝或直接输入修改后的命令: ) # 用户响应可以是字符串 return {human_decision: user_response}# 节点3根据决策执行命令def execute_command_node(state: AgentState) - AgentState: 根据人工决策执行或修改命令 decision state[human_decision] original_command state[generated_command] if decision.strip().upper() Y: # 同意执行原始命令 cmd_to_execute original_command print(f[Agent] 人工同意执行命令: {cmd_to_execute}) elif decision.strip().upper() N: # 拒绝执行 print([Agent] 人工拒绝跳过执行) return {execution_result: Command rejected by human} else: # 用户提供了修改后的命令 cmd_to_execute decision.strip() print(f[Agent] 人工修改命令执行: {cmd_to_execute}) # 模拟执行命令实际环境请使用subprocess等 import subprocess try: result subprocess.run(cmd_to_execute, shellTrue, capture_outputTrue, textTrue, timeout5) output result.stdout result.stderr print(f[Agent] 执行结果:\n{output}) return {execution_result: output} except Exception as e: print(f[Agent] 执行失败: {str(e)}) return {execution_result: fError: {str(e)}}# 构建图workflow StateGraph(AgentState)# 添加节点workflow.add_node(parse_input, parse_input_node)workflow.add_node(human_review, human_review_node)workflow.add_node(execute_command, execute_command_node)# 设置边从开始到parse_input然后到human_review最后到execute_commandworkflow.set_entry_point(parse_input)workflow.add_edge(parse_input, human_review)workflow.add_edge(human_review, execute_command)workflow.add_edge(execute_command, END)# 编译图启用持久化MemorySaverapp workflow.compile(checkpointerMemorySaver())### 代码示例2运行智能体并注入人工干预pythonimport uuiddef run_agent_with_human(user_input: str): 运行智能体模拟人工审核过程 # 初始化状态 initial_state {user_input: user_input} # 生成唯一线程ID用于状态持久化 thread_id str(uuid.uuid4()) config {configurable: {thread_id: thread_id}} # 第一次执行直到中断点 print(*50) print(f用户输入: {user_input}) print(第一次执行到达审核节点前...) # 使用stream模式逐节点产出结果 events [] for event in app.stream(initial_state, config, stream_modevalues): events.append(event) if generated_command in event: print(f当前状态: {event}) # 获取当前状态包含中断信息 current_state app.get_state(config) print(f中断信息: {current_state.tasks}) # 显示中断任务详情 # 模拟人工审核这里我们让用户输入决策 # 实际应用中可通过Web UI、CLI等交互 print(\n--- 人工审核环节 ---) human_input input(请输入您的决策 (Y/N/修改后的命令): ).strip() # 更新状态提交人工决策恢复执行 # 注意update_state会从断点继续执行 app.update_state(config, {human_decision: human_input}, as_nodehuman_review) # 第二次执行从中断点继续直到结束 print(\n第二次执行从审核节点继续...) for event in app.stream(None, config, stream_modevalues): events.append(event) if execution_result in event: print(f最终状态: {event}) # 打印最终结果 final_state app.get_state(config) print(f\n最终执行结果: {final_state.values.get(execution_result, 无结果)}) print(*50)# 运行示例if __name__ __main__: # 示例1用户请求列出文件 run_agent_with_human(请列出当前目录的文件) # 示例2用户请求查看磁盘信息 # run_agent_with_human(查看磁盘使用情况)### 运行效果演示假设用户输入“请列出当前目录的文件”智能体生成命令ls -la。程序会输出用户输入: 请列出当前目录的文件第一次执行到达审核节点前...[Agent] 生成命令: ls -la当前状态: {user_input: 请列出当前目录的文件, generated_command: ls -la, ...}中断信息: [...]--- 人工审核环节 ---请输入您的决策 (Y/N/修改后的命令): Y第二次执行从审核节点继续...[Agent] 人工同意执行命令: ls -la[Agent] 执行结果:total 24drwxr-xr-x 5 user staff 160 Aug 10 12:00 ....最终执行结果: Command output...如果用户输入“N”则命令被跳过如果用户输入“ls -al”则执行修改后的命令。## 原理深入剖析### 中断与状态持久化的协同工作LangGraph的interrupt()函数本质上是一个特殊的“状态标记”。当节点调用它时框架会1. 将当前图的执行上下文包括局部变量、节点指针序列化并保存到checkpointer中。2. 返回一个控制权给外部调用者后者可以通过get_state()获取中断信息。3. 当外部调用update_state()时框架反序列化状态从断点处恢复执行并将新数据注入到中断节点。这种机制类似于操作系统的“进程挂起与恢复”但专门为图计算设计。在我们的示例中human_review_node调用interrupt()后图的状态中会记录tasks字段包含中断时传递给用户的消息。### 为什么不是简单的条件分支传统方法可能通过条件判断if-else实现人工审核例如pythonif need_review: wait_for_input()else: execute()但这种方式的缺陷是-状态丢失如果程序崩溃审核状态丢失。-并发困难多个会话共享状态时容易混乱。-难以回放无法回溯审核历史。LangGraph的图结构天然解决了这些问题每个会话有独立thread_id状态持久化到存储后端可以随时中断、恢复、回放。## 总结本文通过一个具体的shell命令执行审核示例详细展示了如何在LangGraph中实现Human-in-the-loop。核心收获包括1.interrupt()函数在任意节点挂起图执行等待外部输入是实现人工干预的基石。2.状态持久化通过MemorySaver或其他checkpointer确保会话状态不丢失支持断点恢复。3.灵活的审核逻辑用户不仅可以同意/拒绝还可以修改命令内容体现了人机协同的灵活性。LangGraph的Human-in-the-loop机制不仅适用于shell命令审核还可广泛应用于- AI辅助编程中的代码审查- 金融交易中的风险控制- 自动驾驶中的紧急决策通过将“人”引入循环我们既利用了AI的自动化能力又保留了人类的判断力实现了安全与效率的平衡。

相关新闻

提升ChatLab分析效率:语义索引与向量模型优化技巧

提升ChatLab分析效率:语义索引与向量模型优化技巧

提升ChatLab分析效率:语义索引与向量模型优化技巧 【免费下载链接】ChatLab Local-first chat history analyzer with AI. | 本地优先的 AI 聊天记录分析工具 项目地址: https://gitcode.com/ChatLab/ChatLab ChatLab作为一款本地优先的AI聊天记录分析工具&…

2026/7/28 22:18:31阅读更多 →
提升Go API开发效率:api2go自动化CRUD操作的实现技巧

提升Go API开发效率:api2go自动化CRUD操作的实现技巧

提升Go API开发效率:api2go自动化CRUD操作的实现技巧 【免费下载链接】api2go JSONAPI.org Implementation for Go 项目地址: https://gitcode.com/gh_mirrors/ap/api2go 在Go语言开发中,构建符合JSONAPI规范的RESTful API往往需要大量重复工作。…

2026/7/28 19:22:54阅读更多 →
碧蓝幻想Relink战斗数据分析神器:GBFR-Logs完全指南,5分钟掌握你的真实伤害!

碧蓝幻想Relink战斗数据分析神器:GBFR-Logs完全指南,5分钟掌握你的真实伤害!

碧蓝幻想Relink战斗数据分析神器:GBFR-Logs完全指南,5分钟掌握你的真实伤害! 【免费下载链接】gbfr-logs GBFR Logs lets you track damage statistics with a nice overlay DPS meter for Granblue Fantasy: Relink. 项目地址: https://gi…

2026/7/28 21:28:24阅读更多 →
【AI大模型应用开发】【项目实战】32.Agent智扫引擎项目-(六)模型部署

【AI大模型应用开发】【项目实战】32.Agent智扫引擎项目-(六)模型部署

一.服务端 具体位置如下:/main.py 或者 /app.py 具体代码如下: # 通过接口方式来访问import timefrom Agent.ReAct import ReActAgent from Models.Factory import ChatModelFactory from Tools.Tools import * from langchain_community.chat_message_histories.in_memory i…

2026/7/28 22:27:14阅读更多 →
恋活!终极增强指南:如何使用HF Patch解锁200+插件与完整汉化功能

恋活!终极增强指南:如何使用HF Patch解锁200+插件与完整汉化功能

恋活!终极增强指南:如何使用HF Patch解锁200插件与完整汉化功能 【免费下载链接】KK-HF_Patch Automatically translate, uncensor and update Koikatu! and Koikatsu Party! 项目地址: https://gitcode.com/gh_mirrors/kk/KK-HF_Patch 你是否曾为…

2026/7/28 22:27:14阅读更多 →
煎饼排序算法详解:从原理到C++实现与优化

煎饼排序算法详解:从原理到C++实现与优化

1. 项目概述:从“翻煎饼”到高效排序如果你对排序算法的印象还停留在冒泡、快排这些经典模型上,那今天聊的这个“煎饼排序”(Pancake Sort)可能会让你眼前一亮。它不像那些算法在内存里悄无声息地交换数据,它的操作过程…

2026/7/28 22:27:14阅读更多 →
OpenClaw v2026.3.7核心升级:可插拔引擎与记忆重构

OpenClaw v2026.3.7核心升级:可插拔引擎与记忆重构

1. OpenClaw v2026.3.7核心升级解析OpenClaw作为当前最热门的开源AI开发框架之一,其2026.3.7版本带来了两项革命性特性:可插拔ContextEngine架构和记忆重构机制。这次升级不仅仅是功能迭代,更是对AI开发范式的一次重塑。1.1 可插拔ContextEng…

2026/7/28 22:27:14阅读更多 →
【JAVA毕设源码分享】基于SpringCloud的美食分享交流平台的设计与实现(程序+文档+代码讲解+一条龙定制)

【JAVA毕设源码分享】基于SpringCloud的美食分享交流平台的设计与实现(程序+文档+代码讲解+一条龙定制)

博主介绍:✌️码农一枚 ,专注于大学生项目实战开发、讲解和毕业🚢文撰写修改等。全栈领域优质创作者,博客之星、掘金/华为云/阿里云/InfoQ等平台优质作者、专注于Java、小程序技术领域和毕业项目实战 ✌️技术范围:&am…

2026/7/28 22:27:14阅读更多 →
Takin 全链路压测平台深度解析:从设计哲学到生产落地

Takin 全链路压测平台深度解析:从设计哲学到生产落地

1. Takin 简介 Takin 是由 Shulie Technology(原数列科技)开源的全链路压测平台,专门为微服务架构下的生产环境性能测试而设计。它通过流量染色、数据隔离、影子库等核心技术,在不污染真实数据、不影响真实用户的前提下,直接在线上环境施加大规模并发流量,精准测量系统容…

2026/7/28 22:25:14阅读更多 →
覆盖国产 + 海外 + 开源模型,OpenClaw 2.7.9 Windows/Mac 双端部署详解

覆盖国产 + 海外 + 开源模型,OpenClaw 2.7.9 Windows/Mac 双端部署详解

🔹 工具基础介绍 OpenClaw 是开源生态中一款实用性较强的本地智能工具,凭借本地离线运行、可视化图形操作和任务自动化三大核心特性,赢得了众多用户的青睐。与普通在线对话AI工具不同,它属于能够直接操控本机软硬件的智能数字员工…

2026/7/28 4:06:39阅读更多 →
伺服阀焊完微漏毁整机?精密激光焊接三关锁住高压

伺服阀焊完微漏毁整机?精密激光焊接三关锁住高压

所谓液压伺服阀体的精密激光焊接,是用激光束对阀座壳体(通常为不锈钢或铝合金)进行密封焊接,使阀体在21-35MPa的高压液压油或压缩气体中长期运行而不发生介质泄漏。液压伺服阀是高端液压系统的"大脑"。从航空航天飞行控…

2026/7/28 2:08:06阅读更多 →
D2DX:三步实现《暗黑破坏神2》高清宽屏体验的终极指南

D2DX:三步实现《暗黑破坏神2》高清宽屏体验的终极指南

D2DX:三步实现《暗黑破坏神2》高清宽屏体验的终极指南 【免费下载链接】d2dx D2DX is a complete solution to make Diablo II run well on modern PCs, with high fps and better resolutions. 项目地址: https://gitcode.com/gh_mirrors/d2/d2dx 你是否还在…

2026/7/28 1:38:28阅读更多 →
告别臃肿!3步让你的暗影精灵笔记本重获新生

告别臃肿!3步让你的暗影精灵笔记本重获新生

告别臃肿!3步让你的暗影精灵笔记本重获新生 【免费下载链接】OmenSuperHub Control Omen laptop performance, fan speeds, and keyboard lighting, and unlock power limits. 项目地址: https://gitcode.com/gh_mirrors/om/OmenSuperHub 你是否也曾为官方Om…

2026/7/28 0:00:29阅读更多 →
RAG必踩坑!财报法规检索不准?这款开源工具让答案浮出水面,准确率飙升98.7%!

RAG必踩坑!财报法规检索不准?这款开源工具让答案浮出水面,准确率飙升98.7%!

做 RAG 的人应该都踩过这个致命的坑:把几百页的财报、法规、技术手册扔给向量库,问一个具体问题,搜出来的全是沾边但没用的内容 —— 关键信息要么被硬切块拆碎了,要么藏在几十条结果的最下面。语义相似≠真正相关,这个…

2026/7/28 0:00:29阅读更多 →
抖音视频文案提取工具全指南:免费2026版、手机App、在线工具一网打尽

抖音视频文案提取工具全指南:免费2026版、手机App、在线工具一网打尽

2026年做短视频运营,从抖音上扒文案早就不是偷偷抄笔记的事了。我刚开始做内容的时候,每天刷半小时抖音,手动把爆款视频的口播敲进备忘录,一条2分钟的视频得花十来分钟,碰到语速快的还要反复回听。后来试了一圈工具&am…

2026/7/28 0:00:29阅读更多 →
YOLOv8推理性能优化:从1.2FPS到35FPS的全链路加速实践

YOLOv8推理性能优化:从1.2FPS到35FPS的全链路加速实践

如果你在部署 YOLOv8 时,发现推理速度只有可怜的 1-2 FPS,而别人的演示视频却能跑到 30 FPS 以上,那么问题很可能不在模型本身,而在于你的整个处理链路。很多开发者拿到一个训练好的 YOLOv8 模型后,会直接使用官方示例…

2026/7/28 20:22:24阅读更多 →
Coze与Dify对比指南:低代码AI应用开发从入门到实战

Coze与Dify对比指南:低代码AI应用开发从入门到实战

1. 从零到一:为什么你需要了解 Coze 和 Dify?如果你对 AI 应用开发感兴趣,但一看到“大模型”、“智能体”、“工作流”这些词就头疼,觉得门槛太高,那这篇文章就是为你准备的。很多开发者,包括我自己&#…

2026/7/28 3:17:03阅读更多 →
AI生图工具怎么选?2026年6月版实测对比

AI生图工具怎么选?2026年6月版实测对比

做自媒体的朋友应该都有体会:配图一直是个让人头疼的问题。2026年,AI生图工具已经非常成熟了,但工具太多反而不知道怎么选。以下是截至2026年6月我对主流AI生图工具的实测对比。Midjourney V8.1:速度之王2026年6月11日&#xff0c…

2026/7/28 2:35:58阅读更多 →