人机交互(Human-in-the-loop, HITL)指智能体为了向人类索要执行权限或额外信息而主动中断,并在获得人类回复后继续执行的过程。
LangGraph 特别开发了 HITL 中间件,用于人机交互。当触发人机交互时,HITL 中间件会中断程序执行,等待人类回复。在中断前,LangGraph 会将当前状态保存在检查点 checkpointer 中,直到中断结束,再将状态从检查点中恢复出来。
注意:本文只是演示 checkpoint 在人机交互过程中的作用,无所谓线程结束后记忆是否保持,因此使用
InMemorySaver。在生产环境中,请使用由数据库支持的检查点,例如:
SqliteSaver
PostgresSaver
MongoDBSaver
RedisSaver
import os
import uuid
from dotenv import load_dotenv
from langchain_openai import ChatOpenAI
from langchain.agents import create_agent
from langchain.agents.middleware import HumanInTheLoopMiddleware
from langchain_core.tools import tool
from langgraph.checkpoint.memory import InMemorySaver
from langgraph.types import Command
# 加载模型配置
_ = load_dotenv()# 配置大模型服务
llm = ChatOpenAI(
api_key=os.getenv("DASHSCOPE_API_KEY"),
base_url=os.getenv("DASHSCOPE_BASE_URL"),
model="qwen3-coder-plus",
)
# 工具函数
@tool
def get_weather(city: str) -> str:
"""Get weather for a given city."""
return f"It's always sunny in {city}!"
@tool
def add_numbers(a: float, b: float) -> float:
"""Add two numbers and return the sum."""
return a + b
@tool
def calculate_bmi(weight_kg: float, height_m: float) -> float:
"""Calculate BMI given weight in kg and height in meters."""
if height_m <= 0 or weight_kg <= 0:
raise ValueError("height_m and weight_kg must be greater than 0.")
return weight_kg / (height_m ** 2)
# 创建带工具调用的Agent
tool_agent = create_agent(
model=llm,
tools=[get_weather, add_numbers, calculate_bmi],
middleware=[
HumanInTheLoopMiddleware(
interrupt_on={
# 无需触发人工审批
"get_weather": False,
# 需要审批,且允许approve,edit,reject三种审批类型
"add_numbers": True,
# 需要审批,允许approve,reject两种审批类型
"calculate_bmi": {"allowed_decisions": ["approve", "reject"]},
},
description_prefix="Tool execution pending approval",
),
],
checkpointer=InMemorySaver(),
system_prompt="You are a helpful assistant",
)# 运行Agent
config = {'configurable': {'thread_id': str(uuid.uuid4())}}
result = tool_agent.invoke(
{"messages": [{
"role": "user",
"content": "我身高180cm,体重180斤,我的BMI是多少"
# "content": "what is the weather in sf"
}]},
config=config,
)
# result['messages'][-1].content
result.get('__interrupt__')[Interrupt(value={'action_requests': [{'name': 'calculate_bmi', 'args': {'height_m': 1.8, 'weight_kg': 90}, 'description': "Tool execution pending approval\n\nTool: calculate_bmi\nArgs: {'height_m': 1.8, 'weight_kg': 90}"}], 'review_configs': [{'action_name': 'calculate_bmi', 'allowed_decisions': ['approve', 'reject']}]}, id='b58dbd2802c1ff4f89a7504b20d5d229')]# Resume with approval decision
result = tool_agent.invoke(
Command(
resume={"decisions": [{"type": "approve"}]} # or "edit", "reject"
),
config=config
)
result['messages'][-1].content'您的BMI是27.8。根据中国成人BMI标准,这属于超重范围(BMI ≥ 24为超重,≥ 28为肥胖)。建议您关注饮食健康和适量运动,如有需要可咨询医生或营养师以获得更专业的建议。'参考文档: