AgentHubAgentHub
返回全部博客

针对 MCP 工具调用微调本地轻量大模型:数据集构造与 LoRA 训练全流程

AgentHub 核心团队··5 分钟阅读·51 次阅读
针对 MCP 工具调用微调本地轻量大模型:数据集构造与 LoRA 训练全流程

小参数模型工具调用的痛点

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 / alpha8 / 1616–32 / 2–4 倍 rank过大易过拟合并拖慢推理
dropout0.050.1偏低时小数据集易记住原文
学习率小起点,配 warmup逐步上探偏高会破坏原有指令跟随能力
轮次2–3按验证集早停轮次一多,通用能力先掉

最容易被忽略的一条:训练时用的对话模板和工具调用格式,必须与推理侧完全相同。模板不一致时,模型学到的调用标记在服务端解析不出来,表现就是「训练后反而全都不会调工具」,而不是准确率下降。工具数量也别一次给太多,训练里注入多少工具、评测就注入多少,避免记住「总是选第一个」。

训练后怎么验收

准备一份与训练集完全隔离的固定评测集(几十条即可,但要覆盖每个工具和每种失败模式),跑三档指标:JSON 能否被解析、工具名是否命中、参数是否逐字段匹配。只报「看起来变好了」没有意义,要把基线模型、微调后模型、以及减少数据量后的消融结果放在同一张表里对比,并记录每档的推理耗时。

然后把这套评测接进流程:每次改动模型版本或工具 Schema 都跑一遍,任一指标低于基线就不发布。数据、模板、工具 Schema 三者任何一个变了都要重跑,否则线上出现的是「模型没变但行为变了」这类最难查的问题。

常见故障速查

现象原因处理
微调后完全不调工具训练与推理模板/调用格式不一致用同一份模板重训,先做单条解码比对
JSON 经常不闭合缺少严格格式样本、解码参数随意补格式样本,限制最大长度、检查停止词
臆造不存在的工具名只训了正样本,缺拒答样本加入无匹配工具与追问类样本
通用对话能力明显变差轮次或学习率过高,数据太单一早停、混入通用指令数据
换客户端就失效工具 Schema 措辞与训练时不同以 Schema 为准固定一份,改字段即重训

小结

值得为工具调用做微调的信号很具体:同一个工具反复出现参数缺失或格式错误,且这类错误在评测集上能被稳定复现。此时用几百条对得上模板的样本换取格式稳定,通常比继续堆提示词划算。反过来,如果问题出在「选错工具」而不是「格式错」,先优化工具命名与描述、控制单次注入的工具数量,这比训练更便宜。

延伸阅读

推荐阅读

实战教程

为什么 AI 读错截图里的数字:它拿到的图比屏幕上那张小得多

你把截图原图丢给 AI,它把 9,847 读成 9,347,或者把发票上一行小字整段编出来。原因大概率不在「眼神」,在尺寸:Claude 官方明写它按 28×28 的像素块看图,每块算一个视觉词元,超过上限的图会先缩小;1920×1080 压到 1456×819,你屏幕上 12 像素的小字到它眼里只剩 9.1 像素,而 4K 截图压完和 1080p 一模一样大——分辨率白涨了。这篇给出三张能自己复算的数:面积、字高、词元。最有用的结论反直觉:别放大整张图,裁一块再发——600×400 的局部不缩、字高完整保留、只付 330 个词元,比整张的 1,560 还便宜 4.7 倍。另附一个扫描口径:论文实测约 300ppi 追平传统 OCR、150ppi 以下明显退化,而 9.1 像素的字折算下来只有 62ppi。

实战教程

为什么同一个问题问 AI 两遍,答案不一样:它不是在算答案,是在按概率抽一个词

同一句话原封不动问两遍,AI 的措辞不一样、甚至结论不一样。原因不是它心情不好:它每步拿到的不是一个答案,而是「一整排候选加各自的概率」,然后从中抽一个,连抽几百次就是一篇回答。这篇把「温度」讲回它的本义——softmax 公式里那个除号(Hinton 原话「T 是通常设为 1 的温度」「T 越大概率越平」),再给三张你我能自己复算的表:同一排候选,温度 0 抽一千次只出 1 种结果、0.2 出 2 种、2.0 时最冷门的词已占 7.35%;每个词有九成把握一致,写到 50 个词整段逐字一致的概率只剩 0.5%;单次七成答对的模型,抽九次投票变 90.1%(谷歌 Self-Consistency 论文实测 GSM8K +17.9 个百分点)。最关键的一条纠正:温度调到 0 官方也不保证复现——Anthropic 明写它「从未保证输出相同」,微软 Azure 的 seed=42 自家示例第三遍照样变了。还有一个 2026 年的现在时:Kimi 固定 1.0、传其他值报错,Gemini 新模型直接忽略,Claude 新代传非默认值返回 400,大厂正在把这些旋钮拆掉。

实战教程

为什么 AI 数不清 strawberry 里有几个 r:它看到的不是十个字母,是三块

问 ChatGPT「strawberry 里有几个 r」,它常常答 2。原因不是笨,而是它根本没收到十个字母——我用官方分词库实测,strawberry 在三本不同词表里都是三块:st / raw / berry,三个 r 分散在其中两块里,而「逐块拆开再累加」这个动作从来没被训练过。这篇用「矗字里有几个直」讲清这件事,再给你四个自己跑得出来的数:同一句 17 个汉字,老词表切 34 块、新词表切 15 块;站内一篇 5,500 汉字的中文稿实测 7,112 块,约 0.77 汉字一块,换本词表变 9,491 块、多算 33%(和 Anthropic 官方那句「约 30 percent more tokens」对得上);9.11 之所以比 9.9 大,是因为它看到的是整块「11」。也有一条必须纠正的流行说法:分词不是唯一原因,arXiv 三篇论文给的图景更麻烦,而「换了 tokenizer 就修好了」厂商从未公开解释过。

实战教程

冬天掉的电会还给你,夏天掉的不会:笔记本电池的两条账

冬天续航从六小时掉到三小时,进屋放一会儿又涨回来——这不是电池冻坏了,而是低温让你“暂时取不出”那部分电。Battery University 的 BU-502 给的数是:同一块电池在 27°C 能放出 100%,到 -18°C 只放得出约 50%。真正不会还给你的是另外三件事:高温、长期满电、低温充电。而“充到 80% 更耐用”也有代价——BU-808 的表写明 4.20V(充到 100%)大约 300–500 次循环,压到 4.00V 能到 1,200–2,000 次,但每次能用的电量也更少。这篇把八家厂商(微软、苹果 iPhone、苹果 Mac、华硕、戴尔、三星、谷歌、联想)的官方充电上限摆在一起,讲清“电池健康 87%”是怎么算的、为什么 0°C 以下不要充电,以及充电宝上的 3C 为什么是 2024 年才强制的。

探索更多生产力神器

不想只停留在理论?立即体验下一代 AI 工具与 MCP 插件

收录 ChatGPT 6、Claude 3.7、Devin 等热门 AI,以及 3000+ 开发者开源 MCP 插件与一键安装脚本。