小参数模型工具调用的痛点
7B 或 14B 参数量的开源模型在进行多轮复杂工具调用时,经常出现 JSON 格式不闭合、缺少必填参数或臆造工具名的现象。
本文演示如何构造符合 MCP JSON-RPC 规范的微调样本对(Prompt + Tools Definition -> Correct Tool Call -> Tool Result -> Final Answer),并通过参数高效微调(PEFT/LoRA)让小模型在特定垂直业务工具调用上的成功率提升至 95% 以上。
样本从哪里来:优先挖真实日志
最有效的数据不是手写出来的,而是线上会话。把 MCP Server 的调用日志与客户端会话记录导出来,按「一次完整工具事务」切分:注入的工具 Schema、模型应当产生的调用、工具返回、最终答复,四段对齐就是一条样本。清洗时保留三类高价值情况:参数需要从上下文推断的多轮调用、意图相近但工具不同的对照、失败后需要重试或换工具的路径。
{"messages": [
{"role": "system", "content": "可用工具见 tools 字段,需要时必须以工具调用形式返回。"},
{"role": "user", "content": "帮我把订单 A1024 的收货地址改成杭州"},
{"role": "assistant", "content": "{\"name\":\"update_order_address\",\"arguments\":{\"order_id\":\"A1024\",\"city\":\"杭州\"}}"},
{"role": "tool", "content": "{\"ok\":true,\"updated_at\":\"...\"}"},
{"role": "assistant", "content": "已更新订单 A1024 的收货城市为杭州。"}
],
"tools": ["<该会话实际注入的工具 Schema,与推理时保持逐字一致>"]}
上面的字段结构只是示意,实际要以你所用训练框架的对话格式为准。规模上,垂直业务工具的经验值是每个工具 30–50 条正样本起步,再配一定比例的「参数缺失应追问」与「无匹配工具应拒答」样本,否则模型会倾向于硬编一个工具名出来。
训练配置与模板一致性
| 项 | 保守起点 | 加大后 | 风险 |
|---|---|---|---|
| LoRA rank / alpha | 8 / 16 | 16–32 / 2–4 倍 rank | 过大易过拟合并拖慢推理 |
| dropout | 0.05 | 0.1 | 偏低时小数据集易记住原文 |
| 学习率 | 小起点,配 warmup | 逐步上探 | 偏高会破坏原有指令跟随能力 |
| 轮次 | 2–3 | 按验证集早停 | 轮次一多,通用能力先掉 |
最容易被忽略的一条:训练时用的对话模板和工具调用格式,必须与推理侧完全相同。模板不一致时,模型学到的调用标记在服务端解析不出来,表现就是「训练后反而全都不会调工具」,而不是准确率下降。工具数量也别一次给太多,训练里注入多少工具、评测就注入多少,避免记住「总是选第一个」。
训练后怎么验收
准备一份与训练集完全隔离的固定评测集(几十条即可,但要覆盖每个工具和每种失败模式),跑三档指标:JSON 能否被解析、工具名是否命中、参数是否逐字段匹配。只报「看起来变好了」没有意义,要把基线模型、微调后模型、以及减少数据量后的消融结果放在同一张表里对比,并记录每档的推理耗时。
然后把这套评测接进流程:每次改动模型版本或工具 Schema 都跑一遍,任一指标低于基线就不发布。数据、模板、工具 Schema 三者任何一个变了都要重跑,否则线上出现的是「模型没变但行为变了」这类最难查的问题。
常见故障速查
| 现象 | 原因 | 处理 |
|---|---|---|
| 微调后完全不调工具 | 训练与推理模板/调用格式不一致 | 用同一份模板重训,先做单条解码比对 |
| JSON 经常不闭合 | 缺少严格格式样本、解码参数随意 | 补格式样本,限制最大长度、检查停止词 |
| 臆造不存在的工具名 | 只训了正样本,缺拒答样本 | 加入无匹配工具与追问类样本 |
| 通用对话能力明显变差 | 轮次或学习率过高,数据太单一 | 早停、混入通用指令数据 |
| 换客户端就失效 | 工具 Schema 措辞与训练时不同 | 以 Schema 为准固定一份,改字段即重训 |
小结
值得为工具调用做微调的信号很具体:同一个工具反复出现参数缺失或格式错误,且这类错误在评测集上能被稳定复现。此时用几百条对得上模板的样本换取格式稳定,通常比继续堆提示词划算。反过来,如果问题出在「选错工具」而不是「格式错」,先优化工具命名与描述、控制单次注入的工具数量,这比训练更便宜。