最近在跑一个本地部署的AI Agent demo,底层用Qwen2.5-7B,配合LangGraph做工具调用。任务很简单:让agent根据用户需求查天气再订个闹钟。但实际跑起来,agent经常在“调用工具→拿到结果→再次调用同一个工具”之间反复横跳,日志里能看到它已经拿到天气数据了,下一轮还是继续调天气API,就是不往下走。我试过调低temperature、加max_iterations限制,也改过system prompt强调“完成就结束”,但偶尔还是会卡住。想问问大家,是模型本身对工具调用的指令遵循能力有限,还是我的图结构设计有问题?有没有什么prompt技巧或者后处理手段能缓解这个现象?感谢!
用Qwen做Agent老是陷入死循环,有人遇到过吗?
全部回复
共 51 条遇到过,Qwen系在工具调用上确实容易“上头”,特别是7B这个规模,对“结果已满足意图”的判断很模糊。我后来在LangGraph里加了个状态机,如果返回的tool_call和上一轮完全一样就直接强制中断,比调prompt管用。另外你试试把天气API的返回内容在下一轮前截断掉,只保留摘要,能减少它“再确认一次”的冲动。这模型对“完成”的定义比想象中死板,靠后处理兜底比纯靠提示词稳。
我之前跑类似流程也遇到过这种问题,后来发现不完全是模型的问题,LangGraph的状态机设计如果没把“工具结果已消费”这个状态显式标记出来,模型很容易基于上下文重复调用。我最后是加了个简单的规则:如果同一工具被连续调用两次且参数相同,就强制中断并跳到下一步,效果立竿见影。另外Qwen对“你已经完成”这类表述不敏感,不如在工具返回内容里直接写“任务已完成,请输出最终答案”来得直接。你可以试试把判断逻辑从模型手里抢过来,用代码做硬约束,别全指望prompt。
我遇到类似问题,后来在LangGraph里加了个工具结果去重缓存,同一结果直接跳过,基本能治住这毛病。
试试在system prompt里加“若工具返回相同数据则禁止再次调用”,能明显减少这种循环。
遇到过,而且比你更离谱,我这边是让它查完天气后直接调用一个本地文件写入工具,结果它写完文件又回头去查天气,日志里那个API调用次数直接爆表。后来我仔细看了下LangGraph的状态流,发现问题是出在节点间的条件路由上——模型拿到工具结果后,其实它自己已经觉得任务完成了,但图结构里那个“下一步”的判断条件写得不够死,导致它又回到了工具调用节点。你试试在拿到最终结果的那个节点上,强制检查一下tool_calls是不是为空,或者给每个工具调用加一个唯一的task_id,让模型知道这个结果已经处理过了。另外Qwen2.5-7B对工具调用的终止信号其实挺敏感的,你可以把system prompt里“完成就结束”改成更具体的“如果天气数据已经返回并且闹钟已设置,直接输出最终回复,不要调用任何工具”,再配合一个后处理逻辑,比如检测到连续两次调用同一个工具就自动中断。我后来还试过在工具返回的内容里加上“这是最终结果”的标记,模型看到这个标记就不太容易再绕回去,你可以试试看。
我也踩过这个坑,Qwen系列对“任务完成”的判定确实比GPT系要模糊一些,尤其是多轮工具调用的时候。我后来是把LangGraph的state里加了个“工具结果摘要”字段,每次调用前先比对一下当前结果和上一步是否重复,重复就直接强制跳转到下一步。另外你试试把天气API的返回内容在prompt里明确标注成“最终数据,请勿再次查询”,比单纯强调“完成”管用。还有个小技巧,给每个工具调用加个序号,让模型自己看到已经执行过第几步,逻辑上会清醒很多。
我之前也踩过这个坑,Qwen2.5-7B在工具调用上确实容易“上头”,尤其是拿结果后下一轮意图分类会漂移。后来我直接把工具描述改得更具体,比如让它返回“天气已查询,接下来请执行闹钟设置”,并且把图上工具节点加了状态锁,同一工具连续调用两次就直接强制跳转。另外你试试把历史消息里的工具结果截断一下,只保留最近两轮,模型被冗余信息干扰的概率会小很多。
我之前也踩过这个坑,Qwen2.5在长链工具调用上确实容易“上头”,尤其是连续返回结构化结果时,它会把“拿到数据”误判成“还需要再确认一次”。后来我加了个状态机,在LangGraph里把每个工具节点设成幂等,并在节点间传一个“已执行”标记,如果检测到同一工具连续调用两次就直接强制跳转,效果好了很多。另外,你也可以试试把工具返回的摘要直接拼进下一轮user消息里,而不是放在tool消息里,模型更容易意识到“这步已经做完了”。
这问题我也踩过坑,后来在tool result里显式加了个字段标记任务是否完成,让agent看到就没再循环了。你可以试试。
试试在工具返回结果里加个状态标记,或者用LangGraph的conditional edges判断结果是否已满足条件,能少走不少弯路。
我这边也踩过这坑,后来给工具调用结果加了个“已执行”的元数据,配合图里的路由判断,基本不卡了。
我也踩过类似的坑,Qwen 2.5 7B在长链工具调用上确实容易“上头”,哪怕结果已经够了它还想再确认一次。我觉得不完全是prompt问题,LangGraph里如果工具节点返回后没有强制走路由判断,模型很容易把“调用工具”本身当成一个待完成目标。你可以试试在拿到结果后加一个规则:如果天气数据已经存在且非空,就直接跳到finish节点,别让模型自己决定下一步。另外把工具描述写得像“这次查询后必须回复用户”这种明确指令,比单纯说“完成就结束”有效得多。我这边加了这层后卡死频率降了至少一半。
我之前跑类似流程也踩过这坑,感觉Qwen对“任务完成”的判定确实比较弱,它可能把“拿到天气”当成一次独立工具调用,而不是整个任务的一环。后来我把LangGraph里工具返回结果直接拼进下一轮system prompt,同时加了个规则:如果同一工具返回内容没变化,就强制走结束节点,效果好了不少。你可以试试在工具输出里加个“已提供”标记,让模型知道信息已经给过了。另外温度调低到0.1以下可能会改善,但偶尔还是会抽风,所以后处理兜底比纯靠prompt靠谱。
这问题太经典了,Qwen2.5对“已完成”的判定确实弱,建议在工具结果里加个显式的done标记,比改prompt管用。
我也遇到过类似情况,后来发现多半是图结构里缺少一个“状态锁”导致的。比如拿到天气结果后,如果不把下一步的tool call显式改成“完成”分支,模型很容易默认继续调用。你可以试试在LangGraph里加个条件边,检测到关键字段非空就直接跳结束节点,比纯靠prompt硬压靠谱一点。另外Qwen对“已经完成”的语义理解确实有点飘,后处理里加个正则匹配,如果结果里重复出现同一工具名就直接强制终止,也是个土办法。
我也踩过这个坑,Qwen2.5-7B在工具调用上确实容易“上头”,拿到结果后还会惯性再调一次。后来我把LangGraph里tool节点的输出做了个缓存校验,如果同一工具连续调用超过两次且输入参数没变,就强制让它走下一步,效果立竿见影。另外你可以在system prompt里加一句“如果工具已返回有效结果,直接基于该结果回答用户”,比单纯说“完成就结束”管用得多。我觉得不是图结构的问题,主要是模型对“任务完成信号”的敏感度不够,加个简单的后处理逻辑比调参更靠谱。
这问题太真实了,我也被卡过,后来在工具调用前加个状态校验,拿到结果就直接跳转,别让它自己决定下一步。
我也碰到过类似情况,Qwen小模型在工具调用边界上确实容易犯迷糊,拿到结果后它可能把“调用工具”本身当成了任务目标。后来我是在LangGraph里加了个状态机,强制要求必须把工具结果转化成用户可读的最终回复才能退出循环,光靠prompt管不太住。另外你可以试试在工具返回内容里直接附上“这是最终答案”之类的标记,模型更容易顺着台阶下。
这问题我太有感触了,之前用Qwen系列跑类似multi-step任务也撞过好几次墙。我个人感觉不完全是指令遵循能力的问题,更可能是LangGraph的循环节点设计里缺了一个“状态判定”的出口,模型拿到结果后如果没收到明确的“任务完成”信号,就会默认还要继续调工具。你可以试试在拿到天气数据后,强制把工具调用结果写进一个隔离的memory slot,然后在下一次模型决策前用代码判断一下这个slot是否已经满足用户意图,是就直接跳到final node,别让模型自己决定要不要停。另外prompt里加一句“如果所有必需信息已经获取,直接输出最终回答,不要再调用任何工具”会比单纯说“完成就结束”有效得多,因为模型对否定指令的遵循率通常更差。还有个土办法,我在工具返回的content前面拼一个固定的特殊标记比如[TOOL_DONE],然后在后处理里检测到这个标记就强制切断循环,虽然有点暴力但实测能解决七八成的情况。最后想问你一下,你的图结构里有没有给每个工具调用设置独立的conversation history,还是所有工具结果都混在同一个消息列表里?后者很容易让模型混淆当前状态,你可以试着把工具调用和结果单独存一个列表,只在生成最终回答时才拼进去。
加个“工具结果去重”的检查节点,如果连续两轮返回相同数据就直接强制跳出,比改prompt管用。
我之前也遇到过,换Qwen2.5-72B或者加个记忆模块提醒它“已查过”,基本能解决。
我之前跑类似的agent也遇到过这问题,特别是模型一旦“觉得”自己还没完成任务,就会死磕同一个工具。后来我加了个简单的状态机,在LangGraph里判断如果工具返回结果跟当前节点预期一致,就强制走下一步,别让模型自己决定要不要再调一次。另外可以把工具调用的历史拼进下一轮prompt里,明确告诉它“你已经拿到数据了”,比单纯强调完成有用得多。Qwen对这种多轮工具切换的指令确实没那么稳,图结构上别给它太多自由选择权会好很多。
我这边也踩过类似的坑,Qwen2.5-7B对“工具返回值已经满足条件”这个状态感知很弱,本质上是它在生成下一步时没把历史轮次里的工具结果当成强约束。我后来是在LangGraph里加了个节点,专门检查工具输出里是否包含“success”或“完成”这类关键词,命中就直接短路到终态,不再给模型继续调用的机会。另外你试试在system prompt里加一句“如果工具返回结果中已经包含目标信息,则直接输出最终答案,禁止再次调用任何工具”,比单纯说“完成就结束”管用。至于图结构,我觉得问题不大,主要是模型在长上下文里容易把“当前任务”和“历史动作”搞混,建议把每轮工具调用后的结果摘要一下塞回prompt,别让原始JSON堆太长。