hotai.news
← 返回 AI 百科AI 百科 / 具体问题解决

Agent反复调用工具不结束,怎样查错并限制循环?

通过工具调用与返回结果排查Agent循环,解释步数上限、重复签名和业务完成检查,并附实际运行过的安全本地模拟器。

HotAI.news · Codex 来源核对发布于 2026-10-20来源核对于 2026-10-20
先说结论

先从这里排查

Agent反复调用工具时,先检查上一轮结果有没有按调用ID传回,再比较工具参数与外部状态是否变化。对于状态未变的重复搜索,可以检测相同调用签名并停止;同时给整个任务设置步数和时间上限。达到上限只说明停止了运行,不能据此标记任务成功。下面的Python标准库示例已经在本地运行,用固定动作列表验证重复拦截和最大步数,没有连接真实模型,也没有向外部服务执行写入。

01

先确认工具结果确实反馈给了下一轮

同一搜索连续出现、工具已经报错却仍按原参数重试,以及任务文件已经生成却继续生成,都是需要检查的症状。固定一段失败记录,按实际发生顺序对应每次工具名与参数,接着检查返回结果以及下一轮收到的消息。不要只根据Agent自己的文字解释推断执行过程。

结果缺失时,检查调用ID是否对应、异常有没有被吞掉,以及成功结果是否被长度限制截断成空内容。工具失败应返回清楚的错误类型和可修正信息。如果下游只能读到“失败”,却不知道哪个参数不合法,重复相同尝试就很难带来新信息。

02

比较调用签名时同时检查外部状态

把工具名和参数以稳定字段顺序序列化,可以识别只是字段排列不同的重复请求。对于同一份不变资料的搜索,再次使用相同条件通常不会增加证据。检测到以后应停止这个分支,或者要求下一次动作改变可检查的查询条件,不要让模型仅把相同请求换一种文字解释。

轮询任务需要单独处理:服务器状态确实可能随时间改变,相同查询未必无效。为这类动作规定查询间隔,并设置截止时间;分页则要求游标向前推进。签名检查必须结合业务状态,不能一律拦截所有相同参数,也不能把一次网络超时直接认定为工具未执行。

03

本地模拟器验证重复拦截与最大步数

下面代码只模拟工具执行,把已经执行的动作放进列表,没有请求模型API或实际搜索服务。测试中的第二次搜索仅调整字典字段顺序,规范化后签名相同,因此执行次数停在1。另一组提供10个不同查询,最大步数设为3,结果只执行3次并报告max_steps。

本站已用Python标准库运行代码,两个断言均通过,原始输出为repeat停止在duplicate、executed为1,budget停止在max_steps、executed为3。这些结果只验证程序中的停止检查。动作列表由示例直接给出,不能据此声称真实模型已经会规划任务,或生产系统已经实现持久化去重。

import json


def simulate(actions, max_steps=3):
    seen = set()
    executed = []
    for action in actions:
        if len(executed) >= max_steps:
            return {"stop": "max_steps", "executed": len(executed)}
        signature = json.dumps(action, sort_keys=True)
        if signature in seen:
            return {"stop": "duplicate", "executed": len(executed)}
        seen.add(signature)
        # Simulated tool execution only: no network or external writes.
        executed.append(action)
    return {"stop": "plan_exhausted", "executed": len(executed)}


repeated = [
    {"tool": "search", "args": {"q": "policy", "limit": 1}},
    {"args": {"limit": 1, "q": "policy"}, "tool": "search"},
]
budget = [{"tool": "search", "args": {"q": str(i)}} for i in range(10)]
assert simulate(repeated) == {"stop": "duplicate", "executed": 1}
assert simulate(budget, max_steps=3) == {"stop": "max_steps", "executed": 3}
print("repeat:", json.dumps(simulate(repeated)))
print("budget:", json.dumps(simulate(budget, max_steps=3)))
04

运行停止以后还要检查目标结果

业务成功需要另行判断。例如任务是生成一份含指定字段的报告,应打开实际文件,核对字段内容和来源,再决定是否完成。工具返回成功、列表耗尽或触发步数上限都不能替代这个检查。停止原因应保留为完成、超时或重复拦截等明确状态,已有的部分结果也应可继续检查。

写入动作还要使用服务端业务键处理幂等,尤其是请求已经执行、响应却丢失的情况。本例的内存集合会在进程退出后消失,也没有处理并发,因此不能用于保证真实邮件或订单只执行一次。真实写入重试前应通过现有记录查询结果,避免把传输失败当成业务失败。

05

复测正常结束和应当中止的样本

修复反馈消息以后,重新运行原来的循环样本,确认Agent能够使用上一轮结果继续,或者以明确原因停止。同时加入合法轮询样本,检查状态变化时不会被错误拦截。最大步数应在实际执行之前判断,达到上限后不再启动下一次工具调用;单次工具卡住还需要独立超时控制。

本文适用于可控制编排循环或查看调用记录的Agent。只提供聊天界面的产品未必开放这些设置,使用者可以先保存重复动作的时间和结果,再交给维护方定位。这里给的是实现与验证方法,没有测量特定模型的循环概率,也没有承诺提高步数上限就会更容易完成任务。

核对来源

以下资料用于核对概念和方法。文中的示例与测试范围分别注明,实际使用时请核对所用工具的版本。

返回AI 百科 ↗