157.Agent-LangGraph-工具(实现ReAct Agent模式)

摘要: 本文围绕 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)

相关推荐
Raas1002 小时前
MAI Gateway选购攻略:开源AI网关有哪些?避坑指南与对比
大数据·人工智能·gateway·ai网关·企业级ai网关·企业级ai产品
段一凡-华北理工大学2 小时前
高炉能源系统智能化:热风炉、煤气与极致能效~系列文章03:热风炉烧炉与风温的决定因素
大数据·linux·人工智能·能源·热风炉·高炉能源优化
lucas_AI2 小时前
Anthropic 递交 S-1:半年营收 163 亿美元,招股书里写着'人类生存风险'
人工智能
小小王app小程序开发2 小时前
教育 AI 小程序玩法开发分析
人工智能·小程序
jinggongszh2 小时前
参数退潮,Know-how上台:工业AI的竞争为什么换了赛场?
大数据·人工智能·数据闭环·工业ai
解决问题no解决代码问题2 小时前
Java金融后端转LLM应用开发 Day8:团队搭建、跨行业自动化潜力与AI风险认知全指南
人工智能
Solange__2 小时前
城市更新方案怎么用AI生成3D街区预演?从底图、体块到公众网页展示
人工智能·游戏·3d·ai·自然语言处理·1024程序员节·关卡设计
程序猿乐锅2 小时前
【从0-1学习Python | 第九篇】继承
开发语言·后端·python·学习·fastapi
青少儿编程课堂2 小时前
蓝桥杯·全国青少年信息素养大赛·电子学会Python/C++考级:位运算实战——二进制权限与最大异或解析
c++·python·算法·bfs·信息学竞赛