【零基础入门 LLM 开发 · Day 15】:LangChain 注册工具——告别手写 JSON Schema
【零基础入门 LLM 开发 · Day 15】LangChain 注册工具——告别手写 JSON Schema场景Day 8-9 用原生 SDK 手写工具说明书一个get_weather就写了二十来行 JSON Schema。工具一多手写说明书又臭又长还容易写错字段名。今天用 LangChain 把这件事变省力三种姿势逐级进化手写字典 → Pydantic 模型 → tool 装饰器。起步bind_tools 一行顶一坨工具说明书还是 Day 8 那套字典但绑定和调用交给 LangChainimportosfromdotenvimportload_dotenvfromlangchain.chat_modelsimportinit_chat_model load_dotenv()modelinit_chat_model(modelos.getenv(YUMC_MODEL_NAME),model_provideropenai,api_keyos.getenv(YUMC_MODEL_API_KEY),base_urlos.getenv(YUMC_MODEL_BASE_URL),)# 用字典描述工具和 Day 8 手写的一样tools[{type:function,function:{name:get_weather,description:查询指定城市的天气,parameters:{type:object,properties:{city:{type:string,description:城市名称,如 杭州、北京}},required:[city],},},}]# bind_tools() 将工具绑定到模型model_with_toolsmodel.bind_tools(tools)responsemodel_with_tools.invoke(杭州今天天气怎么样)ifresponse.tool_calls:fortcinresponse.tool_calls:print(f工具名称{tc[name]})print(f参数{tc[args]})print(f调用ID{tc[id]})response.tool_calls是个列表——AI 觉得需要的话会一次请求多个工具调用别只取第一个。进阶Pydantic 模型直接当工具手写字典的问题字段名、类型、描述全靠人肉对齐。换成 Pydantic 模型LangChain 自动帮你生成说明书frompydanticimportBaseModel,FieldclassWeatherInput(BaseModel):查询指定城市的天气情况city:strField(description城市名称如 杭州、北京)unit:strField(defaultcelsius,description温度单位celsius摄氏度或 fahrenheit华氏度,)classCalculatorInput(BaseModel):执行数学计算expression:strField(description要计算的数学表达式,如(35)*2)# 传入 Pydantic 模型LangChain 自动转换为工具描述model_with_toolsmodel.bind_tools([WeatherInput,CalculatorInput])responsemodel_with_tools.invoke(北京今天多少度顺便帮我算一下123*456)print(f模型请求了{len(response.tool_calls)}个工具调用)fortcinresponse.tool_calls:print(f{tc[name]}({tc[args]}))为什么 Pydantic 模型能当工具LangChain 拿到对象后自动提取三样东西——和 Day 8 手写的 JSON Schema 是同一个东西只是框架替你生成Pydantic 里的变成说明书里的类名function.namedocstring查询指定城市的天气情况function.description字段类型 Field(description...)parameters的 JSON Schema更简tool 装饰器普通函数也能注册——函数名、docstring、类型注解就是现成的说明书fromlangchain_core.toolsimporttooltooldefget_location(location:str)-str:获取指定位置的经纬度returnf获取{location}的经纬度# 和 Pydantic 模型混着用也没问题model_with_toolsmodel.bind_tools([WeatherInput,CalculatorInput,get_location])responsemodel_with_tools.invoke(北京今天多少度顺便帮我算一下123*456经纬度)三种方式对比方式工具名描述参数 schema适用场景bind_tools(字典)手写手写手写和 Day 8 等价没必要再用bind_tools(Pydantic)类名docstring字段定义参数结构复杂、需要校验/复用tool函数名docstring类型注解最常用一行搞定tool的本质LangChain 根据函数签名现场生成一个 Pydantic 模型get_location.args_schema可以看所以后两种方式殊途同归。和 Day 13 的血缘with_structured_output(methodfunction_calling)的底层就是 bind_toolsPydantic 模型 → JSON Schema → 发给模型。注册工具模型主动申请调用你执行后把结果喂回去Day 8 流程结构化输出强制模型把你的 Pydantic 模型当工具调用一次直接拿到参数当结果。同一套机制两个用途。学会一个另一个就是白送。运行效果模型请求了3个工具调用 WeatherInput ({city: 北京, unit: celsius}) CalculatorInput ({expression: 123*456}) get_location ({location: 北京})一个问题触发三个工具调用——AI 自己决定要不要用、用哪几个、传什么参数。今日踩坑点tools写成装饰器from langchain import tools导入的是模块模块不能调用报TypeError: module object is not callable。要用from langchain_core.tools import tool然后tool或者tools.tool。Field(decription...)拼错Pydantic 不认识的关键字被当额外参数只给一条 DeprecationWarning不报错——结果描述丢了模型只能瞎猜参数含义工具质量悄悄下降。警告也要看f-string 括号位置f{tc[name] ({tc[args]})}会把tc[name]当函数调用name 后面跟了个括号报str object is not callable。正确写法f{tc[name]} ({tc[args]})。Pydantic 类名直接变工具名WeatherInput这种名字出现在给模型看的说明书里很怪。tool用函数名更自然坚持用 Pydantic 就把类名起得像工具名。今日小练习必做用tool写一个get_current_time()跑通现在几点了——对比 Day 8 的必做题感受少写了多少行。进阶print(get_current_time.args_schema)看看 tool 现场生成的 Pydantic 模型长什么样。思考把 Day 8 手写说明书的工具全部换成 tool 版本模型的工具选择行为有变化吗明日预告Day 15工具又多又杂时AI 容易选错、token 也贵。学公司设前台——主 Agent 只管转接子 Agent 各管一摊。附录完整练习代码langchainTest4-tools.py字典版 bind_toolsimportosfromdotenvimportload_dotenvfromlangchain.chat_modelsimportinit_chat_model load_dotenv()modelinit_chat_model(modelos.getenv(YUMC_MODEL_NAME),model_provideropenai,api_keyos.getenv(YUMC_MODEL_API_KEY),base_urlos.getenv(YUMC_MODEL_BASE_URL),)# 用字典描述工具tools[{type:function,function:{name:get_weather,description:查询指定城市的天气,parameters:{type:object,properties:{city:{type:string,description:城市名称,如 杭州、北京}},required:[city],},},}]# bind_tools() 将工具绑定到模型model_with_toolsmodel.bind_tools(tools)responsemodel_with_tools.invoke(杭州今天天气怎么样)ifresponse.tool_calls:print(模型调用了以下工具)fortcinresponse.tool_calls:print(f工具名称{tc[name]})print(f参数{tc[args]})print(f调用ID{tc[id]})else:print(f模型直接回复:{response.content})langchainTest4-tools2.pyPydantic 模型版importosfromdotenvimportload_dotenvfromlangchain.chat_modelsimportinit_chat_modelfrompydanticimportBaseModel,Field load_dotenv()modelinit_chat_model(modelos.getenv(YUMC_MODEL_NAME),model_provideropenai,temperature0,api_keyos.getenv(YUMC_MODEL_API_KEY),base_urlos.getenv(YUMC_MODEL_BASE_URL),)classWeatherInput(BaseModel):查询指定城市的天气情况city:strField(description城市名称如 杭州、北京)unit:strField(defaultcelsius,description温度单位celsius摄氏度或 fahrenheit华氏度,)classCalculatorInput(BaseModel):执行数学计算expression:strField(description要计算的数学表达式,如(35)*2)# 传入pydantic 模型LangChain 自动转换为工具描述model_with_toolsmodel.bind_tools([WeatherInput,CalculatorInput])responsemodel_with_tools.invoke(北京今天多少度顺便帮我算一下123*456)print(f模型请求了{len(response.tool_calls)}个工具调用)fortcinresponse.tool_calls:print(f{tc[name]}({tc[args]}))langchainTest4-tools3.pytool 装饰器版importosfromdotenvimportload_dotenvfromlangchain_core.toolsimporttoolfromlangchain.chat_modelsimportinit_chat_modelfrompydanticimportBaseModel,Field load_dotenv()modelinit_chat_model(modelos.getenv(YUMC_MODEL_NAME),model_provideropenai,temperature0,api_keyos.getenv(YUMC_MODEL_API_KEY),base_urlos.getenv(YUMC_MODEL_BASE_URL),)classWeatherInput(BaseModel):查询指定城市的天气情况city:strField(description城市名称如 杭州、北京)unit:strField(defaultcelsius,description温度单位celsius摄氏度或 fahrenheit华氏度,)classCalculatorInput(BaseModel):执行数学计算expression:strField(description要计算的数学表达式,如(35)*2)tooldefget_location(location:str)-str:获取指定位置的经纬度returnf获取{location}的经纬度# 传入pydantic 模型LangChain 自动转换为工具描述model_with_toolsmodel.bind_tools([WeatherInput,CalculatorInput,get_location])responsemodel_with_tools.invoke(北京今天多少度顺便帮我算一下123*456经纬度)print(f模型请求了{len(response.tool_calls)}个工具调用)fortcinresponse.tool_calls:print(f{tc[name]}({tc[args]}))

相关新闻

Lunar 5.6.4a3 更新解读:HDR 兼容性收窄、DDC 强制检测与 Gamma 滑块修复

Lunar 5.6.4a3 更新解读:HDR 兼容性收窄、DDC 强制检测与 Gamma 滑块修复

桌面应用 【免费下载链接】Lunar Intelligent adaptive brightness for your external monitors 项目地址: https://gitcode.com/gh_mirrors/lu/Lunar 点击查看 免费下载 本篇文章围绕 macOS 显示器亮度管理工具 Lunar 的 5.6.4 系列 alpha 版本发布说明 ReleaseNo…

2026/10/16 6:22:52 阅读更多 →
读懂频率稳定度:短稳、长稳与阿伦标准偏差

读懂频率稳定度:短稳、长稳与阿伦标准偏差

时间频率是现代信息系统的“脉搏”。通信组网、智能电网、卫星导航、精密测控与科研实验,整套系统的精度、一致性与可靠性,都高度取决于频率源的频率稳定度。西安同步电子科技深耕时频领域,专注高稳定频率源与时序同步设备研发。本文严格依据…

2026/10/16 6:21:52 阅读更多 →
空洞卷积:不降分辨率扩大感受野,原理、实现与避坑指南

空洞卷积:不降分辨率扩大感受野,原理、实现与避坑指南

做图像分割和检测的朋友,大概率都被同一个问题折磨过:网络想看得远,就得把特征图一路缩水,高层语义是有了,边缘细节却糊成一团。空洞卷积(Dilated Convolution)是我在解决这类“又想看得远、又想…

2026/10/16 6:21:52 阅读更多 →

最新新闻

深入理解 DOM ProcessingInstruction:用法与实战

深入理解 DOM ProcessingInstruction:用法与实战

1. 引言在 DOM(文档对象模型)中,除了常见的元素节点、文本节点和注释节点之外,还存在一类相对冷门但功能明确的节点类型——ProcessingInstruction(处理指令)。它通常出现在 XML 文档中,用于向解…

2026/10/17 11:54:35 阅读更多 →
顺序表逆置:双指针原地算法原理与工程实现

顺序表逆置:双指针原地算法原理与工程实现

1. 项目概述:为什么一个“顺序表逆置”值得花时间深挖?你可能刚学完数据结构,看到“设计一个高效算法,将顺序表L的所有元素逆置,要求空间复杂度为O(1)”这个题目时,第一反应是:“不就…

2026/10/17 11:54:35 阅读更多 →
AI报销实践:从1小时到5分钟的流程改造与落地指南

AI报销实践:从1小时到5分钟的流程改造与落地指南

处理过报销的人,大概率都经历过那种既烦躁又无奈的时刻:业务同事抱着一摞票据在工位上贴贴填填,财务在审核界面来回核对发票真伪、税号、预算科目,一个月里总有几天大家都在为同一张纸反复折腾。我后来仔细算过账:一趟…

2026/10/17 11:54:35 阅读更多 →
Ionic 表单与输入框实战指南:从基础到进阶

Ionic 表单与输入框实战指南:从基础到进阶

1. 引言在移动应用开发中,表单是用户与系统交互的核心方式之一。Ionic 框架基于 Angular、React 或 Vue 构建,提供了一套功能强大的表单组件,帮助开发者快速构建美观、易用的表单界面。本文将围绕 Ionic 表单和输入框展开,通过丰富…

2026/10/17 11:54:35 阅读更多 →
戴尔集成阵列S150驱动详解:从Windows到ESXi部署与排错

戴尔集成阵列S150驱动详解:从Windows到ESXi部署与排错

简介:戴尔服务器集成阵列S150驱动面向服务器运维人员,解决系统无法正确识别或管理S150阵列卡的问题。该驱动支持RAID 0、RAID 1、RAID 10及直通模式,能帮助企业入门级与中端服务器获得稳定的存储读写与容错能力。压缩包相当精简,共…

2026/10/17 11:54:35 阅读更多 →
单目相机加平面镜实现低成本三维重建:镜像虚拟多视角采集与3DGS实践

单目相机加平面镜实现低成本三维重建:镜像虚拟多视角采集与3DGS实践

搞三维视觉的朋友估计都遇到过这种尴尬:明明只需要重建一个小物件或一片室内场景,手里却只有一台普通相机。买一套多相机阵列?成本直接起飞。手持环绕拍一圈?又容易丢特征、糊成一片。我自己前阵子在某实验室折腾一个代号叫“某跨…

2026/10/17 11:53:35 阅读更多 →

日新闻

DeepSeek选型与部署:V3/R1、Ollama、API全攻略

DeepSeek选型与部署:V3/R1、Ollama、API全攻略

简介:《DeepSeek使用方法.pdf》是一份面向DeepSeek入门及进阶用户的完整使用指南,重点围绕V3与R1两款模型的能力差异与适用场景展开,帮助读者根据任务类型与成本选择合适的模型。资源共1个PDF文件,压缩包大小约311KB,篇…

2026/10/17 0:00:25 阅读更多 →
200+Deepseek润色指令拆解:从底层原理到场景落地的完整指南

200+Deepseek润色指令拆解:从底层原理到场景落地的完整指南

简介:这是一份聚焦DeepSeek提示词优化的《200Deepseek润色指令》PDF文档,共收录两百余条可直接套用的润色指令,涵盖语法修正、风格统一、逻辑梳理、表达精炼等维度,并针对商务写作、学术论文、广告文案等场景给出差异化建议。文档…

2026/10/17 0:00:25 阅读更多 →
OpenCV轮廓法物体计数系统:轻量、可控、可落地的工业级实现

OpenCV轮廓法物体计数系统:轻量、可控、可落地的工业级实现

简介:本资源是一份基于OpenCV的本科课程设计完整报告,面向计算机视觉初学者、图像处理学习者及高校通信/信息类专业学生,解决物体智能计数与检测结果结构化记录的实际问题。项目覆盖图像预处理、轮廓检测、边界框绘制、轨迹栏交互式参数调节、…

2026/10/17 0:00:25 阅读更多 →

周新闻

流感时间序列预测实战:ARIMA/LSTM全流程拆解与避坑指南

流感时间序列预测实战:ARIMA/LSTM全流程拆解与避坑指南

简介:基于 ARIMA、LSTM、Transformer 等模型的流感时间序列预测 Python 源码,面向计算机相关专业课程设计与期末大作业学生,以及项目实战学习者。内容覆盖预处理、平稳性检验、定阶、残差分析、多模型对比预测的完整时序建模流程,…

2026/10/16 21:35:51 阅读更多 →
影刀RPA新手教程:键盘模拟输入实战——输入文本与模拟按键的区别

影刀RPA新手教程:键盘模拟输入实战——输入文本与模拟按键的区别

影刀RPA新手教程:键盘模拟输入实战——输入文本与模拟按键的区别 做影刀RPA自动化,十个新手有八个栽在"往输入框里填东西"这件事上:要么填不进去,要么填了一半,要么直接把原来内容追加在后面。这背后的根因&…

2026/10/17 1:44:59 阅读更多 →
影刀RPA新手教程:阅文起点小说数据采集实战——书籍信息与章节内容

影刀RPA新手教程:阅文起点小说数据采集实战——书籍信息与章节内容

影刀RPA新手教程:阅文起点小说数据采集实战——书籍信息与章节内容 1. 认识影刀:什么场景该用RPA采小说数据 起点中文网的页面结构相对稳定——分类榜单、书籍详情、章节内容三块独立页面,跳转链路清晰。这种场景非常适合影刀自动化&#x…

2026/10/16 15:04:24 阅读更多 →

月新闻

我发现了一个新思路:用 Remotion + Claude Code 像写代码一样自动化生成短视频

我发现了一个新思路:用 Remotion + Claude Code 像写代码一样自动化生成短视频

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/16 21:54:38 阅读更多 →
Windows下 Codex 中 Chrome 和 Computer Use 插件不可用问题排查及解决参考方式:TaoToken 统一 Key 配置与验证

Windows下 Codex 中 Chrome 和 Computer Use 插件不可用问题排查及解决参考方式:TaoToken 统一 Key 配置与验证

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/16 3:49:43 阅读更多 →
黑夜航拍船只数据集训练YOLOV5模型全流程解析

黑夜航拍船只数据集训练YOLOV5模型全流程解析

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/16 14:23:36 阅读更多 →