当前位置: 首页 > news >正文

LangGraph 工具完整介绍(分基础概念、两种工具模式、完整流程、实战代码)

LangGraph 工具完整介绍(分基础概念、两种工具模式、完整流程、实战代码)

一、什么是 LangGraph 工具

LangGraph 工具 =可供大模型自动调用的外部能力,用于弥补 LLM 短板:

  • 实时计算、联网搜索、数据库查询、API 调用、文件读写、RAG 检索等
  • 核心两类使用场景:
    1. 前置规则工具:代码路由提前判断(你之前的classify_node判断数学问题,直接走计算器分支)
    2. LLM 自动工具调用(ReAct 循环):模型自主判断要不要调用工具,多轮循环直到给出答案

配套核心依赖

bash

运行

pip install langgraph langchain langchain-openai python-dotenv

二、工具的两种定义方式

方式 1:@tool 装饰器(最常用,你计算器用的这种)

python

运行

from langchain.tools import tool @tool def calculator_tool(expression: str) -> str: """ 计算基础数学表达式 Args: expression: 四则运算字符串,如 "10 + 20 * 3" """ try: allowed_names = {"abs": abs, "round": round, "sum": sum, "int": int, "float": float} res = eval(expression, {"__builtins__": {}}, allowed_names) return str(res) except Exception as e: return f"计算错误: {str(e)}"

关键特性:

  1. 自动解析文档字符串给 LLM 看用途、参数格式
  2. 自动生成 JSON Schema,大模型能看懂传参规则
  3. 直接放入工具列表tools = [calculator_tool]即可绑定模型

方式 2:自定义 BaseTool(复杂工具,多参数 / 异步)

适合需要复杂初始化、鉴权、异步请求的场景,日常简单函数优先用@tool

三、LLM 绑定工具:bind_tools ()

模型必须绑定工具列表,才具备生成工具调用指令的能力:

python

运行

from langchain_openai import ChatOpenAI import os from dotenv import load_dotenv load_dotenv() llm = ChatOpenAI( model=os.getenv("OPENAI_MODEL"), api_key=os.getenv("OPENAI_API_KEY"), base_url=os.getenv("OPENAI_API_BASE"), temperature=0 # 工具调用必须0,稳定无随机输出 ) # 绑定计算器工具 tools = [calculator_tool] llm_with_tools = llm.bind_tools(tools)

作用:

  • LLM 收到用户提问后,判断需要计算时,输出带tool_callsAIMessage
  • tool_calls包含:工具名、参数、唯一调用 ID,给工具节点执行

四、LangGraph 内置工具执行节点:ToolNode

官方预制工具执行器,不用手动写循环分发逻辑,一键执行所有模型发起的工具调用

python

运行

from langgraph.prebuilt import ToolNode # 传入工具列表,生成工具执行节点 tool_node = ToolNode(tools)

内部自动逻辑(无需手动实现):

  1. 读取 state 中最后一条 AI 消息的tool_calls
  2. 循环匹配对应工具、执行函数
  3. 生成ToolMessage携带返回结果,放回 messages 列表,维持对话上下文匹配

五、标准工具调用工作流(ReAct 循环架构)

流程图

START → LLM节点(生成回答/工具调用) → 条件路由判断

  • tool_calls→ 进入ToolNode执行工具 → 回到 LLM 整合结果
  • tool_callsEND结束输出答案

完整标准组件

  1. State(状态):存储对话消息,通用内置MessagesState
  2. LLM Node:调用绑定工具的模型,生成 AIMessage
  3. ToolNode:执行所有工具调用
  4. 路由函数 should_continue:条件分支判断是否要执行工具
  5. add_conditional_edges:实现循环逻辑

完整可运行标准工具调用代码

python

运行

from typing import Literal from langgraph.graph import StateGraph, START, END from langgraph.prebuilt import ToolNode, MessagesState from langchain_openai import ChatOpenAI from langchain.tools import tool import os from dotenv import load_dotenv load_dotenv() # 1. 定义工具 @tool def calculator_tool(expression: str) -> str: """计算基础数学表达式,支持四则运算、abs、round""" try: allowed_names = {"abs": abs, "round": round, "sum": sum, "int": int, "float": float} res = eval(expression, {"__builtins__": {}}, allowed_names) return str(res) except Exception as e: return f"计算错误: {str(e)}" tools = [calculator_tool] tool_node = ToolNode(tools) # 2. 初始化绑定工具的LLM llm = ChatOpenAI( model=os.getenv("OPENAI_MODEL"), api_key=os.getenv("OPENAI_API_KEY"), base_url=os.getenv("OPENAI_API_BASE"), temperature=0 ) llm_with_tools = llm.bind_tools(tools) # 3. LLM节点函数 def llm_agent(state: MessagesState): messages = state["messages"] response = llm_with_tools.invoke(messages) return {"messages": [response]} # 4. 路由函数:判断是否需要调用工具 def should_continue(state: MessagesState) -> Literal["tools", END]: last_msg = state["messages"][-1] # 如果存在工具调用,去执行工具;否则直接结束 if last_msg.tool_calls: return "tools" return END # 5. 构建图 builder = StateGraph(MessagesState) # 注册节点 builder.add_node("agent", llm_agent) builder.add_node("tools", tool_node) # 入口 builder.add_edge(START, "agent") # 条件分支:agent输出后分流 builder.add_conditional_edges("agent", should_continue) # 工具执行完回到大模型重新整合答案 builder.add_edge("tools", "agent") graph = builder.compile() # 测试调用 res = graph.invoke({"messages": [("human", "125乘以36再减去200等于多少")]}) print(res["messages"][-1].content)

六、你之前业务场景:前置关键词路由 + 工具分流(非自动 ReAct)

区别于模型自动调用工具,代码提前判断分支,就是你写的classify_node+add_conditional_edges模式:

  1. 关键词匹配判断是否数学问题
  2. 条件边分流:数学走计算器节点,普通问题走通用问答节点

python

运行

from typing import TypedDict from langgraph.graph import StateGraph, START, END # 自定义状态 class State(TypedDict): query: str is_math: bool # 工具函数(计算器) @tool def calculator_tool(expression: str) -> str: try: allowed_names = {"abs": abs, "round": round, "sum": sum, "int": int, "float": float} res = eval(expression, {"__builtins__": {}}, allowed_names) return str(res) except Exception as e: return f"计算错误: {str(e)}" # 分类节点:关键词判断 def classify_node(state: State): query_lower = state["query"].lower() math_keywords = ["+", "-", "*", "/", "plus", "minus", "times", "divided", "calculate", "sum"] is_math = any(kw in query_lower for kw in math_keywords) return {"is_math": is_math} # 路由函数:根据标记分流 def route_query(state: State) -> Literal["calc_node", "qa_node"]: if state["is_math"]: return "calc_node" return "qa_node" # 业务节点 def calc_node(state: State): # 提取表达式调用计算器 expr = state["query"].replace("calculate ", "").replace("sum of ", "") result = calculator_tool.invoke(expr) return {"answer": f"计算结果:{result}"} def qa_node(state: State): return {"answer": f"普通问答回答:{state['query']}"} # 搭建流程图 builder = StateGraph(State) builder.add_node("analyze", classify_node) builder.add_node("calc_node", calc_node) builder.add_node("qa_node", qa_node) builder.add_edge(START, "analyze") # 条件分支分流 builder.add_conditional_edges( source="analyze", path_fn=route_query, path_map={ "calc_node": "calc_node", "qa_node": "qa_node" } ) builder.add_edge("calc_node", END) builder.add_edge("qa_node", END) graph = builder.compile() # 测试 print(graph.invoke({"query": "calculate sum of 10 and 90"}))

七、两种工具使用模式对比

表格

模式适用场景核心特点
LLM 自动工具调用(ToolNode+ReAct 循环)不确定是否需要工具、多工具混合(搜索 / 计算 / 数据库)模型自主决策,支持多轮循环,通用 Agent 标准方案
前置代码路由工具(关键词 / 规则分流)固定关键词可预判场景(数学、翻译、天气)速度更快,无需大模型决策分支,简单业务优先

八、关键知识点与踩坑点

1. bind_tools 必须搭配 temperature=0

温度大于 0 会随机丢失工具调用逻辑,数学 / 工具场景强制 0。

2. ToolNode 依赖 MessagesState

内置工具节点需要 state 包含messages列表,存储 HumanMessage/AIMessage/ToolMessage。

3. 循环逻辑必须手动加边builder.add_edge("tools", "agent")

工具执行结果必须回传给大模型,让模型整合工具输出给出自然语言答案,否则流程直接中断。

4. @tool 函数参数必须标注类型

expression: str,LangChain 自动解析 Schema 给 LLM,无类型标注会导致模型传参失败。

5. eval 安全要点(计算器工具)

必须清空__builtins__+ 自定义白名单,防止代码注入攻击,线上环境不可省略。

九、拓展:多工具共存

可同时放入计算器、搜索、天气等多个工具,LLM 会自动选择匹配的工具调用:

python

运行

@tool def get_weather(city: str): """查询城市天气""" return f"{city} 今日26℃,晴天" tools = [calculator_tool, get_weather] llm_with_tools = llm.bind_tools(tools) tool_node = ToolNode(tools)
http://www.cnnetsun.cn/news/3181725.html

相关文章:

  • Python Web框架实战对照:Bottle、Flask、Pyramid与Django核心差异解析
  • 高校多CMS协同方案:基于Pubsubhubbub的松耦合内容同步
  • AI时代我们应该怎么审核代码:从审核到审计
  • 从零玩转Postman接口测试:环境变量、断言与自动化实战
  • Playwright浏览器上下文:多账号隔离测试与并行模拟实战
  • HElib实战指南:基于CKKS的同态加密原理与工程实践
  • ARM车载QT影音系统源码:集成天气预报、视频播放、音乐歌词同步、百度地图四大功能
  • Java加密策略与提供者配置实战:从原理到生产环境部署
  • Ehole工具实战指南:高效Web指纹识别与安全资产梳理
  • 基于MCP协议的AI自动化安全测试平台HexStrike AI v6.0实战指南
  • 手把手搭建Windows 10渗透测试靶场:从Metasploit到Meterpreter实战
  • 基于PyQt的桌面文件加密与数字签名系统开发实践
  • 从零设计Python+Selenium自动化测试框架:避坑指南与实战蓝图
  • SeleniumBase零代码录制与JSON自动化测试方案:从录制到执行的完整实践
  • AI辅助科研写作实战指南:从文献到论文的六步工作流
  • Java版医院排队叫号系统(SpringBoot+MyBatis+Thymeleaf,含部署文档与可运行源码)
  • WebShell查杀实战:从原理到工具选型与应急响应全流程
  • 掌握虚幻引擎UMG的数据驱动设计
  • 网络安全基础与防护策略
  • OWASP Top 10 2021深度解析:从原理到实战的Web安全防御指南
  • 易语言EXE反编译技术解析:从PE结构到算法还原的逆向实战
  • SQL注入绕过技巧:空格与逗号过滤的实战解决方案
  • 任意文件读取漏洞:从路径遍历到系统沦陷的攻防实战
  • 网络安全漏洞知识图谱实战资源包:含数据清洗脚本、关系抽取代码、演示案例与教学PPT
  • MediaPipe+OpenCV三合一姿态追踪工程:手部关键点、全身骨架、人脸网格实时识别与结果可视化
  • Web安全攻防:CSRF与SSRF漏洞原理、代码审计与防御实战
  • Java SWT桌面UI实战代码包:含按钮/表格/菜单/布局等50+可运行示例
  • 彻底移除Windows 11 AI组件:终极隐私保护与系统性能优化指南
  • 自主AI Agent:规划-执行-反思循环
  • DrissionPage与OCR实战:破解动态加密网站的数据采集方案