第 5 章 运维、成本与安全
学习目标
- 通过最大轮数、预算上限和无进展循环检测,防止失控运行与无限循环。
- 按错误类型和幂等性设计超时与重试,防止重试风暴。
- 按可撤销性和影响范围选择人工审批节点,并将审批绑定至执行内容。
- 在执行路径中部署钩子、回调和护栏,了解各机制的覆盖范围。
- 用沙箱与最小权限限制损害范围,并制定事故响应顺序。
引言
某个星期五晚上,一个研究智能体把同样的搜索重复执行了数百次。由于搜索结果的格式发生变化,智能体无法读取结果;因为读不懂,它又再次搜索。当时轮数限制处于关闭状态,直到星期一早晨,才有人在邮箱中发现成本告警。另一家公司则发生了完全相反的事。团队给所有行动都设置了人工审批,于是每天有数百条审批请求涌来,审批者往往只花几秒钟就按下按钮。最终,一条危险的请求在无人阅读内容的情况下获得了通过。
这两起事故有一个共同点:安全依靠的是模型的判断或人的注意力。本章介绍如何把安全措施放进系统中。我们先用停止条件、预算、超时、重试和过载控制来防止运行失控,仅在危险的环节设置审批,再用钩子、回调、护栏与沙箱把强制措施嵌入执行路径,最后梳理事故响应的顺序。
核心概念
把停止条件写进系统
“任务结束就停止”只是一条建议。停止必须由运行循环的代码强制执行。OpenAI Agents SDK 的运行器是一个循环:产生最终输出后结束,出现 handoff 或工具调用则继续。通过 max_turns 限制轮数,超过时抛出 MaxTurnsExceeded 异常。传入 max_turns=None 会关闭限制,因此生产环境应由公共运行包装层强制设置上限。在 error_handlers 中配置 "max_turns" 处理器,可以不抛出异常,而返回“请缩小请求范围后重试”等受控最终输出。
result = await Runner.run(agent, "检查本周结算差异", max_turns=15)
仅有轮数限制还不够:单轮可能多次调用高开销工具,子智能体也会各自消耗轮数,相同搜索也可能反复发生。
| 机制 | 防止什么 |
|---|---|
| 最大轮数 | 无限循环 |
| 每次运行的 token 与成本上限 | 轮数无法捕捉的成本失控 |
| 子任务数量与再次委派深度上限 | 工作智能体不断派生新的工作智能体 |
| 无进展重复检测 | 不断重复相同尝试的停滞 |
| 整体截止时间 | 单次调用正常,整体却不断拖长的任务 |
停止时应留下原因、部分结果与后续选项,让用户和运营者能够决定下一步。
预算上限的层次
成本上限应分层叠加,即使一层失守,下一层也能阻挡。
| 层次 | 示例 | 达到上限时 |
|---|---|---|
| 运行 | 单个请求的 token、工具调用、金额上限 | 停止该运行并返回部分结果 |
| 用户、任务 | 每日用量 | 告警后阻断,或切换至更便宜的路径 |
| 租户、团队 | 各客户公司或团队的月预算 | 隔离,避免影响其他租户 |
| 组织、提供商账户 | 提供商控制台的支出与速率限制 | 最后一道安全网 |
也应利用提供商的限制。Claude API 支持自行设置组织与工作区级支出上限,并为各工作区设置更低的支出、速率限制,避免一个工作区过度使用影响其他工作区(默认工作区除外)。达到自行设置的支出上限时,通常返回 400 错误(Claude Code 工作区可能是带 retry-after 的 429);达到用量等级的月度支出上限时,返回不带 retry-after 的 429。后一种情况下,访问恢复前,包括 SDK 自动重试在内的任何重试都会失败,因此应根据错误内容区分,转为通知运营者,而不是继续重试。
OWASP Top 10 for LLM Applications 2025 将这类风险归为无界消耗(Unbounded Consumption,LLM10),并举出通过过量调用使成本暴涨的钱包拒绝服务(denial of wallet)攻击。对策包括验证输入大小、设置用户级速率限制与配额、超时与吞吐调节、用量监测,以及保留部分功能的优雅降级。
多个执行者并发运行时,仅靠事后结算难以守住上限。可以在启动执行者前预留预计费用,结束后再结算,减少同时出发的执行者合计超限的情况。
检测无进展循环
即使调用次数不多,只要反复遭遇同一失败,任务就没有创造价值。衡量进展的信号如下。
- 连续 N 次以相同参数调用同一工具。
- 连续返回相同错误消息。
- 最近 M 轮没有新依据、新文件或状态变化。
- 失败后仍以相同工具和参数组合重试。
发现信号后,应停止运行,把重复调用记录、错误信息和截至目前的产出整理后转交人工。检测在工具包装层或循环代码中进行,因此无论模型是否遵守指令,都能生效。
超时与截止时间
超时是客户端等待请求完成的最长时间。Amazon Builders' Library 的文章建议,不要凭感觉决定超时时间,而应先确定能够容忍的误超时比例,例如 0.1%。误超时指的是放弃等待一个本来很快就会完成的请求。然后,以该比例对应的百分位数(例如 p99.9)上的下游服务延迟为依据,设置超时时间。对于远程调用,应同时设置连接超时和请求超时。
对于智能体,还需要为整个任务设置截止时间。即使每个步骤都符合各自的超时设置,随着重试次数和步骤不断增加,整个任务仍可能无限拖长。因此,要将剩余时间分配给后续步骤;时间不足时,就不再启动新的步骤。MCP 规范也建议为所有请求设置超时,并补充说明:虽然收到进度通知时可以重新计时,但始终应强制执行最大超时限制。对于模型调用,Claude API 文档建议,可能耗时超过 10 分钟的长请求应使用流式传输或批处理 API。
重试
重试有助于从瞬时故障中恢复,但用 Amazon 的话说,它是“自私的”:为了提高成功概率,会消耗更多服务器容量。过载时重试只会加剧过载。原则如下。
| 原则 | 内容 |
|---|---|
| 区分错误类型 | 只重试暂时性错误(速率限制、过载、连接断开)。输入错误与违反业务规则不应原样重试,应利用错误信息恢复 |
| 指数退避与抖动 | 等待时间指数增长,但设置上限,并加入随机性(抖动),避免重试同时涌入 |
| 次数限制 | 设置尝试次数上限 |
| 只在一个层级重试 | 各层分别重试会使调用负载按各层尝试次数的乘积放大。Amazon 的文章警告,五层调用中每层尝试三次,会让数据库负载增加至 243 倍(3⁵) |
| 遵守服务器等待指示 | 存在 retry-after 时,等待指定时长 |
| 幂等性 | 有副作用的 API 只有提供幂等性,才能安全重试 |
也应把 SDK 默认重试计算在内。Claude 官方 SDK 对连接错误、速率限制、5xx 等暂时性失败,默认按指数退避重试两次,并遵守 retry-after。如果上面的工具包装层再重试三次,智能体又重试三次,一次失败就会变成数十次调用。应明确只由一个层级负责重试。无法确认是否已经执行的失败(第 2 章),应先查询处理结果,再考虑重试。
并发与过载控制
单个任务失控,不应阻碍其他用户的正常工作。可以使用四种机制。
- 并发限制:按组织、用户、工具限制同时运行的任务与外部调用数量。
- 队列与准入控制:队列变长时,延缓接收新任务或降低其优先级,排队等待也设置过期时间。
- 熔断器(circuit breaker):下游服务失败率超过阈值时,在一段时间内阻断调用,避免把资源浪费在注定失败的请求上,并为下游恢复留出时间。就像电路断路器在电流过大时断开电路。平时处于闭合(放行)状态,阻断时打开,一段时间后进入半开状态发送探测调用,成功后重新闭合。
- 优雅降级:无法处理时,只保留部分功能,例如“已受理,处理完成后通知”。
内部限流相比固定时间段重置,使用持续补充额度的令牌桶方式更容易处理瞬时激增(Claude API 的速率限制也采用这种方式)。
人工审批节点
所有行动都要求审批,审批者很快就会不读内容直接点击,这就是审批疲劳。OpenAI 指南建议,根据工具是读还是写、能否撤销、所需账户权限与金钱影响,为每个工具划分低、中、高风险,并在高风险函数执行前自动接入护栏检查或转交人工等措施。指南列举的两类人工介入时机是:超过失败阈值(多次尝试仍无法理解意图)和高风险行动(取消订单、大额退款、付款);高风险行动应在信任建立之前保持人工监督。
判断有两个维度:可撤销性与影响范围。
| 影响小(个人、内部) | 影响大(客户、外部、金钱) | |
|---|---|---|
| 可撤销 | 自动执行 | 限额内自动,超限审批 |
| 难以撤销 | 请求用户确认后执行 | 必须由有权限的审批者批准 |
审批界面应展示实际执行内容(对象、金额、收件人、数量)、依据和追踪链接。只有审批请求减少,每一项才会被认真阅读。
将审批绑定至执行内容
审批与执行之间存在空隙:审批者看到的金额可能与实际参数不同;审批后对象可能变化;同一审批可能被执行两次。将审批与执行内容绑定,就能封住这些空隙。
- 审批请求包含全部执行参数,将执行参数按固定键顺序规范化序列化后的内容哈希值,或预览 ID(第 2 章),保存到审批记录。
- 执行前由服务器核对实际参数是否与已批准内容一致;不一致则不执行,重新获取审批。
- 为审批授权设置有效期,且仅限使用一次,用后即失效。
- 执行时重新核实审批者权限。审批本身不会赋予新的业务权限。
在 OpenAI Agents SDK 中,为工具设置 needs_approval 后,运行会暂停,待审批条目进入结果的 interruptions。将其转换为 RunState,批准或拒绝后,以相同状态继续。序列化状态包含待执行工具参数,因此应按文档建议,保存在服务器控制的存储中,只恢复可信快照。还应记住,本地 ShellTool 与 ApplyPatchTool 的审批是可选的,needs_approval 默认值为 False。
放在执行路径中的阻断机制
禁止事项应放进执行路径,而不是只写进提示词。工具真正执行之前,代码必须能够检查并阻断。
| 框架 | 执行路径中的阻断机制 |
|---|---|
| Claude Code | PreToolUse 钩子以退出码 2 结束时,工具调用被阻断,钩子的标准错误输出会作为阻断原因传给 Claude。阻断发生在权限规则评估前,即使有 allow 规则也会阻断。反过来,即使钩子返回允许,也不能跳过 deny、ask 规则。权限规则按 deny → ask → allow 顺序评估,首个匹配规则决定结果。但在没有托管设置或 Team、Enterprise 登录的环境中,已安装扩展模块(mod)的 tool.check 处理器可能推翻这一结果 |
| Google ADK | before_tool_callback 返回值时,跳过真实工具执行,并将该值作为工具结果;返回 None 则正常执行。文档建议安全护栏与策略使用插件,而不是回调。插件向 Runner 注册一次,即可应用于所有智能体、工具与模型调用;它先于对象级回调运行,返回值时会跳过后续插件与原操作 |
| OpenAI Agents SDK | 输入、输出护栏与工具护栏。违规检测信号(安全绊线,tripwire)触发时,通过抛出异常停止运行 |
ADK 插件的短路(short-circuit)规则带来顺序问题。在 Python 中,插件按注册顺序运行,遇到第一个返回值的插件就停止;如果直接返回结果的插件放在前面,后面的检查不会执行。必须通过注册顺序确认强制检查的位置。
护栏的适用范围
必须准确了解 OpenAI Agents SDK 护栏覆盖哪些位置。
- 输入护栏只在链中的第一个智能体运行,输出护栏只在产生最终输出的智能体运行。
- 输入护栏默认与智能体并行运行(
run_in_parallel=True)。护栏触发前,智能体可能已经消耗 token 并执行工具。对使用有副作用工具的智能体,应设为run_in_parallel=False,让智能体等护栏完成后再开始。文档也建议用这种方式节约成本、防止工具副作用。 - 工具护栏包裹函数工具(
FunctionTool),不适用于 handoff 调用本身;托管工具,以及ShellTool、ApplyPatchTool等内置执行工具,不经过这条管道;Agent.as_tool()目前也不直接暴露工具护栏选项。
注意
只说“已经加了护栏”,并不能保证安全。请确认它作用于哪个智能体、哪个时点、哪类工具调用。空隙往往出现在 handoff、托管工具与并行执行中。
沙箱与最小权限
对于处理不可信输入或执行代码的智能体,要通过环境本身保障安全,而不能依赖模型的判断。沙箱是一种隔离环境,在操作系统层面限制正在运行的程序能够触及哪些文件、进程和网络。
Claude Code 的沙箱就是一个很好的例子。沙箱默认关闭,开启之后,shell 命令及其子进程就会受到操作系统强制执行的边界限制:macOS 使用 Seatbelt,Linux 和 WSL2 使用 bubblewrap。在 Windows 原生环境中运行时没有沙箱,因此必须在 WSL2 内使用。文档所说明的边界如下。
- 写入范围限制在工作目录、临时目录等位置,但读取范围默认对设备上的大部分内容开放,其中包括
~/.ssh等凭据文件。要阻止这些读取,需要设置denyRead。 - 网络通信必须经过代理,由代理检查允许访问的域名列表;这个列表最初为空。文档警告,如果允许访问
github.com等范围宽泛的域名,就可能为数据泄露提供通道。 - 内置的文件和网页工具在沙箱之外运行,由权限规则控制。命令钩子和本地 MCP 服务器以用户的完整权限运行,因此如果连它们内部的操作也需要限制,就必须另行隔离。
- 如果命令在沙箱中执行失败,可以请求到沙箱之外重试。设置
allowUnsandboxedCommands: false可以关闭这个出口。如果希望在无法启动沙箱时完全不执行命令,则要开启failIfUnavailable。
文档把权限规则和沙箱解释为相互补充的防护层。原因在于,即使提示词注入绕过了模型的判断,沙箱的限制依然存在。文档还警告,跳过全部确认的 bypassPermissions 模式,只应在容器或虚拟机等不会让损害扩散出去的隔离环境中使用。
OWASP 将智能体采取有害行动的风险归为过度代理权(Excessive Agency,LLM06),并将其根源归结为过多的功能、过大的权限和过高的自主性。应对措施包括:尽量减少扩展功能及其作用范围,避免范围开放、不受限定的扩展,遵循最小权限原则,在用户的权限上下文内执行,对影响较大的行动要求人工审批,以及实行完全中介(complete mediation),即由下游系统判断行动是否获准,而不是让 LLM 作出这一判断。
提示词注入与权限隔离
提示词注入是指输入能够使模型的行为偏离原定意图的一种漏洞(OWASP LLM01)。它分为用户直接输入的直接注入,以及隐藏在网页、文件等外部来源内容中的间接注入。对于能够使用工具的智能体,间接注入尤其危险,因为智能体本来只是想阅读一份文档,文档却反过来向它发出了行动指令。
OWASP 提出的应对措施包括:约束模型行为,定义并验证预期的输出格式,过滤输入和输出,实施权限控制与最小权限,对高风险行动要求人工审批,分离并标记外部内容,以及进行包含攻击模拟在内的对抗测试。设计的关键,是从无法完全检测出注入这一假设出发。因此,需要在读取不可信内容的步骤与执行不可撤销行动的步骤之间,设置权限边界。例如,读取外部内容之后,要求对外发送工具在执行前取得人工确认;或者让只读的子智能体阅读内容,只把摘要传回来。
事故响应
智能体执行了错误批量操作时,应遵循以下顺序。
- 阻断:立即关闭写入工具或智能体本身(紧急停止开关)。提前准备无需部署即可修改的配置(功能开关),支持按工具、租户或整体关闭,并确保关闭时不丢弃追踪与日志。
- 确定范围:用追踪与审计日志确定受影响对象和时间,保存证据。
- 恢复:只对已确认范围执行撤销或补偿。回滚程序版本,与消除或补偿外部操作已经造成的影响,是两回事。
- 防止复发后恢复运行:修复原因,将案例加入回归评估并确认通过,再逐步重新开放权限。
要做到这些,平时就必须具备审计日志、追踪、紧急停止开关,以及可撤销的写入设计。组织层面可以从 NIST AI 风险管理框架(AI RMF)入手。该框架供自愿使用,通过治理(Govern)、背景识别(Map)、测量(Measure)、管理(Manage)四项功能处理 AI 风险,并另有生成式 AI 配套文件(NIST AI 600-1)。法律规定的报告或记录义务,因行业与司法辖区不同,应另行确认。
深入阅读
部分成功与补偿操作
一项任务如果需要依次修改多个外部系统,那么中途发生失败时,就会留下只有部分修改已经生效的状态。这些修改不能像数据库事务那样一次性全部取消,因此必须为每个步骤预先定义补偿操作,也就是抵消已经发生的效果的反向操作。这种方式在分布式系统中称为 saga 模式。如果已经创建了预约,补偿操作就是取消预约;如果已经发放了额度,补偿操作就是收回额度。
补偿也有其局限。补偿操作本身可能失败,而且还存在发送通知、转账等实际上无法收回的行动。因此,需要安排好各步骤的先后顺序:容易撤销的步骤放在前面,无法撤销的步骤放在最后。对外通知要等全部内部修改都已确定生效之后再发送。如果记录了各步骤的确定生效节点和部分成功的状态,事故响应时就能够更快地确定影响范围并实施恢复。
不破坏运行中任务的部署
长时间运行的智能体改变了部署的性质。数小时任务仍在运行时,如果改变工具参数格式或提示词,现有任务可能在新代码中失败。Anthropic 的研究系统指出,他们使用彩虹部署(rainbow deployment),让新旧版本同时运行,逐步转移流量,避免干扰正在执行的智能体。
设计原则有三条。第一,将模型、提示词、工具定义和策略绑定为一个运行配置版本,并记录每个任务启动时的版本。第二,进行中的任务用原版本运行到底,只有新任务进入新版本。第三,改变工具参数格式时,在一段时间内同时接受新旧格式。变更前,还可以通过影子运行降低风险:并行运行新版本,但不产生真实副作用,观察行为差异。
逐步扩大自主性
不可逆工具不应一次性完全开放。先通过模拟运行观察行为,实际运行开始时对每一项都加人工审批;随后只从人工修改比例和事故数量持续低于标准的低风险区间,逐步扩大自动化。应预先量化扩大自动化与回退的触发条件。正如 OpenAI 指南所说,对高风险行动的人工监督应保持到信任建立为止。
工作场景
出游票务:开票日的重试风暴
演出票务平台“出游票务”的咨询智能体帮助用户查询预订、变更座位和提交取消申请。热门演出开票当天,外部订票系统的响应延迟由平时的 p99 0.8 秒增加到了 12 秒。模型 SDK 先进行了默认重试,工具包装层又额外尝试三次,智能体看到失败后,又重新调用了同一个工具。在一个小时内,对订票系统的调用次数达到了平时的 9 倍,每次咨询的成本变成了原来的 5 倍。等待队列不断积压,连正常咨询也迟迟得不到响应。
团队否决了三个替代方案。把超时时间延长到 60 秒,会更长时间地占住连接,使并发处理量进一步下降。增加执行者的数量,则会给已经变慢的订票系统施加更多负载。降低 max_turns 虽然能够减少成本,却没有改变各层重试次数相乘的结构。
修改内容如下:只允许工具包装层这一处进行重试,采用指数退避和抖动,最多重试两次;同时向智能体返回恢复指引:“订票系统正在延迟响应。不要再次调用,请向用户提供受理说明。”对于订票系统的调用,按租户设置并发上限。如果 30 秒内的失败率超过 50%,熔断器就打开,阻断调用 2 分钟;之后,如果探测调用成功,熔断器便重新闭合。在熔断器打开期间,智能体只受理座位变更和取消申请,等处理完成后再发送通知。每次咨询设置 90 秒的整体截止时间,同时设置 token 用量和工具调用次数上限。座位变更请求则附上由预订编号和变更申请编号生成的幂等键,即使发生重试,也只受理一次。
下一次开票当天,同样的延迟再次出现,但对订票系统的调用量仅维持在平时的 1.4 倍,正常咨询的响应时间几乎没有变化。
溪流结算:减少审批,让审批真正有效
结算代理公司“溪流结算”试运行一个查找并更正商户结算错误的智能体。所有更正都要求审批后,每天审批请求超过 400 项,平均审核时间降至 4 秒。
团队按风险划分工具:查询与报告撰写自动执行;不超过 10 万韩元、且会在下一次结算抵扣的更正,在日限额内自动执行;超过 10 万韩元的更正及对商户的外部通知,必须审批。审批不靠指令,而是在更正工具前的执行步骤强制实施;审批界面同时展示金额、依据与追踪链接。审批记录保存更正内容的哈希,执行前参数不一致则不执行,重新请求审批。审批 24 小时后过期。每天审批请求降至约 30 项,审核者逐渐开始为每项请求花费超过 1 分钟,实际阅读其内容。
团队还设置每次运行的最大轮数与成本上限,相同参数查询超过五次则停止并通知。一个月后,源数据格式变化,重复查询再次发生,但检测机制在 3 分钟内停止了运行。运营者用紧急停止开关仅关闭更正工具,保留查询,修复解析器,把案例加入回归集后再开放更正工具。被否决的方案是“增加审批者”,因为请求仍有 400 项,增加审批者也不会增加对每项的注意力。
易错点
- “所有行动都要求审批,才最安全。” 控制措施越多,看上去就越安全,但如果审批疲劳使审核流于形式,危险请求同样会得到通过。应根据可撤销性和影响范围,选择哪些行动需要审批。
- “已经在系统提示词中写明禁止事项,就能阻止这些行为。” 模型大多数时候都会遵循指令,因此容易让人相信这一点,但指令只是建议。对于无法撤销的行动,必须在执行路径中实施阻断。
- “既然有输入护栏,带有副作用的工具也安全。” 入口处设有检查站,会让人感到安心;然而,在默认的并行执行方式下,护栏触发之前,工具就可能已经执行过了。
- “重试次数越多,成功率就越高。” 人们容易觉得再试一次就会成功,但在过载时,重试会进一步加重负载;如果每一层都重试,调用量还会按乘积增加。应只在一个层级重试,设置退避、抖动和次数上限。
- “设置了轮数限制,就不会出现成本失控。” 循环终会结束,这让人放心,但轮数无法约束一轮内的昂贵调用、子智能体不断派生,以及重复搜索造成的成本。
- “打开了沙箱,秘密就不会泄露。” “隔离”听上去可靠,但如果读取范围仍然开放,或者允许访问范围宽泛的域名,泄露通道就仍然存在。还有一些工具是在沙箱之外运行的。
- “只要留下审计日志,就不需要审批。” 有了记录,看起来就像受到了控制,但日志是用来事后追踪的,不能让已经删除的数据恢复原状。
- “既然已经获得批准,直接照着执行就行。” 人已经确认过,似乎事情就结束了,但在审批与执行之间,参数仍可能改变。应将审批绑定到具体执行内容,设置有效期,并限制为一次性使用。
要点速览
| 项目 | 应记住的答案 |
|---|---|
| 谁强制停止 | 循环代码:轮数 + 成本 + 子任务数 + 进展检测 + 截止时间 |
| 预算 | 运行、用户、租户、组织分层限制,提供商上限是最后安全网 |
| 超时 | 根据误超时率和延迟百分位设置,始终强制最大超时 |
| 重试 | 仅暂时性错误、单一层级、指数退避与抖动、次数上限、幂等性 |
| 过载 | 并发限制、熔断器、优雅降级 |
| 审批对象 | 难以撤销且影响大的行动,按风险等级自动接入 |
| 审批绑定 | 对照内容哈希与预览 ID,设置过期、一次性使用,重新检查权限 |
| 护栏范围 | 输入在首个智能体,输出在最终智能体;默认并行运行;工具护栏仅覆盖函数工具 |
| 沙箱 | 对 shell 命令施加操作系统边界;单独检查读取、宽泛域名与沙箱外工具 |
| 事故响应 | 阻断 → 确定范围 → 恢复 → 防止复发后逐步恢复运行 |
查阅官方文档
- OpenAI Agents SDK: Running agents — 智能体循环、
max_turns、错误处理器 - OpenAI Agents SDK: Guardrails — 输入、输出与工具护栏的适用范围和执行方式
- OpenAI Agents SDK: Human-in-the-loop —
needs_approval、中断与恢复 - Claude Code: Hooks reference — PreToolUse 阻断与退出码
- Claude Code: Configure permissions — 规则评估顺序、与钩子的优先级、bypass 警告
- Claude Code: Sandboxing — 沙箱边界、网络允许列表与局限
- Google ADK: Plugins — 全局策略、与回调的优先级、短路规则
- OWASP: LLM06 Excessive Agency — 过多的功能、权限、自主性及其对策
自测
5-1. 列出仅靠最大轮数无法防止的两种成本失控,并写出各自的防范机制。
5-2. 模型 SDK、工具包装层和智能体各自重试,会产生什么问题?建议采用什么设计?
5-3. 工具调用因超时结束后,哪些情况下不能立即记为失败并重新发送?应改做什么?
5-4. 解释为什么所有行动都要求人工审批反而可能更危险,并列出选择审批对象的两个维度。
5-5. Claude Code 中,PreToolUse 钩子的阻断(退出码 2)与权限规则(allow、deny)是什么关系?
5-6. 列出 Claude Code 沙箱没有包裹的两类内容,并说明它们应如何控制。
5-7. 为单个用户设置每日智能体成本上限,设计系统分别在达到上限 80% 与 100% 时的行为。
实操练习
练习
编写风险表并加入停止机制(60 分钟)
- 列出一个正在运营的智能体的所有工具,分别标注可撤销性(可撤销、难撤销、不可撤销)与影响范围(个人、客户、外部)。
- 对难以撤销或影响外部的工具,在执行步骤设置审批(钩子、回调、工具包装层任选其一),在审批记录中保存执行参数哈希。
- 设置最大轮数、每次运行成本上限,以及相同参数重复检测。
- 分别使用诱导持续调用同一工具的输入,以及审批后改变参数的输入进行测试。
完成标准: 需审批工具未经批准不会执行,审批后参数改变的调用被拒绝;面对重复诱导输入,运行在限额内停止,原因记录在日志中。
练习
重试与成本上限模拟(45 分钟)
- 创建包裹一个工具的模拟服务器,使其可按配置产生延迟与暂时性错误(速率限制、过载)。
- 将当前结构中 SDK、包装层和智能体的尝试次数相乘,计算一次失败最多会产生多少次调用,并实际测量。
- 将重试集中至一个层级,加入指数退避、抖动、上限,并遵守
retry-after。 - 设置每次运行成本上限与用户每日上限,确认达到 80% 时告警、100% 时阻断。
完成标准: 表中记录修改前后“一次失败的最大调用次数”的实测值,并至少各记录一次达到限额后的告警与阻断。