news 2026/7/6 10:12:21

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

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
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)
版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/7/6 10:10:09

Python Web框架实战对照:Bottle、Flask、Pyramid与Django核心差异解析

1. 这不是框架选型指南,而是一份“踩过坑之后才敢写的实战对照表” 我用 Python 做 Web 开发整十三年,从 2009 年手写 WSGI 中间件开始,到带团队落地过日均千万请求的 SaaS 后台、支撑过百万级用户教育平台的前后端分离架构、也维护过运行五年…

作者头像 李华
网站建设 2026/7/6 10:09:25

高校多CMS协同方案:基于Pubsubhubbub的松耦合内容同步

1. 项目概述:当高校网站群陷入“双CMS困局”,我们为什么选择握手而非合并? 在2014年那场至今仍被不少Plone老用户提起的Plone Symposium Midwest(PSM14)上,Calvin Parker没有一上来就讲Zope架构或Dexterity…

作者头像 李华
网站建设 2026/7/6 10:05:58

AI时代我们应该怎么审核代码:从审核到审计

PR Review的迷思 在这个时代最迷茫的一群人就是程序员,程序员每天做的最迷茫的一件事情就是review PR。 agent写代码太快了,行数太多了,人工review不过来。大部分都是机械式的点approveagent写代码基本不犯低级错误,看了感觉也是白…

作者头像 李华
网站建设 2026/7/6 9:57:52

从零玩转Postman接口测试:环境变量、断言与自动化实战

1. 项目概述:为什么接口测试是开发者的必修课? 如果你是一名开发者、测试工程师,或者正在学习后端开发,那么“接口测试”这个词你一定不陌生。简单来说,接口就是不同软件模块或系统之间进行通信和交换数据的约定。想象…

作者头像 李华
网站建设 2026/7/6 9:57:41

Playwright浏览器上下文:多账号隔离测试与并行模拟实战

1. 项目概述:为什么我们需要浏览器上下文? 如果你做过Web自动化测试,尤其是涉及登录态或者多账号的场景,大概率遇到过这样的头疼事:脚本里登录了一个账号A,执行完操作后,想换个账号B再跑一遍&am…

作者头像 李华
网站建设 2026/7/6 9:57:02

HElib实战指南:基于CKKS的同态加密原理与工程实践

1. 项目概述:为什么是HElib?如果你正在关注隐私计算、联邦学习或者任何需要在加密数据上直接进行计算的前沿领域,那么“同态加密”这个词对你来说一定不陌生。它被誉为密码学的“圣杯”,因为它允许我们在不解密的情况下&#xff0…

作者头像 李华