本地模型能对话了,但一让它查数据库、调天气接口、读本地文件就卡住——多半不是模型不行,是没把工具协议这层接上。这篇给已经跑通推理服务的开发者一条路径:先分清函数调用和工具协议各自管什么,再按你的推理框架挑接入方式,最后用一张清单把调不通的常见原因逐个排掉。不涉及具体模型版本和跑分,那些数字到站内模型库和测评榜单核对即可。
本地模型能对话了,可一让它查数据库、调天气接口、读本地文件就卡住,这时候先别怀疑模型能力。多数情况不是模型不行,而是中间那层「意图翻译成结构化参数、代码再去执行」的接线没搭起来。这篇不讲概念史,只给一条可执行的路径:先分清接的是哪一层,再按推理框架选接法,最后拿一张清单把调不通的原因逐个排掉。
需要提醒一句:下面所有判断都不涉及具体模型版本和跑分。你手上那套推理服务到底适不适合上工具,得看它实际的指令跟随和结构化输出表现,这类数字请到 /rankings 和 /models 按其时更新的资料核对,别拿记忆里的旧结论套。
先分清你要接的是哪一层:函数调用、工具协议还是外部服务
- 函数调用
- 模型只负责吐出一段结构化参数,真正发请求、连数据库的动作全部由你的代码完成
- 工具协议
- 解决工具怎么被发现、怎么跨客户端复用的问题,适合工具多或要给多个前端共用
- 外部服务接入
- 执行层的事,数据库、检索、HTTP 接口都在这一层,协议只把意图送过去
- 函数调用不等于模型自己去调接口,别指望它绕过你的后端直接联网,权限和鉴权始终在代码里
- 工具协议的收益随工具数量增长,三五个工具时它带来的抽象成本往往比收益大
- 外部服务的稳定性和模型无关,接工具前先确认接口本身有没有超时和限流,否则排查方向会跑偏
- 判断标准:工具不超过三五个、只在自家程序里用,直接写函数调用;工具有十几个、还要给多个前端复用,再上协议层
- 不适用的情况:如果你的「工具」其实只是一个固定查询,参数永远不变,那写死在代码里比让模型生成更稳
把输出格式约束住:结构化输出的三条硬要求
接工具的失败,一大半死在格式上。模型不是不会调,而是它吐出来的那串东西你的解析器认不出来。所以工具清单和输出约束要当成接口文档来写,而不是在提示词里随口提一句。
- 工具清单必须写全三样:名字、用途一句话、参数类型与必填项,缺任何一项都会导致模型瞎填参数
- 输出用 JSON Schema 或推理框架自带的结构化输出参数来约束,只在提示词里写「请返回 JSON」在本地小模型上基本靠运气
- 工具数超过十个就分组,或者做二级路由:先让模型选类别,再在类别里选具体工具,能明显降低串参数概率
- 参数里凡是枚举值,全部列出来,别让模型自由发挥字符串
- 不适用的情况:任务只需一次固定调用且参数不变,直接后端写死,绕一圈让模型生成反而多一个故障点
| 常见毛病 | 大概原因 | 先改哪里 |
|---|---|---|
| 返回里夹着解释文字 | 提示词没约束住,或框架没开结构化模式 | 打开框架的结构化输出参数,再加一条只输出 JSON 的约束 |
| 参数名对不上 | 工具清单里的字段名和解析代码不一致 | 以代码里的字段名为准,回改工具描述 |
| 必填参数给空值 | 描述里没标必填,或工具用途写得含糊 | 补必填标记,把用途写成一句人话 |
| 长清单下选错工具 | 工具太多、描述太像 | 分组或二级路由,顺手把相似工具合并 |
按你的推理框架选接法:三类常见路子
同样是接工具,不同推理框架给的接口差别很大。硬套别人的写法,往往在字段名和返回结构上卡半天。先认清你属于哪一类,再选最短的那条路。
- 确认框架认不认工具字段查你用的推理服务文档里有没有 tools / functions 这类参数。认的话,直接复用官方 SDK 的写法最快,连解析都省了。
- 不认就做两段式第一轮让模型只输出意图和参数,你的代码解析后执行,再把执行结果拼回对话做第二轮。验证方法是把两轮原始返回都打日志,看清哪一轮开始偏。
- 用了 Agent 框架就别再手写一层多数 Agent 框架自带工具注册、重试和循环控制。你在外面再包一层,很容易出现同一工具被调两次的情况。
- 先量延迟基线动手前到 /tools/speed-test 量一下你接口的响应基线。工具体系会把往返次数翻倍,基线本身慢的方案,接完工具基本没法用。
调不通时的排查顺序:从参数到超时逐层看
调不通的时候最容易乱改,一会儿改提示词一会儿换模型。按下面这个顺序从里往外排,大部分问题在前两步就能定位,不用动模型。
- 第一看模型到底吐了什么:把原始返回完整打日志,多数问题是参数名对不上,或者外面套了多余的说明文字
- 第二看 Schema 有没有被框架截断:工具描述太长时,部分实现会把参数定义截掉,表现就是必填项突然消失
- 第三看执行层:权限、网络、超时,本地模型响应慢时尤其容易在第二轮往返里超时
- 第四看多轮循环有没有出口:工具连续报错要有最大轮次限制,不然会一直重试把上下文烧满
- 排查完仍不稳的,退回「单工具加固定参数」的最小可用版本,确认通了再一个一个加回去
| 现象 | 优先怀疑 | 验证动作 |
|---|---|---|
| 第一轮就报解析失败 | 输出格式没约束住 | 打印原始返回,看是不是夹了说明文字 |
| 参数解出来是空的 | Schema 被截断或字段名不一致 | 比对工具描述和解析代码的字段名 |
| 第二轮必超时 | 执行层慢或循环没出口 | 单独压测那个外部接口的响应时间 |
| 偶尔调错工具 | 工具描述太相似或数量过多 | 把相似工具合并或分组 |
| 多轮后上下文爆掉 | 报错重试没有轮次上限 | 加最大轮次,并在超限时直接返回错误 |
什么情况下不该接工具,以及必须加的两道闸
不是所有场景都值得上工具。模型本身指令跟随弱、经常忽略工具约束时,硬上生产只会把故障点从模型挪到你的代码里。这种阶段用固定流程脚本更可靠,等指令跟随稳了再接。
- 涉及写操作的工具有两类要拦:改数据库、动本地文件,一律加人工确认或白名单,不要让模型直接执行
- 每次调用的入参出参都记下来,出问题时这是唯一能复盘的东西,日志别只记成功的那几次
- 工具多了以后权限要按调用方隔离,同一个进程里谁都能调所有工具,是本地部署最常见的风险口
- 给每个工具设一个调用频率上限,防止模型陷入循环时把外部接口打爆
- 不适用的情况:纯读的、幂等的查询类工具可以放宽,但只要有副作用,确认和白名单就别省
接工具的能力上限,取决于执行层给你的权限;先把权限收小,再谈让模型多干点活。下一步把你当前这套推理服务的延迟、稳定性和工具支持情况过一遍,再决定走原生字段还是两段式。站内的中转站可信度检测和价格追踪页面能帮你判断长期跑工具时的成本和稳定性风险,具体数字以页面当时显示的为准。→
常见问题
本地模型不支持 function calling 字段,还能接工具吗
能。退回两段式:第一轮让模型按约定格式输出意图和参数,你的代码解析执行,第二轮把执行结果拼回上下文再问一次。代价是多一次往返,好处是不依赖框架能力,任何能稳定输出文本的模型都能用。参数格式要在提示词里写死并给一两个示例。
工具接上以后模型老是乱调,是不是得换个更大的模型
先别急着换。多数乱调来自工具描述含糊、工具数量过多或参数没有类型约束。先把工具压到五个以内、每个描述写清什么时候用和什么时候不用,再看效果。仍不行才考虑换模型,具体哪个模型适合这类任务可以到站内测评榜单和模型库按当时的评测数据核对。
接工具之后延迟翻倍,正常吗
基本正常,一次工具调用至少两轮模型推理加一次外部请求。要压下来就三件事:把工具描述缩短、并行执行互不依赖的调用、给外部接口设短超时并允许失败降级。上线前建议先到站内测速页量出无工具时的延迟基线,再对比接入后的数字,才知道是模型慢还是外部接口慢。