最近在尝试用Qwen2.5和Llama3.1本地搭一个简单的AI Agent,主要想让它调用几个自定义工具(比如查天气、发邮件)。但发现一个问题:模型经常在工具调用时“脑补”参数,比如明明工具要求city参数是字符串,它给我传个数字,或者干脆不传就瞎执行。我用的是function calling格式,也试过ReAct prompt模板,感觉不太稳定。想问下大佬们,这种情况是模型本身对工具调用的理解能力不行,还是我的prompt设计有坑?或者有没有推荐的专门优化过tool use的开源基座模型?求指点,调得有点自闭了。
用开源模型搭Agent,工具调用总翻车,是选型不对还是prompt没写好?
全部回复
共 177 条试试把工具描述写得更死板点,比如直接限定枚举值,再用GLM-4-Flash或Functionary这类专门调优的模型,会稳很多。
试试把工具描述写成带few-shot的例子,Qwen对格式敏感,给个标准输入输出它能稳很多。
工具调用翻车多半是温度调太高了,降到0.1以下,再给schema里加个必填字段校验,能少一半幺蛾子。
说实话这问题我太有体会了,Qwen2.5在strict function calling上确实有点飘,尤其参数类型约束这块,它更擅长理解意图而不是严格执行schema。我后来做了个妥协方案,就是在prompt里把每个工具的参数示例写得极其具体,比如city直接写明“必须是字符串,例如北京、上海”,然后加一句“如果用户没提供城市,必须反问而不是猜测”,效果好了不少,但代价是prompt变得很长。另外你提到ReAct,那玩意儿对中文支持好的模型来说更容易跑偏,因为模型会在thought里自由发挥,然后action输入就开始胡编。建议你试试把工具定义改成更接近自然语言描述,而不是纯JSON schema,有些模型对前者理解更稳。至于专门优化过tool use的开源模型,可以看看Qwen2.5的function calling微调版(官方有出),或者试试GLM-4,它在工具调用上比Llama3.1原生强不少,而且对中文参数类型错误容忍度高一些。不过说真的,如果只是简单几个工具,不如自己写个规则校验层,模型输出先过一遍正则和类型检查,不合法就打回让它重新生成,比指望模型自觉靠谱得多。
说实话这问题我踩过一模一样的坑,Qwen2.5的function calling对参数类型约束确实比较松,后来我换成在system prompt里把每个工具的json schema示例写死,还加了一步“先输出思考再调用”的强制格式,稳定性提升不少。另外可以试试FireFunction V2或者GLM-4这类专门调过工具调用的模型,本地跑起来也没压力。你用的温度参数调低一点了吗?太高容易瞎编参数。
说实话两个模型裸跑function calling都不算稳,Qwen2.5对参数类型约束会松一些,Llama3.1则容易多填默认值。建议先试试把工具schema里的description写得更狠一点,比如“city必须是字符串,禁止数字”,再不行就上GLM-4或FireFunction V2这种专门调优过的,体感会好不少。
试试把工具描述里的参数格式写成JSON Schema再配两三个few-shot例子,Qwen2.5对强约束的遵循会稳很多。
我最近也踩过类似的坑,Qwen2.5对参数类型的约束确实比预期弱,后来把工具描述改成JSON Schema格式并明确写"city必须是字符串"才稳定些。不过Llama3.1在ReAct下表现更飘,感觉它更擅长推理而不是严格遵循API。你要是图省事,可以看看FireFunction-v2或者Glm-4-9b这类专门强化过tool use的模型,实测比通用底座靠谱不少。另外,建议在prompt里加一步"先检查参数合法性再执行",能减少很多脑补情况。
试试Qwen3,工具调用能力比2.5稳不少,参数校验也严格,另外你的tool schema里把参数类型写死再给几个few-shot例子。
我之前也踩过这坑,换模型比调prompt效率高,Llama3.1对复杂指令的跟随性确实差点意思。
说实话这俩模型在tool use上确实差点意思,Qwen2.5的function calling对参数类型约束挺弱的,我试过给它一个严格JSON schema都能给你编出花来。你不如试试看把每个工具的描述写得更细,比如在prompt里直接给个示例调用,告诉它“city必须是字符串,比如'北京'而不是100101”,效果会比单纯改模板好很多。另外可以看看FireFunction V2或者ToolACE这类专门调过的模型,本地跑起来也不费劲,至少参数乱传的问题会少一些。
我之前也遇到过类似情况,Qwen2.5对参数类型的约束确实弱一些,尤其是自定义工具多的时候更容易乱来。可以试试把工具描述写得更细,比如在city参数后面加个“必须是字符串,例如北京”这种示例,比单纯写类型管用。另外你不如直接换FireFunction-v2或者Glaive,这俩在tool use上专门调过,稳定不少。还有个土办法,就是加一层校验逻辑,模型输出后强行检查参数类型,不对就让它重生成一次,虽然笨但能救急。
这锅得让模型背一半,Qwen2.5对参数类型约束就是弱,换GLM-4-Flash或者Functionary试试,稳很多。
要不试试把工具参数示例直接写进system prompt里,多给几个正例,比调模板管用。
说实话你这情况我也踩过坑,Qwen2.5和Llama3.1在function calling上确实有差异,前者对参数类型约束更敏感,后者容易在复杂指令下放飞自我。我后来把工具schema里的description写得更具体,比如city字段直接注明“必须是中文城市名,例如北京”,效果立刻好了不少,模型脑补概率降了一半。另外你试试把工具调用拆成两步:先让模型输出一个中间JSON草案,再用代码校验并强制修正再执行,这样就算它传错类型,你也能在代码层兜底。至于推荐模型,可以看看FireFunction V2或者ToolACE,这俩专门在工具调用数据上微调过,比通用模型稳很多,不过本地跑起来对显存有点压力。还有个细节,ReAct模板里如果示例不给足,模型很容易模仿出错误格式,我建议你给每个工具至少配两个正例一个反例,让它知道边界在哪。你现在是用的流式输出还是等完整结果再解析?有时候截断也会导致参数不全。
这俩模型原生tool calling确实偏弱,Qwen2.5得用他们自家的qwen_chat_format模板才稳一点,Llama3.1对参数类型约束更松。我之前也踩过这坑,后来改成先让模型输出JSON再程序校验,比直接让它调函数靠谱得多。
另外可以试试把每个工具的必填参数和类型用更死板的描述写进system prompt,比如“city必须是字符串,缺省就反问用户”,比单纯给function schema更有用。实在不行换FireFunction-v2或者Glm-4-9B-chat,这俩对工具调用的指令遵循强不少。
Qwen2.5工具调用确实容易乱填参数,Llama3.1稍微好点但也不稳定。你可以试试在prompt里把每个工具的schema用json格式写得更细,比如city字段后面加个“必须是字符串”的示例,然后把温度调低到0.1。我之前也是调了半天,最后换成glm-4-flash或者functionary小模型,反而稳不少,你可以先拿它们跑通流程再换回去。
说实话Qwen2.5和Llama3.1在function calling上都不是强项,尤其Qwen2.5对参数类型的约束经常是“模棱两可”的,你换成Qwen2.5-72B或者直接上Qwen3(如果显存够)会好很多。另外你试试把工具描述写得更“死”一点,比如在prompt里明确标注“city必须是字符串,否则返回错误”,比单纯依赖function calling格式管用。我自己用glm-4-9b-chat调工具调用时也踩过这坑,后来换成toolllama这类专门微调的模型才稳定下来。你本地部署的话,可以看看firefunction-v2,对参数校验和缺失处理都更严格。
说实话你这问题我太有共鸣了,Qwen2.5和Llama3.1我都折腾过,工具调用翻车基本是常态。我觉得大概率不是prompt的锅,这俩模型本身在function calling上就偏弱,尤其是参数类型约束和必填项校验,它们经常“自由发挥”。我后来换成了Qwen2.5的72B版本,情况好一些,但小参数模型真的别指望它能严格遵循schema。你试试把工具描述写得极其啰嗦,比如“city必须是字符串,例如'北京',不能是数字”,然后每个参数都加一个示例值,这样能压住一部分脑补。另外ReAct模板对这类模型其实不太友好,容易引导它们先编推理再乱调工具,不如直接给一个极简的“工具名+参数JSON”的few-shot示例,让它模仿格式。如果你想省心,可以看看专门做tool-use的微调模型,比如NexusRaven或者ToolLLM的衍生版本,它们在这块稳定很多,不过本地部署得看显存。最后想说,别自闭,这问题太普遍了,我调了快两周才勉强能用,多试试不同的格式组合,肯定能找到平衡点。
这俩模型裸跑function calling确实容易飘,尤其Qwen2.5对参数类型约束比较弱。你可以试试在system prompt里把每个工具的参数schema用JSON示例写死,比如明确“city必须是字符串,如'北京'”,比纯描述管用。另外可以看看FireFunction-V2或者Gorilla这类专门为tool use微调的模型,实测比通用模型稳不少。实在不行就先加个规则校验层,模型输出先过滤一遍再执行,能挡住大部分脑补参数。
我之前也踩过这个坑,Qwen2.5对function calling的schema挺敏感的,参数类型必须写死清楚,尤其数字和字符串别用模糊描述,不然它真敢给你瞎编。Llama3.1倒是更吃ReAct那套,但得把工具描述里的示例带上,它才不容易跑偏。你要是想省心,可以试试FireFunction V2或者GLM-4,这俩在tool use上专门调过,比通用模型稳不少。不过说实话,本地小模型翻车太正常了,建议先把你那个city参数改成枚举类型,能挡掉一半错误。
试试加两三个带错误参数的few-shot示例,Qwen对格式敏感,比改模板管用得多。
建议换GLM-4-Flash试试,tool call这块调得比较稳,Qwen对参数约束就是容易放飞自我。