面试官可能会问:“搜索工具超时了,你让 Agent 自动重试几次?重试还失败怎么办?”
这道题最危险的回答,是背一个固定次数,再补一句指数退避。每次重试都是一项有成本、有副作用、可能放大故障的业务决定,不能在错误发生后默认触发。工具为什么失败、是否可能自行恢复、请求能否幂等重放、剩余时间和预算还有多少,都会改变策略。
一个成熟的 Agent 不应该把所有异常都扔回模型,让模型凭一段错误文字自由选择。执行层先把错误分类,运行时根据工具策略和任务状态决定重试、切换兼容工具、返回缓存、交付部分结果、请求用户补充或安全停止。模型可以在有限候选中调整路径,但不能绕过超时、预算与副作用边界。
先给出 30 秒回答
工具超时后我先区分可重试的暂时故障、不可重试的参数或权限错误,以及结果不确定的写操作。每个工具同时设置单次调用超时、整步截止时间和整任务预算。只读且幂等的暂时故障可以在预算内做有限重试,使用退避与随机抖动,避免并发重试风暴;持续失败时根据契约切换等价备用、返回允许使用的缓存、交付部分结果或转人工。权限、参数和业务拒绝不自动重试;写操作超时先查幂等状态。所有策略由执行层强制,并通过故障注入验证,不照抄固定重试次数。
这段回答强调三件事:先分类,再看预算,最后选择有语义保证的退路。

重试只是其中一种出口,很多错误继续重试只会让问题更严重。
第一步不是重试,而是识别错误类型
参数错误
缺少必填字段、枚举不合法、日期范围颠倒、URL 不允许访问。这类错误通常不会随时间自行恢复。正确做法是修正参数或询问用户,原样重试没有意义。
权限错误
当前用户或 Agent 没有访问目标资源的权限。权限错误不能通过换模型、改描述或反复请求解决。系统应停止该动作,提供安全解释或进入授权与人工流程。
资源不存在
工具执行正常,但目标对象没有找到。可能是标识写错、对象已删除、当前数据域不对,也可能是合法空结果。先核对条件,再决定澄清或换数据源,不能默认上游故障。
暂时故障
网络抖动、上游限流、服务暂时不可用、短时超时,可能在稍后恢复。只读和幂等动作可以在预算内重试,但需要退避、抖动和上限。
永久故障或契约不兼容
接口已经下线、版本不兼容、返回结构发生破坏性变化。继续重试不会恢复,应触发熔断、禁用候选并通知负责人。
结果不确定
写请求发出后超时,程序不知道下游是否已经成功。这是最不能直接重试的情况。必须用幂等键或业务查询核对,确认未执行后才考虑再次提交。
错误分类应由工具适配器和网关完成,返回结构化 error_type、retryable 和状态证据。模型看到的是可理解摘要,不是内部堆栈;真正的重试权限仍由策略控制。
超时至少有三层
单次工具超时
限制一个外部调用最多占用多久,防止某个网页、数据库或 API 无限挂起。不同工具的正常耗时不同,不能共用一个随意数字。
当前步骤截止时间
一个计划步骤可能包含多次搜索、访问和验证。即使每次调用都没有超过单次限制,累计时间也可能远超用户预期。步骤需要自己的截止时间。
整个任务预算
Agent 是多步循环。前面消耗过多后,后续可用时间、模型调用和工具调用都要减少。每次准备重试前,系统应查看剩余预算,而不是只看当前工具的重试次数。
还可以有用户侧截止时间与后台任务截止时间。交互请求可能需要快速返回“任务已转后台”,后台仍可继续;但转后台不是取消预算,而是换一套明确的状态与通知机制。
超时信号要能向上传递。工具超时不等于整个任务必须失败,Planner 可以选择替代路径;整任务耗尽则必须停止或交付部分结果,模型不能继续发起新动作。
什么时候允许自动重试
自动重试至少满足四个条件。
第一,错误被明确判断为暂时故障。第二,动作是只读或具有可靠幂等。第三,剩余时间与调用预算足够。第四,重试不会违反上游限流或放大故障。
满足条件后,也不是立刻连续请求。退避让下游有恢复时间,随机抖动让大量任务不要在同一时刻再次冲击服务。上游返回建议等待时间时,应优先遵守协议,而不是自己更激进地请求。
重试次数不能用一个全局常量回答。搜索和写库风险不同,用户交互与离线任务时限不同,故障率和恢复时间也不同。合理阈值来自工具历史分布、服务目标和故障演练。
同一次 Agent 任务中的重试要有共享预算。否则工具 A 重试若干次、工具 B 再重试若干次、Planner 重规划后又从头重试,局部都没超上限,整体却已经失控。
重试放在哪一层
客户端或 SDK 层
适合处理连接重置等非常底层、明确安全的瞬时错误。它看不到完整业务语义,次数要保守,并把实际尝试记录出来。
工具网关层
掌握工具契约、幂等、超时和备用执行器,是多数工具重试的主位置。它能把底层错误转换为统一 Observation。
Agent 规划层
不负责原样重发同一请求,而是在工具层已经判断失败后决定是否换关键词、换工具、拆小任务或请求澄清。这里是策略调整,不应与网络重试混为一谈。
多层都自动重试会产生乘法放大。SDK 重试、网关重试、Agent 又重试,最终一次用户请求可能触发远超预期的下游调用。系统要明确每层职责,并在 Trace 中记录总尝试次数。

底层重试解决瞬时传输问题,Agent 换路解决任务策略问题。
换工具之前先确认是不是等价替代
“搜索 A 失败就换搜索 B”听起来简单,但不同工具可能覆盖范围、时效、权限、排序和返回格式不同。
只有契约兼容、证据质量满足当前任务时,才能作为自动备用。备用工具的结果要标明来源,最终答案不能把降级数据冒充主数据源。
若备用只能提供摘要而主工具提供正文,系统可以交付部分结果或继续等待,但不能把两者视为完全等价。若用户要求最新信息,过期缓存也不是合格备用。
Tool Registry 可以为工具声明兼容组、能力差异和降级等级。网关根据任务要求选择,模型只在允许集合中调整。任何涉及权限或写操作的替代,都要重新鉴权和审批。
缓存降级有什么边界
缓存能在上游暂时不可用时提供结果,但会引入新鲜度风险。
缓存条目需要来源、生成时间、有效期、数据版本和适用范围。用户问“今天”“最新”或实时状态时,过期缓存不能作为确定答案。可以明确告诉用户结果来自较早快照,并让用户选择是否接受。
权限变化也会让缓存失效。不能因为用户过去看过某条数据,就在当前无权限时直接返回旧缓存。租户、身份和数据范围必须进入缓存隔离与校验。
缓存命中不应跳过业务验收。它只是另一种工具结果,仍需判断是否满足当前子目标。
熔断解决什么问题
当工具持续故障时,继续尝试会占满连接、拖慢所有任务,并可能压垮正在恢复的下游。熔断器在失败达到条件后暂时拒绝新调用,让请求快速走备用或降级。
熔断状态要反映到工具暴露和路由。若 Registry 已经标记不可用,但模型仍看到 Schema,就会反复选择它。新请求可以暂时不展示故障工具,正在运行的任务则收到明确 temporarily_unavailable。
恢复不能一次全量放开。可以用少量探测请求确认服务,再逐步恢复。具体触发和恢复阈值必须基于工具历史与服务目标,文章和面试中都不要把示例数字说成通用答案。
怎样返回部分结果
多工具任务中,部分来源可能成功,部分失败。系统应保存已完成证据和未完成项,而不是因为一个工具超时丢掉全部结果。
部分结果适合只读、可解释的任务。最终输出说明已完成什么、缺少什么、缺口会影响哪些结论、用户能否稍后继续。Checkpoint 保存已完成步骤,下次恢复不重复昂贵调用。
有完整性硬要求的任务不能部分交付为“成功”。例如关键审批材料缺失、写操作依赖未满足,应暂停或失败。是否允许部分结果来自任务定义,不由模型临场决定。
什么时候应该停止而不是继续聪明地尝试
达到总时间或调用预算;同一错误连续出现;备用工具也不可用;多轮没有新信息;权限或关键依赖无法满足;高风险写操作状态不确定。出现这些条件时,继续探索的预期收益已经低于风险和成本。
停止不等于丢给用户一句“失败”。系统可以返回失败位置、已完成证据、未完成原因、是否可稍后恢复,以及需要用户或人工做什么。可解释停止比无限重试更像生产系统。
超时以后,旧请求真的停了吗
应用侧返回超时,不代表下游工作已经终止。HTTP 客户端放弃等待后,服务器可能还在计算;模型请求取消后,网关可能仍然收到迟到结果;后台任务可能已经进入队列。
只读请求的迟到结果通常可以丢弃或写入缓存,但要防止它覆盖更新的数据。写请求的迟到结果更危险,用户看到失败后可能再次提交,而第一次请求稍后才完成。
因此工具需要可传播取消信号,并定义不支持取消时怎样处理。运行时给每次调用分配唯一 ID,任务停止后把该调用标记为过期。迟到结果仍进入审计和幂等台账,但不能悄悄推动已经结束的 Agent 状态。
如果下游采用异步任务,超时返回的应是“仍在处理”或任务 ID,而不是失败。Agent 可以暂停等待回调或查询状态。把所有长耗时请求硬塞进同步超时,会制造大量结果不确定。
怎样防止重试风暴
单个任务的重试看起来很轻,但大量任务同时遇到故障时,重试流量可能比正常流量更大。下游刚恢复一点容量,又被同步重试压垮,形成反复故障。
除了退避和抖动,还需要全局重试预算。网关按工具和租户限制同时重试数量,新请求与重试请求可以使用不同队列,避免旧任务占满所有资源。熔断打开后,直接走降级,不再让每个 Agent 各自试探。
恢复探测也要集中管理。由少量探针验证服务,不让所有等待任务同时成为探针。确认健康后分批放量,持续观察错误和延迟,再恢复正常路由。
重试风暴验收不能只跑单任务。要模拟一批任务同时遇到限流或超时,检查下游请求总量、排队、熔断和用户出口。没有并发场景,很多重试策略在测试中看起来都正确。
降级顺序应该提前定义
故障发生时临时让模型想一个替代方案,容易出现能力越界。可以为每类任务预先定义降级阶梯。
例如公开研究任务的阶梯可能是:主搜索服务,契约兼容备用服务,符合新鲜度要求的缓存,已有证据的部分报告,明确停止。每一级都写清证据质量和用户提示。
内部业务查询的阶梯则可能完全不同:主数据库只读接口,授权只读副本,稍后重试或人工查询。不能因为公开搜索可用,就拿它替代内部订单事实。
写操作通常不做“换一个工具继续写”。同一业务动作有多个执行通道时,需要统一幂等和事务语义。否则备用通道可能重复提交。高风险动作的安全降级往往是只生成建议或 Dry-run,不产生真实副作用。
降级阶梯应进入 Registry 或任务策略,并通过版本管理。备用工具上线、缓存策略变化和权限调整后,都要跑对应故障样本。
重规划和重试有什么区别
重试保持目标、工具和参数基本不变,假设错误是暂时的。重规划则承认原路径可能不可行,根据 Observation 修改查询、拆分步骤或选择另一种能力。
工具超时一次,网关可能先做安全重试;搜索持续为空,Agent 更适合重规划关键词;关键数据源明确不可用,Planner 可以调整输出范围。若只是换一个同名备用执行器,仍属于工具层降级,不必让模型重新生成全局计划。
这个区分能减少无意义模型调用。网络抖动不需要 Planner,任务假设被推翻才需要重规划。Trace 分开记录 retry、fallback 和 replan,才能看出系统究竟在哪里消耗资源。
怎样评估重试与降级策略
不能只统计“最终有没有成功”。还要看无重试首轮结果、重试后恢复、降级后完成、部分交付、人工接管和安全停止。重试掩盖的下游故障需要单独可见。
资源指标包括每任务尝试次数、额外工具调用、等待时间和剩余预算。安全指标包括非幂等重复、越权重试、过期缓存和停止后迟到结果是否改变状态。
任务质量要比较降级前后证据。备用来源是否满足同样要求,缓存是否明确标注时间,部分结果是否暴露缺口。若降级让系统总能输出文本,却降低事实可靠性,不能算成功。
评估集按错误类型分层,并保留不重试基线、有限重试、备用和停止策略的对照。具体阈值和收益都从真实运行记录计算,设计稿里只写判定规则。

参数、权限、暂时故障和状态不确定分别需要澄清、拒绝、退避或核对。
Trace 要记录哪些信息
每次尝试至少记录工具、版本、调用 ID、请求摘要、错误类别、单次耗时、剩余预算、是否重试、退避原因、备用选择和最终出口。
不要只记录最后一次成功。首次失败和中间尝试决定系统是否稳定,也能揭示重试掩盖了多少下游问题。
Trace 还要区分网络重试和策略换路。前者参数与目标不变,后者可能改写查询或选择不同工具。两者混在一个 retry_count 中,无法诊断问题。
敏感参数只保存脱敏摘要或引用。错误堆栈进入受控日志,模型得到安全、结构化的 Observation。
怎样做故障注入验收
注入超时
分别让工具在连接、读取和执行阶段超时,检查单次、步骤和任务预算是否生效,是否能及时取消无用请求。
注入限流
让上游返回限流信号,检查退避、抖动和服务建议等待是否被遵守,多个并发任务是否形成重试风暴。
注入返回格式变化
验证适配器能否识别契约不兼容并熔断,而不是把错误结构当正常结果交给模型。
注入空结果与权限
确认系统不会把空结果当暂时故障死循环,也不会对权限拒绝换参数探测。
注入写操作结果不确定
模拟下游成功但本地超时,恢复时应先按幂等键核对,而不是直接再次提交。
注入备用故障
主工具和备用都失败时,系统要能交付部分结果或停止,不能在工具之间来回切换。
故障演练要检查 Trace 和用户结果,不只看进程有没有崩。没有真实测试结果时,按验收方案表述,不填写预期恢复率。

可靠性不是永远成功,而是在失败时能限制损失并给出正确出口。
面试官会怎样连续追问
追问一:最大重试次数设多少
没有通用数字。根据错误恢复分布、工具幂等性、单次耗时、任务截止时间和上游限流确定,并用故障演练验证。回答方法比背次数更重要。
追问二:指数退避为什么还要随机抖动
大量任务同时失败时,如果按相同间隔重试,会再次同时冲击下游。抖动分散请求时间,降低同步重试峰值。
追问三:工具超时后为什么不能让模型决定重试
模型可以在允许动作中建议换路,但是否可重试涉及幂等、预算、权限和下游状态,应由执行策略强制。尤其写操作结果不确定时不能自由重放。
追问四:缓存为什么不能总作为降级
缓存可能过期、越权或不满足当前任务的新鲜度。必须校验来源、时间、身份和业务要求,并明确告知降级语义。
追问五:熔断后模型还会不会选这个工具
要让健康状态同步到工具暴露和路由,新请求不展示故障工具;执行网关仍拒绝旧上下文发来的调用,并返回可路由错误。
追问六:怎样避免三层重试叠加
明确 SDK、网关和 Agent 的职责,使用共享总预算和统一 Trace。底层处理瞬时传输,网关按工具策略重试,Agent 只做任务换路。
工具失败以后,怎样讲清重试决策
工具超时后我不会直接背一个重试次数,而是先分类。参数、权限和业务拒绝不自动重试;只读或可靠幂等的暂时故障,才在剩余预算内有限重试,并做退避和随机抖动;写操作超时先按幂等键查询结果,不能直接重放。超时有单次调用、当前步骤和整任务三层,重试共享总时间与调用预算,避免 SDK、网关和 Agent 多层叠加。持续失败后,只在契约等价时切备用;缓存要检查新鲜度和权限;否则返回部分结果、请求澄清、转人工或安全停止。工具健康状态同步到 Registry 和路由,避免模型持续选故障工具。最后通过超时、限流、格式变化、权限、状态不确定和备用故障注入验证完整退路。
重试策略不是口号:项目里要有这些记录
- 是否先区分参数、权限、暂时故障、永久故障和结果不确定。
- 是否同时设置单次、步骤与整任务预算。
- SDK、网关和 Agent 各自的重试责任是否清楚。
- 备用和缓存是否真的满足任务能力、新鲜度与权限。
- 写操作超时是否先核对幂等状态。
- 是否做过故障注入;没做过就只讲设计,不报恢复指标。
重试的目标不是让错误暂时消失,而是在有限预算和安全边界内争取恢复。知道什么时候不重试、什么时候降级和什么时候停止,才是这道题真正的工程深度。