最近在做一个内部工具调用的微调项目,基于Qwen2.5-7B,用MCP协议连了十几个内部API。训练数据是真实的调用日志,清洗后大概2万条,喂了3个epoch,loss降得挺快,但实际推理时有个很头疼的问题:模型经常把工具参数的类型搞错,比如把字符串填成数组,或者漏掉必填字段。我试过在system prompt里加强格式说明,也试过few-shot,但效果不稳定。想问问有经验的朋友,这种问题一般是训练数据里负样本不够,还是说7B模型本身就不太适合这种需要严格约束输出的任务?如果换更大的模型或者用function calling的专用模型,会好很多吗?
MCP微调后总把工具参数填错,是数据问题还是模型架构该换?
全部回复
共 84 条2万条数据3个epoch大概率过拟合了,loss降得快不代表泛化好。参数类型填错这种问题,我更倾向是训练数据里缺“边界case”的负样本,比如同个字段在不同场景下类型不一样的情况,模型没见过就容易瞎填。另外7B做严格schema约束确实吃力,可以试试在推理层加个校验重试机制兜底,比硬调模型划算。换32B或者专门的function calling模型会有改善,但数据侧的坑不填上,大模型照样翻车。
2万条真实日志微调7B模型,参数类型错误这种问题我踩过类似的坑。我当时的体会是,数据里“正确调用”占绝对多数时,模型学到的是“大概该调哪个工具”,但对参数结构的约束其实没真正内化,因为loss主要来自token层面的拟合,格式错了未必惩罚够重。你可以先检查一下训练集里有没有刻意构造的负例,比如类型填错、漏字段的样本,并且这些负例的label要是明确的纠错信号,而不是简单丢掉。另一个容易被忽略的点是MCP那层schema有没有在训练时作为强约束输入进去,如果只是把工具描述塞进prompt,7B模型确实容易在生成时漂移。换更大的模型或者专门的function calling模型会有帮助,但不是万能药,因为核心还是监督信号有没有覆盖“结构合法性”这件事。我建议先做个消融:固定数据,只把schema用更结构化的方式注入,看错误率降不降;如果不降,再考虑换模型或者上constrained decoding。另外推理时用grammar/JSON schema约束解码,往往比重新训一版来得快。
我之前也遇到过类似问题,后来换了方案。
2万条真实日志微调3个epoch,loss降得快但参数类型乱填,这个现象挺典型的——模型学到的是“调用意图”而不是“参数约束”,真实日志里大概率大部分调用都是成功的,负样本几乎为零,模型没见过填错被纠正的场景,自然对类型边界不敏感。system prompt和few-shot不稳定也正常,7B在长上下文里对格式指令的服从性本来就飘。我建议先别急着换模型,把训练数据改造一下:从成功日志里人工构造参数类型错误、漏字段的样本,配上“修正后”的目标输出,让模型学会自我检查这一步,同时把工具schema以结构化形式拼进输入而不是只靠prompt描述。另外检查一下推理时是不是用了约束解码或者JSON schema校验,如果全靠模型裸生成,7B确实容易翻车。换更大的模型会有帮助但成本不低,function calling专用模型在参数严格性上确实更强,不过内部API的schema适配可能又得折腾一轮,可以先试试数据侧和推理侧的改动再决定。