ARTICLE DETAIL

资讯详情

深耕网站建设与运营推广的一线实战洞察。

LangChain到底能干嘛!

LangChain到底能干嘛! 一.前言想必大家看到LangChain这个词就会觉得很熟悉但是这个到底是什么到底能干什么呢简单来说LangChain 是一套用于构建大语言模型LLM应用的编排框架。它本身不提供模型而是帮你把模型、工具、数据、记忆这些“零件”像搭积木一样组合起来形成能完成复杂任务的链Chain或智能体Agent。它的核心抽象是Runnable 协议——所有组件都可以通过统一的接口串联、流式输出、批量调用。而LangGraph我们后续会了解LangGraph的作用 则是基于 LangChain 之上的图编排引擎用状态图StateGraph的方式解决传统链式调用无法处理的循环、条件分支和持久状态特别适合构建需要多步推理、工具调用、人机协作的智能体。说白了其实就是一个简单的框架能够让我们想要的实现的动作能够一次性的执行下去多说不如实战今天我们来讲解LangChain的第一个主要功能工具的调用和结构化的输出二.实战2.1 聊天模型如何调用工具大模型擅长理解和生成文本但它无法天然知道实时天气、直接查询数据库或者真的执行计算与业务操作。工具调用Tool Calling的意义就是为模型提供连接外部世界的能力。典型场景包括- 查询实时天气、搜索网页或读取内部知识库- 调用订单、库存、客户等业务系统- 执行计算、生成报表或处理文件- 将自然语言请求拆成多步任务再由 Agent 协调不同工具完成。工具调用要分清一件事模型负责判断“要调用什么工具、传入什么参数”真正执行函数、访问数据库或请求 API 的仍然是我们的应用程序。2.1 创建工具2.1.1 使用 tool 装饰器tool 是定义工具最直接的方式。函数名会成为工具名称类型注解和文档字符串会帮助 LangChain 生成工具的 Schema。from langchain_core.tools import tool from typing_extensions import Annotated tool def multiply( a: Annotated[int, 第一个整数], b: Annotated[int, 第二个整数], ) - int: 计算两个整数的乘积。 return a * b print(multiply.invoke({a: 2, b: 3})) # 6 print(multiply.name) # multiply print(multiply.description) # 计算两个整数的乘积。 print(multiply.args) # 工具参数 Schema这里的 Schema 可以理解为“工具说明书”它定义了工具叫什么、用于做什么、需要哪些参数、每个参数是什么类型。模型正是依据这些信息生成工具调用请求。因此定义工具时建议做到三点1. 函数名要准确例如 search_weather 比 get_data 更容易让模型理解2. 参数必须有类型注解3. 文档字符串要说明工具用途、参数含义和边界。2.1.2 用 Pydantic 定义更清晰的参数 Schema当参数较多或需要更严格的数据校验时可以通过 Pydantic 的 BaseModel和Field来定义输入结构。from pydantic import BaseModel, Field from langchain_core.tools import tool class AddInput(BaseModel): a: int Field(..., description第一个整数) b: int Field(..., description第二个整数) tool(args_schemaAddInput) def add(a: int, b: int) - int: 计算两个整数之和。 return a bPydantic 的好处是能集中定义字段类型、必填规则、默认值和字段描述并在实际调用前进行数据验证。2.1.3 使用 StructuredTool如果需要显式指定工具名称、描述或输入 Schema可以使用 StructuredTool.from_function()from langchain_core.tools import StructuredTool from pydantic import BaseModel, Field class CalculatorInput(BaseModel): a: int Field(description第一个数字) b: int Field(description第二个数字) def multiply(a: int, b: int) - int: return a * b calculator_tool StructuredTool.from_function( funcmultiply, namecalculator, description计算两个数字的乘积, args_schemaCalculatorInput, ) print(calculator_tool.invoke({a: 2, b: 3}))默认情况下工具结果会作为文本 content 返回给模型。如果还要保留原始结构化数据供日志、追踪或后续程序使用可以设置 response_formatcontent_and_artifact并让函数返回 (content, artifact)。from typing import Any from langchain_core.tools import StructuredTool def search_weather(city: str) - tuple[str, dict[str, Any]]: raw_data {city: city, temperature: 26, condition: 晴} content f{city}当前晴气温 26℃ return content, raw_data weather_tool StructuredTool.from_function( funcsearch_weather, namesearch_weather, description查询指定城市的实时天气, response_formatcontent_and_artifact, )其中 content 应保持简洁、便于模型理解artifact 则可保留完整响应、链接、原始 JSON 等给程序后续使用。不要把体积很大的原始数据直接塞给模型这会增加 token 消耗也会干扰模型判断。2.2 绑定工具到聊天模型工具定义完成后还要调用 bind_tools() 将工具声明交给模型from langchain_openai import ChatOpenAI model ChatOpenAI(modelgpt-4o-mini, temperature0) model_with_tools model.bind_tools([add, multiply])bind_tools() 返回的仍然是一个 Runnable。常用配置如下| 参数 | 说明 || ----------------------------------|-------------------------------------------------------------|| tools | 工具列表可传 Python 函数、Pydantic 模型或 BaseTool 对象 || tool_choiceauto | 由模型自行决定是否调用工具 || tool_choicerequired / any | 强制模型至少调用一个工具 || tool_choice工具名 | 要求调用指定工具具体兼容性取决于模型提供商 || strictTrue | 要求工具参数严格符合 JSON Schema || parallel_tool_callsFalse | 禁止模型在一次响应中发起多个工具调用 |一般业务场景建议先让模型自动选择工具只有工作流明确要求执行某类操作时才考虑使用强制调用。强制调用并不会让不相关的工具变得合理反而可能得到无意义参数。2.3 发起工具调用绑定后的模型可以直接调用result model_with_tools.invoke(9 乘 6 等于多少) print(result.tool_calls)当模型决定调用工具时返回值仍是 AIMessage但它的 content 可能为空重点在 tool_calls 属性[ { name: multiply, args: {a: 9, b: 6}, id: call_xxx, type: tool_call, } ]这一步只是模型生成了“调用计划”工具还没有真正执行。应用程序要根据 name 找到对应函数使用 args 执行工具再把工具结果作为 ToolMessage 放回消息列表最后交给模型组织自然语言答案。完整流程如下from langchain_openai import ChatOpenAI from langchain_core.messages import HumanMessage from langchain_core.tools import tool tool def add(a: int, b: int) - int: 计算两个整数之和。 return a b tool def multiply(a: int, b: int) - int: 计算两个整数的乘积。 return a * b model ChatOpenAI(modelgpt-4o-mini, temperature0) tools {add: add, multiply: multiply} model_with_tools model.bind_tools(list(tools.values())) # 1. 用户提问 messages [HumanMessage(content9 乘 6 等于多少5 加 3 等于多少)] # 2. 模型决定调用哪些工具 ai_message model_with_tools.invoke(messages) messages.append(ai_message) # 3. 程序实际执行工具并将 ToolMessage 追加到上下文 for tool_call in ai_message.tool_calls: tool tools[tool_call[name]] tool_message tool.invoke(tool_call) messages.append(tool_message) # 4. 模型读取工具结果生成面向用户的最终回答 final_message model.invoke(messages) print(final_message.content)整个链路可以概括为用户问题- 模型选择工具并生成参数- 应用程序执行真实工具- ToolMessage 回传执行结果- 模型整理出最终回答到这里我们已经掌握了 LangChain 中工具调用的基本闭环。后续学习 Agent 时本质上就是把“模型判断 - 工具执行 - 结果回传”的过程交给一个更完善的循环和状态管理机制来处理。小结本节的重点可以归纳为1. **Runnable** 为 LangChain 组件提供了统一的调用标准2. **LCEL** 可以用 | 将多个 Runnable 连接成数据处理链3. **聊天模型** 接收消息列表并返回 AIMessage可统一接入云端或本地模型4. **工具调用** 让模型能够规划并驱动外部能力但真实执行必须由应用程序完成5. 完整的工具调用需要经历“模型请求工具 - 程序执行工具 - 工具结果回传 - 模型生成最终回复”四步。如果这篇文章对你有帮助欢迎点赞、收藏和关注。下一篇继续学习 LangChain 的结构化输出与流式能力。
返回列表