LangGraph预构建组件实战指南
【免费下载链接】langgraph 项目地址: https://gitcode.com/GitHub_Trending/la/langgraph
本文深入探讨LangGraph框架中的核心预构建组件,包括ReAct代理创建与工具集成、ToolNode工具执行节点、ValidationNode验证机制以及人类在环交互功能。通过详细的代码示例和架构解析,展示如何利用这些组件构建高效、可靠的智能代理系统,涵盖从基础工具集成到高级状态管理、错误处理和人工审核的全流程实践。
ReAct代理创建与工具集成
LangGraph的create_react_agent函数提供了一个强大的预构建组件,用于快速创建基于ReAct(Reasoning and Acting)模式的智能代理。这个组件封装了复杂的代理工作流,让开发者能够专注于工具定义和业务逻辑,而无需关心底层的状态管理和循环控制。
核心架构与工作原理
ReAct代理的核心架构基于一个状态机模型,通过消息传递和工具调用的循环来实现推理和执行的过程。整个工作流可以概括为以下几个关键步骤:
创建基础ReAct代理
创建一个基础的ReAct代理非常简单,只需要提供模型和工具列表:
from langgraph.prebuilt import create_react_agent
from langchain_openai import ChatOpenAI
# 定义工具函数
def get_weather(city: str) -> str:
"""获取指定城市的天气信息"""
return f"{city}的天气:晴朗,25°C"
def get_time(location: str) -> str:
"""获取指定地点的当前时间"""
return f"{location}的当前时间:14:30"
# 创建代理
model = ChatOpenAI(model="gpt-4")
tools = [get_weather, get_time]
agent = create_react_agent(
model=model,
tools=tools,
prompt="你是一个有用的助手,能够回答天气和时间相关问题"
)
# 运行代理
result = agent.invoke({
"messages": [{
"role": "user",
"content": "北京现在的天气和时间是什么?"
}]
})
工具定义与集成规范
在LangGraph中,工具可以是简单的Python函数、LangChain工具对象或字典格式的工具定义。每个工具都需要有清晰的文档字符串,因为LLM会使用这些描述来决定何时调用哪个工具。
工具定义的最佳实践:
from typing import Annotated
from langchain_core.tools import tool
# 方式1:使用装饰器定义结构化工具
@tool
def search_products(query: str, category: Annotated[str, "产品类别"]) -> str:
"""搜索指定类别的产品信息
Args:
query: 搜索关键词
category: 产品类别(电子、服装、食品等)
Returns:
匹配的产品列表信息
"""
return f"找到{category}类别的产品:{query}"
# 方式2:普通函数作为工具
def calculate_shipping(zipcode: str, weight: float) -> str:
"""计算运费
Args:
zipcode: 邮政编码
weight: 包裹重量(kg)
Returns:
运费计算结果
"""
return f"到{zipcode}的运费:{weight * 5}元"
# 方式3:字典格式的工具定义
custom_tool = {
"name": "get_user_profile",
"description": "获取用户个人信息",
"parameters": {
"type": "object",
"properties": {
"user_id": {"type": "string", "description": "用户ID"}
},
"required": ["user_id"]
}
}
高级配置选项
create_react_agent提供了丰富的高级配置选项,支持复杂的业务场景:
from langgraph.checkpoint.memory import MemorySaver
# 配置检查点用于持久化
checkpointer = MemorySaver()
agent = create_react_agent(
model=model,
tools=tools,
prompt="专业客服助手",
response_format=("structured_response", ResponseSchema),
pre_model_hook=pre_processing_hook, # 模型调用前的预处理
post_model_hook=post_processing_hook, # 模型调用后的后处理
state_schema=CustomState, # 自定义状态schema
checkpointer=checkpointer, # 持久化支持
store=custom_store, # 自定义存储
interrupt_before=["model"], # 在模型调用前可中断
interrupt_after=["tools"], # 在工具调用后可中断
version="v2" # 使用最新版本
)
状态管理与注入
LangGraph支持强大的状态注入机制,工具可以访问代理的当前状态:
from typing import Annotated
from langgraph.types import InjectedState, InjectedStore
def personalized_recommendation(
product_id: str,
state: Annotated[dict, InjectedState], # 注入整个状态
user_prefs: Annotated[dict, InjectedState("user_preferences")], # 注入特定状态字段
store: Annotated[BaseStore, InjectedStore()] # 注入存储
) -> str:
"""基于用户偏好生成个性化推荐"""
user_id = state.get("user_id")
preferences = user_prefs.get("interests", [])
return f"为用户{user_id}推荐{product_id},基于兴趣:{preferences}"
错误处理与重试机制
ReAct代理内置了完善的错误处理机制:
from langgraph.errors import ToolException
def handle_tool_errors(
error: Exception,
call: ToolCall,
schema: Type[BaseModel]
) -> str:
"""自定义工具错误处理"""
if isinstance(error, ValueError):
return "输入参数无效,请检查后重试"
elif isinstance(error, ToolException):
return f"工具调用失败:{error.message}"
else:
return "系统繁忙,请稍后重试"
# 在工具节点配置错误处理
tool_node = ToolNode(
tools=[get_weather, get_time],
handle_tool_errors=handle_tool_errors
)
实际应用案例
以下是一个完整的客户服务代理示例:
from langgraph.prebuilt import create_react_agent
from langchain_anthropic import ChatAnthropic
class CustomerServiceAgent:
def __init__(self):
self.model = ChatAnthropic(model="claude-3-sonnet-20240229")
self.tools = [
self.get_order_status,
self.process_refund,
self.escalate_issue,
self.provide_product_info
]
self.agent = create_react_agent(
model=self.model,
tools=self.tools,
prompt="你是专业的客户服务代表,帮助用户解决订单、退款、产品咨询等问题",
checkpointer=MemorySaver()
)
def get_order_status(self, order_id: str) -> str:
"""查询订单状态"""
return f"订单 {order_id} 状态:已发货,预计明天送达"
def process_refund(self, order_id: str, reason: str) -> str:
"""处理退款申请"""
return f"订单 {order_id} 的退款申请已受理,原因:{reason}"
def escalate_issue(self, issue: str) -> str:
"""升级复杂问题"""
return f"问题已升级给专家团队:{issue}"
def provide_product_info(self, product_name: str) -> str:
"""提供产品信息"""
return f"产品 {product_name} 的信息:高性能,耐用,性价比高"
def handle_query(self, user_message: str) -> str:
"""处理用户查询"""
result = self.agent.invoke({
"messages": [{"role": "user", "content": user_message}]
})
return result["messages"][-1].content
# 使用代理
service_agent = CustomerServiceAgent()
response = service_agent.handle_query("我的订单12345状态怎么样?")
性能优化建议
- 工具选择优化:使用动态模型根据上下文选择最合适的工具集
- 缓存策略:对频繁调用的工具结果进行缓存
- 批量处理:支持并行工具调用提高效率
- 监控指标:跟踪工具调用成功率、响应时间等关键指标
# 动态工具选择示例
def dynamic_model_selector(state: dict, runtime: Runtime) -> BaseChatModel:
"""根据对话上下文选择最合适的模型和工具"""
context = state.get("conversation_context", {})
if context.get("is_technical_issue"):
return technical_model.bind_tools(technical_tools)
elif context.get("is_billing_issue"):
return billing_model.bind_tools(billing_tools)
else:
return general_model.bind_tools(general_tools)
通过create_react_agent组件,开发者可以快速构建出功能强大、可扩展的智能代理系统,充分利用LangGraph提供的状态管理、持久化、错误处理等高级特性。
ToolNode工具执行节点详解
在LangGraph的预构建组件生态中,ToolNode扮演着至关重要的角色——它是连接AI模型与现实世界功能的桥梁。作为专门负责工具执行的节点,ToolNode能够解析AI模型发出的工具调用请求,执行相应的工具函数,并将执行结果封装成标准化的消息格式返回给工作流。
核心功能与架构设计
ToolNode继承自RunnableCallable,是一个高度可配置的工具执行引擎。它的核心职责包括:
- 工具调用解析:从AIMessage中提取工具调用信息
- 并行执行:支持多个工具调用的并发执行
- 错误处理:提供灵活的错误处理机制
- 状态注入:支持将图状态和持久化存储注入到工具中
- 结果标准化:将工具输出转换为标准的ToolMessage格式
核心配置参数详解
ToolNode提供了丰富的配置选项来满足不同的使用场景:
| 参数 | 类型 | 默认值 | 说明 |
|---|---|---|---|
tools | Sequence[Union[BaseTool, Callable]] | 必填 | 可用的工具列表 |
name | str | "tools" | 节点名称,用于调试和可视化 |
tags | Optional[list[str]] | None | 元数据标签,用于过滤和组织 |
handle_tool_errors | Union[bool, str, Callable, tuple] | True | 错误处理配置 |
messages_key | str | "messages" | 状态字典中消息列表的键名 |
工具执行流程深度解析
ToolNode的执行流程经过精心设计,确保工具调用的高效性和可靠性:
-
输入解析阶段
- 支持三种输入格式:消息列表、字典状态、BaseModel状态
- 自动从最后一条AIMessage中提取工具调用信息
- 验证工具名称的有效性
-
参数注入阶段
- 支持
InjectedState注解,将图状态注入到工具参数中 - 支持
InjectedStore注解,将持久化存储注入到工具中 - 自动处理参数类型匹配和转换
- 支持
-
并行执行阶段
- 使用
asyncio.gather实现真正的并发执行 - 每个工具调用在独立的执行上下文中运行
- 支持同步和异步工具函数
- 使用
-
结果处理阶段
- 将工具输出转换为标准化的ToolMessage格式
- 支持多种输出格式:字符串、JSON、内容块列表
- 自动生成工具调用ID和元数据
错误处理机制
ToolNode提供了多层次的错误处理策略,确保工作流的稳定性:
# 基础错误处理 - 捕获所有异常
tool_node = ToolNode(tools, handle_tool_errors=True)
# 自定义错误消息
tool_node = ToolNode(tools, handle_tool_errors="执行工具时发生错误")
# 类型特定的错误处理
tool_node = ToolNode(tools, handle_tool_errors=(ValueError, TypeError))
# 自定义错误处理函数
def custom_error_handler(e: ZeroDivisionError) -> str:
return "数学运算错误:不能除以零!"
tool_node = ToolNode(tools, handle_tool_errors=custom_error_handler)
错误处理支持的类型推断机制能够自动分析自定义处理函数的签名,确保只有匹配的异常类型会被捕获和处理。
状态注入功能
ToolNode支持两种类型的依赖注入,极大增强了工具的灵活性:
状态注入示例:
from langgraph.prebuilt import InjectedState
@tool
def process_with_state(data: str, state: Annotated[dict, InjectedState]) -> str:
"""使用图状态处理数据"""
user_preferences = state.get('user_preferences', {})
return f"Processed {data} with preferences: {user_preferences}"
# 存储注入示例
from langgraph.prebuilt import InjectedStore
@tool
def save_to_store(data: str, storage: Annotated[BaseStore, InjectedStore]) -> str:
"""使用持久化存储保存数据"""
storage.set("user_data", data)
return f"Data saved: {data}"
高级使用模式
并行执行优化:
# 创建支持并行执行的ToolNode
tool_node = ToolNode([
weather_tool,
calculator_tool,
database_query_tool
])
# 在StateGraph中使用
graph_builder.add_node("tools", tool_node)
graph_builder.add_conditional_edges(
"agent",
tools_condition,
{"tools": "tools", "__end__": "__end__"}
)
graph_builder.add_edge("tools", "agent")
条件路由函数:
from langgraph.prebuilt import tools_condition
# 自动检测是否需要执行工具
def should_use_tools(state):
return tools_condition(state, messages_key="messages")
性能优化建议
-
工具设计原则:
- 保持工具函数的纯净性,避免副作用
- 使用异步工具处理I/O密集型操作
- 合理设置超时时间,避免阻塞
-
内存管理:
- 及时清理不再需要的工具实例
- 使用轻量级的工具参数传递
- 避免在工具中存储大量状态
-
错误恢复:
- 实现重试机制处理临时性错误
- 使用断路器模式防止级联失败
- 记录详细的执行日志用于调试
ToolNode作为LangGraph工作流中的关键组件,通过其强大的工具执行能力和灵活的配置选项,为构建复杂的多工具AI应用提供了坚实的基础。无论是简单的计算工具还是复杂的外部系统集成,ToolNode都能提供可靠、高效的执行环境。
ValidationNode验证机制实现
LangGraph的ValidationNode是一个强大的预构建组件,专门用于在AI代理工作流中验证工具调用的参数。它充当一个智能的验证层,确保模型生成的工具调用符合预定义的数据结构要求,同时保持对话上下文的完整性。
核心架构设计
ValidationNode继承自RunnableCallable,采用装饰器模式封装验证逻辑。其核心架构基于多态设计,支持多种schema类型:
class ValidationNode(RunnableCallable):
def __init__(
self,
schemas: Sequence[Union[BaseTool, Type[BaseModel], Callable]],
*,
format_error: Optional[Callable[[BaseException, ToolCall, Type[BaseModel]], str]] = None,
name: str = "validation",
tags: Optional[list[str]] = None,
):
该架构支持三种主要的schema来源:
- Pydantic BaseModel类 - 提供严格的数据验证
- BaseTool实例 - 使用工具的args_schema进行验证
- 普通函数 - 自动从函数签名生成验证schema
验证流程详解
ValidationNode的执行流程遵循严格的验证管道,确保每个工具调用都经过完整的验证处理:
多schema管理机制
ValidationNode内部维护一个schema名称到验证类的映射字典,支持复杂的多工具验证场景:
self.schemas_by_name: Dict[str, Type[BaseModel]] = {}
for schema in schemas:
if isinstance(schema, BaseTool):
# 处理BaseTool实例
self.schemas_by_name[schema.name] = schema.args_schema
elif isinstance(schema, type) and issubclass(schema, (BaseModel, BaseModelV1)):
# 处理Pydantic模型
self.schemas_by_name[schema.__name__] = cast(Type[BaseModel], schema)
elif callable(schema):
# 处理函数
base_model = create_schema_from_function("Validation", schema)
self.schemas_by_name[schema.__name__] = base_model
并行验证执行
ValidationNode利用线程池执行器实现并行验证,显著提升多工具调用场景下的性能:
def _func(self, input: Union[list[AnyMessage], dict[str, Any]], config:
【免费下载链接】langgraph 项目地址: https://gitcode.com/GitHub_Trending/la/langgraph
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考



