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

LLM 是如何学会调用外部工具的?

前言:

• 预训练让模型学会语言,但不会天然学会可执行的工具调用。

• SFT 让模型见过标准工具调用样本,学会按 schema 输出结构化 tool_calls。

• RLHF/RLAIF 让模型学会边界感:该调才调,不该调就直接回答。

• 上线运行时,模型只负责决策;真正执行工具的是你的应用代码。

一、它不是“学会用 API”,而是“学会写调用单”

很多人一听工具调用,就以为模型真的拿到了浏览器、数据库、支付接口的执行权。其实不是。模型本质上还是在生成文本,只不过这次生成的不是普通聊天内容,而是一段机器能看懂的结构化调用请求。

可以把工具调用理解成外卖系统:用户说“帮我点杯拿铁”,大模型不是自己去咖啡店买,而是写出一张订单:商品是拿铁、数量是 1、地址是某处。真正下单、支付、配送的是外卖平台的程序。

所以工具调用最关键的分工是:模型负责理解意图和写调用单;代码负责校验调用单、执行工具、拿回结果,再把结果交给模型总结。

二、预训练为什么不够?

预训练阶段的目标很简单:给模型一大段文本,让它预测下一个 token。这个过程能让模型学会语言、知识和推理模式,但它并不知道你的生产系统里有哪些函数,也不知道这些函数的参数格式。

即使模型在互联网上见过很多 API 文档,也不等于它会稳定输出你的系统要求的 JSON。因为工具调用不是“懂 API 名字”这么简单,而是要做到三件事:识别何时需要工具、选对工具、按严格格式填对参数。

这就是为什么光靠参数规模不够。工具调用能力需要专门训练,也需要运行时约束。小林面试笔记这章也强调:工具调用不是大模型自然涌现出来的能力,而是通过 SFT、RLHF 和 Function Calling 机制组合出来的能力。

三、SFT:先让模型“见过正确答案”

SFT 可以理解成带答案的模仿学习。你给模型看很多标准样本:用户怎么问、系统有哪些工具、正确的 tool_calls 应该怎么写、工具结果回来后应该怎么回答。模型看多了,就学会了这种固定套路。

它解决的是“会不会调”的问题。比如看到“北京今天天气怎么样”,模型要学会这不是普通常识问答,而是需要实时数据,于是输出 get_weather 的调用请求,而不是编一个天气。

一条高质量训练样本,通常不是一问一答,而是一整段轨迹:System 工具说明、User 用户问题、Assistant 结构化调用、Tool 工具结果、Assistant 最终回答。

四、训练样本里的关键:正确答案不是一句话,而是 tool_calls

如果训练答案只是“我需要调用天气接口”,程序还是没法执行。真正有用的是下面这种结构化结果:

JSON:模型应该输出的调用请求

{"tool_calls":[{"name":"get_weather","arguments":{"city":"北京","unit":"celsius"}}]}

这段 JSON 的价值在于:宿主程序能稳定读到函数名和参数,然后走白名单、鉴权、参数校验,最后才真正执行 API。

五、RLHF / RLAIF:教模型建立边界感

SFT 有一个天然问题:它让模型学会了调用工具,但容易把模型训练得过于积极。别人问“1+1 等于几”,它也可能想调用计算器;别人让它写一段祝福语,它也可能想调用搜索。

这就需要 RLHF 或 RLAIF。它们的核心不是再教格式,而是用反馈告诉模型:哪种行为更合理。该直接回答的时候直接回答,该查实时数据的时候才查工具,工具失败时要诚实说明,而不是继续硬编。

如果说 SFT 是“新员工看模板学会填工单”,那 RLHF 就是“主管不断点评,告诉他什么时候该走流程,什么时候别浪费流程”。

SFT 解决格式问题,RLHF/RLAIF 解决边界问题。

六、Function Calling:训练好之后,运行时怎么落地?

上线以后,模型不是带着所有工具到处跑。每一次请求,应用程序都会把当前允许使用的工具说明传给模型。模型根据用户问题和工具说明,决定是否输出 tool_calls。

当模型输出 tool_calls 后,它的工作就暂停了。接下来由宿主程序解析 JSON,检查工具是否在白名单内,检查参数是否合法,检查当前用户有没有权限。通过后,程序才真正调用 API、数据库、搜索或代码执行环境。

工具结果返回后,宿主程序把结果作为 tool_result 放回对话,再让模型组织成人能看懂的回答。这套“模型决策、代码执行、结果回传”的链路,就是 Function Calling 的运行时机制。

七、工具 Schema 要写清楚,模型才不容易乱用

Schema 可以理解为工具说明书。它告诉模型:这个工具叫什么、什么时候用、需要哪些参数、参数范围是什么。OpenAI 文档里也建议 strict 模式,让函数调用更可靠地遵守 schema;Structured Outputs 文档还强调,schema 约束比普通 JSON mode 更能保证结构一致。

JSON:一个更规范的工具定义

{"type":"function","function":{"name":"get_weather","description":"查询指定城市的实时天气。只在用户询问当前天气时使用。","strict":true,"parameters":{"type":"object","properties":{"city":{"type":"string","description":"城市名称,例如:北京、上海"},"unit":{"type":["string","null"],"enum":["celsius","fahrenheit", null]}},"required":["city","unit"],"additionalProperties":false}}}

八、到底什么时候该调工具?

判断逻辑可以很简单:如果问题依赖实时信息、外部系统、精确计算或业务动作,就倾向于调用工具;如果是稳定知识、解释、创作和简单问答,就直接回答。

工具调用不是越多越好。每一次工具调用都会增加成本、延迟和失败概率。一个成熟的 Agent,不是疯狂调工具,而是该调时稳准狠,不该调时安静回答。

九、运行时代码必须兜底,不能完全相信模型输出

下面这段伪代码展示了正确思路:模型输出只是建议,真正执行前必须经过白名单、参数校验、权限校验和异常处理。

Python:工具执行前的最小安全兜底

ALLOWED_TOOLS={"get_weather":get_weather}REQUIRED_ARGS={"get_weather":["city","unit"]}def execute_tool_call(tool_call, user): name=tool_call["name"]args=tool_call.get("arguments",{})ifname notinALLOWED_TOOLS: raise ValueError("tool is not allowed")forkeyinREQUIRED_ARGS[name]:ifkey notinargs: raise ValueError(f"missing argument: {key}")ifnot user.can_use(name): raise PermissionError("no permission to call this tool")try:returnALLOWED_TOOLS[name](**args)except TimeoutError:return{"error":"tool timeout, please try again later"}

这才是生产系统里最关键的一层:不要让模型直接碰数据库、支付接口、文件系统或生产环境。它只负责输出结构化意图,执行权必须握在代码手里。

十、常见翻车点和治理办法

工具调用项目真正难的地方,往往不是模型能不能输出 JSON,而是上线以后能不能稳定、可控、可追踪。下面这些问题非常常见。

十一、工程落地清单

第一,工具描述要清楚。尤其是 description,要写明“什么时候用”和“什么时候不要用”,否则模型很容易误触发。

第二,schema 要严格。尽量使用 required、enum、additionalProperties=false、strict=true 等约束,降低模型瞎填参数的空间。

第三,工具数量要控制。一次性塞给模型几十个相似工具,会明显增加选错工具的概率。可以按场景动态注入工具。

第四,所有高风险动作都要二次确认。发邮件、删除文件、转账、下单、改配置等动作,不能让模型一句话直接执行。

第五,必须做日志和评估。记录每次问题、工具选择、参数、工具结果、最终回答和失败原因,后续才能复盘优化。

十二、一个最简单的判断示例

同样是用户提问,有些问题不需要工具,有些必须工具。把边界讲清楚,模型才会更稳。

示例:该直接答就直接答,该调用才调用

# 不需要工具
User: 1 + 1 等于几?
Assistant: 2。
# 需要工具
User: 北京现在天气怎么样?
Assistant tool_calls:
name: get_weather
arguments: {"city": "北京", "unit": "celsius"}
# 工具失败时不要硬编
Tool result: {"error": "timeout"}
Assistant: 我现在没能查到实时天气,可以稍后再试。

十三、面试怎么回答最稳?

如果面试官问:LLM 是如何学会调用外部工具的?不要只回答 Function Calling。Function Calling 是运行时机制,不是训练方法。完整答案要同时讲训练层和运行层。

训练层:SFT 用工具调用样本教模型输出格式,RLHF/RLAIF 用反馈教模型建立边界感。

运行层:应用把工具 schema 传给模型,模型输出 tool_calls,宿主程序执行工具,再把 tool_result 回传给模型生成最终回答。

**关键认知:**模型不是执行器,模型是决策器。真正执行工具、控制权限、处理异常的,永远是宿主程序。

内容来源:LLM 是如何学会调用外部工具的?

http://www.jsqmd.com/news/1100725/

相关文章:

  • 【Claude Code】----Claude Code 全套高效开发实战技巧|16个实战高效技巧,程序员必看AI编程提效干货
  • 学习C语言的第十三天06.29
  • 怎么给电脑加密?分享这6款热门电脑加密软件,公认好用
  • 别再只用sleep了!C语言里usleep和nanosleep的实战用法与毫秒级休眠封装
  • 无需专业CAD,轻量化CAD看图绘图工具就够了
  • 保姆级教程:用Cache模拟器手把手理解多核CPU的数据一致性(附避坑指南)
  • 从零开始:用Luckfox Pico Pro Max开发板(RV1106)搭建一个简易网络摄像头
  • 初代剧粉集体脱坑:短剧的精品化,真的错了吗?
  • 从玩具项目到产品原型:我是如何用EasyVision快速搭建一个人脸打卡Demo的
  • 3分钟掌握G-Helper:华硕笔记本轻量控制工具的终极指南
  • 保姆级教程:用Ansys Zemax OpticStudio搞定单模光纤耦合效率分析(附避坑指南)
  • 方寸感知战场:MEMS IMU 在坦克中的实战价值
  • 保姆级教程:用EMQX和MQTTX从零搭建你的第一个物联网消息系统(Windows环境)
  • AI高薪神话褪去,普通人如何构建工程化能力应对行业新常态
  • PUBG罗技鼠标压枪宏:5分钟快速配置终极指南
  • 如何为嵌入式系统打造高效图像与字体资源生成器:LCD Image Converter深度解析
  • 别再盲目训练模型了!用PyTorch的EarlyStopping回调函数,5分钟搞定早停策略
  • 终极指南:如何用SuperPNG插件优化Photoshop PNG输出质量
  • Mi-Create终极指南:为小米穿戴设备创建个性化表盘的完整教程
  • VMware NAT端口无法访问?这6种隐藏原因90%工程师从未检查过——含DHCP租期冲突、host-only适配器优先级、防火墙链顺序详解
  • acme.sh:用 Shell 脚本搞定 SSL 证书申请和续期
  • 亮相 MWC2026,YunSDR 赋能NTN网络测试及科研原型落地
  • 告别单调地图!用ArcGIS Pro给要素弹窗加图片的3种方法全解析(附HTML排版技巧)
  • 霞鹜文楷:如何用一款开源字体改变你的数字阅读体验?
  • 手把手教你用ATGM332D-5N31模块DIY一个高精度GPS/北斗定位器(附STM32代码)
  • Codex:从AI代码补全到智能体开发平台的演进与实践指南
  • YOLOv10模型改进-卷积层改进-第14篇:YOLOv10改进策略【卷积层】| MobileNetV3深度可分离卷积
  • 手把手教你用STM32F429+FreeRTOS+CycloneTCP做个开源SIP电话(附代码和避坑指南)
  • STC89C52单片机密码锁DIY:从Proteus仿真到面包板搭建的完整避坑指南
  • iOS 崩溃日志分析与定位 从手动符号化到自动分析