ARTICLE · INTELLIGENCE

战地情报 · 详情页

来自尧图项目组的一线实战观察与深度解析

你的 agent 凌晨把 API 账单打爆了?先给它装五个「刹车」(死循环治理清单)

你的 agent 凌晨把 API 账单打爆了?先给它装五个「刹车」(死循环治理清单)

你的 agent 凌晨把 API 账单打爆了?先给它装五个「刹车」(死循环治理清单)

模型没有「我已经试过」的概念,唯一可靠的兜底是你代码里的硬限制。五道确定性防线:最大步数、循环检测、会话级 token 预算、重试纪律、退出条件+人工介入,全带数字可直接抄。先说结论:agent 卡住不是模型笨,是你没给它装刹车。模型根本不知道「我刚才已经试过这个了」,它只会顺着上下文继续生成「再来一次」。所以别指望它自己喊停,能拦住它的只有你代码里那几行确定性的限制:最大步数、循环检测、token 预算、重试纪律、退出条件。## 01 现象:凌晨两点,账单先替你醒了我见过最典型的翻车:一个研究型 agent 凌晨自己跑起来,调同一个搜索工具,参数一模一样,重试了 40 多次。每重试一次,就把上一次的报错原文再喂回上下文。token 账单半小时涨了 4 倍,用户第二天醒来看到的是「会话卡死」和一张吓人的账单。这不是个例。CSDN 有人写复盘,同一个命令无限重试,后台刷出几十条重复工单,会话线程直接卡死 [来源 14]。DEV 社区把死循环列为 agent 头号故障 [来源 8]。## 02 根因:模型没有「我已经试过」这个概念先说清楚为什么模型会卡住。Mervin 做过一个实验:让 agent 调一个注定失败的接口,返回"error": "rate_limited"。模型把这行字当成「任务进展」,继续生成下一步——它根本不判断「这个错误是不是说我不该再试了」[来源 4]。这就是死循环的根:模型分不清「失败了」和「我需要换个方式再来一次」。它不知道自己在循环,因为它没有「历史轨迹」这个概念——每一轮看到的都是拼接好的对话,它以为自己每次都是新的尝试。所以真正拦住它的,从来不是模型,是外层代码。Mervin 实验里唯一有效的兜底是--max-turns 8,一个他自己加的参数 [来源 4]。官方也一样:Claude Code 的 agent loop 默认maxTurns: 30,注释写着 “Prevent runaway sessions” [来源 1]。子 agent 最多重启 5 次,第 6 次还卡死就直接报agent stalled on all 6 attempts[来源 2]。## 03 反转:无脑重试,是故障放大器你可能会说:那给它重试不就行了?不行。重试是把双刃剑。服务器过载时,一群 agent 同时重试,等于给着火的服务器再添柴——每一秒都在创建一模一样的重复工单 [来源 14]。有些工具是永久性报错(参数错、权限错),重试一万次也还是错,只是把账单烧得更快。重试必须分类型:临时网络抖动可以重试(指数退避),服务过载要退避+限流(并发上限),参数错误/权限错误直接标记失败返回,绝不重试。无脑重试只会放大故障。## 04 五道防线:全是确定性代码,不靠模型自觉下面是治理清单,数字都是社区和官方反复验证过的经验值,按你的任务规模加减。01 最大步数:先装最粗的那根刹车给每个 agent 任务设一个执行步数上限。官方示例 30 步 [来源 1],社区常用 10-15 步 [来源 6、8],研究型长任务可以放宽到 50。到点强制终止,返回当前已有结果,并明确标注「任务已达到最大执行步数,结果可能不完整」[来源 6]。这一步最简单粗暴,也最有效,是五道防线里性价比最高的一道。02 循环检测:同一工具+同一参数,两次即熔断模型不知道自己在重复,但你的代码知道。记录最近的工具调用(工具名+参数哈希),同一个调用出现两次,直接熔断 [来源 11、15]。进阶做法是轨迹相似度检测:不只看单次调用,看整段轨迹是否在打转,命中就中断并告警,不用等次数耗尽 [来源 7 的 Warn→Block→Halt 分级:警告→拦截→第 4 次硬停]。03 token 预算:按会话累计,不是按单次单次请求的 token 限制是自欺欺人——agent 的坑就在多轮调用。预算必须按会话累计:输入+输出之和超过上限就终止 [来源 11、14]。你可以在系统提示词里把预算写出来:「本任务有 5 次工具调用预算,已用 4 次,下一次请直接回复用户。」实测模型对可见预算相当遵守 [来源 12]。04 重试纪律:指数退避 + 分类型 + 固定上限临时类错误:指数退避重试,1 秒起步、60 秒封顶,最多 4-5 次 [来源 9]。别把重试次数设太高——有团队从 5 次降到 3 次,抖动期反而稳了 [来源 14]。关键配套:幂等。重试之前先想清楚,同一个操作执行两遍会不会产生重复数据?不会才允许重试 [来源 14 的重复工单就是没做幂等]。05 退出条件 + 人工介入:循环该结束的时候,谁来喊停给循环定义明确的出口:- 改代码类 agent:最多 3 轮「改-测」循环,之后强制人工复查 [来源 16]。- 改动幅度小于 5% 说明在打转,直接停 [来源 16]。- 自动续跑两三次还卡在原地,强制停下交人 [36氪转述官方做法,来源 17]。- 停的时候要告诉人:因为什么停的、卡在哪个工具、参数是什么 [来源 7]。## 05 三个坑,先踩给你看坑一:步数上限的换算别算错。LangGraph 里 recursionLimit 是「步数」不是「工具轮数」,8 轮工具实际要走 17 步(每轮 agent+工具,最后多一步收工)。你按 8 轮设 8 步,任务跑一半就「抽筋」[来源 13]。坑二:别把限制堆成大山。每轮都做全量自检会拖慢任务、更贵。轻量方案是阿里云那套思路:大模型只当推理单元,状态切换和循环拦截全部放到确定性代码里 [来源 10],而不是靠叠多 agent 互相盯着。坑三:预算和退出条件要写进提示词,但不能只写在提示词里。模型会遵守可见预算 [来源 12],但提示词不是兜底——--max-turns、token 上限、熔断器这些硬限制必须在你的代码里强制生效 [来源 4]。## 06 反方:刹车装太多,车也开不动别一上来把五道防线全上齐。三个边界想清楚:1.步数上限会误杀长任务。研究型、探索型 agent 天然需要长循环,上限设死了任务做不完。按任务类型分档:交互型 10-15 步,长研究型 50 步起。2.限制越多,agent 越笨越贵。过度自检和频繁打断会让 agent 变慢,token 反而烧更多。能不加的检测别加。3.简单任务根本不该用 agent。固定流程用 workflow(确定性编排)更省钱更可控,agent 适合需要自主决策的开放任务 [来源 2 的官方判断]。先问自己:这个任务真的需要模型自主决定下一步吗?## 07 互动你的 agent 卡死过吗?最后是靠什么救回来的——步数上限、熔断器,还是干脆换了 workflow?评论区聊聊,我收集一轮真实案例。—事实与来源(均为原文经验值,落地前请按你的任务规模复测):- 官方:Claude Code Agent SDK maxTurns:30(2026-10)、Claude Code Workflows 子 agent 5 次重启上限(2026-10-09)、Claude Platform stop reasons pause_turn max_continuations=5(2026-10-12)- 社区实验:Mervin Praison 失败工具调用被当成功(2026-08-14)、broken tool 无限重试复现(2026-08-25)- 社区/开源:CSDN 四层防御(2026-10-06)、ferstar Warn→Block→Halt(2026-08-31)、DEV 社区死循环治理(2026-10-12)、Misar 错误处理指南(2026)、阿里云状态机+决策沙箱(2026-08-07)、Developers Digest 三控制、72technologies 预算提示词(2026-09-04)、CSDN LangGraph 步数换算(2026-10-12)、CSDN 账单打爆复盘(2026-08-10)、agent-fender 熔断器(2026-07)、InsiderLLM exit conditions、36氪 Opus 5.5 硬刹车(2026-09-28)

RELATED READING

延伸阅读

更多一线实战笔记与深度复盘,助您持续精进