AI创想
标题:
[ToolNode在LangGraph中的运用-01]LangChain和LangGraph两种编程模式的同一性
[打印本页]
作者:
米落枫
时间:
2026-7-6 07:24
标题:
[ToolNode在LangGraph中的运用-01]LangChain和LangGraph两种编程模式的同一性
作者:CSDN博客
LangGraph赋予我们根据推理任务自由构建流程图的能力,所以我们完全可以不使用工具,而将每个工具的功能实现在某个节点中,这样对于流程的每个步骤都具有精准的控制。但是任何事都有利弊,这样的编程模式让我们摒弃了ToolNode具有的很多能力,在利用LangGraph开发Agent过程中有效地使用ToolNode,有时可以起到事半功倍的作用。
1. create_agent工厂函数如何构建状态图
基于LangGraph的编程模式将推理任务转换成由节点和边的状态图。我们利用StateGraph作为Builder来构建这个状态图,在在添加所有功能节点后,通过在节点之间添加“边(包括静态边和条件边)”实现节点之间基于状态的路由。对于常规调用(区别于中断恢复调用),入口节点率先执行,节点执行后会改变状态,边决定的路由规则根据当前状态选择下一步执行的节点。整个执行就以这样的方式向前推进,直到没有后续节点需要执行或者达到设定的步数限制。
对于LangChain编程模式(这里指利用create_agent工厂函数创建的Agent),它依然会利用StateGraph来构建上述的状态图,而且绑定的默认状态类型为AgentState,它具有一个核心的字段messages用来存储整个执行过程中产生的各种消息(HumanMessage、AIMessage和ToolMessage)。它关联的reducer函数确保针对该字段的更新永远是往此消息列表中追加新的消息。
在没有中间件注册的情况下,状态图的节点只有两个,一个是用于封装指定模型组件的model节点,另一个则是用于封装所有注册工具的tools节点,其类型就是ToolNode,注册的工具同样会被绑定到model节点封装的模型组件上。tools节点到model节点之间由一条静态边,而model节点到tools和__end__节点有一条条件边,所以整个图结构总是如下所示的样子。我们调用Agent时可以在状态成员messages添加一条(HumanMessage)或者多条消息(为LLM的推理模拟一段对话),作为入口的model节点率先被执行,它会将整个消息历史、系统提示词和注册的工具集作为调用LLM的输入。
2. 双节点状态图推进流程
LLM会根据提示词体现的推理任务,以及可用的工具集,确定是否需要对其中的一个或者多个工具发起调用。如果需要,它会为每个待调用的工具生成一个ToolCall对象,该对象承载着工具名称、工具调用ID以及从输入提取出来的参数列表。这个ToolCall列表作为AIMessage的核心内容返回给model节点,后者将其添加到状态成员messages保存的对话历史中。
model到tools和__end__节点的条件边体现了这样的路由规则:如果消息历史中的最后一条AIMessage携带ToolCall对象,则路由到tools节点,否则任务AIMessage携带的就是最终的回答,流程立即终止。tools节点执行的时候会从消息历史中提取最后一条AIMessage,并提取所有的TooCall对象,如果自己封装的工具包含其中,则以并发的方式执行它们。如果工具返回一个Command对象,其updates字段返回的内容会被用来增量更新状态(其中必需包含一个ToolMessage保证整个消息历史结构完整性),goto字段用于实现跳转。返回的非Command内容会被用来创建一条ToolMessage,并被添加到消息历史中。如果在没有利用Command的goto字段完成跳转的情况下,tools到model之间的边会再次路由到model节点上。整个Agent的执行就按照这样的方式不断循环。
3. 两种编程模式的同一性
对于任何一个利用LangChain(create_agent)编程模式创建的Agent,都可以采用基于LangGraph的编程模式来编写。比如如下这个简单至极的用于提供天气信息的Agent。
from langchain_openai import ChatOpenAI
from langchain_core.tools import tool
from langchain_core.messages import HumanMessage
from langchain.agents import create_agent
from dotenv import load_dotenv
load_dotenv()@tooldefget_weather(city:str)->str:"""A tool to get weather information for a given city."""returnf"It's sunny today in {city}."
agent = create_agent(
model = ChatOpenAI(model="gpt-5.2-chat"),
tools=[get_weather])
message = HumanMessage(content="What is the weather like in Suzhou?")for message in agent.invoke({"messages":[message]})["messages"]:
message.pretty_print()
复制代码
输出结果:
================================ Human Message =================================
What is the weather like in Suzhou?
================================== Ai Message ==================================
Tool Calls:
get_weather (call_I1qmj6ySikQ7TbefTCCY3zUg)
Call ID: call_I1qmj6ySikQ7TbefTCCY3zUg
Args:
city: Suzhou, China
================================= Tool Message =================================
Name: get_weather
It's sunny today in Suzhou, China.
================================== Ai Message ==================================
It’s **sunny in Suzhou, China** right now. ☀️
If you’d like, I can also tell you the **temperature, humidity, or a multi‑day forecast**.
复制代码
如果采用基于LangGraph的编程模式来重写,就是如下这个样子:
from langchain_openai import ChatOpenAI
from langchain_core.tools import tool
from langchain_core.messages import HumanMessage
from langgraph.graph import StateGraph
from langgraph.prebuilt import ToolNode, tools_condition
from langchain.agents import AgentState
from dotenv import load_dotenv
load_dotenv()@tooldefget_weather(city:str)->str:"""A tool to get weather information for a given city."""returnf"It's sunny today in {city}."
llm = ChatOpenAI(model="gpt-5.2-chat").bind_tools(tools=[get_weather])defmodel(state: AgentState):
response = llm.invoke(state["messages"])return{"messages":[response]}
agent =(StateGraph(AgentState).add_node("model", model).add_node("tools", ToolNode(tools=[get_weather])).set_entry_point("model").set_finish_point("model").add_edge("tools","model").add_conditional_edges("model",path=tools_condition).compile())
message = HumanMessage(content="What is the weather like in Suzhou?")for message in agent.invoke({"messages":[message]})["messages"]:
message.pretty_print()
复制代码
输出:
================================ Human Message =================================
What is the weather like in Suzhou?
================================== Ai Message ==================================
Tool Calls:
get_weather (call_iRrmDOHkfnmTw8WSi5CFmDDP)
Call ID: call_iRrmDOHkfnmTw8WSi5CFmDDP
Args:
city: Suzhou
================================= Tool Message =================================
Name: get_weather
It's sunny today in Suzhou.
================================== Ai Message ==================================
It’s sunny in Suzhou today. ☀️
复制代码
原文地址:https://blog.csdn.net/JaydenAI/article/details/159814452
欢迎光临 AI创想 (https://llms-ai.com/)
Powered by Discuz! X3.4