2026/4/18 12:45:54
网站建设
项目流程
遵义市在哪里做网站,wordpress使用方法,网站后台更新栏目,wordpress小工具调用AI 不再嘴炮#xff1a;用 Tools 给大模型接上“执行力”
在大模型应用开发中#xff0c;单纯的对话能力早已无法满足复杂场景需求#xff0c;大模型仅凭自身训练数据很难给出准确答案。这时候#xff0c;LangChain Tools 就像给大模型装上了「手脚」#xff0c;让它从「只…AI 不再嘴炮用 Tools 给大模型接上“执行力”在大模型应用开发中单纯的对话能力早已无法满足复杂场景需求大模型仅凭自身训练数据很难给出准确答案。这时候LangChain Tools 就像给大模型装上了「手脚」让它从「只会聊天」升级为「能办实事」。今天我们就来深入聊聊 LangChain Tools 的核心知识结合实战代码带你快速掌握这个强大功能一、LangChain Tools 是什么 LangChain Tools工具是 LangChain 框架中扩展大模型能力的核心组件。它的本质是将「具体的业务逻辑或操作能力」封装成标准化接口让大模型能根据用户请求自主判断要不要调用工具调用哪个工具该传什么参数最终通过工具弥补大模型自身的局限性。简单来说大模型是「大脑」负责分析问题、判断需求、制定方案Tools 是「手脚」负责执行具体操作比如查天气、算数据、调接口。二者结合才能实现从「思考」到「行动」的完整闭环。二、LangChain Tools 为了解决什么问题 ➡️✅大模型虽然强大但存在不少「天然短板」而 Tools 正是为了弥补这些短板而生突破知识滞后性⏳大模型的训练数据有时间截止线无法获取实时信息比如 2024 年的天气、最新股票行情。通过自定义工具如对接实时天气 API 的weatherTool就能让大模型获取「新鲜数据」。访问私有数据 / 系统企业内部数据库、本地文件、私有 API 等信息大模型无法直接访问。通过工具封装这些私有资源的访问逻辑如下文示例中的fakeWeatherDB模拟私有天气库既能安全调用数据又不泄露敏感信息。扩展操作边界除了查数据、算结果工具还能实现更复杂的操作发送邮件、操作数据库、执行代码、控制硬件设备等。只要能写成函数的逻辑都能封装成工具让大模型调用。三、LangChain Tools 的核心组成要素 一个完整的 LangChain 工具由两部分组成「核心执行逻辑」和「工具配置对象」。我们以下面核心代码中的weatherTool和addTool为例拆解每个要素的作用Tools核心代码const weatherTool tool( async({city}) { // 工具做什么事情 从fakeWeatherDB中获取天气信息 const weather fakeWeatherDB[city]; if(!weather) { return 暂无${city}的天气信息; } return 当前${city}的天气是${weather.condition}温度${weather.temp}风力${weather.wind}; }, // 配置schema 定义工具的输入参数的类型 传给大模型 { name:get_weather, description:查询指定城市的今日天气情况, // 函数的描述 schema:z.object({ city:z.string().describe(要查询天气的城市) }) } ) // 函数 定义一个加法工具 const addTool tool( // 两个参数 // 等大模型来调用这个函数工具 // 参数是一个对象包含a和b两个属性可以解构出来 async({a,b}) String(a b), { name:add, // 函数名字 description:计算两个数字的和, // 函数的描述 // 定义参数的类型 参数schema 是一个对象 调用时也要传一个对象 schema:z.object({ a:z.number().describe(第一个数字), b:z.number().describe(第二个数字) }) } )1. 核心执行逻辑异步函数 这是工具的「灵魂」负责接收参数、执行具体操作、返回结果。比如weatherTool的执行逻辑是从fakeWeatherDB中查询城市天气并格式化结果addTool的执行逻辑是计算两个数字的和并返回字符串。关键要求必须是「异步函数」带async关键字因为工具常涉及网络请求如调用 API、IO 操作如读文件等耗时任务异步执行可避免阻塞整个流程。入参格式需与schema定义的结构一致推荐用对象解构如async ({ city }) {...}或async ({ a, b }) {...}方便参数匹配。2. 工具配置对象给大模型的「使用说明书」 配置对象是大模型理解工具的关键包含 3 个核心字段工具名称name️工具的唯一标识如get_weather、add大模型通过这个名称确定要调用的工具。注意多个工具绑定时名称必须唯一否则会出现调用混乱就像两个人重名会认错人一样。工具描述description大模型判断是否调用该工具的「核心依据」。描述需清晰说明工具的功能和适用场景比如weatherTool的描述是「查询指定城市的今日天气情况」大模型看到用户问「北京天气」时就知道该调用它addTool的描述是「计算两个数字的和仅支持纯数字加法运算」用户问「34 等于几」时大模型会匹配到这个工具。参数校验 Schemaschema用zod库定义的参数规则有两个核心作用代码层面校验传入工具的参数是否合法比如city必须是字符串a和b必须是数字防止非法参数导致报错大模型层面告诉大模型「需要传什么参数、参数是什么意思」。比如city: z.string().describe(要查询天气的城市必须是中文城市名称)大模型就知道要传中文城市名。四、LangChain Tools 的核心工作流程 先来看看完整代码// 1. 导入 DeepSeek 聊天模型用于和大模型进行对话及工具调用交互 // 从 langchain/deepseek 包中导出专门适配 DeepSeek 大模型的 LangChain 封装 import { ChatDeepSeek } from langchain/deepseek; // 2. 导入 dotenv 配置用于加载 .env 文件中的环境变量如 DeepSeek API KEY // 执行此导入后.env 文件中的变量会被注入到 process.env 中无需额外配置 import dotenv/config; // 3. 导入 LangChain 核心工具装饰器/工具创建函数用于封装自定义工具供大模型调用 // 来自 langchain/core/tools 包是 LangChain 工具系统的核心API import { tool } from langchain/core/tools; // 4. 导入 zod 数据校验库用于定义工具输入参数的校验规则和描述同时提供给大模型理解参数含义 // zod 不仅能做参数类型校验还能通过 describe 方法给大模型提供参数说明是 LangChain 工具调用的标配 import { z } from zod; // 5. 模拟天气数据库无真实接口请求用本地对象模拟城市天气数据方便演示工具调用效果 // 键城市名称值包含温度、天气状况、风力的天气详情对象 const fakeWeatherDB { 北京: { temp: 30°C, condition: 晴, wind: 微风 }, 上海: { temp: 28°C, condition: 多云, wind: 东风 3 级 }, 广州: { temp: 32°C, condition: 阵雨, wind: 南风 2 级 }, }; // 6. 创建 天气查询工具使用 tool 函数封装自定义工具供大模型自动调用 // tool 函数接收两个参数① 工具执行的异步函数 ② 工具配置项名称、描述、参数校验规则 const weatherTool tool( // 工具核心执行逻辑异步函数接收解构后的参数对象city 城市名 async ({ city }) { // 从模拟天气数据库中获取目标城市的天气信息 const weather fakeWeatherDB[city]; // 容错处理如果数据库中没有该城市的天气数据返回提示信息 if (!weather) { return 暂无${city}的天气信息; } // 格式化返回结果让大模型和用户都能清晰理解 return 当前${city}的天气是${weather.condition}温度${weather.temp}风力${weather.wind}; }, // 工具配置项给大模型提供工具元信息用于大模型判断是否调用该工具及如何传参 { name: get_weather, // 工具唯一标识大模型通过该名称识别工具 description: 查询指定城市的今日天气情况, // 工具功能描述核心大模型根据该描述判断何时调用此工具 schema: z.object({ // 参数校验规则zod 定义同时给大模型提供参数说明 city: z.string().describe(要查询天气的城市必须是中文城市名称如北京、上海) }) } ); // 7. 创建 加法计算工具同样使用 tool 函数封装演示多参数工具的定义 const addTool tool( // 工具核心执行逻辑异步函数接收解构后的两个数字参数 a 和 b // 计算求和后转换为字符串返回大模型更易解析字符串格式结果 async ({ a, b }) String(a b), // 工具配置项定义工具元信息和多参数校验规则 { name: add, // 工具唯一标识大模型通过该名称识别加法工具 description: 计算两个数字的和仅支持纯数字加法运算, // 工具功能描述明确工具适用场景 // 多参数校验规则z.object 中定义多个参数分别指定类型和描述 schema: z.object({ a: z.number().describe(第一个要相加的数字必须是数字类型整数或小数), b: z.number().describe(第二个要相加的数字必须是数字类型整数或小数) }) } ); // 8. 初始化 DeepSeek 聊天模型实例配置模型参数建立和 DeepSeek 大模型的连接 const model new ChatDeepSeek({ model: deepseek-chat, // 指定使用的 DeepSeek 模型版本deepseek-chat 为对话模型 temperature: 0, // 温度参数0 表示输出结果确定性强无随机性值越大随机性越高 }).bindTools([addTool, weatherTool]); // 给模型绑定自定义工具核心让大模型知晓可用的工具列表 // 9. 第一个请求让模型计算 3 和 4 的和触发加法工具调用 const res await model.invoke(计算3和4的和); // 10. 处理模型返回结果执行工具调用并获取最终结果 // 可选链操作符 ?. 说明 // - 作用判断 res.tool_calls 是否存在若存在则访问 length 属性若不存在则返回 undefined不会报错 // - 场景如果大模型未识别到需要调用工具如用户问题无需工具则 res 中无 tool_calls 属性直接访问 res.tool_calls.length 会抛出 TypeError // - 优势简化容错处理代码无需额外写 if (res.tool_calls) 判断让代码更简洁优雅 if (res.tool_calls?.length) { // 此处仅处理第一个工具调用示例中用户问题仅需调用一个工具 if (res.tool_calls[0].name add) { // 调用加法工具的 invoke 方法传入模型返回的工具参数res.tool_calls[0].args const result await addTool.invoke(res.tool_calls[0].args); // 打印最终计算结果 console.log(最终结果:, result); } } // 11. 第二个请求让模型查询北京的天气触发天气查询工具调用 const res2 await model.invoke(查询北京的天气); // 12. 同理处理天气查询的工具调用结果 if (res2.tool_calls?.length) { // 判断调用的工具是否为天气查询工具get_weather if (res2.tool_calls[0].name get_weather) { // 调用天气工具的 invoke 方法传入模型返回的城市参数 const result await weatherTool.invoke(res2.tool_calls[0].args); // 打印最终天气查询结果 console.log(最终结果:, result); } }结合上面代码我们一步步拆解工具调用的完整流程看看大模型是如何「思考并行动」的步骤 1定义 / 封装工具 用 LangChain 提供的tool函数将业务逻辑和配置对象封装成工具实例。以weatherTool为例javascript// 天气查询工具定义 const weatherTool tool( // 核心执行逻辑从模拟数据库查询天气 async ({ city }) { const weather fakeWeatherDB[city]; return weather ? 当前${city}的天气是${weather.condition}温度${weather.temp}风力${weather.wind} : 暂无${city}的天气信息; }, // 工具配置给大模型的「使用说明」 { name: get_weather, description: 查询指定城市的今日天气情况, schema: z.object({ city: z.string().describe(要查询天气的城市必须是中文城市名称如北京、上海) }) } );同理addTool也按照这个结构封装定义加法逻辑和参数规则。步骤 2将工具绑定到大模型 通过模型的.bindTools()方法把工具「告诉」大模型让它知道自己有哪些「技能」javascript// 初始化DeepSeek模型并绑定工具 const model new ChatDeepSeek({ model: deepseek-chat, // 指定模型版本 temperature: 0, // 0表示结果更确定无随机性 }).bindTools([addTool, weatherTool]); // 绑定工具列表这一步是工具调用的前提 —— 不绑定工具大模型就只能「空谈」无法执行任何操作。步骤 3发送用户请求模型生成工具调用指令 通过model.invoke(用户请求)向大模型提问大模型会分析需求并决定是否调用工具javascript// 示例1请求计算3和4的和 const res await model.invoke(计算3和4的和); // 示例2请求查询北京天气 const res2 await model.invoke(查询北京的天气);大模型会返回包含tool_calls的结果如果需要调用工具tool_calls里会包含工具名称如add和参数如{ a: 3, b: 4 }如果不需要调用工具比如简单闲聊则没有tool_calls。步骤 4解析指令执行工具并获取结果 ️解析tool_calls中的信息调用对应的工具执行逻辑javascript// 处理加法工具调用 if (res.tool_calls?.length) { // 可选链操作符避免无tool_calls时报错 if (res.tool_calls[0].name add) { const result await addTool.invoke(res.tool_calls[0].args); console.log(最终结果:, result); // 输出7 } } // 处理天气工具调用 if (res2.tool_calls?.length) { if (res2.tool_calls[0].name get_weather) { const result await weatherTool.invoke(res2.tool_calls[0].args); console.log(最终结果:, result); // 输出当前北京的天气是晴温度30°C风力微风 } }这里的?.可选链操作符是个小技巧如果大模型没调用工具无tool_calls直接访问res.tool_calls.length会报错用?.可优雅避免这种情况。步骤 5可选整理结果生成自然语言回复 复杂场景中可将工具结果再次传给大模型让它整理成更友好的回复。比如将天气结果传给模型让它生成「今天北京天气晴朗温度 30°C适合户外活动」这样的自然语言。示例中我们为了简化流程直接打印了结果。执行结果亮个相五、面试官会问这些问题 Q工具的description字段有什么作用能不能省略A不能省略。description是大模型判断是否调用工具的核心依据描述越清晰大模型调用工具的准确率越高。比如如果addTool的描述写成「处理数字」大模型可能在用户问「3 乘以 4」时也错误调用它。Q为什么工具的执行逻辑必须是异步函数A因为工具常涉及网络请求如调用 API、IO 操作如读文件等耗时任务异步执行可避免阻塞整个程序流程保证应用的响应速度。Qzod在工具中起到了什么作用A有两个作用① 代码层面校验参数合法性比如防止给addTool传字符串② 告诉大模型参数的类型和含义指导它正确传参比如city必须是中文城市名。Q多个工具绑定时需要注意什么A工具的name必须唯一否则会出现覆盖或调用混乱同时description要区分度高避免大模型混淆工具的功能比如一个查天气、一个查空气质量描述要明确区分。Q如何处理工具调用失败的情况A可以在工具执行逻辑中加入错误处理如try/catch返回明确的错误信息如「查询天气失败请检查城市名称」也可以将错误信息反馈给大模型让它决定重试或提示用户。六、结语 LangChain Tools 是大模型从「对话助手」升级为「实用工具」的关键。通过封装工具我们能让大模型突破自身局限对接实时数据、执行具体操作、访问私有资源真正解决实际问题。文中我们的示例代码加法工具、天气查询工具已经包含了工具开发的核心逻辑你可以在此基础上扩展比如对接真实的天气 API、封装数据库查询工具、实现邮件发送工具等。记住只要能写成函数的逻辑都能成为大模型的「工具」快去动手试试吧让你的大模型应用从「能说会道」变成「能干实事」