一个 SaaS 开发者在 Vercel 上跑了三个月的 Claude API,收到 Anthropic 的账单时发现某天凌晨被一个前端 while(true) 循环打掉了 180 美元。查日志发现那段代码在报错后没有 break,同一个 prompt 在 4 小时内被重复调了 2600 次。
这种事故不需要后端大改。Cloudflare AI Gateway 在 API 调用链路上插了一层边缘代理,不改现有代码就能卡住速率、缓存重复请求、并在 Claude 不可用时自动切到备用模型——核心功能全部免费。
五分钟接入:从 api.anthropic.com 到 Gateway
登录 Cloudflare Dashboard,左侧菜单找到 AI → AI Gateway,点 Create Gateway,起个名字(比如 my-saas-prod)。创建完成后你会得到一个端点地址:
https://gateway.ai.cloudflare.com/v1/{account_id}/{gateway_id}/anthropic/
然后改一行代码。以 Anthropic Python SDK 为例:
# 改之前
client = Anthropic(api_key="sk-ant-...")
# 改之后
client = Anthropic(
api_key="sk-ant-...",
base_url="https://gateway.ai.cloudflare.com/v1/abc123/my-saas-prod/anthropic/"
)
Node.js / TypeScript 同理:
import Anthropic from '@anthropic-ai/sdk';
const client = new Anthropic({
apiKey: process.env.ANTHROPIC_API_KEY,
baseURL: 'https://gateway.ai.cloudflare.com/v1/abc123/my-saas-prod/anthropic/',
});
不需要装任何新依赖,不需要改请求体或响应解析。Gateway 对 Anthropic SDK 是协议兼容的透传——它只是把 HTTP 流量在边缘节点上拦截、记录、可选择性缓存或限速。
如果你用的是 2026 年 5 月新上的 Unified REST API,还可以指向 https://gateway.ai.cloudflare.com/v1/{account_id}/{gateway_id}/ai/v1/messages,这个端点的请求/响应格式与 Anthropic Messages API 完全一致。
速率限制:固定窗口 vs 滑动窗口,选哪个
在 Gateway 设置页打开 Rate Limiting,你会看到三个参数。
| 参数 | 可选值 | 适用场景 |
|---|---|---|
| 限制类型 | 请求次数 / Token 消耗量 | Token 模式适合按成本控制,请求次数模式适合防滥用 |
| 窗口技术 | 固定窗口 / 滑动窗口 | 固定窗口有边界突刺风险,滑动窗口更严格 |
| 窗口大小 | 10s / 1min / 10min / 1h | 按你的用户交互频率选择 |
固定窗口的一个实际案例:你设每分钟 60 次限制。用户在 12:00:59 发 60 个请求,全部通过;12:01:00 又发 60 个请求,再次全部通过。两秒内实际通过了 120 个请求,但速率限制一条都没拦。
滑动窗口解决了这个问题:它检查「过去 60 秒内」而不是「这一分钟窗口内」。同一个用户在第 61 个请求时会被 429 拦截。
对于 SaaS 产品,建议同时使用两个维度:
- 网关级滑动窗口:限制单 IP / 单 API Key 每分钟不超过 20 次 Claude 调用。这层拦住明显的脚本攻击。
- 应用层 Token 预算:在请求里通过
cf-aig-metadataheader 附加用户 ID,在 Worker 或应用层再做按用户日 Token 计数。这层拦住正常用户的无意超支。
当一个独立开发者的 SaaS 跑在 Vercel 上、通过 Cloudflare Gateway 调用 Claude API 时,整条链路是 Vercel → Cloudflare 边缘节点 → Anthropic。如果部署环境与 Cloudflare 边缘之间的网络不稳定,Gateway 的 20-60ms 额外延迟可能被放大到 200ms 以上。保持海外银行 + Stripe + AI 工具全场景的网络路径稳定,能让 Gateway 的延迟开销保持在可忽略的范围内。
响应缓存:什么时候开,TTL 设多少
Gateway 的缓存是精确匹配模式:它把 provider、endpoint、model、auth header 和完整 request body 拼在一起做 SHA-256,完全相同的请求才会命中缓存。
这意味着两个关键行为:
- 同一句
"给我写一篇 SEO 文章"被两个不同用户调用,只要 API Key 不同,不会共享缓存。缓存 Key 里包含了 auth header。 temperature: 0的请求命中率远高于temperature: 0.7,因为随机种子不同会导致 body 不同。
| 请求类型 | 建议 TTL | 理由 |
|---|---|---|
| 系统 prompt(固定的 system message) | 3600 秒(1 小时) | 这段文本不变,缓存直接省掉每次的 input token |
| 知识库问答(RAG 场景) | 300-900 秒 | 知识库会更新,但用户重复问相同问题的概率高 |
| 对话续写(chat history) | 不缓存 | 聊天记录每次都不同,缓存命中率趋近于 0 |
| 工具调用(function calling) | 60-300 秒 | 同一组工具定义 + 相同用户意图可能重复出现 |
通过 cf-aig-cache-ttl header 可以按单次请求覆盖默认 TTL:
curl https://gateway.ai.cloudflare.com/v1/{account}/{gateway}/anthropic/v1/messages \
-H "cf-aig-cache-ttl: 600" \
-H "x-api-key: sk-ant-..." \
-d '{...}'
回复里的 cf-aig-cache-status: HIT 或 MISS header 告诉你本次是否命中缓存。上线后先跑 24 小时看 Dashboard 里的缓存命中率,再决定是否调整 TTL。
多提供商回退:Claude 挂了自动走 OpenAI
这是 Gateway 最被低估的功能。在 API 请求里指定一个有序的 providers 数组,Gateway 会先尝试第一个,失败后自动回退到第二个、第三个:
{
"providers": [
{
"provider": "anthropic",
"endpoint": "v1/messages",
"headers": { "x-api-key": "sk-ant-..." },
"query": {
"model": "claude-sonnet-4-5",
"max_tokens": 1024,
"messages": [{"role": "user", "content": "..."}]
}
},
{
"provider": "openai",
"endpoint": "chat/completions",
"headers": { "Authorization": "Bearer sk-..." },
"query": {
"model": "gpt-4o",
"messages": [{"role": "user", "content": "..."}]
}
}
]
}
回退行为可以叠加自动重试。在请求里加上三个 header:
cf-aig-retry-count: 3:当前提供商失败后重试最多 3 次cf-aig-retry-backoff: exponential:重试间隔指数增长cf-aig-retry-delay: 500:第一次重试延迟 500ms
那么实际流程是:Anthropic 请求 → 失败 → 500ms 后重试 → 又失败 → 1s 后重试 → 又失败 → 2s 后重试 → 三次全失败 → 自动切到 OpenAI → 成功。
注意:不同提供商的输出格式不完全一致。Anthropic 返回 content 数组,OpenAI 返回 choices[0].message.content 字符串。如果你的前端直接渲染原始消息对象,需要在回退场景做格式兼容。最好在中间层统一输出格式,而不是让每个调用方自己处理。
自建 Worker 中转 vs AI Gateway:什么时候值得自己写
有些团队已经用 Cloudflare Worker 手写了 Claude API 的代理层。这时候还值不值得迁移到 AI Gateway?
| 维度 | 自建 Worker 代理 | Cloudflare AI Gateway |
|---|---|---|
| 部署速度 | 需要写代码、处理 CORS、测试 | 2 分钟,在 Dashboard 点几下 |
| 缓存 | 需要自己实现 KV / Cache API | 内置,精确匹配,可配 TTL |
| 速率限制 | 自己维护 KV 计数器 | Dashboard 开关,固定/滑动窗口可选 |
| 多提供商回退 | 自己写 fallback 逻辑 | 声明式 providers 列表 |
| 分析面板 | 需要第三方(Grafana / Datadog) | 内置,Token 消耗、成本、延迟一目了然 |
| 灵活性 | 完全控制,可以做数据脱敏、格式转换 | 受限于 Gateway 的能力范围 |
| 延迟 | 0 额外跳(本身就是 Worker) | 20-60ms 额外开销 |
| 成本 | Worker 免费额度内免费 | 核心功能免费 |
如果你的 Worker 代理只是做了简单的 URL 改写和 API Key 注入,那直接切到 Gateway 省掉维护成本。如果你的 Worker 还做了 prompt 脱敏、审计日志写入 D1、动态模型选择等业务逻辑,可以保留 Worker 代码但把底层的 fetch('https://api.anthropic.com/...') 改成指向 Gateway 端点——Worker 继续做业务逻辑,Gateway 接管速率和缓存。
设置完当天要做的三件事
- 打开 Logging 确认流量进来了:Gateway → Logs 页面看最近 1 小时的请求。如果连续 5 分钟没有记录,检查你的 base_url 有没有写对 account_id 和 gateway_id。
- 设一个保守的速率限制:先设每分钟 30 次请求 / 滑动窗口。然后看 Dashboard 里有没有正常流量被误拦(如果 API 返回了 429 但你的前端没有处理,用户会看到空白页)。
- 给关键 prompt 加 cache-ttl:固定 system message 设 3600 秒,RAG 场景设 600 秒。不设 TTL 的请求只会被记日志,不会被缓存。