[智能体-229]:LangChain 工具调用原理 + 两类代码示例(传统 Agent / LCEL 原生 bind_tools,推荐 LCEL)

📅 2026/7/24 21:10:47 👁️ 阅读次数 📝 编程学习
[智能体-229]:LangChain 工具调用原理 + 两类代码示例(传统 Agent / LCEL 原生 bind_tools,推荐 LCEL)

结合前面硬件类比:

工具调用 = LLM (CPU) 发起网卡网络请求,向外获取外部数据 / 算力

RAG 是本地硬盘读数据,Tool 是跨网拉取外部资源。

一、工具调用核心原理

  1. 工具定义:封装外部能力(查天气、计算器、SQL、HTTP 接口),具备名字、功能描述、入参格式;
  2. 工具绑定 LLM:把工具列表注入大模型LLM 识别用户问题缺信息时,输出结构化工具调用 JSON;工具注入大模型之后,大模型就可以在理解自然语言语义之后知道如何调用外部工具。
  3. 解析 + 执行工具:框架截取模型输出的工具名 + 参数,调用对应函数拿到结果;
  4. 工具结果回灌上下文把返回数据拼入 Prompt,再次送入 LLM 生成最终答案。

二、环境依赖

bash

运行

pip install langchain langchain-openai

python

运行

from langchain_openai import ChatOpenAI from langchain_core.tools import tool from langchain_core.messages import HumanMessage, ToolMessage

方式 1:LCEL 原生工具调用(新项目首选,RISC 思想,无黑盒)

1. 自定义工具(计算器示例)

python

运行

# 装饰器快速定义工具 @tool def calculator(a: float, b: float, op: str) -> float: """ 数学计算器,支持加减乘除 :param a: 第一个数字 :param b: 第二个数字 :param op: 运算符,可选 + - * / """ if op == "+": return a + b elif op == "-": return a - b elif op == "*": return a * b elif op == "/": return a / b else: raise ValueError("运算符非法") tools = [calculator]

2. LLM 绑定工具

python

运行

llm = ChatOpenAI(model="gpt-3.5-turbo", temperature=0) # bind_tools:把工具元数据注入模型,原生输出function_call llm_with_tools = llm.bind_tools(tools)

3. 完整一轮工具调用链路

python

运行

query = "123加456等于多少?" msg = [HumanMessage(content=query)] # 第一步:模型生成工具调用指令,由大模型生成调用指令指示。 ai_msg = llm_with_tools.invoke(msg) msg.append(ai_msg) # 第二步:由Agent负责遍历工具调用、调用执行函数,并把执行的结果添加的消息列表中 for tool_call in ai_msg.tool_calls: name = tool_call["name"] args = tool_call["args"] # 根据名字匹配工具 tool_func = globals()[name] res = tool_func(**args) # 工具执行结果封装成ToolMessage塞回消息列表 msg.append(ToolMessage(content=str(res), tool_call_id=tool_call["id"])) # 第三步:携带工具结果再次调用LLM生成最终答案 final_ans = llm_with_tools.invoke(msg) print(final_ans.content)

输出:

plaintext

123加上456的结果是579。

方式 2:传统 OpenAI Agent(旧版预定义 Chain/CISC 黑盒,老项目维护用)

python

运行

from langchain.agents import AgentExecutor, create_openai_tools_agent prompt = ChatPromptTemplate.from_messages([ ("system", "你是擅长使用工具的助手"), ("user", "{input}") ]) # 构造Agent链 agent = create_openai_tools_agent(llm, tools, prompt) agent_executor = AgentExecutor(agent=agent, tools=tools, verbose=True) res = agent_executor.invoke({"input": "78乘以9等于多少"}) print(res["output"])

三、拓展:多工具混合(计算器 + 查字符串长度)

python

运行

@tool def str_len(s: str) -> int: """获取字符串长度 :param s: 输入字符串 """ return len(s) tools = [calculator, str_len] # 重新绑定工具 llm_with_tools = llm.bind_tools(tools)

提问:"abcdef有几个字符,100除以20是多少",模型会自动拆分两次工具调用。

四、关键知识点(贴合之前架构类比)

  1. LCEL bind_tools:原子化,工具绑定、调用、结果拼接全流程白盒可控(ARM 精简指令);
  2. 传统 AgentExecutor:整套思考 + 调用逻辑内部封装黑盒(x86 CISC 复合指令);
  3. Tool ≈ 网卡外设:不在 LLM 上下文 / 内存 / RAG 硬盘中,需要跨外部系统实时获取数据;
  4. LangGraph 场景:复杂多轮循环工具调用(思考→调用→结果→再思考),用 LangGraph 替代手动循环。

五、生产常用扩展

  1. 第三方工具:LangChain 内置WikipediaQueryRun、DuckDuckGoSearchRun搜索引擎工具;
  2. 工具异常with_fallbacks做工具调用失败降级;
  3. 流式工具调用astream分段捕获模型输出的工具参数。