OpenRouter 的零数据保留与主权 AI:两个常被混为一谈的开关
合规问卷发过来的时候,问题往往只有一句:「你们的数据会不会被留存?会不会出境?」很多人当场就把它当成一个问题回答了。但在 OpenRouter 的文档体系里,这是两个独立的开关,写在两页不同的文档上,生效的位置不一样,覆盖的范围也不一样,而且其中一个还分企业与非企业。
这篇沿着一次 chat/completions 请求的路径走一遍,看看这两个开关分别卡在哪一步。依据是 openrouter.ai/docs/guides/features/zdr 与 openrouter.ai/docs/guides/features/sovereign-ai 两页。
先把两个词的定义对齐
ZDR(Zero Data Retention)这一页开宗明义:ZDR 的含义是供应商不会在任何时段存储你的数据。注意主语是 provider,不是 OpenRouter 自己——OpenRouter 自身的留存策略被单独放在同一页的末尾讲:文档写明 OpenRouter 自己也有 ZDR 策略,除非你专门开启了 prompt logging,否则你的 prompt 不会被留存。
Sovereign AI 这一页的定义则完全在另一个维度上:一个国家或地区在自己的边界内、用本地基础设施、在本地监管框架下开发、部署和控制 AI 系统的能力。文档自述它由两股力量推动,一是监管合规(该页点名了 EU AI Act、GDPR 以及医疗、金融、国防的行业规则),二是数据驻留与隐私。
一句话对齐:ZDR 管的是「请求结束之后数据还在不在」,主权 AI 管的是「数据在哪个辖区被处理」。 一份数据完全可以在境外被处理、且不被留存;也完全可以在境内被处理、但被留存下来扫描滥用。这两种情况在合规问卷里是两条不同的题。
而且 Sovereign AI 那一页自己就把 ZDR 列成了主权栈的一个组件——它给的组合是三步:先启用 in-region routing 把数据锁在 EU 或 US,再启用 ZDR 防止供应商留存,最后用 data collection 控制防止拿你的数据训练。这三步是文档里编号列出的,把它当成「一个开关」用,就会漏掉另外两个。
第一步:请求打到哪个域名——in-region routing
主权那一页里唯一带具体调用方式的机制是 in-region routing。文档写明它面向企业客户,覆盖 EU 与 US,需要联系企业团队为账号开通。这是本文里第一个要划清的边界:不是所有账号打开某个参数就有的。
用法不是加字段,而是换 base URL。文档给出的两个区域域名是:
https://eu.openrouter.ai
https://us.openrouter.ai
SDK 侧则是把 serverURL 指过去,官方文档的 TypeScript 示例是这样写的:
import { OpenRouter } from '@openrouter/sdk';
const openRouter = new OpenRouter({
apiKey: '<OPENROUTER_API_KEY>',
serverURL: 'https://eu.openrouter.ai/api/v1',
});
const completion = await openRouter.chat.send({
model: 'meta-llama/llama-3.3-70b-instruct',
messages: [{ role: 'user', content: 'Hello' }],
stream: false,
});
示例里的那个 model slug 只是官方文档当时用的示例值,平台上有哪些模型、哪些模型进得了 in-region 名单一直在变,别把它当清单用。
这个机制在文档里的描述值得逐字读:启用后,请求保证只在指定区域内被解密,并且只路由到在该区域运营的 provider,prompt 与 completion 完全在该区域内处理,在请求生命周期的任何一点都不会离开。「只在区域内解密」这句话的分量比「只路由到区内供应商」更大,但文档到此为止,再往下是怎么实现的,属于我们没有依据的部分,不猜。
想知道哪些模型进得了 in-region 路由,文档给的是两条自查路径:通过 EU 域调 /api/v1/models 拿到完整列表,或者在主域上带 region 查询参数(取值 eu 或 us);网页侧则是模型页上的 In-Region Routing 筛选项。这两条是文档写明的入口,具体返回哪些模型请自己去查,本文不抄名单。
第二步:允许落到哪些 endpoint——ZDR 的四个生效层级
请求进了正确的区域,接下来才轮到 ZDR 决定它能落到哪个 endpoint 上。ZDR 页写明这个开关可以全局、按 model group、按 guardrail、按请求四种方式施加,四者不是互斥的替代品。
按 model group 这一层是很多人没注意到的。文档明确说它不是一个全局单开关,而是五个 model group scope 各自独立(这一页的表格就是五行):
| Model group | 启用后的效果(文档表格原文口径) |
|---|---|
| Anthropic | 移除第一方 Anthropic endpoint,Bedrock 与 Vertex 仍可用 |
| OpenAI | 移除第一方 OpenAI endpoint,Azure 仍可用 |
| 移除 AI Studio endpoint,Vertex 仍可用 | |
| SpaceXAI | 移除非 ZDR 的 SpaceXAI endpoint,ZDR 的那个 endpoint 仍可用 |
| Non-frontier | 移除其余所有非 ZDR endpoint |
这张表是静态写在文档正文里的,但平台上的供应商与端点随时在变,以官方文档最新内容为准。文档给出的使用场景(属于文档自述)是:你可能只想对 non-frontier 模型强制 ZDR,而让第一方的 Anthropic、OpenAI、Google endpoint 不受这个限制。
同样的五个 scope 在 guardrail 上有对应的 API 字段:
| 字段 | 作用 |
|---|---|
enforce_zdr_anthropic | 对 Anthropic endpoint 强制 ZDR |
enforce_zdr_openai | 对 OpenAI endpoint 强制 ZDR |
enforce_zdr_google | 对 Google endpoint 强制 ZDR |
enforce_zdr_xai | 对 SpaceXAI endpoint 强制 ZDR |
enforce_zdr_other | 对 non-frontier endpoint 强制 ZDR |
这里有一条容易踩的迁移坑:文档写明旧的 enforce_zdr 字段已 deprecated。它被提供时,取值会被复制进那些没有在请求里显式设置的 per-model-group 字段。也就是说旧字段现在还有行为,但官方要求新接入直接用分组字段。如果你的代码同时写了旧字段和部分新字段,得清楚「未显式设置的才会被覆盖」这个语义,否则会以为旧字段整体失效或整体生效。
请求级的开关则是 provider preferences 里的 zdr:
{
"model": "gpt-4",
"messages": [...],
"provider": {
"zdr": true
}
}
以上为按官方文档中的字段语义组合的示例,未经实测,以官方文档与 API 的实际响应为准;model 处的取值同样只是官方文档当时的示例值,不代表推荐或可用清单。
这个参数的语义有一处反直觉,文档专门写了:请求级 zdr 与账号级、guardrail 级设置之间是 OR 关系。任何一处开着,ZDR 就会生效。所以 zdr: false 并不能把账号上开着的强制关掉——这个参数只能加强,不能放宽。指望用它给某条请求「开个口子」的思路,从一开始就走不通。
第三步:谁不在 ZDR 的射程内
ZDR 页有一个 Warning 块,是这篇里最该抄给合规同事看的一段:ZDR 的强制只作用于推理请求的 provider routing,不作用于你自己启用的 plugins 与 tools(该页举的例子是 web search)。这些可能由第三方服务运营,有各自的数据留存策略,文档要求你在有严格留存要求时自行审阅它们的策略。
对照着看还有一处:主权那一页对 in-region routing 的描述是「在请求生命周期的任何一点都不会离开该区域」,但 plugins 与 tools 是否落在这个范围内,我们在这两页文档里没有找到对应说明。这一点别自己脑补结论,问官方或按最保守的假设走。
另外两条边界也值得记:
一是不留存 ≠ 不训练。文档写明确实存在一些不拿你的数据训练、但会留存的 endpoint 与供应商(该页给的理由是扫描滥用或法律原因),OpenRouter 把这两类策略分开给你控制。对应到主权那一页,防训练的那个开关是 provider preferences 里的 data_collection:
{
"provider": {
"data_collection": "deny"
}
}
设为 "deny" 时,请求只会路由到不收集用户数据的供应商,这一项也可以在隐私设置里配成账号级默认值。
二是供应商的通用策略与具体 endpoint 的策略可能不一致。文档写明 OpenRouter 逐 endpoint 跟踪策略,并且在无法确认某个供应商或 endpoint 的策略时,采取保守立场:假定它既留存也训练,并按此标记。所以看那张按供应商列出的默认策略表时要留个心眼,某个 endpoint 与其供应商默认值不同时,开着「ZDR Only」它可能就不可用。
还有一条容易被合规质疑的口径,文档主动表了态:部分 endpoint 提供 implicit caching,把重复的 prompt 片段留在供应商数据中心的内存缓存里以免重复处理。OpenRouter 的立场(文档自述)是内存中的 prompt 缓存不算「留存」,因此 ZDR 路由策略生效时,带 implicit caching 的 endpoint 仍然允许命中。这个口径未必和你们内部的定义一致,最好提前对齐。
怎么自己查,而不是抄一份名单
哪些 endpoint 具备 ZDR 策略,文档给的是一个程序化入口:
https://openrouter.ai/api/v1/endpoints/zdr
文档写明这个列表在供应商数据策略发生变化时会自动更新,ZDR 文档页上那张模型/供应商对照表用的也是同一份数据。既然它是随策略变动的,任何文章里手抄的「支持 ZDR 的供应商名单」,从抄下来那一刻就开始过期了。要么按这个接口去拉,要么就别在内部文档里固化名单。
Linux/macOS 侧直接 curl 这个地址即可。Windows 侧要注意的不是 OpenRouter 的问题,而是 shell 差异:官方文档给的 cURL 示例用的是反斜杠续行和单引号包裹 JSON,这两点在 cmd.exe 和 PowerShell 里都不成立——PowerShell 里 curl 默认还是 Invoke-WebRequest 的别名。要跨平台一致,用文档里那段 Python requests 示例最省事。这一段是通用的 shell 常识,不是 OpenRouter 官方文档的内容。
最后收一下这两个开关的边界
- ZDR:约束「数据会不会被存下来」。全局/按 model group/按 guardrail/按请求四层,OR 关系,只能加强;覆盖推理请求的 provider routing,不覆盖 plugins 与 tools;implicit caching 按官方口径不算留存。
- Sovereign AI / in-region routing:约束「数据在哪个辖区被处理」。EU 与 US 两个区域,走区域专属 base URL,面向企业客户按需开通;主权那一页把 ZDR 与
data_collection: "deny"一起列为组合方案的另外两步。
合规问卷上那两栏,得分别对应到这两处,填一个不能算另一个。
本文依据 OpenRouter 官方文档(openrouter.ai/docs)于 2026-08-18 的公开内容整理。
该平台闭源,本文只复述官方文档写明的机制,不推断其内部实现;
我们没有对文中涉及的功能做过实测,因此不涉及界面外观与运行表现的任何描述。
该平台的供应商、模型与路由策略随时变动,文中不列具体供应商名单与模型清单;
价格、额度与限流的具体数值请以官方定价页与用量说明为准。
合规与许可条款请以官方原文与你所在组织的要求为准,本文不构成法律意见。