最近在拿Qwen2.5-72B接自己的工具集做Agent,用的ReAct框架。发现模型经常在一个工具返回结果后,不根据结果做下一步判断,反而把同样的参数再调一遍,甚至连续调三四次。我试过改prompt强调“如果结果已满足需求就直接输出”,也调过temperature和top_p,但效果不稳定。是不是这类开源模型本身就不适合做多步推理?还是我的工具描述写得不够清楚?有没有大佬用Qwen系模型跑通过Agent,能分享一下工具schema怎么写,或者有没有必要换MCP协议?目前用的LangGraph,谢谢。
Qwen2.5做Agent老是循环调用工具,有人调好过吗?
全部回复
共 3 条我也遇到过类似问题,Qwen2.5在ReAct下确实容易“复读机”,后来我把工具返回结果里加了个“是否需要继续调用”的显式字段,并在prompt里要求模型必须引用该字段再决定下一步,效果好了不少。另外LangGraph的话,你可以在工具节点后加个轻量规则判断,比如结果里包含“完成”标志就直接走输出,别全指望模型自觉。MCP倒不一定是关键,主要还是工具描述要带触发条件和终止条件,写得太开放就容易绕圈。
我也遇到过一模一样的情况,Qwen2.5在ReAct框架下确实容易陷入工具调用的死循环,尤其是当工具返回结果比较结构化但又不完全匹配prompt里给的示例时。后来我试了个笨办法,把工具描述里每个返回字段的“下一步决策条件”写死,比如“如果status=success且data非空,直接回答,不要调用任何工具”,效果比单纯改system prompt要好不少。
另外我觉得LangGraph的默认路由逻辑可能也有影响,它倾向于让模型“再确认一次”,所以我在节点之间加了显式的终止条件判断,比如当某类工具被调用超过两次就强制走输出分支。MCP协议我试过,但对这个循环问题帮助不大,它更多是解决工具发现和权限的,不是推理策略。
说到底这类开源模型对“结果已满足”的语义理解还是偏弱,尤其是当工具返回里有多余字段时,模型容易误以为还得再处理一下。你可以试试把工具返回的JSON精简到只剩必要字段,或者干脆在工具内部把“最终答案”直接拼好,让模型只需要复述。我目前是用Qwen2.5-32B跑通的,72B反而更容易绕进去,可能和参数量大、注意力分布更散有关。你要是调通了记得回来分享下,我也想知道有没有更稳的prompt模板。
说实话你这个现象我太熟了,当时用Qwen2.5-72B跑Agent的时候也差点被搞崩溃,后来发现核心问题可能不在模型本身,而在工具返回结果的结构上。你试试把每个工具输出的关键信息强制提取成结构化字段,比如status、next_step_hint、confidence这类,让模型一眼就能看出“该不该继续”,而不是给它一大段自然语言描述让它自己猜。另外ReAct框架里那个“Thought”步骤的输出质量很关键,你可以把prompt里“根据结果判断”改成“如果结果包含final_answer字段,直接输出该字段,不要调用任何工具”,同时把工具描述里每个参数的限制条件写得极端明确,比如“当且仅当用户明确要求XX时才传这个参数”。我后来还发现一个坑,就是模型会把历史对话里的工具调用记录当成可参考的模板,所以如果某次调用成功了,它下次会无脑复制,这时候你可以在系统提示里加一句“每次调用工具前必须重新阅读用户最新输入”。MCP协议我试过,对减少重复调用帮助不大,它主要是解决工具发现和权限问题,LangGraph这边你倒是可以加个循环检测节点,统计同一工具连续调用次数,超过两次就强制中断并让模型重新总结当前状态。总的来说我觉得Qwen系能做Agent,但需要你把外部逻辑补得更硬核一些,不能太指望它自己“想明白”。