最近在试着用qwen2.5-7b(本地跑)搭一个简单的Agent,就是让它调用天气API和日历API做日程提醒。结果发现工具调用成功率特别低,有时候参数格式不对,有时候模型直接不调用工具就开始瞎编。我按官方文档写了function calling的格式,也试了temperature调低到0.1,但还是不稳定。想问下大家,是qwen2.5本身对工具调用支持不够好,还是我少配了什么prompt模板?或者有没有更稳的7B级别开模型推荐?感谢!
用开源模型搭Agent,工具调用老是崩,是qwen2.5的问题还是我姿势不对?
全部回复
共 146 条说实话qwen2.5的function calling我试下来确实有点看运气,特别是7B这个规模,模型对工具调用的“意图边界”有时候很模糊,参数多一两个或少一两个就崩。我之前也踩过类似的坑,后来发现一个关键点:官方给的示例格式只是基础,实际跑的时候得把每个工具的description写得更“啰嗦”一点,比如明确告诉它“这个参数是YYYY-MM-DD格式,别给我传时间戳”,不然它真会自己发挥。另外你提到temperature 0.1,我建议干脆设到0,然后加上repetition penalty稍微调高,能减少瞎编概率。还有个小技巧是,在system prompt里把“如果你不确定,就调用工具获取实时数据”这种话写死,它会更倾向于走工具而不是编造。至于更稳的模型,可以试试glm-4-9b-chat,它官方对tool use的fine-tune做得更细,但也要注意它有时会多调一次工具返回空结果。如果你愿意折腾,用llama3.1-8b配一个专门优化过的tool-use prompt模板,效果可能比qwen稳,但推理速度会慢一点。最后想问你,你用的是vLLM还是llama.cpp跑的?不同推理后端对工具调用的logits处理也有影响,我之前换到vLLM后成功率明显提了一截。
7B模型做工具调用本来就有点勉强,qwen2.5的function calling在7B这个尺寸上确实不如14B或72B稳定,我试过同样的问题,它经常把工具参数里的字符串类型搞混,比如日期格式传成数组或者漏掉必填字段。你调低temperature是对的,但光这个不够,我后来是把system prompt里工具描述写得特别细,每个参数都加示例值,甚至把“如果不确定就调用工具”这句话反复强调,成功率才上来一点。另外你本地部署的话,推理框架也有影响,vLLM和llama.cpp的采样逻辑不一样,有时候换一下后端,tool call的格式错误就少很多。要是想换模型,可以看看functionary或者glm-4-9b-chat,这两个在7B级别对工具调用的支持比qwen2.5要专门优化过,尤其functionary的tool格式设计得更贴近实际agent场景。不过说实话,真要稳定跑生产,还是得用API版的qwen-plus或者gpt-4o-mini,本地7B当玩具玩玩可以,别指望它每次都规规矩矩。你那个天气API和日历调用,是不是没加“当前时间”的上下文?模型经常因为不知道现在几点,就随便填个时间戳进去,我加了个实时时间字段后,日历这块好了非常多。
qwen2.5的tool calling确实弱,试试加个ReAct格式的system prompt,或者直接换glm-4-9b-chat。
我之前也踩过这个坑,qwen2.5的function calling对格式要求挺死的,尤其是参数嵌套一深就容易崩。你可以试试在system prompt里把每个工具的参数schema用JSON Schema的完整形式写清楚,再给个few-shot示例,效果会好不少。另外,7B这个级别想稳定调工具,其实更推荐试下glm4-9b或者yi-1.5-9b,它们对工具调用的指令遵循性调教得更好,我自己换过去后成功率明显上来了。
试试给工具加个few-shot示例,qwen2.5对格式理解会好很多,我之前也踩过这坑。
我之前也卡在qwen2.5的工具调用上,后来发现是system prompt里没把工具描述写清楚,尤其是参数类型和必填项,模型容易理解偏。你可以试试把工具定义写成类似JSON schema的详细格式,再给一两个few-shot示例,成功率会明显上去。另外7B级别的话,glm-4-9b-chat对function calling的支持我觉得比qwen稳一些,你可以对比下。温度0.1确实够了,但有时候采样方式换成top_p=0.9反而更听话。
qwen2.5的function calling确实有点看运气,我试过它经常把参数类型搞混,尤其是嵌套对象。你可以试试把工具描述写得更啰嗦一点,比如每个参数都加示例值,我这么改完成功率能提两三成。另外,7B级别里glm4-9b-chat的工具调用会稳一些,不过偶尔也会犯懒不触发。你本地部署用的什么推理框架?vllm和llama.cpp对tool的支持差别还挺大的。
qwen2.5-7b在工具调用上确实有点看运气,参数格式错多半是system prompt里没把工具schema写清楚,建议把每个参数的类型和必填性都显式列出来,别省。另外你试试把模型输出先强制成JSON再解析,别让它自由发挥。7B里其实glm-4-9b-chat的工具调用比qwen稳一些,或者直接上qwen2.5-14b,本地显存够的话差距挺明显的。
试试把工具描述写详细点,qwen对格式挺敏感,另外看看是不是max_tokens设太小把调用截断了。
qwen2.5-7b在function calling上确实偏弱,尤其本地量化后更明显,参数格式崩是常态,建议先试试官方推荐的Qwen2.5-7B-Instruct版别用base。另外你temperature调到0.1是对的,但最好把工具描述写得更死板一点,比如强制要求“必须输出JSON且key名严格匹配”,不然模型容易自由发挥。我最近换了glm-4-9b-chat,同样7B级别但工具调用稳不少,你可以对比下。不过也可能你少加了system prompt里的few-shot示例,给两个成功调用样例能大幅提升成功率。
说实话qwen2.5的function calling在7B这个规模上确实有点看运气,我试过同样的格式在Qwen2.5-72B上稳很多,但本地跑不动。你temperature都压到0.1了还乱来,那大概率是模型对工具schema的语义理解不够深,尤其是嵌套参数或者枚举值多的时候特别容易崩。我自己后来换成了glm-4-9b-chat,工具调用成功率明显高一些,但它对中文指令的依赖比较强,prompt里必须把每个参数的含义和约束写得很死,不能只给JSON schema。另外你可以试试把工具描述改得更口语化,比如“如果用户没明确说城市,就默认北京”这种话直接写进去,比单纯列参数要管用。还有个小技巧,在system prompt里加一句“你必须先调用工具,再根据工具结果回答”,能稍微减少瞎编的概率。你要是还卡着,可以试试用vLLM部署然后开guided decoding,强制模型输出符合schema的JSON,虽然不能完全解决不调用工具的问题,但至少格式错的比例能降一半。
之前我也遇到过类似情况,qwen2.5的function calling对格式要求其实挺细的,尤其是参数类型和嵌套结构,稍微差一点它就容易乱来。你可以试试把tools定义里的description写得更具体,甚至给每个参数加示例值,这样模型猜错的概率会小很多。另外,7B级别的话,glm-4-9b-chat在工具调用上感觉比qwen稳一些,不过它的中文对话风格可能需要你调一下system prompt。还有个小技巧,如果模型开始瞎编,可以在系统提示里加一句“如果工具调用失败,就明确回答无法完成”,这样至少不会胡扯。
说实话qwen2.5-7b的function calling确实是弱项,尤其本地量化后更明显,我试过它经常把参数类型搞混或者干脆无视tools字段。你试试把系统提示里把工具描述写得更啰嗦一点,比如明确“必须返回JSON且只能调用工具”,能改善一点但别抱太大期望。7B级别想稳的话可以看看glm-4-9b-chat,对工具调用的指令遵循能力比qwen好一截,或者直接上32B的模型,本地跑不动就调API。另外你temperature调0.1还不够,我试过0.01配合few-shot示例(给两个完整调用范例)成功率能上去不少,但本质还是模型能力天花板在那。
qwen2.5-7b在function calling上确实有点随缘,我试过同样的prompt在72b上就稳很多,小模型对工具调用的指令遵循能力还是弱,参数格式崩多半是它自己理解偏了。你试试在system prompt里把每个工具的JSON schema拆开单独强调一遍,再给一个“必须用工具”的硬性约束,别给它自由发挥的空间。要是还不行,换glm-4-9b或者functionary-small-v2试试,后者专门为工具调用调过,体感比qwen2.5稳不少。
说实话qwen2.5的function calling在7B这个规模上确实有点弱,尤其是参数多的时候格式容易飘,我试过把工具描述写得更啰嗦一点、每个参数加示例值,成功率会明显上来。另外你有没有试过把system prompt里明确加上“必须调用工具才能回答,否则直接说不知道”这种硬约束?我这么改完以后瞎编的情况少了很多。要是还不行,可以看看glm4-9b-chat,它的工具调用格式更简单些,本地跑起来也稳。
说实话qwen2.5-7b的function calling我试下来确实不太跟手,特别是要传复杂json参数时容易崩,后来我干脆把工具描述写成特别直白的伪代码例子塞进system prompt里,成功率能好点。再就是别全指望模型自己理解格式,你可以把每个工具的参数做成固定模板让它选填,减少自由发挥的空间。要是想换模型的话,glm-4-9b-chat或者llama3.1-8b在tool use上我个人体感比qwen稳一些,但本地显存占用也会上去一点。你跑的是fp16还是量化版?有时候量化太狠也会影响输出层的格式稳定性。
qwen2.5的function calling确实有点看运气,我试过7B和14B,参数格式崩是常态,尤其你本地跑量化版的话更容易出问题。建议先确认下你用的推理框架是不是支持完整的tool_use协议,有些框架会悄悄截断输出。另外可以试试在system prompt里给一个非常具体的工具调用示例,比官方文档那种抽象模板管用。要是还不行,换glm-4-9b或者functionary小模型试试,后者对工具调用专门优化过,稳定性会好不少。
我之前也遇到过类似情况,qwen2.5-7b对function calling的支持确实不算特别稳,尤其是本地部署时参数格式容易飘。你试试把system prompt里明确写出“必须调用工具才能回答”这种强约束,再给一个few-shot示例,比单纯调temperature有效。另外检查下你的tool schema是不是和官方最新版本对齐了,老版本格式会有差异。如果想省心点,同级别里glm-4-9b-chat的工具调用我体感要稳一些,虽然偶尔也会抽风,但至少不会瞎编。
qwen2.5-7b的function calling确实不太稳,我试过类似场景,它经常把参数类型搞混,尤其嵌套json的时候。你可以试试在system prompt里把每个工具的参数示例写得更具体,甚至给一个“如果拿不准就调用”的强制指令,能稍微好点。另外7b级别的话,glm-4-9b-chat的工具调用我体感比qwen稳一些,或者干脆上qwen2.5-14b,参数量上来后逻辑错误少很多。你本地显存够的话,值得换一下。
qwen2.5-7b的function calling确实不太稳,我试过同样的问题,后来发现把工具描述写得更细,比如每个参数都给示例值,成功率能上去一点。另外你检查下是不是没做few-shot,给模型一两个调用范例会好很多。7B里试试glm-4-9b-chat,工具调用这块调得比qwen顺。