在一家生意火爆的餐厅后厨,主厨就是那位 AI 智能体,每天把几十张点菜单派给各档口——凉菜、炒锅、蒸锅、甜品站,这些档口就是“工具”。生意好的时候看不出差距,真正的本事全藏在“出错之后”:点菜单字迹潦草看不懂(参数格式错误)、招牌菜原料缺货(服务不可用)、蒸笼里的一道菜二十分钟没动静(超时)、客人催单后同一道菜被做了两遍(重复副作用)。一位成熟的主厨早有整套应急预案:接单先核对菜单(参数校验),偶发小问题等一会儿再催(指数退避重试),催了三次还不上就换替代菜(超时降级),同时用订单号保证催过的菜绝不上两遍(幂等去重),还要提防故意捣乱的客人(对抗攻击防范)。本文就用这间后厨的故事,把工具调用错误处理设计讲得明明白白。

岗位关联

在对抗样本生成与攻防实战中,工具调用错误处理是 AI 系统的最后防线。掌握校验、重试、降级、幂等四大设计,能让你的 Agent 应用在真实环境中既稳且安,是 AI 工程师从“能跑”走向“可靠”的必修课。

目录
  1. 可视化演示
  2. 错误处理概述
  3. 参数校验重试
  4. 超时降级
  5. 幂等性设计
  6. 攻击风险防范
  7. 工程实践要点
  8. AI 应用场景
  9. Python 演示
  10. 常见误区
  11. 面试题

可视化演示

展示工具调用从校验、执行到错误重试、超时降级的完整状态机流转,点击按钮切换不同环节视图

本节配有交互动效(进入视口后自动加载,约 3KB)。

错误处理状态机总览 调用→校验→执行构成正常路径 校验失败或执行错误进入重试 重试达上限触发降级兜底 成功路径直接返回结果 七状态机构成完整错误处理闭环

错误处理概述

后厨最怕的不是忙,而是“没有预案的忙”。新来的主厨接到一张字迹潦草的点菜单,可能当场懵在原地;而老主厨在接单的瞬间就已经想好了三件事:这张单子可能错在哪里、错了该怎么办、怎么保证补救本身不会闯出更大的祸。预案,才是后厨真正的定海神针。

工具调用也一样。大模型生成的参数可能缺字段、外部服务可能随时宕机、网络环境可能突然抖动——任何一个环节都可能出错。把“出错”当作常态来设计,是 AI 应用工程化的起点。错误处理不是事后补救的补丁,而是调用方与被调用方之间事先约定好的一份“应急预案”。

一个工具调用链路通常包含四个环节:生成参数、参数校验、执行工具、返回结果。每个环节都有典型错误:校验失败、执行超时、结果异常、被恶意利用。处理策略要组合使用——参数校验负责筛掉坏请求,指数退避重试对付暂时性故障,超时降级负责止损,幂等设计防止重复副作用。四者互相配合,构成完整的防御纵深。

这就像后厨的应急预案要覆盖“接单—备料—烹制—上菜”每一个环节:哪个环节都可能出岔子,而整套流程的可靠性,取决于最弱的那一环。工具调用错误处理的本质,就是把每一环的失败概率都压下来。

Psuccess=∏i=1n(1−pi)P_{\text{success}} = \prod_{i=1}^{n} (1 - p_i)
整条工具调用链路共 n 个环节,只要任何一个环节失败,这次调用就失败。所以总成功率等于所有环节成功率的乘积。
  1. 成功概率符号$P_{\text{success}}$ 表示整条调用链路最终成功的概率。
    PsuccessP_{\text{success}}
  2. 连乘符号$\prod$ 表示对 $i$ 从 1 到 $n$ 逐个相乘,把每个环节的成功率乘在一起。
    ∏i=1n\prod_{i=1}^{n}
  3. 单环节成功率环节 $i$ 的失败概率为 $p_i$,则它的成功率是 $1 - p_i$。
    1−pi1 - p_i

参数校验重试

主厨接到菜单不会马上下锅,而是先做三件事:菜名在不在菜单上、辣度写法对不对、桌号存不存在。这三件事哪怕错一件,做出来的菜也只会被退回来,白白浪费一整条烹饪链路。所以老主厨的规矩是:单子没看清,绝不开火。

这就是参数校验的价值。它把“请求本身写错了”和“服务临时不可用”区分开来:前者叫永久性错误,后者叫暂时性错误。永久性错误重试一万次还是错,就像菜单上根本没有“红烧鲸鱼”,主厨再看十遍菜单也做不出来——所以面对校验失败,最优策略是快速返回错误码,而不是无谓重试。

真正值得重试的是暂时性错误,比如服务繁忙、网络抖动。重试也不是莽撞地狂点,而是要“指数退避”:第一次等 0.2 秒,第二次等 0.4 秒,第三次等 0.8 秒——给下游恢复的时间,也避免自己变成新的攻击源。同时必须设最大重试次数,比如 3 次,防止无限等待耗尽调用方资源。

后厨的规矩是“催菜最多催三次,越催等得越久”。指数退避重试的本质与此完全一致:既表达了调用方的诚意,又给了对方喘息的空间,还用次数上限管住了自己的耐心。

P成功=1−pk+1P_{\text{成功}} = 1 - p^{k+1}
假设单次调用失败概率为 $p$(仅限暂时性错误),最多重试 $k$ 次,总共 $k+1$ 次尝试,那么全部失败的概率是 $p^{k+1}$,反之至少成功一次的概率就是公式所示。
  1. 单次失败率$p$ 表示一次工具调用因暂时性故障而失败的概率。
    pp
  2. 全部失败的概率$k$ 次重试加上首次尝试,一共 $k+1$ 次独立尝试全部失败。
    pk+1p^{k+1}
  3. 至少一次成功用 1 减去“全部失败”的概率,就是整体成功率。
    1−pk+11 - p^{k+1}

超时降级

蒸笼里那道粉蒸肉二十分钟没动静,主厨绝不会干等。他会先看一眼蒸锅温度计(超时检测),再问切配师傅原料备好了没(排查根因),最后果断决定:换一道凉拌菜顶上(降级)。宁可让客人吃上一道替代菜,也不能让整桌人空着肚子干等。

工具调用同样要设“耐心上限”——超时时间。超时要分两层:连接超时(连都连不上)和读超时(连上了但不回话)。超时设太久,调用方线程被占满,下游一故障就是雪崩;设太短,正常的慢请求又会被误杀。实践中讲究“快速失败”:宁可早降级,不可死等待。

降级策略通常分三档:第一档用缓存结果,拿上次的查询结果顶上;第二档换替代工具,用一个便宜的近似服务;第三档简化功能,只返回核心字段。同时配合熔断机制——连续失败 N 次后,直接拒绝后续调用并快速返回失败,让下游有时间恢复。指数退避的节奏,同样适用于超时后的重试。

主厨最清楚:一道菜坏了事小,整桌客人的体验坏了事大。超时降级就是这种“弃车保帅”的智慧——用一次可以接受的损失,换整体流程的持续可用。

tn=t0×2n−1t_n = t_0 \times 2^{n-1}
指数退避的时间公式:第 $n$ 次重试前要等待的时长,是基础等待时间 $t_0$ 的 $2^{n-1}$ 倍,即 1 倍、2 倍、4 倍、8 倍地增长。
  1. 基础等待$t_0$ 是第一次重试前的基准等待时间,例如 0.2 秒。
    t0t_0
  2. 次数关系$n$ 表示第几次重试,$n-1$ 是它相对第一次多翻倍的次数。
    2n−12^{n-1}
  3. 第 n 次等待将基准时间乘以翻倍数,得到本次重试的等待时长。
    tn=t0×2n−1t_n = t_0 \times 2^{n-1}

幂等性设计

客人催了一次菜,主厨大声答应“马上上”,结果传菜员又把这张单子送到了后厨,同一道菜被做了两遍。客人不会感激“双份菜”,只会为多出来的等待和浪费皱眉。后厨的解法很简单:每张订单都有唯一订单号,上菜前先核对这个号做过没有。

这就是幂等性:同一个操作执行一次与执行多次,效果完全一样。对工具调用而言,最危险的不是“调用失败”,而是“调用失败后重试,结果把副作用重复执行了”——比如重复扣款、重复下单、重复发消息。重试本身是安全的,前提是重试的请求必须携带同一个幂等键。

工程实现上,调用方为每次逻辑请求生成唯一的 request_id(幂等键),服务端维护一张“键 → 结果”的缓存表:收到请求先查 key,命中就直接返回已缓存结果,不再执行;未命中才真正执行并把结果写入缓存。这样一来,即使请求在网络里被重发了十次,也只有第一次会真正产生副作用。幂等键需要稳定、唯一、可预测——同一个逻辑请求每次都算出同一个键。

后厨用“订单号”换来了“催菜自由”:客人怎么催都不怕重复上菜。幂等性给重试和超时策略上了保险——有了它,重试才敢放手去做。

f(f(x))=f(x)f(f(x)) = f(x)
幂等性的数学定义:操作 $f$ 对输入 $x$ 执行两次,和执行一次的效果完全相同。
  1. 一次执行操作 $f$ 对输入 $x$ 执行一次,得到结果。
    f(x)f(x)
  2. 再次执行把 $f(x)$ 当作新的输入再执行一次 $f$。
    f(f(x))f(f(x))
  3. 结果不变两次执行的结果等于一次执行的结果,即幂等成立。
    f(f(x))=f(x)f(f(x)) = f(x)

攻击风险防范

不是所有客人都善良。有的客人故意报假菜名,让主厨白忙一场;有的客人不停地催菜,把传菜员的精力耗尽;还有客人反复投诉同一道菜,企图让后厨免费重做。后厨的应急预案,必须把这些“捣乱者”也考虑进去,否则预案本身就会变成漏洞。

在对抗攻防视角下,错误处理逻辑本身就可能成为攻击面。攻击者会利用参数校验“只查有没有、不查合不合理”的漏洞,注入超长字符串或特殊字符的边界参数,让校验层防不胜防——这本质上就是对抗样本的思路:在合法边界内制造极小扰动,让系统行为偏离预期。

典型的攻击有三类:参数注入攻击,构造恶意参数绕过校验或触发危险工具;超时滥用攻击,反复触发超时和重试,耗尽调用方与下游资源,形成拒绝服务;重放攻击,截获合法请求重复提交,利用幂等缺失造成重复副作用。防护上需要做到:严格校验参数长度与类型、限制单来源调用频率、强制幂等键、对敏感工具实施二次确认与行为审计。

后厨对捣乱者的态度不是“不接待”,而是“有制度地接待”——核对身份、限量催单、留痕取证。工具调用错误处理中加入对抗思维,才能在攻防博弈中立于不败之地。

δ=arg⁡max⁡∥δ∥∞≤ϵL(f(x+δ),ytarget)\delta = \arg\max_{\|\delta\|_\infty \le \epsilon} \mathcal{L}(f(x+\delta), y_{\text{target}})
对抗样本的构造公式:在合法输入 $x$ 上叠加一个微小的扰动 $\delta$,让模型 $f$ 的预测向攻击者期望的标签 $y_{\text{target}}$ 偏移,同时保持扰动幅度不超过 $\epsilon$ 以维持隐蔽性。
  1. 叠加扰动$x + \delta$ 表示在原始合法输入上叠加噪声 $\delta$,仍然通过参数校验。
    x+δx + \delta
  2. 最大化损失$\arg\max \mathcal{L}$ 表示寻找让损失函数最大化的扰动方向,使预测偏向目标标签 $y_{\text{target}}$。
    arg⁡max⁡∥δ∥∞≤ϵL(f(x+δ),ytarget)\arg\max_{\|\delta\|_\infty \le \epsilon} \mathcal{L}(f(x+\delta), y_{\text{target}})
  3. 幅度约束$\|\delta\|_\infty \le \epsilon$ 限制每个维度上的扰动幅度不超过 $\epsilon$,保证攻击难以被察觉。
    ∥δ∥∞≤ϵ\|\delta\|_\infty \le \epsilon

工程实践要点

预案写得再好,不演练也是废纸。老主厨每个月都会做一次“后厨演习”:假装断水、假装停电、假装食材被调包,看后厨能不能在十分钟内完成切换。演习之后,把每个环节的耗时记录在案,下一次继续提速。

工具调用错误处理的工程化,同样离不开三件事:看得见、说得清、靠得住。看得见,是日志与监控;说得清,是错误码规范;靠得住,是降级演练。没有监控的错误处理如同盲人摸象——你不知道重试到底成功了多少次,降级到底触发了多少次。

具体的实践清单包括:建立统一的错误码体系,区分客户端错误(4xx)与服务端错误(5xx);用结构化日志记录每次调用的工具名、参数摘要、耗时、错误类型和幂等键;为关键指标设置告警,如重试率、超时率、降级率和熔断打开次数;定期进行故障演练,验证降级链路真的能跑通。系统整体可用性,则由平均无故障时间与平均修复时间共同决定。

后厨的底气来自日复一日的演练与记录,AI 系统的可靠亦是如此。所有错误处理设计,最终都要落到“可观测、可演练、可改进”的工程闭环里,才算真正落地生根。

A=MTBFMTBF+MTTRA = \frac{\text{MTBF}}{\text{MTBF} + \text{MTTR}}
可用性公式:MTBF 是平均无故障时间,MTTR 是平均修复时间。可用性等于“正常运行时间”占“总时间”的比例。
  1. 平均无故障时间$\text{MTBF}$ 表示系统两次故障之间的平均间隔时间,越长越可靠。
    MTBF\text{MTBF}
  2. 平均修复时间$\text{MTTR}$ 表示故障发生到恢复的平均耗时,越短恢复越快。
    MTTR\text{MTTR}
  3. 可用性$A$ 是可用时间占总时间的比例,分子是正常运行时间,分母是总时间。
    A=MTBFMTBF+MTTRA = \frac{\text{MTBF}}{\text{MTBF} + \text{MTTR}}

AI 应用场景

智能助手替用户完成预订

阶段:Agent 工具调用与执行

解决的问题:智能助手替用户订机票、订酒店时,一次调用可能涉及真实扣款。若网络抖动触发重试而没有幂等保护,用户会被重复扣款;若参数校验缺失,模型幻觉生成的车次、日期会被直接提交。通过“参数校验 + 幂等键 + 超时降级”三件套,可以保证“只扣一次款、失败有兜底”。

具体案例:用户对 AI 助手说“帮我订一张周三北京到上海的经济舱机票”。助手调用订票工具,第一次请求因网络抖动超时;系统用同一个 request_id 重试,服务端识别是同一逻辑请求,直接返回已生成的订单,不重复扣款。若查询航班接口持续超时,则降级为返回热门的推荐航班列表,而不是让用户干等。

大模型 Function Calling 的安全防护

阶段:模型推理输出 → 工具指令执行

解决的问题:大模型生成的函数参数可能缺字段、格式出错,甚至被恶意用户的 prompt 注入诱导,输出危险的工具调用指令(如删除文件、转账)。错误处理中的校验层成为安全闸门:校验工具白名单、参数类型和长度,同时对敏感工具做权限确认与频率限制。

具体案例:攻击者通过精心构造的提示词诱导模型调用"delete_file"工具并传入任意 file_id。参数校验层发现该工具不在当前会话白名单内,直接拒绝执行并记录告警;即使攻击者反复发送请求触发超时,限流与熔断机制也会快速失败,避免调用方资源被耗尽。

对抗样本攻击下的错误处理链路

阶段:对抗攻防中的输入清洗与容错

解决的问题:对抗样本生成方向的研究者发现,攻击者可以在合法参数边界内制造微小扰动,使工具调用输出偏离预期。错误处理设计中的“校验边界收紧 + 幂等去重 + 行为审计”能够有效缩小攻击面,把对抗扰动挡在工具执行之前。

具体案例:在评测一个 AI 问答系统时,红队构造了“超长文本 + 特殊 Unicode”的查询参数,企图绕过长度校验触发后端接口异常。系统按预案识别为非合规参数并快速返回错误,同时限制同一来源的高频调用,最终该攻击向量未能造成任何实际影响。

Python 演示

python71 行
import hashlibimport jsonimport time  class ToolCaller:    def __init__(self, max_retries=3, base_delay=0.2):        self.max_retries = max_retries        self.base_delay = base_delay        self.result_cache = {}        self.exc_count = 0     def validate(self, tool_name, params):        schema = {            "search": ["query"],            "book_ticket": ["flight_no", "date"],            "delete_file": ["file_id"],        }        if tool_name not in schema:            raise ValueError("unknown tool: " + tool_name)        missing = [k for k in schema[tool_name] if k not in params]        if missing:            raise ValueError("missing params: " + ",".join(missing))     def execute(self, tool_name, params):        self.exc_count += 1        if self.exc_count < 3:            raise TimeoutError("simulated transient timeout")        if tool_name == "search":            return {"result": "flights found: CA123"}        if tool_name == "book_ticket":            return {"result": "booked", "ticket": params["flight_no"]}        if tool_name == "delete_file":            return {"result": "deleted", "file": params["file_id"]}        raise ValueError("unsupported tool")     def invoke(self, tool_name, params, request_id=None):        if request_id is None:            request_id = hashlib.md5(                json.dumps([tool_name, params], sort_keys=True).encode()            ).hexdigest()        if request_id in self.result_cache:            return self.result_cache[request_id]        try:            self.validate(tool_name, params)        except ValueError as exc:            return {"ok": False, "error": str(exc), "retryable": False}        last_error = None        for attempt in range(self.max_retries + 1):            try:                result = self.execute(tool_name, params)                self.result_cache[request_id] = result                return result            except TimeoutError as exc:                last_error = exc                time.sleep(self.base_delay * (2 ** attempt))        fallback = {"ok": False, "error": str(last_error), "retryable": True}        self.result_cache[request_id] = fallback        return fallback  if __name__ == "__main__":    caller = ToolCaller(max_retries=2, base_delay=0.05)    req_id = "req-001"    r1 = caller.invoke("book_ticket", {"flight_no": "CA123", "date": "2025-01-01"}, req_id)    r2 = caller.invoke("book_ticket", {"flight_no": "CA123", "date": "2025-01-01"}, req_id)    print("first call: ", r1)    print("second call:", r2)    print("idempotent hit:", r1 == r2)    bad = caller.invoke("book_ticket", {"flight_no": "CA123"})    print("validation fail:", bad)
目的:实现一个带参数校验、指数退避重试、超时兜底和幂等去重的工具调用器,演示完整错误处理设计。
  1. if request_id in self.result_cache:幂等检查:同一个幂等键直接返回缓存结果,不重复执行工具。
  2. request_id = hashlib.md5(json.dumps([tool_name, params], sort_keys=True).encode()).hexdigest()由请求内容生成确定性幂等键,相同逻辑请求映射到同一个键。
  3. self.validate(tool_name, params)执行前的参数校验,对照 schema 检查必填字段。
  4. return {"ok": False, "error": str(exc), "retryable": False}校验失败标记为不可重试(永久性错误),直接返回。
  5. time.sleep(self.base_delay * (2 ** attempt))指数退避:重试等待时间逐次翻倍。
  6. self.result_cache[request_id] = result成功结果写入缓存,保障后续相同请求的幂等返回。

常见误区

误区“我遇到过校验失败,多试几次说不定就通过了,所以给校验失败也加上重试逻辑,甚至重试 5 次。”

正解校验失败是永久性错误——参数本身不符合 schema,重试不会改变参数,只会白白浪费资源。就像菜单上根本没有“红烧鲸鱼”这道菜,主厨再看十遍菜单也做不出来。正确做法是区分永久错误与暂时错误:校验失败直接返回错误码,网络抖动等暂时性错误才进入重试流程。

为何常见:初学者分不清“请求写错了”和“服务临时不可用”的区别,把所有失败都当成网络抖动来处理。

误区“把超时设成 60 秒,这样慢一点的服务也能等到结果,调用成功率就上去了。”

正解超时是调用方的保护性预算。设太长会导致调用方线程被长期占用,下游一旦故障,大量请求堆积形成雪崩。正确做法是分层设置超时(连接超时 + 读超时),并遵循“快速失败”原则,配合降级与熔断,让系统尽早止损。

为何常见:只看到了单次成功率的提升,没看到资源占用和故障放大效应。

误区“调用失败后重试一次很安全,最多多花一点时间,不会有别的影响。”

正解如果工具调用有副作用——下单、扣款、发消息——无幂等保护的重试会导致重复执行。必须配合幂等键:同一个逻辑请求携带相同的 request_id,服务端按 key 去重,重试只是再取一次已缓存的结果。就像后厨用订单号保证同一位客人的催单不会变成两份菜。

为何常见:用查询类工具(无副作用)的经验套用到写操作类工具,忽视了状态变更的重复执行风险。

误区“降级兜底返回了结果,流程走通了,这件事就可以翻篇了。”

正解降级只是止损,不是治疗的终点。必须记录日志、触发告警,并分析根因——是超时参数不合理?下游服务故障?还是被攻击者利用?如果长期“带病运行”,主路径的质量会持续退步,用户最终流失。后厨每次换替代菜后,主厨都会追问“为什么会缺货”,而不是一换了之。

为何常见:把“流程没断”误当成“系统健康”,缺乏故障闭环与根因分析的意识。

误区“幂等键嘛,每次请求生成一个随机 UUID 就完事了。”

正解幂等键必须对同一个逻辑请求保持稳定。如果每次重试都生成新的随机键,服务端会认为是不同请求,幂等保护完全失效。正确做法是基于请求内容生成确定性哈希,或者由上层业务流程显式传入业务单号。

为何常见:把“唯一性”当成了幂等键的全部要求,忽略了“可复现”这一更关键的属性。

面试题

Q1. 工具调用中参数校验失败通常属于哪类错误?

单选题 · easy

  • A.永久性错误,应避免重试← 正确答案
  • B.暂时性错误,应立即重试
  • C.网络波动导致,可长时间重试
  • D.超时导致的错误,需快速降级

答案:A。参数校验失败意味着请求本身不符合 schema,重试不会改变请求内容,属于永久性错误。就像菜单上不存在的菜,主厨再看十遍单子也做不出来。正确策略是快速返回错误码,而非重试。

Q2. 指数退避重试的核心思想是什么?

单选题 · easy

  • A.每次重试使用固定间隔
  • B.重试间隔随次数指数增长← 正确答案
  • C.重试次数不设任何限制
  • D.对所有错误类型都进行重试

答案:B。指数退避让等待时间按 1 倍、2 倍、4 倍递增,既给下游恢复时间,也避免自己成为新的攻击源。固定间隔和大重试次数都不可取,永久性错误更不应重试。

Q3. 幂等键在工具调用中的主要作用是什么?

单选题 · easy

  • A.提升请求网络传输速度
  • B.识别相同逻辑请求并去重← 正确答案
  • C.作为参数加密的密钥
  • D.代替参数格式校验

答案:B。幂等键让服务端识别“同一个逻辑请求”,命中缓存键后直接返回结果,不再重复执行副作用操作。它不负责传输加速、加密或校验,这些是其他机制的分工。

Q4. 工具调用持续超时时,推荐的降级策略是?

单选题 · mid

  • A.无限重试直到成功为止
  • B.立即抛出异常终止流程
  • C.采用缓存或替代工具兜底← 正确答案
  • D.忽略错误并继续执行

答案:C。降级的本质是“用可接受的损失换整体可用”:缓存结果、替代工具、简化功能都是常见兜底。无限重试会放大故障,直接终止则牺牲用户体验,忽略错误更是灾难。

Q5. 熔断机制的核心目标是什么?

单选题 · mid

  • A.提高工具调用的成功率
  • B.快速失败以保护下游依赖← 正确答案
  • C.增加每次调用的重试次数
  • D.消除系统中所有的超时

答案:B。熔断在连续失败达到阈值时直接拒绝新请求,让下游有时间恢复,属于保护性机制。它不直接提高成功率,也不是为了多重试,更无法消灭超时,而是把故障隔离在局部。

Q6. 攻击者反复构造超时请求的主要危害是什么?

单选题 · mid

  • A.窃取工具返回的敏感数据
  • B.耗尽资源造成拒绝服务← 正确答案
  • C.注入恶意代码并远程执行
  • D.篡改工具调用的参数

答案:B。反复触发超时会让调用方持续占用线程、等待和重试,最终耗尽计算资源,形成拒绝服务攻击。这类攻击不直接窃取数据,也不执行代码,而是利用错误处理设计的“宽容”来拖垮系统。

Q7. 攻击者构造对抗样本攻击工具参数校验时,核心思路是什么?

单选题 · hard

  • A.让校验规则完全失效
  • B.在合法边界内做微小扰动← 正确答案
  • C.直接绕过网络防火墙
  • D.删除服务端的审计日志

答案:B。对抗样本的精髓是“扰动足够小、但足以让系统偏离预期”,对应 $\|\delta\|_\infty \le \epsilon$ 的约束。攻击者不会试图让校验完全失效,而是在合法边界上找漏洞,保持隐蔽的同时达成攻击目标。

Q8. 关于工具调用重试策略,以下说法正确的有?

多选题 · mid

  • A.永久性错误不应重试← 正确答案
  • B.暂时性错误可以重试← 正确答案
  • C.重试需配合退避等待← 正确答案
  • D.重试次数越多越可靠

答案:ABC。永久性错误重试无意义,暂时性错误配合指数退避重试才有价值。重试次数并非越多越好——无限重试会放大故障、耗尽资源,必须设上限并配合熔断。

Q9. 一个完整的工具调用错误处理方案通常包含?

多选题 · mid

  • A.参数校验规则← 正确答案
  • B.指数退避重试← 正确答案
  • C.超时降级兜底← 正确答案
  • D.幂等结果去重← 正确答案

答案:ABCD。四个环节缺一不可:校验筛掉坏请求,重试对付暂时故障,降级负责止损,幂等防止重复副作用。它们组合起来才构成完整的防御纵深,单靠任何一项都不够。

Q10. 防御针对错误处理链路的对抗攻击,以下哪些是有效措施?

多选题 · extreme

  • A.严格校验参数长度与类型← 正确答案
  • B.限制单来源调用频率← 正确答案
  • C.用幂等键防止重放攻击← 正确答案
  • D.无限制增加重试次数

答案:ABC。严格校验可挡住注入攻击,限流可遏制超时滥用,幂等键可消除重放危害,这些都是对抗防护的关键手段。而无限制增加重试次数恰恰是攻击者希望看到的——它会让资源耗尽更快发生。