人机交互(Human-in-the-loop, HITL)指智能体为了向人类索要执行权限或额外信息而主动中断,并在获得人类反馈后继续执行的过程。
LangGraph 的人机交互功能可以通过内置中间件 HumanInTheLoopMiddleware(HITL)实现。触发人机交互后,HITL 会将当前状态保存到 checkpointer 检查点中,并等待人类回复。获得回复后,再将状态从检查点中恢复出来,继续执行任务。
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.tools import tool
from langgraph.checkpoint.memory import InMemorySaver
from langgraph.types import Command
# 加载模型配置
_ = load_dotenv()下面使用 HITL 中间件,为三种工具配置人工审批流程。
# 配置大模型服务
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='fee064093af8bee2b29f108c79c64d36')]从中断信息来看,智能体已触发 calculate_bmi 工具调用,并进入等待审批状态。下面我们向智能体发送「审批通过」指令,使其恢复运行。
# 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为肥胖)。建议您关注饮食健康和适量运动,如有需要可咨询医生或营养师以获得更专业的指导。'