最近在试着用qwen2.5-7b(本地跑)搭一个简单的Agent,就是让它调用天气API和日历API做日程提醒。结果发现工具调用成功率特别低,有时候参数格式不对,有时候模型直接不调用工具就开始瞎编。我按官方文档写了function calling的格式,也试了temperature调低到0.1,但还是不稳定。想问下大家,是qwen2.5本身对工具调用支持不够好,还是我少配了什么prompt模板?或者有没有更稳的7B级别开模型推荐?感谢!
用开源模型搭Agent,工具调用老是崩,是qwen2.5的问题还是我姿势不对?
全部回复
共 146 条试试把工具描述写得极简,再给个few-shot示例,qwen对格式敏感,光调温度没用。
说实话我也踩过这个坑,qwen2.5的function calling在7B这个规模上确实有点飘,尤其是参数多的时候,它经常把JSON里的字符串值给截断或者加个多余逗号。我后来试了个土办法,把工具定义写得更啰嗦一点,每个参数都加example和description,甚至把可能的错误格式写进去当few-shot,成功率能上来一点,但离“稳”还差得远。
另外你temperature调到0.1是对的,但我发现它对system prompt里工具描述的敏感度比想象中高,稍微改个措辞结果就完全不一样。我甚至怀疑是不是vLLM或llama.cpp的采样参数没对齐,比如top_p或者repetition_penalty会干扰工具调用的token分布——你可以试试把repetition_penalty设成1.0,然后强制用greedy decoding,别用beam search。
至于替代方案,我个人觉得如果非要7B级别,可以看看最新的glm-4-9b-chat,它的tool use指令遵循能力明显比qwen2.5-7b强,而且对中文API描述更友好。不过它需要更长的prompt模板,网上有现成的chat-template,你可以直接扒下来用。
最后说个坑:你本地跑的话,量化级别很关键,Q4_K_M和Q8_0在工具调用上表现差很多,如果显存够,尽量上Q8或者直接用fp16,不然模型在生成参数时很容易“幻觉”出错误类型。先试试这几个方向,如果还崩,可能得把Agent的re-plan机制加上,让它失败后自动纠正参数再调一次,而不是直接放弃。
qwen2.5-7b本身工具调用能力确实偏弱,不是你的姿势问题,7B这个量级对function calling的指令跟随天然不稳,尤其参数多的时候容易崩。我之前也踩过这个坑,后来发现把工具描述写得更啰嗦、每个参数都加示例能明显提升成功率,但依然做不到100%。你要是想省心,可以试试glm-4-9b-chat或者llama3.1-8b,这俩对工具调用的内置支持比qwen好一截。另外你temperature调到0.1是对的,但别忘了把top_p也压到0.3以下,有时候采样策略比温度更影响稳定性。最后建议把工具调用的system prompt单独写一版,明确告诉模型“必须调用工具,禁止直接回答”,能治住瞎编的毛病。
7B模型做function calling确实容易翻车,qwen2.5在工具调用上对prompt格式特别敏感,你试试把工具描述写成json schema那种详细带示例的,比单纯列参数管用。我原来也老遇到它不调用工具直接编,后来发现得在system prompt里反复强调“必须调用工具才能回答”,不然模型总想自己发挥。另外你用的是vllm还是llama.cpp?不同推理后端对工具调用的支持差异挺大的,我之前换了个后端成功率直接上来了。要是还不行,可以看看glm-4-9b-chat,那个工具调用比qwen稳一些,不过速度稍慢。
试试把工具描述的schema写详细点,再加个强制json输出的system提示,qwen对格式敏感但没那么差。
我最近换glm-4-9b-chat跑工具调用,稳定性比qwen好不少,你可以对比下。
qwen2.5工具调用确实容易抽风,建议试试glm4-9b或者加个ReAct模板兜底。
说实话qwen2.5的function calling在7B这个规模上确实不太稳,尤其参数多的时候容易乱,我后来干脆自己写了个简单的JSON schema校验兜底,崩了就让模型重试一次,成功率能上来一点。你试试把工具描述写得更具体,比如明确每个参数的类型和枚举值,别让模型自由发挥。另外如果非要用7B,我试过glm-4-9b-chat在工具调用上比qwen2.5稍微靠谱点,但也不是完美。你用的是vLLM还是transformers加载的?有时候采样参数和推理后端对输出格式影响也挺大的。
qwen2.5-7b的function calling确实有点玄学,我试过类似的场景,发现它经常把参数类型搞混,尤其嵌套json的时候。你可以试试在system prompt里把每个工具的参数示例写得更具体,比如直接给一段“输入示例”而不是只描述schema。另外,温度调低不一定有用,我感觉它的问题更多是注意力分配,有时候模型会“忘记”去调用工具,干脆把工具描述也塞进user消息里试试。如果还不行,可以看看glm-4-9b-chat,工具调用比qwen稳一些,但偶尔也会犯轴,得做一层兜底校验。
试试把工具schema描述写详细点,qwen对格式敏感,再不行换glm-4-9b或functionary小模型。
这问题我太有同感了,qwen2.5-7b的function calling确实有点“薛定谔的稳定”,特别是本地部署的时候,量化精度和采样参数影响都很大。我试过类似场景,发现光调temperature没用,得把top_p也压到0.8以下,不然模型容易在参数里加些奇怪的字段。还有个坑是system prompt里必须把每个工具的使用场景写得很死,比如“只有用户明确问天气时才调用天气API”,否则它一犹豫就开始自由发挥。你试试把工具描述改成json schema那种带example的格式,比纯文本描述管用得多。另外7B级别里,我后来换了glm-4-9b-chat,工具调用稳定度明显高一截,虽然速度慢点,但至少不瞎编参数。如果你不想换模型,可以试试在输出层强制加个json校验,解析失败就自动重试一次,能救回来不少case。反正多试几个prompt模板,这东西有时候就是玄学,别太怀疑自己。
说实话qwen2.5的function calling在7B这个规模上确实不太稳,我试过类似的场景,它经常把参数类型搞混或者直接忽略工具。建议你检查下系统提示里有没有明确告诉模型“必须调用工具才能回答”,同时可以试试把工具描述的格式改成更口语化,比如“当用户问天气时调用get_weather”,我这样改完成功率提升了不少。另外如果条件允许,可以试试glm-4-9b-chat,那货在我的项目里工具调用比qwen稳一点,但也要配合严格的prompt约束。
说实话qwen2.5在7B这个体量上工具调用确实不算强项,我之前在vllm上部署也遇到类似问题,尤其是多轮对话里上下文一长,它就开始忽略工具定义。你试过把工具描述写得更“啰嗦”一点吗?比如在function的description里直接塞一个示例调用,包括完整的参数JSON,这样模型会更容易照着模板输出,而不是自己脑补格式。另外它的system prompt里最好明确强调“当且仅当用户请求涉及天气或日程时,必须调用工具,否则不调用”,不然它经常自作主张回答。还有个小细节,temperature调低虽然有用,但我觉得更关键的是把top_p也压到0.8以下,甚至试试其他解码参数,比如frequency_penalty设成0.2,能减少它胡编乱造的概率。如果你愿意折腾,可以试试glm-4-9b-chat,那个在tool use上比qwen2.5稳定不少,只是中文指令理解稍微差点。反正我最后是用了两套模型,简单查询用qwen,复杂工具调用切到别的,才勉强跑通。
Qwen2.5的工具调用确实偏弱,试试加个system提示强制它先输出JSON再解释,或者换glm-4-9b-chi。
说实话qwen2.5-7b的function calling在本地部署下确实容易翻车,我拿它跑了几个工具调用场景,发现模型对JSON schema的遵循能力比同尺寸的Llama 3.1要弱一些,尤其是在多轮对话里工具状态容易混乱。你温度调低是必要的,但更关键的是prompt里得把工具说明写得特别死板,比如“你必须严格按以下JSON输出,不要添加任何解释”,否则它一自由发挥就崩。另外我怀疑你用的是vLLM或者Ollama的默认采样参数,试试把top_p也压到0.8以下,并且关闭repetition penalty,这对格式稳定性有帮助。如果你愿意换模型,我推荐试一下Qwen2.5-7B-Instruct的AWQ量化版(虽然也是qwen),或者看看Llama-3.1-8B-Instruct配合官方的tool calling模板,我这边实测成功率能到七八成。还有个坑是本地推理的上下文窗口别开太大,工具定义和对话历史挤在一起时注意力会散,建议只保留最近两轮对话。你要是坚持用qwen,可以先去HuggingFace上搜下“qwen2.5 function calling prompt”看看社区调的模板,比官方文档那个好用不少。
qwen2.5对工具调用的稳定性确实一般,建议试试glm-4-9b-chat,格式要求没那么苛刻。
说实话qwen2.5的function calling在7B这个规模确实有点吃力,我试过好几次,它经常把参数类型搞混,尤其是嵌套的JSON结构。你可以试试在system prompt里把每个工具的示例调用写得更具体一点,比如直接给一个完整输入输出对,比单纯描述格式管用得多。另外如果还是不稳,建议看看glm4-9b或者functionary,这俩在工具调度上专门优化过,体感比qwen稳。
我跟你遇到的情况几乎一样,后来发现是温度太低了反而让它容易陷入重复模式。你可以试试在tool call前加一个强制“先输出工具名再输出参数”的中间步骤,相当于把决策拆成两步,成功率会高不少。不过你要是追求省心,直接换internlm2.5-7b吧,它内置的工具调用prompt比qwen友好,我本地跑下来感觉更跟手。
工具调用崩大概率是模型对“什么时候该调用”这件事的边界感很弱,qwen2.5尤其容易在上下文里看到日期就自己脑补日程。我建议你在每轮用户输入后面加一句“如果无法确定,必须使用工具获取信息”,然后配合few-shot给两个失败案例。另外你把max_tokens调大点,有时候它其实想调用,但输出被截断了,只生成了半个工具调用。
qwen2.5-7b工具调用确实偏弱,试试加个ReAct模板或者换glm-4-9b,会稳不少。
说实话qwen2.5-7b在function calling上确实有点拉胯,我自己试过类似场景,感觉它更擅长把工具描述当普通文本理解,而不是严格按schema去生成参数。你temperature调到0.1是对的,但我觉得问题可能出在prompt的结构上,官方文档那个格式太简略了,我后来是把工具的定义拆成多轮对话里的system消息,每条工具都给了非常详细的示例,成功率才提上来一点。另外有个坑是qwen对JSON输出的引号经常搞出全半角混乱,我干脆在解析层加了正则修复,不然十个调用能崩五个。你要是想换模型,可以试试glm-4-9b-chat,它对工具调用的格式遵循度比qwen稳不少,而且同样能本地跑,不过推理速度慢一些。还有个小技巧,别让它直接输出最终答案,强制先输出一个“action”字段,再输出“action_input”,这样模型会更倾向于走调用流程而不是瞎编。你检查下是不是在tool定义里漏了“required”字段,qwen对缺这个的敏感度特别高。
试试把工具描述写得更细,few-shot给两个示例,qwen2.5对格式很敏感,另外7B里glm4-9b的工具调用更稳。
说实话qwen2.5的function calling在7B这个规模上确实有点吃力,尤其是参数多的时候格式容易飘,我试过把few-shot示例直接塞进system prompt里会稳不少,你可以试试。另外工具描述别写太长,模型注意力一散就瞎编了。如果还不行,可以看看glm-4-9b-chat,它那版工具调用我觉得比qwen稳,或者干脆上qwen2.5-14b,量变引起质变。