最近在试着用qwen2.5-7b(本地跑)搭一个简单的Agent,就是让它调用天气API和日历API做日程提醒。结果发现工具调用成功率特别低,有时候参数格式不对,有时候模型直接不调用工具就开始瞎编。我按官方文档写了function calling的格式,也试了temperature调低到0.1,但还是不稳定。想问下大家,是qwen2.5本身对工具调用支持不够好,还是我少配了什么prompt模板?或者有没有更稳的7B级别开模型推荐?感谢!
用开源模型搭Agent,工具调用老是崩,是qwen2.5的问题还是我姿势不对?
全部回复
共 146 条我之前也踩过这个坑,qwen2.5-7b的function calling其实没那么“开箱即用”,尤其是本地部署的量化版本,对工具调用的指令遵循能力会明显缩水。你调低temperature是对的,但更关键的可能在于系统提示词里对工具描述的方式——如果API的JSON schema写得太抽象,模型很容易理解偏,建议把每个参数的含义、类型、甚至示例值都直接塞进prompt里,别指望它自己推理。
另外,你提到“不调用工具就开始瞎编”,这大概率是模型对“何时该触发工具”的边界没学好,可以试试在对话历史里强制加入几轮“用户提问→模型返回tool_call→工具结果→最终回答”的few-shot例子,比单纯写格式管用得多。我自己的经验是,qwen2.5-7b对多工具并行调用的支持很差,只能老老实实一次一个,稍微复杂点就崩。
如果你愿意换模型,可以试试同级别的glm-4-9b-chat或者yi-1.5-9b,前者工具调用格式更规范,后者在指令跟随上更稳,但都需要自己微调或加很细的约束。还有个取巧的办法:用llama.cpp跑qwen2.5-3b-instruct,虽然模型更小,但配合严格的grammar约束反而比7b裸奔更可靠,你可以对比下效果。
最后想问下,你有没有试过用vLLM或者SGLang跑,而不是原生transformers?有时候采样参数对工具调用的影响比模型本身还大,比如top_p调到0.8,frequency_penalty设成0.2,能减少乱生成。
qwen2.5的function calling确实有点挑prompt,我之前试过同样格式在7B上就是比14B差一截,尤其是参数多的时候容易崩。你试试把工具描述写得特别啰嗦,每个参数都加示例值,再在系统提示里明确“不调用工具就回复不知道”,成功率能上来一点。另外别只调temperature,把top_p也降到0.8以下试试。要是还不行,可以看看firefunction-v2或者glm-4-9b,这俩在工具调用上比qwen稳不少,我最近刚换过去。
试试把工具描述写得更详细,再给个few-shot示例,qwen2.5对格式敏感,光调温度不够。
我之前也踩过这个坑,qwen2.5的function calling对格式要求很死,尤其温度调低后它反而容易偷懒不触发工具。建议你试试把工具描述写得更具体,比如加上参数示例和边界条件,有时候是模型没理解该在什么时候调用。另外可以看下系统prompt里有没有混入其他指令,我上次就是被一段历史对话带偏了。如果还不行,换glm4-9b或者yi-1.5-9b试试,我之前跑工具调用比qwen稳一点,但速度稍慢。
我之前也卡在这过,qwen2.5的function calling确实有点抽风,参数格式稍微偏一点就崩。你试试用json schema严格约束一下工具定义,别给它自由发挥的空间。
另外可以把系统提示词里加上“必须调用工具才能回答”这种强指令,能明显减少瞎编的情况。7B里要是嫌它麻烦,可以看看glm4-9b-chat,工具调用比qwen稳不少。
或者你干脆换个思路,用外部函数调用框架兜底,比如让模型输出意图和参数,然后代码里去匹配执行,别完全依赖模型的工具调用能力。
我之前也遇到过一模一样的情况,qwen2.5-7b在function calling上确实有点飘,尤其参数多的时候容易漏字段。你可以试试在system prompt里把每个工具的参数schema写成json示例,比单给description管用得多。另外温度0.1还是偏高,我直接设0才稳一点。如果还不行,换glm-4-9b或者yi-1.5-9b都试过,工具调用比qwen这个尺寸的靠谱不少。
我之前也踩过一模一样的坑,qwen2.5-7b在function calling上确实有点飘,尤其本地量化后更明显。你试试把工具的description写得更啰嗦一点,比如参数里每个字段都加上例子,模型对“怎么用”的理解会好很多,单纯靠JSON schema经常不够。另外温度0.1可能还是高了,我最后调到0才勉强稳住,但代价是回复变得特别机械。还有个细节,你有没有在system prompt里明确给模型“必须调用工具才能回答”的指令?有时候它不调用是因为觉得自己能编出来。我后来换了个思路,用llama3.1-8b配合一个叫“tool-former”的微调版本,成功率确实比qwen高,但速度慢不少。如果你不想换模型,可以试试把工具拆成更小粒度的函数,比如get_weather_today和get_weather_tomorrow分开,别让模型自己组合参数,减少出错面。最后建议你开一下qwen的built-in tools模式,虽然文档里说实验性,但实测比手写function calling稳。反正别全信官方示例,多试几种prompt结构,这东西真的靠玄学。
我之前也踩过这个坑,qwen2.5的function calling对prompt格式特别敏感,官方文档那个模板少个换行或者缩进都可能翻车。你可以试试在system prompt里把每个工具的description写得极其啰嗦,甚至给个few-shot例子,成功率会明显上去。另外建议换个推理框架跑,比如vllm或者sglang,对工具调用的解析更稳,我之前用transformers原生跑也是各种崩。如果还不行,7B级别可以看看glm4-9b-chat,它的tool call相对皮实一点,不过得自己写解析逻辑。
qwen2.5的function calling确实偏弱,试试加个ReAct格式的few-shot示例,或者换glm-4-9b-chat会更稳。
qwen2.5的function calling确实偏弱,试试加个ReAct格式的system prompt,或者直接换glm-4-9b-chat,稳很多。
说实话qwen2.5的function calling在7B这个规模上确实不太稳,我试过几次也是参数格式容易飘,尤其是有多个工具可选的时候。你可以试试把系统prompt里每个工具的schema用json格式再强调一遍,或者干脆把工具调用拆成两步,先让模型决定调哪个,再单独生成参数,成功率会高不少。另外glm-4-9b-chat的tool use比qwen2.5稳一些,不过推理速度慢点,你可以对比下。
说实话qwen2.5-7b在function calling上确实有点“偏科”,尤其是7b这个尺寸,对工具调用的指令遵循能力比同级别的glm或者yi-1.5要弱一些,但也不全是模型的问题。我上次用vllm部署的时候发现,采样参数里有个top_p和temperature的联动很容易被忽略,你只调温度不够,可以把top_p也压到0.8以下,另外把max_tokens稍微调大点,防止生成到一半被截断导致json不完整。还有个坑是系统提示词里如果写了“你必须调用工具”这类强制指令,反而会让模型产生幻觉去编造参数,我后来改成“如果用户需求涉及天气或日程,请优先使用对应工具”,成功率明显上来了。你要是想省事,可以直接试试glm-4-9b-chat,它的tool call格式跟openai完全兼容,而且对参数类型校验更严格,我本地跑下来比qwen稳定很多。不过你要是非要坚持qwen,建议去看下它官方给的chat_template里是否带了tool_calls的special token,有些框架加载时默认不启用,这个很容易漏。最后问一下,你用的是transformers原生推理还是fastchat或者llama.cpp?不同推理框架对function calling的支持差异还挺大的,我之前在llama.cpp上跑qwen就死活不输出工具调用,换回transformers立刻就好了。
qwen2.5-7b的function calling确实有点看运气,我试过它经常把参数类型搞混,尤其是嵌套对象特别容易崩。你试试把工具描述写得特别死板,比如“参数必须是字符串,不能是数字”,再配合system prompt里强调“必须调用工具,禁止编造答案”,成功率能上来一点。另外7B级别里glm-4-9b-chat的工具调用我觉得比qwen稳,但中文场景下它偶尔会啰嗦,你可以对比下。还有个小技巧,把API返回结果强制塞进对话历史里喂回去,能减少它瞎编的概率。
qwen2.5的function calling确实调起来费劲,试试把system prompt里把工具说明写得更细一点,再不行就换glm4-9b吧。
qwen2.5-7b的function calling确实不太稳,我试过类似场景,参数格式经常对不上,后来发现得在system prompt里把每个工具的schema再重复一遍,光靠模型自己理解不行。另外你试试把max_tokens调大点,有时候它生成到一半截断了就不调工具。换模型的话,glm-4-9b-chat对工具调用支持好一些,或者干脆用qwen2.5-14b,7b在复杂指令上确实吃力。
qwen2.5工具调用确实偏弱,试试加个system提示词强制它输出JSON,或者换glm4-9b-chat,那个稳很多。
qwen2.5的function calling确实弱,试试加个ReAct格式的system prompt,或者换glm-4-9b-chat稳很多。
7B级别跑function calling确实容易翻车,qwen2.5的tool格式要求挺严格,我试过它连参数类型都容易搞混。你可以试试把工具描述写得更细,比如每个参数给个示例值,再在system prompt里明确说“必须返回json且键名完全一致”。另外我换过glm-4-9b-chat,工具调用稳定性明显好一些,但吃显存。你本地显存多大?如果够的话可以考虑量化版Qwen2.5-14B,效果提升不是一点半点。
温度降到0.1够呛,不如试试把工具描述写得更具体,再加个few-shot示例,qwen2.5对格式敏感但吃这套。
qwen2.5-7b的function calling确实不太稳,我试过几次,感觉它更擅长理解意图而不是严格生成参数,尤其长上下文里格式容易飘。你可以试试把工具描述写得更啰嗦一点,每个参数都加示例值,甚至用few-shot给几个完整调用样例,比调temperature管用。或者换个思路,用llama3.1-8b或者glm-4-9b-chat,这俩在工具调用上明显更规矩,但得注意显存占用。另外检查下你的system prompt里有没有明确说“必须优先调用工具”,有时候模型是偷懒直接编答案。