DeepAgents 人工介入实战|LangGraph 实现 Agent 高危工具人工审批
为什么 Agent 需要人工介入
Agent 最大的价值是可以根据用户目标自主规划并调用工具。
但并不是所有工具都适合完全自动执行。比如:
- 删除数据库表
- 删除文件
- 发起转账
- 修改线上配置
- 调用外部系统执行不可逆操作
这些动作一旦执行错误,影响可能非常大。
所以比较合理的模式是:
普通查询类动作可以让 Agent 自动执行,高风险动作必须先进入人工审批。
在本文示例中,我们定义了三个工具:
query_table_data:查询表数据,低风险,可以自动执行delete_table:删除数据表,高风险,需要人工审批delete_file:删除文件,高风险,需要人工审批
用户输入的任务是:
先查询product表的数据!再删除user表,最后,删除lucaju.txt文件
Agent 会先分析任务,并尝试依次调用工具。但当执行到删除表、删除文件这类高风险动作时,会被框架中断,等待人工确认。
二、初始化大模型
首先初始化模型:
import os
from langchain.chat_models import init_chat_model
llm = init_chat_model(
model="kimi-k2.5",
model_provider="openai",
api_key=os.getenv("AliQwen_API"),
base_url="https://dashscope.aliyuncs.com/compatible-mode/v1",
model_kwargs={"reasoning_effort": "none"},
)
这里使用的是 OpenAI 兼容模式,所以 model_provider 设置为 openai,同时把 base_url 指向阿里云 DashScope 的兼容接口。
需要提前配置环境变量:
export AliQwen_API="你的 API Key"
model_kwargs={"reasoning_effort": "none"} 是模型调用参数,可以根据实际模型支持情况调整。
三、定义工具
示例中定义了三个工具:
from langchain.tools import tool
@tool
def delete_table(table_name: str) -> str:
"""
删除指定的表
"""
return f"删除表{table_name}"
@tool
def delete_file(file_name: str) -> str:
"""
删除指定的文件
"""
return f"删除文件{file_name}"
@tool
def query_table_data(table_name: str) -> str:
"""
查询指定表的数据
"""
return f"查询表{table_name}的数据"
这里为了演示效果,工具内部只是返回字符串,并没有真的连接数据库或删除文件。
在真实项目中,delete_table 可能会执行 SQL,delete_file 可能会操作对象存储或服务器文件系统。这类工具就非常适合加人工审批。
四、为什么必须配置 Checkpointer
Human-in-the-loop 的核心不是简单地打印一句“是否确认”,而是让 Agent 的执行流程真正暂停下来,并且后续可以从暂停点继续执行。
这就需要保存执行状态。
示例代码中使用了 LangGraph 提供的内存检查点:
from langgraph.checkpoint.memory import InMemorySaver
checkpointer = InMemorySaver()
config = {
"configurable": {
"thread_id": "123"
}
}
这里有两个关键点:
checkpointer用来保存 Agent 的执行状态。thread_id用来标识当前会话。
当 Agent 执行到需要人工介入的节点时,LangGraph 会把当前状态保存下来。等人工审批完成后,再通过同一个 thread_id 找回之前的状态,并继续执行。
如果没有检查点,框架就不知道应该从哪里恢复执行。
五、创建支持人工介入的 DeepAgent
接下来创建 Agent:
from deepagents import create_deep_agent
main_agent = create_deep_agent(
model=llm,
name="主智能体",
system_prompt="回答使用中文,调用对应的工具实现对应的功能!",
tools=[delete_table, delete_file, query_table_data],
interrupt_on={"delete_table": True, "delete_file": True},
checkpointer=checkpointer
)
这里最关键的是两个参数:
interrupt_on={"delete_table": True, "delete_file": True}
以及:
checkpointer=checkpointer
interrupt_on 用来声明哪些工具调用需要中断。
在这个例子中:
- 调用
query_table_data不会中断 - 调用
delete_table会中断 - 调用
delete_file会中断
也就是说,Agent 可以自动查询数据,但不能自动删除表或文件。
这就是人工介入的核心配置。
六、第一次执行:触发中断
第一次执行 Agent:
result_1 = main_agent.invoke(
{
"messages": [
{
"role": "user",
"content": "先查询product表的数据!再删除user表,最后,删除lucaju.txt文件",
}
]
},
config=config,
)
这次调用并不一定会完整执行完所有工具。
如果执行链路中包含需要人工审批的工具,Agent 会暂停,并把中断信息放到返回结果的 __interrupt__ 字段中。
示例代码中这样获取:
interrupt = result_1["__interrupt__"]
当 interrupt 不为空时,说明当前执行过程中存在需要人工介入的动作。
七、查看待审批动作
更多推荐
所有评论(0)