跳转到内容

预构建 Agent 与 ToolNode 集成

预构建 Agent 与 ToolNode 集成

学习目标

本章要解决什么问题:

  • 如何使用 create_react_agent 一键构建标准 ReAct Agent
  • ToolNode 如何将模型的工具调用路由到对应函数
  • 如何配置工具沙箱与错误处理
  • 预构建 Agent 的内部 StateGraph 结构

前置知识

本章涉及工具调用的通用原理,建议先阅读:

下文假设你已理解上述概念,直接聚焦 LangGraph 的具体实现。


项目实践

create_react_agent 一键构建

from langgraph.prebuilt import create_react_agent
from langchain_core.tools import tool
@tool
def search(query: str) -> str:
"""搜索互联网获取信息。"""
return "搜索结果..."
@tool
def calculate(expression: str) -> float:
"""计算数学表达式。"""
return eval(expression)
tools = [search, calculate]
agent = create_react_agent("anthropic:claude-sonnet-4-6", tools)
result = agent.invoke({"messages": ["今天天气如何?"]})

create_react_agent 内部构建的 StateGraph 结构:

ToolNode 的工具路由

ToolNode 是 LangGraph 预构建的工具执行节点,核心行为:

  1. 读取状态中的 AIMessage,提取 tool_calls 字段
  2. 根据 name 字段查找对应的工具函数
  3. 执行工具函数,返回 ToolMessage
  4. 将 ToolMessage 追加到状态的 messages 列表
from langgraph.prebuilt import ToolNode
tool_node = ToolNode([search, calculate])
# 独立使用
result = tool_node.invoke({
"messages": [AIMessage(
content="",
tool_calls=[{"name": "search", "args": {"query": "天气"}, "id": "call-1"}]
)]
})

工具错误处理

ToolNode 内置工具错误处理机制:

  • 工具不存在:返回包含错误信息的 ToolMessage
  • 工具执行异常:捕获异常,返回错误描述
  • 参数不匹配:返回参数错误信息

这些错误以 ToolMessage 形式返回给模型,模型可以自行修正。

自定义 Agent 结构

create_react_agent 不够用时,可以手动构建:

from langgraph.graph import StateGraph, START, END
from langgraph.graph.message import MessagesState
from langgraph.prebuilt import ToolNode
class State(MessagesState):
pass
def call_model(state):
response = llm.invoke(state["messages"])
return {"messages": [response]}
def should_use_tools(state):
if state["messages"][-1].tool_calls:
return "tools"
return END
graph = StateGraph(State)
graph.add_node("model", call_model)
graph.add_node("tools", ToolNode(tools))
graph.add_edge(START, "model")
graph.add_conditional_edges("model", should_use_tools)
graph.add_edge("tools", "model")
app = graph.compile()

问题与规避

工具返回值格式不匹配

问题:工具返回值格式不符合预期(如返回对象而非字符串),会导致状态污染。

规避:工具函数始终返回字符串或可序列化的值。对于复杂返回值,在工具内部序列化为字符串。

无限循环

问题:模型反复调用同一工具,导致无限循环。

规避

  • 使用 remaining_steps 限制最大执行步数
  • 在状态中记录工具调用历史,模型可以发现重复模式
  • 配置 recursion_limit

工具沙箱缺失

问题:工具可以访问任意系统资源,存在安全风险。

规避

  • 对敏感工具添加权限检查
  • 使用外部沙箱环境执行不可信工具
  • 限制工具的输入范围

设计取舍

优势

  • 快速上手create_react_agent 一行代码构建标准 Agent
  • 可定制:ToolNode 可独立使用或替换
  • 错误恢复:工具错误以消息形式返回,模型可自行修正

代价

  • 灵活性受限create_react_agent 只支持标准 ReAct 模式
  • 隐式依赖:依赖 langchain-core 的消息类型定义

替代方案

  • 手动构建 StateGraph:完全控制图结构,适合复杂场景
  • Functional API:用装饰器定义工作流,适合线性流程

参考来源