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

发布时间:2026/7/1 6:05:01
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 有一个天然问题它让模型学会了调用工具但容易把模型训练得过于积极。别人问“11 等于几”它也可能想调用计算器别人让它写一段祝福语它也可能想调用搜索。这就需要 RLHF 或 RLAIF。它们的核心不是再教格式而是用反馈告诉模型哪种行为更合理。该直接回答的时候直接回答该查实时数据的时候才查工具工具失败时要诚实说明而不是继续硬编。如果说 SFT 是“新员工看模板学会填工单”那 RLHF 就是“主管不断点评告诉他什么时候该走流程什么时候别浪费流程”。SFT 解决格式问题RLHF/RLAIF 解决边界问题。六、Function Calling训练好之后运行时怎么落地上线以后模型不是带着所有工具到处跑。每一次请求应用程序都会把当前允许使用的工具说明传给模型。模型根据用户问题和工具说明决定是否输出 tool_calls。当模型输出 tool_calls 后它的工作就暂停了。接下来由宿主程序解析 JSON检查工具是否在白名单内检查参数是否合法检查当前用户有没有权限。通过后程序才真正调用 API、数据库、搜索或代码执行环境。工具结果返回后宿主程序把结果作为 tool_result 放回对话再让模型组织成人能看懂的回答。这套“模型决策、代码执行、结果回传”的链路就是 Function Calling 的运行时机制。七、工具 Schema 要写清楚模型才不容易乱用Schema 可以理解为工具说明书。它告诉模型这个工具叫什么、什么时候用、需要哪些参数、参数范围是什么。OpenAI 文档里也建议 strict 模式让函数调用更可靠地遵守 schemaStructured 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): nametool_call[name]argstool_call.get(arguments,{})ifname notinALLOWED_TOOLS: raise ValueError(tool is not allowed)forkeyinREQUIRED_ARGS[name]:ifkey notinargs: raise ValueError(fmissing 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、additionalPropertiesfalse、stricttrue 等约束降低模型瞎填参数的空间。第三工具数量要控制。一次性塞给模型几十个相似工具会明显增加选错工具的概率。可以按场景动态注入工具。第四所有高风险动作都要二次确认。发邮件、删除文件、转账、下单、改配置等动作不能让模型一句话直接执行。第五必须做日志和评估。记录每次问题、工具选择、参数、工具结果、最终回答和失败原因后续才能复盘优化。十二、一个最简单的判断示例同样是用户提问有些问题不需要工具有些必须工具。把边界讲清楚模型才会更稳。示例该直接答就直接答该调用才调用# 不需要工具User: 1 1 等于几Assistant: 2。# 需要工具User: 北京现在天气怎么样Assistant tool_calls:name: get_weatherarguments: {city: 北京, unit: celsius}# 工具失败时不要硬编Tool result: {error: timeout}Assistant: 我现在没能查到实时天气可以稍后再试。十三、面试怎么回答最稳如果面试官问LLM 是如何学会调用外部工具的不要只回答 Function Calling。Function Calling 是运行时机制不是训练方法。完整答案要同时讲训练层和运行层。训练层SFT 用工具调用样本教模型输出格式RLHF/RLAIF 用反馈教模型建立边界感。运行层应用把工具 schema 传给模型模型输出 tool_calls宿主程序执行工具再把 tool_result 回传给模型生成最终回答。**关键认知**模型不是执行器模型是决策器。真正执行工具、控制权限、处理异常的永远是宿主程序。内容来源LLM 是如何学会调用外部工具的