当前位置: 首页 > article >正文

【 LangChain v1.2 入门系列教程】【三】工具(Tools)开发,让 Agent 连接外部世界

系列文章目录【 LangChain v1.2 入门系列教程】【一】开篇入门 | 从零开始跑通你的第一个 AI Agent【 LangChain v1.2 入门系列教程】【二】消息类型与提示词工程【 LangChain v1.2 入门系列教程】【三】工具Tools开发让 Agent 连接外部世界【 LangChain v1.2 入门系列教程】【四】结构化输出让 Agent 返回可预测的结构【 LangChain v1.2 入门系列教程】【五】记忆管理让 Agent 记住对话【 LangChain v1.2 入门系列教程】【六】流式输出 让 Agent 告别“想好了再说”文章目录系列文章目录前言一、 什么是Tools工具二 、Agent 什么时候调用工具三、 tool 装饰器1. 参数类型注解1 基础类型注解2 复杂参数用 Pydantic 模型做强校验2. 工具重命名3. 覆盖描述四、ToolRuntime 运行环境注入1. 访问会话(State)2. 获取用户上下文Context五 、 多工具协同让 Agent 完成复杂任务六 、 工具调用调试七、总结前言在前两篇中我们已经学会了搭建基础的 Agent而 Agent 之所以能从 “只会聊天的大模型” 变成 “能解决实际问题的智能体”核心就在于Tools工具。本篇文章我们将循序渐进用最简洁的代码和概念带你掌握LangChain v1.2中工具开发的核心技巧。一、 什么是Tools工具工具就是 Agent 可以使用的“外部能力”。比如查询数据库、发送邮件、搜索网页、计算数学表达式……任何一个具体的、可重复执行的动作都可以封装成一个工具其本质是一个函数。二 、Agent 什么时候调用工具当用户的问题无法仅靠模型自身的知识回答时例如实时天气、库存数量、用户等级。当模型判断需要执行某个动作才能完成用户指令时例如发送邮件、保存文件、查询 API。调用时机完全由 Agent 内部的模型自主决定。你只需要把工具注册给 Agent它会像人类一样思考“这个问题我能- 不能直接回答不能的话该用哪个工具”三、 tool 装饰器在LangChain v1.2中使用 tool 装饰器创建一个工具。它可以把一个普通的Python函数瞬间变成Agent可用的工具。示例fromlangchain.toolsimporttool........#定义工具从数据库查询商品库存tooldefcheck_stock(product_id:str)-str:查询商品库存数量# 模拟库存数据stock_data{A1001:15,B2002:0,C3003:3,}stockstock_data.get(product_id,0)ifstock0:returnf商品{product_id}库存充足剩余{stock}件else:returnf商品{product_id}已售罄暂时无货#创建agentagentcreate_agent(modelllm,tools[check_stock]#注册工具)#调用模型responseagent.invoke({messages:[HumanMessage(A1001商品还有货吗)]})print(response[messages][-1].content)#商品 A1001 当前库存充足还有 15 件在售说明参数类型注解是必需的 —— 它们定义了工具的输入参数模式Schema大模型据此知道该传什么参数函数名即工具名 —— 建议用动词名词具有语义化命名帮助模型理解函数作用如 get_weather、send_emailDocstring 示例中的““查询商品库存数量””被自动提取为工具描述 —— 这是模型决定是否调用该工具的重要依据描述越清晰Agent调用工具的时机和方式就越准确。1. 参数类型注解LangChain v1.2 中参数的类型注解是强制要求的—— 没有类型注解的参数无法生成正确的工具 Schema大模型也就不知道该传什么类型的参数会直接导致工具调用失败。1 基础类型注解最常用的基础类型包括str、int、float、bool直接给参数加上即可可选参数必须设置默认值tooldefsearch_customer_info(customer_name:str,max_result:int6)-str:查询客户信息当用户需要查找指定客户的资料时调用此工具。 Args: customer_name: 要查询的客户姓名必填项 max_result: 返回的最大结果条数默认为6条 returnf找到{max_result}条名为【{customer_name}】的客户信息2 复杂参数用 Pydantic 模型做强校验frompydanticimportBaseModel,FieldfromtypingimportOptional# 定义参数类型classEmailInput(BaseModel):邮件发送参数to:strField(description收件人邮箱地址)subject:strField(description邮箱主题)body:Optional[str]Field(default,description邮件正文内容可选)# 定义工具发邮件tooldefsend_email(param:EmailInput)-str: 发送邮件到指定收件人。 当用户需要发送邮件、通知或报告时使用此工具。 #模拟发送成功响应returnf邮件已发送至{param.to}主题{param.subject},正文内容{param.body}用 Pydantic 模型的核心优势自动做参数校验用Field给每个参数加精细化说明比写在 docstring 里更清晰支持可选值Optional支持枚举值Literal2. 工具重命名默认情况下工具名称 函数名。但你可以通过传入字符串参数来显式指定# 默认工具名 searchtooldefsearch(query:str)-str:搜索网页内容returnf搜索结果{query}# 自定义工具名 web_searchtool(web_search)defsearch(query:str)-str:搜索网页内容returnf搜索结果{query}3. 覆盖描述默认情况下工具描述 函数的 docstring。但你可以通过 description 参数强制覆盖# 方式1依赖 docstring默认tooldefcalculator(expression:str)-str:执行数学计算# 模型看到的就是这行returnstr(eval(expression))# 方式2显式覆盖优先级最高tool(description专门用于处理加减乘除和复杂数学表达式。当用户询问任何数学问题时必须调用此工具。)defcalculator(expression:str)-str:执行数学计算# 这行会被忽略returnstr(eval(expression))四、ToolRuntime 运行环境注入LangChain v1.2 中ToolRuntime 是一项核心升级。它会在工具执行时自动将当前 Agent 的运行环境注入到工具中,而且这个参数不会暴露给 LLM完全不影响工具的输入 Schema既保留了功能又保障了安全性。通过 ToolRuntime你的工具可以访问常用三类核心信息State状态短期记忆包括当前对话的消息列表、自定义字段等。Context上下文不可变的配置信息如用户ID、会话ID等在调用时传入。Store存储长期记忆跨会话持久化保存的数据。1. 访问会话(State)通过 runtime.state[“messages”]工具可以读取当前会话的 State短期记忆比如对话历史、自定义的会话状态等从而做出更智能的决策。tooldefget_user_question_count(runtime:ToolRuntime)-str:统计当前会话中用户提出的问题总数当用户询问自己问了多少个问题时调用。# 从State中获取所有对话消息all_messagesruntime.state[messages]# 统计用户发送的消息数量user_message_countlen([msgformsginall_messagesifisinstance(msg,HumanMessage)])returnf当前会话中您一共提出了{user_message_count}个问题agentcreate_agent(modelllm,tools[get_user_question_count],system_prompt你是一个智能客服助手回答用户的提问和帮助用户解决问题,)# 调用时注入具体上下文responseagent.invoke({messages:[HumanMessage(我想买iPhone 16),AIMessage(好的iPhone 16 是我们的热门商品。),HumanMessage(现在有货吗),AIMessage(库存充足需要我帮你下单吗),HumanMessage(我问了多少个问题了),]},)print(response[messages][-1].content)#输出你一共提出了3个问题2. 获取用户上下文Context通过 runtime.context可以让你获取调用时传入的不可变配置信息例如用户ID、权限等级等。这对于实现个性化服务至关重要。fromlangchain.toolsimportToolRuntime,toolfromdataclassesimportdataclass# 定义上下文的数据结构dataclassclassUserContext:user_id:struser_level:int2# 用户等级1vip用户2普通用户默认普通用户# 工具获取当前用户信息tooldefget_user_info(runtime:ToolRuntime[UserContext])-str: 获取当前用户信息并根据等级返回不同的权限说明。 ctxruntime.context# 获取当前上下文user_idctx.user_id# 获取用户IDlevelctx.user_level# 获取用户等级iflevel1:return(f 用户{user_id}VIP会员特权无限制访问可查询历史订单、专属折扣。)else:returnf 用户{user_id}普通用户限制仅可查询本月订单每日限查询 3 次。# 创建 Agentagentcreate_agent(modelllm,tools[get_user_info],context_schemaUserContext,# 指定 context_schemasystem_prompt你是客服助手了解用户身份后再提供相应服务。,)# 调用时注入具体上下文responseagent.invoke({messages:[{role:user,content:请问我的账户有什么权限}]},contextUserContext(user_iduser_1,user_level1),# 注入用户配置VIP 用户)print(response[messages][-1].content)# 输出用户 user_1VIP会员特权无限制访问可查询历史订单、专属折扣。五 、 多工具协同让 Agent 完成复杂任务实际业务场景中一个复杂的用户需求往往需要多个工具配合才能完成。LangChain 的 Agent 天生支持多工具协同你只需要把所有工具注册到 Agent 中它会自动规划调用顺序完成多步操作无需你手动写流程控制代码。来看下面一个经典示例# 定义上下文的数据结构 dataclassclassUserContext:user_id:str # 获取用户所在城市 tool defget_user_location(runtime:ToolRuntime[UserContext])-str:获取当前用户所在的城市名称user_idruntime.context.user_id # 从上下文获取用户ID# 模拟用户位置数据库数据 user_locations{user_1:北京,user_2:上海,user_3:广州,}returnuser_locations.get(user_id,未知城市)# 查询指定城市天气 tool defget_city_weather(city:str)-str:查询指定城市的天气# 模拟查询天气数据,实际从api获取 weather_data{北京:北京小雨气温10-18℃,上海:上海暴雨气温15-22,广州:广州晴转多云气温20-28℃,}returnf{weather_data.get(city, 未知天气)}agentcreate_agent(modelllm,tools[get_user_location,get_city_weather],)# 调用时注入具体上下文 responseagent.invoke({messages:[HumanMessage(今天的天气如何)]},contextUserContext(user_iduser_3),)print(response[messages][-1].content)# 输出今天广州的天气是晴转多云气温在20到28摄氏度之间。运行这段代码你会看到 Agent 的自动执行流程1.收到用户问题发现没有指定城市先调用get_user_location工具拿到用户所在城市 “广州”2.再调用get_city_weather工具传入 “广州”拿到天气信息3.最后整理成自然语言回答用户全程 Agent 自动规划、自动调用无需我们写任何流程控制代码这就是 LangChain 中 Agent 提供的强大能力。六 、 工具调用调试Agent 的决策过程对开发者来说并非完全透明——我们知道它有哪些工具可用但如果不主动观察就难以直观了解它何时调用了工具、传入了哪些参数、哪一步出现了问题。想看清Agent的思考过程最直接的方式是查看response[“messages”]观察工具调用痕迹仍以上面的多工具协同示例为例print(response[messages])输出结果中可以看到如下关键信息[HumanMessage(content今天的天气如何,....),AIMessage(content,tool_calls[{name:get_user_location,args:{},id:...,type:tool_call}],invalid_tool_calls[]),ToolMessage(content广州,nameget_user_location,id...,tool_call_id...),AIMessage(tool_calls[{name:get_city_weather,args:{city:广州},id:...,type:tool_call}],invalid_tool_calls[]),ToolMessage(content广州晴转多云气温20-28℃,nameget_city_weather,...),AIMessage(content今天广州的天气是晴转多云气温在20到28摄氏度之间。)]通过分析这些消息可以清晰看到 Agent 的每一步决策与执行第一个 AIMessagetool_calls 非空表示模型决定调用 get_user_location 工具参数为空且未进入 invalid_tool_calls说明参数格式合法可正常执行。第一个 ToolMessage表示工具执行完成返回内容为“广州”。第二个 AIMessage再次发起工具调用这次是 get_city_weather参数为 {“city”: “广州”}。第二个 ToolMessage返回天气信息。最后一个 AIMessage模型根据工具返回结果生成最终回答。说明若 invalid_tool_calls 数组非空则表示模型生成的工具调用参数格式错误框架会跳过执行这也是排查工具调用失败的重要线索。可以使用如下代码过滤保留工具调用关键信息formsginresponse[messages]:ifhasattr(msg,tool_calls)and msg.tool_calls:# AIMessage 中的工具调用意图print(f【模型想调用】: {msg.tool_calls})elifisinstance(msg,ToolMessage):# 工具执行后的返回结果print(f【工具返回】: {msg.content[:100]}...)运行输出【模型想调用】:[{name:get_user_location,args:{},id:019d3de71518050cae285450f221b027,type:tool_call}]【工具返回】:广州...【模型想调用】:[{name:get_city_weather,args:{city:广州},id:019d3de7188dc957ba14814eaba5b41c,type:tool_call}]【工具返回】:广州晴转多云气温20-28℃...七、总结工具是 Agent 连接外部世界的桥梁掌握了工具开发你就能给 Agent 赋予无限的能力比如让它帮你查实时股票、操作数据库、发送邮件、控制智能家居、调用任意第三方 API 等等。在下一篇教程中我们将继续学习Agent“结构化输出“。

相关文章:

【 LangChain v1.2 入门系列教程】【三】工具(Tools)开发,让 Agent 连接外部世界

系列文章目录 【 LangChain v1.2 入门系列教程】【一】开篇入门 | 从零开始,跑通你的第一个 AI Agent 【 LangChain v1.2 入门系列教程】【二】消息类型与提示词工程 【 LangChain v1.2 入门系列教程】【三】工具(Tools)开发,让…...

硅谷新宠Hermes Agent,能否逆袭OpenClaw?

硅谷新宠Hermes Agent一夜爆火,GitHub揽6.6万星,原生接入微信引开发者关注。它在OpenRouter表现出色,还发布首篇“顶会级”论文,提出新推理方法。 爆火的Hermes Agent Hermes Agent历经9个月打磨,在GitHub狂揽66k星、F…...

Chrome文本替换插件终极指南:如何智能编辑任何网页内容

Chrome文本替换插件终极指南:如何智能编辑任何网页内容 【免费下载链接】chrome-extensions-searchReplace 项目地址: https://gitcode.com/gh_mirrors/ch/chrome-extensions-searchReplace 在浏览网页时,你是否曾遇到过需要修改页面内容却无能为…...

忙得上天入地的导师派师姐助我毕设之救我狗命笔记(一)

开源模型探索实践-环境配置与参数修改一、环境配置按照 README 说明进行基础配置。在终端中依次执行以下命令:bashconda create -n aqatrack python3.8 conda activate aqatrack bash install.sh⚠️ 注意:Windows 系统执行最后一行会报错,此…...

Blender 3MF插件:从建模到3D打印的终极桥梁

Blender 3MF插件:从建模到3D打印的终极桥梁 【免费下载链接】Blender3mfFormat Blender add-on to import/export 3MF files 项目地址: https://gitcode.com/gh_mirrors/bl/Blender3mfFormat 在3D打印技术日益普及的今天,你是否曾为文件格式转换的…...

Retinaface+CurricularFace镜像作品集:高清人脸比对效果展示

RetinafaceCurricularFace镜像作品集:高清人脸比对效果展示 你是否好奇,一个开箱即用的人脸识别镜像,究竟能做出多惊艳的效果?今天,我们不谈复杂的配置,也不讲枯燥的原理,直接带你看看这个Reti…...

FreeRTOS时间管理实战:如何用vTaskDelay和vTaskDelayUntil实现精准任务调度

FreeRTOS时间管理实战:精准任务调度的艺术与科学 1. 嵌入式实时系统中的时间管理基础 在嵌入式实时操作系统中,时间管理如同交响乐团的指挥,协调着各个任务的执行节奏。FreeRTOS作为轻量级RTOS的代表,其时间管理机制直接影响着系统…...

406记录

栈(Stack)是限定仅在表尾进行插入或删除操作的线性表。因此,对栈来说,表尾端有其特殊含义,称为栈顶(top),相应地,表头端称为栈底(bottom)。不含元…...

Java的java.util.HexFormat自定义格式

Java的HexFormat:十六进制处理的现代方案 在数据处理、网络通信或安全加密领域,十六进制格式的转换与解析是常见需求。Java 17引入的java.util.HexFormat类,为开发者提供了标准化且灵活的十六进制处理工具,告别了以往依赖手动拼接…...

LeetCode hot 100 (12-16,自用2026.04.06)

LeetCode hot 100 (12-16,自用2026.04.06) 53. 最大子数组和 给你一个整数数组 nums ,请你找出一个具有最大和的连续子数组(子数组最少包含一个元素),返回其最大和。 子数组是数组中的一个连续部分。 示例 1: 输入…...

Qwen3.5-9B-AWQ-4bit图文理解参数详解:temperature=0.7时的稳定性与丰富度平衡

Qwen3.5-9B-AWQ-4bit图文理解参数详解:temperature0.7时的稳定性与丰富度平衡 1. 模型概述 Qwen3.5-9B-AWQ-4bit是一个支持图像理解的多模态模型,能够结合上传图片与文字提示词,输出中文分析结果。这个量化版本特别适合处理以下任务&#x…...

YOLO12工业场景迁移指南:从COCO预训练到产线缺陷检测的微调路径

YOLO12工业场景迁移指南:从COCO预训练到产线缺陷检测的微调路径 1. 引言:当通用模型遇上工业难题 想象一下,你拿到一个在通用场景下表现优异的“全能选手”——YOLO12,它能轻松识别照片里的人、车、猫、狗。现在,你需…...

01-秒杀系统设计详解

秒杀系统设计详解 一、知识概述 秒杀系统是电商领域最具挑战性的高并发场景之一,典型特征是瞬时高并发、库存有限、时间敏感。一个成功的秒杀系统需要在极短时间内处理海量请求,同时保证数据一致性和用户体验。 核心挑战: 流量突增:平时QPS可能只有几十,秒杀开始瞬间可…...

MiniCPM-V-2_6部署不求人:Ollama三步走,小白也能轻松玩转

MiniCPM-V-2_6部署不求人:Ollama三步走,小白也能轻松玩转 1. 为什么选择MiniCPM-V-2_6? MiniCPM-V-2_6是目前视觉多模态领域的一颗新星,它虽然体积小巧(仅8B参数),但性能却能与GPT-4V、Gemini…...

AudioSeal Pixel Studio快速上手:移动端Safari/Chrome对Streamlit音频组件兼容性

AudioSeal Pixel Studio快速上手:移动端Safari/Chrome对Streamlit音频组件兼容性 1. 工具简介与核心价值 AudioSeal Pixel Studio是一款基于Meta开源的AudioSeal算法构建的专业音频水印工具。它能够在保持原始音质几乎不变的情况下,为音频文件嵌入隐形…...

Python 多线程爬虫性能调优方案

Python多线程爬虫性能调优方案 在当今大数据时代,网络爬虫已成为数据采集的重要工具。面对海量数据和高频请求,单线程爬虫往往效率低下,难以满足需求。Python多线程爬虫因其并发特性,能够显著提升爬取效率,但若未合理…...

Phi-4-mini-reasoning多场景落地:教育科技公司AI助教产品核心推理模块

Phi-4-mini-reasoning多场景落地:教育科技公司AI助教产品核心推理模块 1. 模型介绍与定位 Phi-4-mini-reasoning是一款专注于推理任务的文本生成模型,特别适合数学题解答、逻辑推理、多步分析和简洁结论输出等场景。与通用聊天模型不同,它被…...

从人工到智能:Ostrakon-VL-8B助力中小餐饮企业巡检效率提升80%

从人工到智能:Ostrakon-VL-8B助力中小餐饮企业巡检效率提升80% 1. 引言:餐饮老板的日常烦恼与AI解法 开过餐馆的朋友都懂,每天一睁眼就是各种操心。后厨的卫生达标了吗?食材新鲜度够不够?员工操作规范吗?…...

层次化文本分类:利用文档结构与类别树提升分类性能

点击 “AladdinEdu,你的AI学习实践工作坊”,注册即送-H卡级别算力,沉浸式云原生集成开发环境,80G大显存多卡并行,按量弹性计费,教育用户更享超低价。 1. 引言:当分类问题有了“上下级” 传统的…...

MiniCPM-o-4.5-nvidia-FlagOS本地化部署:Ollama模式与星图GPU方案对比

MiniCPM-o-4.5-nvidia-FlagOS本地化部署:Ollama模式与星图GPU方案对比 最近在折腾MiniCPM-o-4.5-nvidia-FlagOS这个模型,发现不少朋友在部署时有点纠结。有人想在自己笔记本上快速跑起来试试,也有人希望找个稳定、性能好的地方长期用。我花时…...

Python的__enter__方法返回非自身对象与资源管理代理模式的设计

Python的上下文管理器通过__enter__和__exit__方法实现了资源的自动管理,但鲜为人知的是,__enter__方法可以返回非自身对象,这一特性为资源管理代理模式的设计提供了更多可能性。这种设计模式不仅简化了代码结构,还增强了灵活性和…...

Redis 菜鸟学习

目录 第1章 Redis入门——五个核心的数据结构 Redis 简介 1. Redis 是什么? 2. Redis 的典型应用场景(它用来干嘛?) 3. 开启命令面板、退出、中文显示 4. 侦探三件套 字符串(String)—— 最基础的存…...

**RISC-V生态下的轻量级RTOS移植实战:从零开始构建嵌入式系统核心**在当前国产化

RISC-V生态下的轻量级RTOS移植实战:从零开始构建嵌入式系统核心 在当前国产化替代浪潮中,RISC-V架构凭借其开源、灵活、可定制等优势迅速崛起,成为嵌入式开发领域的热点方向。本文将深入探讨如何在RISC-V平台上移植一个轻量级实时操作系统&am…...

别再死记硬背ESP32 BLE API了!用这个“事件驱动”思维导图,5分钟理清GAP/GATT回调逻辑

用事件驱动思维重构ESP32 BLE开发:从API记忆到逻辑推演的艺术 在物联网设备开发中,BLE(低功耗蓝牙)技术因其低功耗特性成为连接智能设备的首选方案。ESP32作为集成BLE功能的明星芯片,其开发门槛却让不少工程师望而生畏…...

Rust的匹配中的使用规范

Rust的匹配机制是其语言设计中极具特色的一部分,它不仅提供了强大的模式匹配能力,还能在编译时确保代码的完备性和安全性。匹配(match)是Rust中处理多分支逻辑的核心工具,广泛应用于枚举解构、错误处理、条件分支等场景…...

ACE-Step音乐模型部署体验:一键生成高质量音频,创作效率大提升

ACE-Step音乐模型部署体验:一键生成高质量音频,创作效率大提升 1. 音乐创作的新时代 你是否曾经遇到过这样的困境:脑海中有一段美妙的旋律,却苦于不会乐器或不懂乐理,无法将它变成现实?或者作为一名内容创…...

SDPose-Wholebody在Linux系统下的高效部署方案

SDPose-Wholebody在Linux系统下的高效部署方案 1. 引言 想试试那个能精准识别人体133个关键点的SDPose-Wholebody模型吗?作为基于Stable Diffusion的新一代姿态估计方案,它在处理复杂场景和跨域数据时表现相当出色。不过很多朋友在Linux系统上部署时遇…...

Vue实战:打造智能视频播放器——倍速控制、音量调节、进度拖拽与AI字幕生成

1. 从零开始构建Vue智能视频播放器 最近在做一个在线教育项目时,我发现现有的视频播放器功能太过基础,无法满足用户对学习效率的需求。于是决定用Vue自己开发一个带倍速控制、音量调节、进度拖拽和AI字幕的智能播放器。经过两周的实战,我把踩…...

JavaScript跨平台OCR引擎:Tesseract.js实现浏览器与Node.js图像文字识别

JavaScript跨平台OCR引擎:Tesseract.js实现浏览器与Node.js图像文字识别 【免费下载链接】tesseract.js Pure Javascript OCR for more than 100 Languages 📖🎉🖥 项目地址: https://gitcode.com/gh_mirrors/te/tesseract.js …...

5步搞定!BAAI/bge-m3+ChromaDB搭建语义搜索服务

5步搞定!BAAI/bge-m3ChromaDB搭建语义搜索服务 1. 项目概述与核心价值 BAAI/bge-m3是当前开源领域最强大的多语言语义嵌入模型之一,在MTEB榜单上表现优异。结合ChromaDB这一轻量级向量数据库,我们可以快速搭建一个高性能的本地语义搜索服务…...