尧图网络 高端网站定制 · 原创设计
免费咨询热线
400-888-6620
免费获取方案
Langchain.js 实战四:工具的使用
工具扩展了 AgentAgent我们下一小节介绍的功能——使它们能够获取实时数据、执行代码、查询外部数据库并在现实世界中采取行动。在底层工具是具有明确定义输入和输出的可调用函数这些函数会被传递给聊天模型。模型会根据对话上下文决定何时调用工具以及需要提供哪些输入参数。Tool 是让 Agent 能够与外部世界交互的核心组件本质上是有明确输入输出定义的可调用函数。模型根据对话上下文决定何时调用工具以及传入什么参数。Tool 由三部分组成名称、描述和参数 schema使用 Zod 定义。模型读取这些信息来理解工具的用途并正确调用。在 LLM 应用开发中Tool 是实现 Agent智能体的核心组件。核心概念在 LangChain 中Tool 本质上就是一个函数它包含三个核心要素名称大模型用来识别和调用该工具的唯一标识。 描述告诉大模型这个工具是做什么的什么时候应该调用它。描述的质量直接决定了模型是否会准确调用 执行逻辑当大模型决定调用该工具时实际运行的代码逻辑。 工作流用户输入 - Agent 判断是否需要使用 Tool - LLM 返回 Tool 名称和参数 - LangChain 执行 Tool - 将执行结果返回给 LLM - LLM 生成最终回答。创建工具基本工具定义创建工具最简单的方法是从包中导入tool函数langchain。可以使用zod定义工具的输入模式使用 tool 函数 最推荐这是目前 LangChain.js 最推荐的声明式写法结合 Zod 进行参数类型校验清晰且安全。import*aszfromzodimport{tool}fromlangchain// 1. 定义 Schema (约束大模型传入的参数)constweatherSchemaz.object({city:z.string().describe(需要查询天气的城市名称),unit:z.enum([celsius,fahrenheit]).optional().describe(温度单位)});// 2. 创建 ToolconstgetWeatherTooltool(async({city,unit}){// 这里的逻辑在实际应用中是调用外部天气 APIif(city北京){return${city}今天晴朗温度 25${unitcelsius?°C:°F};}return${city}今天多云;},{name:get_weather,// 工具名称description:获取指定城市的当前天气情况,// 工具描述schema:weatherSchema,// 绑定 Schema});console.log(awaitgetWeatherTool.invoke({city:北京,unit:celsius}));// 输出: 北京今天晴朗温度 25°C北京今天晴朗温度 25°CTool 的核心属性解析写好 Tool 的关键在于描述和Schema。描述的编写艺术大模型完全依赖 description 来决定是否调用该工具。一个好的描述应该 清晰说明功能不要写“处理数据”要写“根据城市名称获取实时天气数据”。 说明适用场景例如“当用户询问天气、气温、下雨情况时使用此工具”。 说明不适用场景例如“不要用此工具查询新闻”。Zod Schema 的作用z.string(), z.number() 等类型约束可以防止大模型传入错误类型的数据。 .describe() 极其重要它是对单个参数的解释帮助大模型理解应该传什么值进去。错误处理如果工具调用出错了怎么办不应该让程序崩溃而应该将错误信息返回给 LLM让它尝试自我修正。当 LLM 收到“除数不能为0”的返回时它可能会换一个参数重新调用或者向用户解释不能除以0。constsafeCalculatortool(async(input){try{// 模拟可能出错的逻辑if(input.b0)thrownewError(除数不能为0);returninput.a/input.b;}catch(error:any){// 关键将错误信息作为字符串返回而不是 throwreturn工具调用出错:${error.message};}},{name:safe_divide,description:除法计算,schema:z.object({a:z.number(),b:z.number()})});使用内置工具LangChain 社区提供了大量现成的工具如网页搜索、数据库查询等。通过包 langchain/community 引入。npm install langchain/communityimport{SerpAPI}fromlangchain/community/tools/serpapi;// 使用 Google 搜索工具 (需配置 SERPAPI_API_KEY)constsearchToolnewSerpAPI(process.env.SERPAPI_API_KEY,{hl:cn,gl:cn,});Stack trace: Error: SerpAPI API key not set. You can set it as SERPAPI_API_KEY in your .env file, or pass it to SerpAPI. at new SerpAPI (file:///Users/cheney/Documents/trae_projects/js/langchain-demo/node_modules/langchain/community/dist/tools/serpapi.js:315:13) at anonymous:3:20在 Tool 中访问运行时状态有时工具在执行时需要知道当前的用户 ID 或请求上下文。可以通过 RunnableConfig 传递。import{RunnableConfig}fromlangchain/core/runnables;constqueryDatabaseTooltool(async(input,config:RunnableConfig){// 从 config 中获取元数据constuserIdconfig?.configurable?.userId;return查询到了用户${userId}的数据: ...;},{name:query_user_db,description:查询当前用户的数据库信息,schema:z.object({query:z.string()}),});// 调用时传入:// agentExecutor.invoke({ input: ... }, { configurable: { userId: 12345 } });服务器端工具使用某些聊天模型内置了在服务器端执行的工具例如网页搜索、代码解释器。详情请参阅“服务器端工具使用”部分。工具名称最好使用字母数字下划线分割例如web_search而不是空格Web Search。某些模型提供商对包含空格或特殊字符的名称存在兼容性问题甚至会报错。坚持使用字母数字字符、下划线和连字符有助于提高不同提供商之间的兼容性。让Tool更聪明访问上下文工具在能够访问运行时信息例如对话历史记录、用户数据和持久内存时其功能最为强大。只有能够访问到这些信息工具才能根据上下文进行决策和执行。就像给Tool配一个“秘书”让它知道是谁在调用、在什么场景下调用import*aszfromzod;import{ChatOpenAI}fromlangchain/openai;import{createAgent,tool}fromlangchain;constgetUserNametool((user_me,config){// 从配置中读取用户名constuserNameconfig.context.user_name;// 从上下文获取用户名if(user_meuserName){returnuserName;}returnI dont know your name.;},{name:get_user_name,description:Get the current users name.,schema:z.object({}),},);// 定义上下文结构constcontextSchemaz.object({user_name:z.string(),});constagentcreateAgent({model:newChatOpenAI({model:google-genai:gemini-3.5-flash}),tools:[getUserName],contextSchema,// 告诉Agent上下文长什么样});// 调用时传入上下文constresultawaitagent.invoke({messages:[{role:user,content:What is my name?}],},{configurable:{thread_id:crypto.randomUUID()},// 会话IDcontext:{user_name:John Smith},// 上下文数据},);长期记忆Store让Tool拥有“记忆”跨会话记住信息它BaseStore提供持久存储数据可在会话之间保留。与状态短期记忆不同保存到存储中的数据在以后的会话中仍然可用。 通过以下方式访问存储库config.store。存储库使用命名空间/键模式来组织数据import*aszfromzod;import{createAgent,tool}fromlangchain;import{InMemoryStore}fromlangchain/langgraph;import{ChatOpenAI}fromlangchain/openai;conststorenewInMemoryStore();// 内存存储生产环境可用数据库// 写入记忆constsaveUserInfotool(async({user_id,name,age,email}){awaitstore.put([users],user_id,{name,age,email});returnSuccessfully saved user info.;},{name:save_user_info,description:Save user info.,schema:z.object({user_id:z.string(),name:z.string(),age:z.number(),email:z.string(),}),},);// 读取记忆constgetUserInfotool(async({user_id}){constvalueawaitstore.get([users],user_id);returnvalue;},{name:get_user_info,description:Look up user info.,schema:z.object({user_id:z.string()}),},);constagentcreateAgent({model:newChatOpenAI({model:gpt-5.4}),tools:[getUserInfo,saveUserInfo],store,// 把存储交给Agent管理});// 第一次会话保存用户信息awaitagent.invoke({messages:[{role:user,content:Save the following user: userid: abc123, name: Foo, age: 25, email: foolangchain.dev},],});// 第二次会话查询用户信息记忆跨会话保留constresultawaitagent.invoke({messages:[{role:user,content:Get user info for user with id abc123},],});流式输出Stream Writer给Tool加个“进度条”实时告诉用户它在干什么在工具执行过程中实时传输工具的更新信息。这对于在长时间运行的操作期间向用户提供进度反馈非常有用。 用于config.writer发出自定义更新import*aszfromzod;import{tool,ToolRuntime}fromlangchain;constgetWeathertool(({city},config:ToolRuntime){constwriterconfig.writer;// 像打字一样输出进度if(writer){writer(Looking up data for city:${city});// 打印查找数据的进度writer(Acquired data for city:${city});// 打印数据获取完成的进度}returnIts always sunny in${city}!;},{name:get_weather,description:Get weather for a given city.,schema:z.object({city:z.string()}),},);执行信息通过以下方式从工具内部访问线程 ID、运行 ID 和重试状态runtime.execution_infoimport{tool}fromlangchain;import*aszfromzod;constlogExecutionContexttool(async(_input,runtime){constinforuntime.executionInfo;console.log(Thread:${info.threadId}, Run:${info.runId});console.log(Attempt:${info.nodeAttempt});returndone;},{name:log_execution_context,description:Log execution identity information.,schema:z.object({}),});Tool返回值不只是字符串Tool不仅能返回字符串还能返回结构化数据甚至直接控制流程constweatherTooltool(({city}){// 返回对象而不是字符串return{city:city,temperature:25,condition:晴朗,humidity:45,};},{name:get_weather_detailed,description:获取详细天气信息,schema:z.object({city:z.string()}),},);实战组合Tool Agent 完整流程import{ChatOpenAI}fromlangchain/openai;import{createAgent,tool}fromlangchain;import*aszfromzod;// 1. 创建工具constsearchTooltool(({query})搜索结果关于${query}的信息...,{name:web_search,description:搜索互联网获取实时信息,schema:z.object({query:z.string().describe(搜索关键词)}),},);constcalculatorTooltool(({expression}){// 实际应用中这里用eval或数学库return计算结果${expression};},{name:calculator,description:执行数学计算,schema:z.object({expression:z.string().describe(数学表达式)}),},);// 2. 创建AgentconstagentcreateAgent({model:newChatOpenAI({temperature:0}),tools:[searchTool,calculatorTool],});// 3. 运行Agentconstresultawaitagent.invoke({messages:[{role:user,content:搜索一下LangChain最新版本然后计算20242025等于多少},],});console.log(result);
RELATED

相关推荐

PyCharm Indent Rainbow插件:用颜色高亮解决代码缩进难题

PyCharm Indent Rainbow插件:用颜色高亮解决代码缩进难题

1. 项目概述:为什么我们需要Indent Rainbow?如果你是一名Python开发者,或者经常需要处理JSON、YAML、HTML这类对缩进极其敏感的语言,那么你一定经历过这样的痛苦:在一个嵌套了七八层的循环或条件判断里,突然…

📅 2026/9/5 2:16:29
在windows11上安装p4vasp

在windows11上安装p4vasp

这个直接在win 11上安装p4vasp。之前在虚拟机ubuntu 22.04上安装的时候,p4vasp下载比较麻烦,因为p4vasp用的是python 2而且还得手动添加一些图形化的依赖包;而且VASP的数据一直传来传去非常麻烦。后来找到了在win 11上的安装包的方法就下了这…

📅 2026/9/29 5:32:24
DeepSeek V4接入Codex:0.24元构建AI数据分析Agent实战

DeepSeek V4接入Codex:0.24元构建AI数据分析Agent实战

这次我们来看一个将 DeepSeek V4 大模型接入 Codex 平台,并以极低成本完成真实 AI 数据分析任务的实战项目。核心目标很直接:利用国产大模型 DeepSeek V4 的强大能力,通过 Codex 平台构建一个可执行的 AI 数据分析系统,实现 Agent…

📅 2026/9/1 16:29:53
MORE NEWS

更多资讯

📰

电子保险丝与单片机协同实现工业电源路径保护

做嵌入式和工业控制器,电源路径保护这四个字,很多人觉得是保险丝该干的事。但我自己在电源入口吃过亏:保险管没跳变,后级DC-DC已经热击穿;换过自恢复保险丝,结果动作时间太慢,板子还是挂了。后来…

📰

运动耳机哪个牌子好?2026年运动耳机品牌排行榜前十名实测对比

不少运动爱好者挑选耳机时都很纠结,市面上运动耳机品类繁多,骨传导、开放式挂耳等款式让人眼花缭乱,各类宣传卖点也真假难辨。很多耳机看着参数好看,实际跑步容易滑落、出汗容易故障,或是风噪、漏音问题突出&#xff0…

📰

智能体工程化转型:行为审计、评测基准与成本优化实战

1. 从本周趋势榜看智能体赛道的真实转向过去大半年,只要聊到智能体,圈子里最常见的讨论还是"哪个框架更顺手""提示词怎么写更稳""怎么让模型别乱调工具"。但这一周的 GitHub Trending 中文区给了我一个很明确的信号&#…

📰

FDE实战:用Agent Harness、RAG与MCP串起AI应用全流程

从去年开始,我身边越来越多同事的title里出现了FDE三个字母。有人以为这是前端工程师(Front-End Developer)的缩写,也有人觉得是某个新职级。其实在我做的这条业务线里,FDE指的是Feature/Full-cycle Development Engin…

📰

DeepSeek Harness桌面端详解:内网部署、插件配置与避坑指南

前段时间 DeepSeek Harness 悄悄更新了桌面端 Release,我看到消息的时候先愣了一下——这项目不是一直在终端里跑的吗?等到自己下载下来用了两天,又把安装目录、配置文件、插件机制从头到尾翻了一遍,才意识到这个"桌面端&quo…

📰

命令行参数:main函数的参数

345 命令行参数:main函数的参数 你有没有注意过,Linux命令后面总能跟各种参数?ls -la、gcc -o main main.c、python script.py arg1 arg2。这些参数是怎么传递给程序的呢?答案就藏在main函数的参数里。 一、main函数的完整形式 int main(int argc, char *argv[])参数 类…

TODAY

今日更新

THIS WEEK

本周精选

THIS MONTH

本月热门

读完文章,想聊聊您的网站?

告诉我们您的行业与需求,资深顾问一对一梳理方案与报价,全程免费。

📞 💬