摘要: 本文围绕 LangChain 与 LangGraph 中的工具(Tool)机制展开,先介绍 LangChain 预构建工具的常见类别与获取方式,再说明如何用 @tool 注解定义工具并通过 invoke 调用;随后重点演示在 LangGraph 工作流中使用工具的完整流程,包括工具绑定模型、编写模型调用节点、使用 ToolNode 执行工具、通过条件边与 tools_condition 实现"模型思考---调用工具---回传结果"的循环,最终复现 LangChain 中 create_agent 的 ReAct Agent 模式,并给出可直接运行的 Python 示例代码。
内容参考于:图灵AI大模型全栈
在LangGraph中创建工具和在LangChain里一样使用Function_Calling机制(112节中有写)
LangChain提供了一些预构建的工具
官网地址:Tool integrations - Docs by LangChain
常用类别:但有些工具需要去对应的官网里申请key,比如Tavily搜索是需要去Tavily官网申请key
搜索:Bing、SerpAPI、Tavily
代码执行:Python REPL、Node.js REPL
数据库:SQL、MongoDB、Redis
Web 数据:抓取和浏览
API:OpenWeatherMap、NewsAPI等。
工具的使用,如下图红框,使用tool注解修饰函数,然后就可以通过函数名点 invoke 调用了

在LangGraph工作流中使用
首先把工具跟模型进行一个绑定
然后模型会根据问题从工具列表中选择一个工具
然后我们得到这个工具手动调用它,也就是点 invoke,然后把工具的结果添加到历史聊天记录中
然后模型再根据我们的问题再结合工具的回复,生成最终的答案
代码说明
首先是工具列表
然后是工具列表绑定到模型,注意这里它返回了一个新的模型对象 model_with_tools ,这是一个绑定了工具的模型对象,或者说这里告诉模型有哪些工具,工具有哪些参数,工具的返回值是什么
然后编写节点函数
ToolNode创建工具节点
然后创建图、给图里添加节点、添加边
它边的逻辑,首先通过下图红框绑定的开始节点是下图蓝框里的函数,也就是调用模型的函数
然后当上图蓝框的节点函数执行完后,执行下图红框的条件边,然后就会执行 should_continue节点函数,should_continue就是为了决策,判断是否要执行工具还是结束
如果要执行工具就会进入工具节点,这个工具节点执行完后会返回 ToolMessage
工具节点执行完后又会调用大模型,这样形成一个循环,大模型调用完后又会进入条件边,只有当大模型决定不需要调用工具了,它才会结束工作流
LangGraph给我们提供了一个决策函数,也就是 tools_condition 函数,如下图红框tools_condition函数的逻辑和我们自己写的决策函数的逻辑是一样的,只是它的更加完善
这个工作流的流程图,如下图红框,它和LangChain
也就是说我们这次的LangGraph代码实现了LangChain中create_agent的功能,也就是ReAct Agent模式(边思考边执行模式,107节中)
代码
python
from langchain.tools import tool
# 创建乘法工具
@tool
def multiply(a: int, b: int) -> int:
"""
该工具是专门做乘法的工具
args:
a: int 第一个数值
b: int 第二个数值
return: 两个数相乘的结果
"""
return a * b
# 测试工具
print(multiply.invoke({"a": 111, "b": 2}))
print("=" * 8, "在工作流中使用", "=" * 8)
from langgraph.prebuilt import ToolNode, tools_condition
from langgraph.graph import StateGraph, MessagesState, START, END
from langchain_tavily import TavilySearch
from langchain.chat_models import init_chat_model
from dotenv import load_dotenv
import os
load_dotenv()
model = init_chat_model("qwen3.8-flash",
api_key=os.getenv("DASHSCOPE_API_KEY"),
base_url=os.getenv("DASHSCOPE_BASE_URL"),
model_provider="openai")
# 定义工具列表
tools = [TavilySearch(max_results=1), multiply]
# 1.将工具绑定到模型中
model_with_tools = model.bind_tools(tools)
# 定义工作流
# 定义调用模型的节点
def call_model(state: MessagesState):
# 获取messages消息列表
messages = state["messages"]
# 2.模型根据问题返回tool_calls工具选择列表 # 添加系统提示词
response = model_with_tools.invoke(messages)
# 利用归并函数机制把工具返回的内容写到历史记录中
return {"messages": [response]}
# 创建模型决策是否要使用工具的条件函数
def should_continue(state: MessagesState):
messages = state["messages"]
# 取出最后一条消息
last_message = messages[-1]
# 如果在最后一条消息中包含tool_calls,就代表当前要使用工具
if last_message.tool_calls:
return "tools"
return END
# 3.手动执行工具,获取工具的结果添加到聊天历史中
# 定义工具执行节点 ToolNode是langgraph预构建的工具执行节点
tool_node = ToolNode(tools)
builder = StateGraph(MessagesState)
# 添加模型调用和工具调用节点
builder.add_node("call_model", call_model)
builder.add_node("tool_node", tool_node)
# 添加开始节点、
builder.add_edge(START, "call_model")
# 添加条件边 因为模型判断是否要使用工具
builder.add_conditional_edges("call_model",
tools_condition,
# should_continue,
{"tools": "tool_node", END: END}
)
# 添加边 根据langchain创建智能体的流程:从工具回到模型这一条边是固定的
builder.add_edge("tool_node", "call_model")
graph = builder.compile()
result = graph.invoke(
{"messages":
[
{"role": "user", "content": "上海天气怎么样"}
]
}
)
# from IPython.display import Image, display
# display(
# Image(
# # 生成 Mermaid 流程图并导出为本地图片文件
# graph.get_graph().draw_mermaid_png(output_file_path="./工具.png")
# )
# )
print(result)












