我把所有 AI 的 API Key 都扔给了一个网关
DeepSeek、智谱 GLM、以后再加的任何模型,全部收进一个统一端点,key 托管在 Cloudflare Secrets Store,日志和分析开箱即用。这篇讲我怎么搭的,踩了哪些坑,以及为什么你再也不该把 API key 散落在各个项目的 .env 里。
本页目录

上个月我数了一下自己项目里的 API key。DeepSeek 的 key 在 Echoir 的 Cloudflare 环境变量里,在 Valdos 的 secret 里,在本地某个 .env 里,在我笔记本电脑的另一个 .env 里,还有一个存在备忘录里的(别学)。
智谱的 key 也差不多,两个项目,三个地方。
这还是没算丢的。
问题是这样的:key 一旦散落,轮换就是灾难。DeepSeek 那边要是泄露了 key 要换,我得挨个项目找一遍,改一遍,部署一遍。而且我根本说不清哪个 key 在哪几个地方被引用过。
后来我把它们全收进了 Cloudflare AI Gateway。一个网关,一个统一端点,key 托管在 Cloudflare 那边,我的代码里再也不出现任何明文 key。
这篇讲讲怎么搭的,以及我踩的三个坑。
为什么是 AI Gateway
先说为什么不直接用各家的 SDK。
你用 DeepSeek,端点是 api.deepseek.com。你用智谱,端点是 open.bigmodel.cn 或者国际站的 api.z.ai。你以后用 Claude,是 api.anthropic.com。
每家一套 SDK,一套计费后台,一套日志系统。项目一多,你就有了 N 份心智负担。
AI Gateway 干的事很简单:给你一个统一的入口,所有模型请求都从这走。它管三件事:
统一端点。 所有请求走同一个域名,按路径区分 provider。换模型不改代码,换个路径就行。
密钥托管。 也就是 BYOK(Bring Your Own Key)。你的 DeepSeek key 存在 Cloudflare 的 Secrets Store 里,请求经过网关时自动注入。你的代码、你的环境变量、你的 git 仓库里,都不再有明文 key。
日志和分析。 每个请求的 token 用量、延迟、缓存命中、错误率,全部自动记录。不用你在每个项目里埋点。
对个人开发者来说还有个隐藏好处:所有项目的 LLM 成本集中在一个面板里,月底看一眼就知道这个月模型花了多少钱,不用挨家后台去查。
搭建过程
整个流程比我想象的简单,十分钟的事。
第一步,Cloudflare Dashboard 里进 AI Gateway,创建一个网关。我给它起名叫 jask-llm,你可以叫任何名字。
第二步,添加 provider。我加了两个:DeepSeek 和智谱。每个 provider 绑定一个 secret,secret 存在 Secrets Store 里,内容就是你的 API key。这一步做完,key 就再也不用出现在任何项目代码里了。
第三步,开启网关鉴权和日志。鉴权开启后,每个请求要带一个网关自己的 token,防止你的网关被人白嫖。日志默认开了请求记录和 token 统计。
然后你会拿到两种端点形式。
原生形式,适合服务端调用:
https://gateway.ai.cloudflare.com/v1/<account-id>/<gateway>/<provider>/chat/completions
自定义域名形式,适合对外暴露。我绑了 ai.jask.cc,看起来干净很多。
调用的时候,请求头带上网关 token,body 里的 model 字段选具体模型,就完事了。OpenAI 兼容格式,所有现成的 SDK 都能直接用,改个 baseURL 的事。
我踩的三个坑
第一个坑:自定义域名端点不带 /v1 前缀。
原生形式的 URL 里有 /v1,我绑了自定义域名之后,习惯性地在路径里也加了 /v1。结果返回 2008 错误,Invalid provider。
对着文档看了半天才发现,自定义域名端点的路径是直接从 provider 名开始的。比如 DeepSeek 就是 /deepseek/chat/completions,不是 /v1/deepseek/chat/completions。
这个错误信息完全没提示是路径问题,我是逐段排查 URL 才找到的。
第二个坑:智谱订阅 key 只走 coding 端点。
我的智谱 key 是 GLM Coding Plan 的订阅 key。这种 key 只能用 coding 端点,打到普通 API 端点会报 1113 错误,余额不足。
但报错很有迷惑性,你会以为是账户没钱了,去充钱,充完还是报错。实际上订阅制的 key 不走按量余额,它只认 coding 那条路径。
还有个连带问题:国内端点 open.bigmodel.cn 对 Cloudflare 的海外出口返回 404。所以智谱在 CF 网关上必须走国际站 api.z.ai 的路径。好消息是 key 两站通用。
第三个坑:默认 WAF 拦截脚本 UA。
这个坑最隐蔽。网关搭好之后,我用 Python 脚本测试,一直返回 403,错误码 1010。
换成浏览器 UA 立刻就通了。原因是 Cloudflare 默认的 WAF 规则会拦截一部分无浏览器特征的脚本 User-Agent,python-urllib 这种默认 UA 正好在拦截名单里。
解决方案要么在请求里显式带一个正常的 UA,要么去 WAF 规则里放行你的脚本 UA。我选的前者,代码里写死一个自定义 UA。
用起来什么感觉
我现在的架构是:所有项目的 LLM 调用都指向 ai.jask.cc,网关后面挂着 DeepSeek 和智谱两个 provider,按 URL 路径区分。
我主页 jask.dev 上有个 AI 分身,读了我全部博客和 GitHub 仓库,能替我回答技术选型的问题。它的后端就是走这个网关调 DeepSeek,一个 Pages Function 做转发,SSE 流式输出。整个聊天功能的 LLM 部分,代码里没有一行出现 API key。
以后加新模型,就是网关里加一个 provider 的事,现有项目零改动。
成本方面,AI Gateway 本身免费,日志和分析都在免费额度内。你付的只是模型本来的钱,Cloudflare 不加价。
谁适合这么做
说实话,如果你只有一个项目用一个模型,没必要,直接调官方 API 更简单。
但只要你有两个以上项目,或者两个以上模型的 key,就值得收进来。key 管理的心智负担是随项目数指数上升的,而网关是线性解法。
而且它是渐进的。你不需要一次性迁移所有项目,可以新的先走网关,旧的慢慢挪。反正 key 在网关里托管着,官方 key 没删,两边并行没冲突。
从「改个 DNS 就走」到把所有 API key 都托付给它,我对 Cloudflare 的依赖又深了一层。上个月写的那篇全家桶指南里我说它会让人上瘾,现在我只是又一次验证了这个结论。
下一篇:我把六个站的内容,全塞进了一个 MCP,网关收拢 key,hub 收拢内容,同一个思路。