# 面向 AI 智能体的 CDN 清除范围预览

AI 智能体绝不能只用一句“清除 CDN 缓存”来请求批准。这句话隐藏了操作员授权前唯一真正需要知道的事实：哪个主机、哪条路径、多少个标签，以及可能有多少缓存内容会停止提供服务。

有效的 CDN 清除范围预览会把最终请求转化为一段紧凑的影响范围说明。它还必须把定向失效与全部清除归入不同的风险等级。我见过宽泛的清除操作把一次常规发布变成源站流量事故，原因只是批准对话框让通配符看起来像一条无害的路径。请求在语法上很短，影响却一点也不小。

正确的设计不只是增加一个确认框。它会规范化供应商请求、判断范围类别、诚实地估算影响，并把操作员的批准绑定到这些精确参数上。如果智能体在批准后更改主机、路径、标签、环境或清除模式，网关必须重新请求批准。

## 清除请求需要影响模型

CDN 清除范围是供应商可能使其失效的缓存表示集合，而不是 API 请求中的字符串数量。一个通配符可以覆盖整个分发。一个标签可能对应数千个互不相关的 URL。一个 URL 也可能存在多个缓存变体，因为缓存会按查询字符串、请求头、Cookie、设备类型或语言区分内容。

这是团队经常混淆的第一个区别：请求大小不等于影响大小。Amazon CloudFront 的文档明确说明了这种差异。即使一条通配符失效路径会让数千个文件失效，它仍只算一条提交路径。计费单位描述的是请求，不是影响范围。如果批准卡片只写“1 条路径”，却不说明路径是 `/*`，它在技术上没有说错，在运维上却毫无用处。

应从四个维度描述拟执行的操作：

- **目标：** CDN 账户、服务或分发、环境和主机名。
- **选择器：** 精确 URL、路径前缀、通配符、缓存标签、替代键或供应商的全量清除标志。
- **语义：** 选择器如何组合、覆盖哪些变体，以及供应商会让缓存对象失效还是删除它们。
- **后果：** 预计受影响的对象或请求数量、预期的回填行为，以及陈旧内容能否继续提供。

这个模型应放在执行网关中，靠近凭据和供应商适配器。不要让智能体自行给操作指定风险标签。智能体可以提出清除请求，但理解供应商 API 的代码必须计算这个请求实际意味着什么。

这种分离很重要，因为各供应商的术语并不一致。Fastly 把分组标签称为替代键。Google Cloud 和 Akamai 使用缓存标签。Cloudflare 支持标签、主机名、URL 前缀、单个文件和全部清除。CloudFront 支持路径、通配符和缓存标签失效。通用智能体工具可以提供一个整洁的接口，但预览必须保留供应商真实的匹配规则。

执行组件在显示任何内容前，应解析别名，根据供应商规则规范主机、解码并规范路径、展开便捷选项，并确定实际环境。预览随后描述将被签名和发送的请求。若显示智能体之前提供的、更易读的输入，规范化过程就可能扩大范围，而人类对此毫不知情。

## 定向失效和全部清除是两种不同操作

定向失效通过精确 URL、有限路径或前缀、一个或多个标签，或受支持选择器的交集来选择内容。全部清除会丢弃整个服务、区域或分发的有效状态。把它们当作同一个下拉菜单中的两个值，会弱化两者的差别。

分类必须根据影响，而不是端点名称。以下请求都应标记为全部清除：

- 供应商明确的 `purge_everything` 标志。
- 分发路径 `/*`。
- 规范化后指向根目录的通配符或前缀。
- 根据本地约定会标记服务中每个响应的标签。
- 其并集覆盖全部已配置主机的选择器列表。

最后两种情况需要本地元数据。供应商可能不知道 `release-current` 出现在服务的每个对象上，但应用该标签的部署系统可以记录这一事实。如果网关无法证明某个选择器有明确边界，就应把影响标为未知，并提高批准等级。未知是有效结果。把未知悄悄当作小范围则不可接受。

定向并不等于安全。大型商店中的 `/products/` 前缀可能覆盖大部分流量，`tenant:42` 标签也可能横跨多个主机。这个标签只说明请求表达了一个预览能够展示的边界。操作员仍需要知道边界内大约包含什么。

全部清除需要在视觉和机制上使用独立流程。要求使用 `purge_all` 这样的明确操作名，不要让适配器把空选择器解释为全部内容。在定向模式中拒绝空主机和空路径字段。让操作员明确批准生产环境和作为整体的命名服务。不要因为同一个智能体此前执行过无害的 URL 清除，就让一般会话批准自动覆盖此操作。

有一条流行建议我明确反对：“每次清除都要求确认就够了。”反复出现的同类确认会训练人们批准对话框的外形，而不是阅读内容。发布期间的单文件失效和整个分发的清除，不应该显示相同的按钮、警告或认证步骤。只有界面把实质差异表达清楚时，人工批准才有作用。

## 主机、路径和标签数量应放在按钮上方

批准卡片应先显示实际目标和范围，因为操作员经常在时间压力下阅读。先放供应商和生产环境，再放主机名、规范化路径、标签数量、预计影响和操作类别。补充细节可以在下方展开，但会改变决定的事实必须无需点击就能看到。

供应商无关的预览可以采用这种结构：

```json
{
  "operation": "targeted_invalidation",
  "provider": "example-cdn",
  "environment": "production",
  "hosts": ["assets.example.test"],
  "paths": ["/releases/2026-07-24/*"],
  "tag_count": 2,
  "tag_samples": ["release:842", "asset:bundle"],
  "selector_logic": "host AND path AND (tag OR tag)",
  "estimated_reach": {
    "objects": {"low": 1600, "high": 2300},
    "method": "tag-index snapshot",
    "observed_at": "2026-07-24T14:31:08Z"
  },
  "refill": "origin requests expected on subsequent misses"
}
```

这些数字只是示例，并不承诺 CDN 可以统计每一个仍在边缘节点中的对象。重要的是输出结构：一个范围、估算方法和观测时间。如果估算器没有可靠依据，就返回 `"objects": "unknown"` 并说明原因。

主机只有少数几个时，应全部显示。如果列表很长，则显示数量和排序后的前几个名称，并明确提供查看其余内容的入口。绝不要把混合了生产和预发布环境的列表概括成“12 个主机”。环境边界比数量更能影响决策。

路径既要显示规范化后的值，也要说明匹配规则。在 Google Cloud CDN 上，`/picture*` 和 `/picture/*` 并不是同一个选择器：前者还会匹配 `/pictures/dog.jpg` 和 `/picture1.jpg` 等路径，后者则限制在该目录下。CloudFront 要求通配符位于末尾才会把它当作通配符，其他位置的星号会按普通字符处理。只显示原始字符的预览，会迫使操作员在最不合适的时候回忆供应商语法。

标签数量也需要措辞准确。“2 个标签”表示两个选择器，而不是两个缓存对象。除非标签含有敏感的租户信息，否则应显示全部标签。若确有敏感信息，则显示稳定的脱敏标签，并提供安全的详情视图。还要说明标签以 OR 还是 AND 组合。Google Cloud CDN 会以 OR 处理一次请求中的多个标签，而标签过滤器与主机及路径匹配器组合时，则通过交集缩小结果。这一行简短逻辑往往解释了大部分影响范围。

## 预计影响必须承认 CDN 无法统计的内容

预计影响应回答“可能有多少缓存状态发生变化”，同时承认分布式缓存并不是库存数据库。边缘对象会因过期、淘汰、区域需求和后台回填而出现或消失。许多 CDN 清除 API 接受选择器，却不返回预检数量。

按照固定顺序使用现有的最佳证据。如果 API 提供数据，最近的供应商计数最可靠。其次是部署系统维护的标签索引，它记录每个标签被应用到了哪些 URL。再往后可以使用明确时间范围内的请求日志或缓存状态遥测。已配置的路由目录可以提供粗略上限。如果这些都没有，就报告未知。

每项估算都应包含四个属性：

- 单位，例如缓存对象、URL 变体或最近的缓存命中请求。
- 点估计或范围，绝不能只是一个没有标签的整数。
- 来源和观测时间。
- 由代码根据来源类型和数据新鲜程度得出的置信度标签。

不要把最近的请求量换算成对象数量。“过去一小时约有 80,000 次缓存命中请求匹配此前缀”是有用的影响证据，但并不意味着会有 80,000 个对象失效。如果两类数据都可用，就同时显示：预计对象数描述缓存状态，最近命中量描述可能的回填压力和用户暴露程度。

即使是精确 URL，影响也可能超过一个对象。CloudFront 文档指出，让某个文件失效也会使按转发 Cookie 或请求头区分的缓存变体失效。查询字符串行为取决于配置和选择器。如果实际行为如此，预览应写明“1 个 URL，全部 Cookie 和请求头变体”。只写对象数为一，会隐藏真正重要的部分。

对标签应估算并集，而不是直接求和。如果 `release:842` 覆盖 1,700 个对象，`asset:bundle` 覆盖 900 个对象，重叠对象只能计算一次。供应商以 OR 应用标签时，将两个计数相加可能夸大影响。对批准阈值来说，高估比低估安全，但仍会损害信任。本地索引能够计算真实并集时就这样做，否则把总数明确标成上限。

对于全部清除，不要浪费时间制造精确数字。写明“整个生产服务”，显示已配置的主机数量，再附上最近的缓存命中量作为源站压力指标。操作类别已经告诉操作员缓存边界在哪里。虚假的精度看似信息充分，实际并没有为决定增加任何价值。

## 预览必须说明回填后果

清除会改变后续请求的去向，所以批准内容必须同时描述回填行为和选择器。运维风险通常不在于陈旧内容消失，而在于大量未命中请求集中打到原本按缓存可分担流量来配置容量的源站。

Google Cloud 文档建议只让必要的内容失效，因为大范围失效会把原来由缓存响应的请求推回实例或存储桶。它还要求先确认源站已经返回正确内容，否则 CDN 可能再次缓存错误响应。第二点应成为智能体工作流中的前置条件：提出清除前，先在源站验证新对象。

Fastly 还区分硬清除和软清除，这一点很有用。硬清除会让缓存内容无法用于后续查找。软清除把内容标成陈旧，根据配置，缓存可能在重新验证期间继续提供陈旧内容。Fastly 不支持对全部清除使用软清除。只写“清除”的批准会丢失这项运维差别。

因此，预览应包含：

- 操作是硬失效、软失效，还是供应商特有的删除。
- 刷新期间能否继续提供陈旧内容。
- 如果有数据，所选范围最近的缓存命中请求速率。
- 将接收未命中请求的源站或后端组。
- 源站就绪检查是否通过，以及何时执行。

避免承诺“将产生 2,300 个源站请求”之类的数字。请求合并、区域分布、浏览器缓存、分层屏蔽和新鲜回填都会影响实际负载。应使用近期实测流量并如实描述：“所选范围在此前 15 分钟内产生了 46,000 次缓存命中。”这比虚构的预测更能帮助操作员。

智能体不应通过不受限制的 shell 自行运行就绪检查，再概括检查结果。网关应针对目标源站执行定义明确的检查，记录响应状态和内容版本，并把证据附到预览中。否则，受恶意提示影响的智能体可以在同一段对话中一边声称源站已就绪，一边请求批准。

## 规范化消除显示和执行之间的差距

网关必须批准一个规范操作，然后执行同一个操作。如果 UI 渲染一种表示，而供应商适配器发送另一种表示，批准流程就只剩形式。

规范化从类型明确的字段开始。分别设置 `hosts`、`paths`、`tags`、`purge_all`、`soft`、`provider`、`service_id` 和 `environment`。不要把自由格式的 curl 命令当作批准对象。适配器最终可能生成 HTTP 请求，但策略和显示代码应操作经过验证的数据。

随后在分类前应用供应商规则。把主机名转为小写，删除 DNS 名末尾的点，拒绝内嵌凭据，解析服务别名，并在解析路径时不把片段当作请求的一部分。如果 CDN 区分路径大小写，就必须保留大小写。使用与供应商一致的 URL 规范化规则，并考虑重写。Cloudflare 警告说，如果 Transform Rules 会改写 URL，前缀清除需要使用转换后的源站 URL。CloudFront 建议在查看器请求函数改写路径时，同时让用户看到的 URI 和改写后的 URI 失效。预览应显示两条实际路径，而不是悄悄添加第二条。

规范化后，一个简短的分类函数就能约束危险情况：

```text
if purge_all is true:
    return PURGE_ALL
if any normalized path covers the root:
    return PURGE_ALL
if any tag is cataloged as service_wide:
    return PURGE_ALL
if selectors are empty:
    return REJECT
return TARGETED
```

供应商适配器需要根据各自语法设计测试。测试应涵盖根路径、编码分隔符、重复斜杠、末尾斜杠、通配符位置、空数组、混合主机、查询字符串和重写后的 URL。属性测试可以断言，规范化绝不会让执行范围大于显示范围。回归夹具应把规范化预览和精确的出站请求保存在一起。

最后，对规范操作和预览中的重要元数据计算摘要。批准记录应包含操作员、智能体进程、工具名称、规范参数、环境、估算时间、摘要和过期时间。OWASP 的 AI Agent Security Cheat Sheet 建议把批准绑定到确切操作，并记录操作员、工具、目标、规范参数、时间和过期时间。这个标准是对的。人类针对一个摘要作出的决定，不能授权之后使用不同路径的请求。

## 范围漂移时，批准必须以拒绝告终

预览后的任何实质变化都必须使批准失效。实质字段包括供应商、账户、服务、环境、主机、路径、选择器逻辑、标签、清除模式，以及定向和全部清除的分类。只有估算发生变化时，未必每次都要重新提示，但只要跨过配置的影响阈值，就必须重新批准。

批准有效期应较短，因为缓存状态和流量会变化。如果智能体等待到另一次部署之后，路径中可能已经包含不同对象，源站就绪证据也可能过时。过期后应强制重新生成预览，不能只让操作员再次点击旧数据。

Model Context Protocol 的工具规范说，应用应让人类始终能够拒绝工具调用，并应显示确认提示。这个原则合理，但通用确认不足以保护破坏性基础设施调用。宿主应用可能知道工具名称和 JSON 参数，但只有执行适配器知道某个供应商别名映射到生产环境，也只有它知道 `/` 加通配符意味着全部内容。应由能够解释并强制执行这些事实的组件提供有意义的预览。

批准还必须独立于智能体控制的文本。智能体可以提供“移除召回的商品图片”这样的理由，但应把它放在明确标注为智能体解释的次要区域。范围事实必须由可信代码和供应商配置生成。批准卡片的任何字段都不应允许 Markdown、终端转义序列或任意 HTML。

高影响操作需要更强的阻力。定向的精确 URL 清除可以只需一次点击。宽泛前缀可以要求操作员复述范围后再有意确认。全部清除应要求独立认证，并且不能继承周围智能体会话的批准。Sallyport 可以把凭据留在智能体之外，在受保护的 CDN API 密钥每次使用时显示批准，并记录产生的 HTTP 调用；供应商适配器仍要提供规范化范围字段，才能让这项批准真正有用。

失败时必须关上闸门。如果估算器超时，就显示未知而不是零。如果规范化失败，就拒绝请求而不是透传原始输入。如果审计日志写入失败，就不要执行。如果发送时摘要不同，就丢弃批准并生成新预览。

## 审计记录需要保存决定和结果

清除审计轨迹应保存人类看到的内容、网关发送的内容和 CDN 返回的内容。只记录智能体的工具请求，无法证明规范化、批准和执行指向同一个范围。

记录规范请求、渲染过的预览字段、估算来源、批准摘要、批准者身份、批准时间、执行时间、供应商请求标识和供应商响应。标明供应商是接受、完成、部分完成还是拒绝了操作。如果供应商提供后续状态，应追加状态观测，而不是改写原始事件。

估算和结果必须分开保存。即使供应商返回成功，预计 2,000 个对象仍只是估算。大多数成功响应只代表供应商接受了选择器，并不表示它找到了恰好这么多缓存对象。审计人员应能分辨哪些说法来自本地推断，哪些来自 CDN。

CloudFront 文档说明，提交后的失效无法取消，因为边缘节点会很快开始处理。因此，执行前记录格外重要。撤销按钮可以阻止智能体未来的调用，但不能收回已经分发到边缘节点的清除。审计界面不应暗示它能做到这一点。

调查时，无需阅读聊天记录就应能回答这些问题：

- 哪个已签名的智能体进程提出了操作？
- 哪个人批准了哪个规范摘要？
- 卡片把操作归类为定向还是全部清除？
- 卡片上显示了哪些主机、路径和标签？
- 当时影响估算器掌握了什么信息？

智能体在对话中的理由只是补充背景，不是授权依据。聊天内容可能被截断、概括，或受到不可信内容影响。执行日志才是操作的持久记录。

当自主进程能够反复发起基础设施调用时，防篡改证据非常重要。Sallyport 从同一份加密且带哈希链的审计日志中记录智能体会话和单次调用，因此团队可以在不读取内容的情况下单独验证日志链。这不能撤销错误的清除，但能给响应人员提供一条可辩护的提议、批准和执行顺序。

## 一个完整故障说明四个字段为何重要

假设一个智能体正在准备商店发布。任务要求在部署后刷新新的商品资源。智能体在构建清单中看到 `/products/`，于是选择前缀清除，因为它比枚举带哈希的文件更简单。

原始请求只包含一条路径。薄弱的对话框显示“清除 1 条路径吗？”，操作员随即批准。CDN 在所有已配置主机上解释此前缀，其中包括公开商店、区域主机和图片主机。该路由还包含商品页面、缩略图、库存片段和旧版资源。热门对象一起从缓存中消失，随后又从同一源站组回填。

有效的预览会在执行前改变这个决定。它会显示：

1. **主机：** 三个生产主机，并显示各自主机名。
2. **路径：** `/products/*`，说明它是递归前缀，而不是一个文件。
3. **标签：** 没有标签，尽管当前版本有专用标签。
4. **预计影响：** 38,000 个 URL 变体和最近 120 万次缓存命中请求，两项都标明来源和时间范围。

操作员拒绝该请求。智能体随后只对资源主机提出发布标签清除。网关解析出索引中的 1,840 个对象，指出两个标签值以 OR 组合，并显示该操作不包含商品 HTML 和库存响应。源站检查确认了当前版本标识。操作员批准这个范围更窄的摘要。

场景中的数字仅用于说明，但这种故障模式很常见，因为前缀语法看起来成本很低。补救办法不是写出更聪明的智能体提示。执行边界必须让宽泛选择器清晰可见，并给人类提供范围更窄的选项。

同一模式还能发现另一种错误：智能体要求清除预发布环境，但服务别名解析到了生产环境。如果预览只写“服务 `storefront`”，操作员可能看不出问题。如果它先写“生产”，并列出公开主机，错误就一目了然。

这个过程还说明标签数量为什么不能代替影响范围。一个发布标签可能标记 1,840 个对象，而二十个精确 URL 标签可能只标记二十个对象。应把选择器数量和预计匹配数作为两项独立事实显示。前者描述请求，后者描述可能的影响。

## 把安全边界作为可执行契约交付

团队应把清除预览实现为智能体工具、供应商适配器、批准 UI 和审计日志之间的契约。这个契约足够小，可以测试：规范输入进入系统，经过分类并绑定摘要的预览从系统输出，执行端只接受与该摘要对应且未过期的批准。

至少要强制执行以下不变量：

- 定向模式至少有一个非根选择器，并明确指定环境。
- 全部清除模式使用独立操作，不能由空字段触发。
- 显示的主机、路径、标签数量和选择器逻辑来自规范参数。
- 影响范围必须是有来源的区间、上限、流量指标或明确的未知。
- 执行时重新计算摘要，并拒绝参数已改变的请求。

针对每种受支持的 CDN 操作，用录制的夹具运行适配器。比较出站请求和预览快照。增加一个源站能承受清除的金丝雀服务，然后测试精确 URL、前缀、标签并集、主机限制、重写路径和全部清除。只回显智能体输入的试运行不能证明任何事情，测试必须覆盖规范化和供应商请求构造。

正常发布路径应继续使用带版本的内容。Google Cloud 文档建议使用合适的过期时间或版本化 URL，而不是把失效当作常规操作，这个建议很可靠。清除适用于纠错、召回和无法等待 TTL 的情况。每次部署都执行清除的智能体，会把异常控制变成对源站容量的隐性依赖。

确实需要清除时，预览应让操作员快速批准。操作员无需解读供应商 JSON，就应能看到 `assets.example.test`、`/releases/842/*`、两个标签和预计 1,600 到 2,300 个对象。对于全部清除，卡片上同一位置应写“整个生产服务”，不能用很小的请求数量淡化这个事实。

我的检验标准很直接：操作员能否只看批准按钮上方的可信字段，在两秒内区分单个资源刷新和整个服务清除？如果不能，就不该让智能体持有这项 CDN 操作能力。
