如何为多提供商 LLM API 构建数据保留策略路由器
用于在模型路由之前实施 LLM 数据保留控制的实用架构,具有请求分类、提供商能力记录、默认拒绝策略、区域限制、功能阻止和审计证据。
多提供商 LLM 路由器不应先选择模型,然后再询问保留问题。如果支持工作流程被标记为无保留,则网关必须在请求离开您的边界之前了解所选提供商、端点、区域、帐户设置和功能组合是否能够履行该承诺。
故障模式很容易被忽视。团队从无状态聊天完成开始。路线可以接受。后来,有人添加了文件上传、存储的对话历史记录、网络基础、批处理或矢量存储。模型名称可能保持不变,但数据行为发生变化。简单的延迟或成本路由器可以静默地将受监管或客户合同约束的提示发送到存储内容时间超过工作负载允许的时间的路径。
实际的解决方法是将 LLM 数据保留控制置于模型路由之前。路由器应对请求进行分类,将其与规范的保留策略进行匹配,过滤提供商的功能,阻止不允许的功能,并发出可审核的决策证据。
作为设计约束的事实
提供商数据处理并不统一,很少仅通过提供商名称来捕获。在设计保留感知路由器时,以下事实很重要:
- OpenAI 规定,除非客户选择加入,否则 API 数据不会用于训练或改进模型。符合条件的客户可以在批准后在组织或项目级别配置修改滥用监控或零数据保留。
- OpenAI 的零数据保留会更改端点行为,包括将响应和聊天完成的
store参数视为 false,但某些端点和功能仍然可以存储应用程序状态,并且不符合零数据保留条件。 - Anthropic 记录了 Claude API 的零数据保留,即返回 API 响应后不存储静态客户提示或响应,但覆盖范围取决于端点和功能资格。
- Anthropic 指出某些 Claude 功能或涵盖的型号可能需要保留,并且在零数据保留下可能不可用,除非经过专门授权。
- Google Cloud 文档表明,Gemini 未经事先许可或指示,企业代理平台数据不会用于训练或微调 AI/ML 模型,但零数据保留需要特定的操作,并且对于某些高级功能来说可能无法实现。
- Google Cloud 记录称,Grounding with Google Search 最多可存储派生查询和上下文日志三天,并且无法禁用该功能的存储。当需要零数据保留时,它建议企业使用 Web Grounding。
- Microsoft 记录称,Azure 销售的 Azure 托管模型不会向 OpenAI 或其他模型提供商提供提示和完成,并且未经许可或指示,不会使用它们来训练基础模型。
- Microsoft 记录了 Azure 部署类型会影响处理位置。全局部署可以在部署模型的任何地理位置处理提示和响应,而 DataZone 部署将处理限制在选定区域。存储的数据保留在客户指定的地理位置中。
- Microsoft 记录了一些有状态的 Azure 功能存储数据,包括文件、向量存储、响应消息历史记录、助理线程、批处理输入和存储的完成。
- Microsoft 文档显示,批准的客户可以修改滥用监控,并且 Azure 门户或 CLI 可以在滥用监控数据存储关闭时显示
ContentLogging=false。
这些不是边缘详细信息。它们意味着路由器必须一起评估端点、功能、帐户批准和区域。对于生产政策来说,提供商范围内的标签(例如“ZDR 已启用”)过于粗略。
参考架构
保留感知多模型 AI API网关在请求路径中需要五个组件:
- 请求分类器:提取数据敏感度、租户合同、区域要求、功能使用、文件输入、工具使用和日志记录权限。
- 策略解析程序: 将请求映射到规范的保留策略,通常来自租户、项目、环境、API 键和工作负载元数据。
- 提供商功能注册表:记录提供商、端点、模型、功能、区域和帐户级保留功能以及带有日期的证据。
- 策略评估器: 过滤候选路由并返回批准的路由或带有原因代码的策略拒绝。
- 审核发射器:记录选择的路由、匹配的策略、能力假设、区域、存储标志和内容记录模式。
此架构将保留和驻留决策与成本、延迟和回退分开。成本路由仍然可能发生,但仅限于满足保留策略的路由集内。
定义规范保留策略
从提供商中立的政策对象开始。不要将某一提供商的术语复制到您的内部合同中。您的内部政策应描述允许工作负载执行哪些操作,而不是特定提供商如何营销控制。
{
"policy_id": "support_no_retention_eu_v1",
"max_content_retention": "none_after_response",
"training_allowed": false,
"human_review_allowed": false,
"allowed_regions": ["EU"],
"stateful_storage_allowed": false,
"file_storage_allowed": false,
"grounding_allowed": false,
"batch_processing_allowed": false,
"full_content_logging_allowed": false,
"redacted_content_logging_allowed": true,
"audit_level": "route_decision_with_provider_evidence"
}
对于限制较少的工作负载,请使用显式放宽而不是缺失字段:
{
"policy_id": "internal_analytics_standard_v1",
"max_content_retention": "30_days",
"training_allowed": false,
"human_review_allowed": false,
"allowed_regions": ["US", "EU"],
"stateful_storage_allowed": true,
"file_storage_allowed": true,
"grounding_allowed": true,
"batch_processing_allowed": true,
"full_content_logging_allowed": false,
"redacted_content_logging_allowed": true,
"audit_level": "metadata_and_decision"
}
重要的字段不仅仅是保留期限。有状态功能、文件、接地、批处理和日志记录模式都会影响路线是否可接受。
构建提供商能力注册表
功能注册表是路由器的事实来源。它应该作为受控配置进行维护,而不是通过提供程序适配器分散。
有用的记录包括:
provider:提供商或云平台。account_scope:设置获得批准的组织、项目、部署、订阅或租户。endpoint:聊天、响应、消息、批处理、文件、助手、嵌入、接地、矢量存储或其他API表面。model_family和可选的model_id:因为模型资格可能不同。region_mode:全球、区域、数据区域、客户指定的地理位置或提供商特定的同等位置。content_retention:响应后不存储、滥用监控保留、应用程序状态保留、固定持续时间派生日志或未知。training_use:默认禁用、选择加入或未知。human_review:启用、修改、禁用或未知。stateful_storage:端点或功能是否存储对话状态、文件、矢量数据、完成情况或批量输入。feature_flags:基础、文件、工具、缓存、存储输出、批处理、助手或同等功能。evidence:源文档名称、URL、检索日期和所有者审核日期。
示例:
{
"capability_id": "azure-openai-gpt4o-datazone-chat-zdrlike-v3",
"provider": "azure_openai",
"account_scope": "prod-subscription-123",
"endpoint": "chat_completions",
"model_family": "gpt-4o",
"region_mode": "datazone_eu",
"content_retention": "abuse_monitoring_disabled_when_contentlogging_false",
"training_use": "disabled_without_permission",
"human_review": "modified_abuse_monitoring_approved",
"stateful_storage": false,
"features": {
"files": false,
"vector_store": false,
"stored_completions": false,
"grounding": false,
"batch": false
},
"evidence": {
"source": "provider_data_privacy_and_abuse_monitoring_docs",
"retrieved_at": "2026-10-08",
"review_owner": "security-architecture"
}
}
对于敏感工作负载,建议将未知视为拒绝。如果功能记录缺少保留字段、区域模式或功能资格,则它不应满足严格的政策。
在路由之前对请求进行分类
分类应在模型选择之前进行。一个好的分类器结合了静态元数据和请求检查:
- API关键范围:租户、团队、环境、应用程序和工作负载类型。
- 合同标签:不保留、仅限欧盟、类似 HIPAA 的控制、财务数据、客户机密或仅限内部。
- 负载类型:自由文本、文档、图像、文件引用、嵌入输入、工具结果或检索到的上下文。
- 功能使用:网络基础、文件上传、矢量存储、批处理作业、存储的对话历史记录、工具调用或响应存储。
- 日志记录模式:允许完整内容、允许编辑内容、仅元数据或无应用程序日志内容。
- 区域提示:用户位置、租户数据驻留、项目区域或部署区域。
不要仅依赖自动敏感数据检测。使用 API 键或项目中声明的工作负载策略作为主要来源,然后在负载包含风险信号时使用分类器收紧策略。
function resolvePolicy(request) {
const base = policyForApiKey(request.apiKeyId);
const tenant = tenantContractPolicy(request.tenantId);
const features = detectRequestedFeatures(request);
const sensitivity = classifyPayload(request);
return strictestApplicablePolicy([base, tenant, features, sensitivity]);
}
实际上,这意味着客户支持密钥可以默认为不保留,而内部实验密钥可以允许更广泛的路由。如果相同的支持密钥尝试上传文件,则有效政策应包括 file_storage_allowed=false,除非存在经批准的支持文件的路由。
在进行成本或延迟路由之前评估策略
评估器应充当过滤器。它接收策略、请求功能和候选提供商路由。它仅返回满足政策的路由。
function eligibleRoutes(request, policy, capabilities) {
return capabilities.filter((route) => {
if (!regionAllowed(route, policy.allowed_regions)) return false;
if (!retentionAllowed(route, policy.max_content_retention)) return false;
if (!trainingAllowed(route, policy.training_allowed)) return false;
if (!humanReviewAllowed(route, policy.human_review_allowed)) return false;
if (request.usesFiles && !policy.file_storage_allowed) return false;
if (request.usesFiles && route.features.files !== true) return false;
if (request.usesGrounding && !policy.grounding_allowed) return false;
if (request.requiresState && !policy.stateful_storage_allowed) return false;
if (route.content_retention === "unknown") return false;
return true;
});
}
function routeRequest(request) {
const policy = resolvePolicy(request);
const candidates = capabilityRegistry.findByModelIntent(request.modelIntent);
const eligible = eligibleRoutes(request, policy, candidates);
if (eligible.length === 0) {
return deny("RETENTION_POLICY_NO_ELIGIBLE_ROUTE", policy.policy_id);
}
return chooseByCostLatencyAndHealth(eligible);
}
这个顺序很重要。在中断期间,后备路由不应跳转到不合格的提供商。批量路由不应将无保留请求移至异步作业存储中。当政策禁止时,接地不应启用引入派生日志的功能。
如果您的平台公开OpenAI兼容的多模型API,请保持兼容性层诚实:相同的请求正文可能会编译为不同的提供商原生功能。政策评估者必须检查编译后的请求,而不仅仅是原始的SDK形状。
明确阻止有风险的功能组合
最安全的实施方式是为已知的高风险组合创建明确的拒绝规则。示例:
NO_RETENTION + FILE_UPLOAD:拒绝,除非特定文件端点和帐户设置获得政策批准。NO_RETENTION + VECTOR_STORE:拒绝,除非矢量存储位于您自己的受控存储内并且提供程序永远不会接收持久文件状态。NO_RETENTION + STORED_RESPONSE:如果端点无法禁用存储,则强制关闭或拒绝响应存储标记。EU_ONLY + GLOBAL_DEPLOYMENT:如果处理可能发生在允许的区域或数据区域之外,则拒绝。NO_RETENTION + WEB_GROUNDING:如果基础功能存储超出政策的派生查询或上下文日志,则拒绝。METADATA_ONLY_LOGGING + DEBUG_TRACE:禁止应用程序日志和跟踪中的提示和完成内容。ZDR_REQUIRED + STATEFUL_ASSISTANT_THREAD:拒绝,除非该功能特别符合帐户批准的控制措施。
返回特定错误。有用的拒绝告诉开发者什么失败了以及存在哪些已批准的替代方案。
{
"error": {
"code": "RETENTION_POLICY_DENIED",
"reason": "NO_RETENTION_POLICY_DISALLOWS_FILE_STORAGE",
"policy_id": "support_no_retention_eu_v1",
"requested_feature": "file_upload",
"approved_alternatives": [
"send extracted text without provider file storage",
"use internal document retrieval with metadata-only provider call",
"request policy approval for controlled file processing"
]
}
}
将推理日志记录与操作遥测分开
保留政策不应迫使网关变得盲目。您通常可以在不存储提示或完成内容的情况下保持运行遥测。
对于严格的工作负载,请保留:
- 请求 ID 和跟踪 ID;
- 租户、项目、API 密钥和工作负载标识符;
- 政策 ID 和政策版本;
- 使用的提供商、端点、模型、部署和区域;
- 请求和允许的功能标记;
- 决策原因代码;
- 令牌计数、延迟时间、状态代码和费用元数据;
- 用于重复数据删除的哈希值或稳定指纹(如果政策批准)。
隐藏或编辑:
- 原始提示;
- 原始完成情况;
- 上传的文件内容;
- 包含客户数据的工具输出;
- 从敏感系统检索上下文;
- 提供重复内容的调试负载。
这是保留路由与提供商中立的 LLM 可观察性的连接点。可观察性应该在不扩展保留敏感内容的系统集的情况下证明发生了什么。
为每个决策提供审核证据
审核记录应解释允许或拒绝某条路线的原因。它不需要完整的内容即可发挥作用。
{
"request_id": "req_01J...",
"tenant_id": "tenant_42",
"policy_id": "support_no_retention_eu_v1",
"policy_version": 7,
"decision": "allow",
"provider": "anthropic",
"endpoint": "messages",
"model_family": "claude",
"region_mode": "approved_region",
"features": {
"files": false,
"grounding": false,
"stateful_storage": false,
"batch": false
},
"logging_mode": "metadata_only",
"capability_record_id": "anthropic-claude-messages-zdr-v5",
"capability_evidence_date": "2026-10-08",
"reason_codes": [
"POLICY_MATCHED_NO_RETENTION",
"REGION_ALLOWED",
"STATELESS_ENDPOINT",
"CONTENT_LOGGING_SUPPRESSED"
]
}
对于被拒绝的请求,请保持与 decision=deny 和原因代码(例如 REGION_NOT_ALLOWED、GROUNDING_RETENTION_EXCEEDS_POLICY 或 STATEFUL_STORAGE_NOT_ALLOWED.
使用保留规则的合同测试
保留路由应具有自动化测试。重要的测试不仅仅是针对各个提供商的单元测试;它们是跨提供商组合的策略行为的合同测试。
高价值测试用例包括:
- 除非存在特定批准的支持文件的路由,否则无保留政策和文件上传应拒绝。
- 即使模型可用,仅限欧盟的政策加上全球部署也应拒绝。
- 零保留政策加上存储的对话历史记录应在支持时拒绝或强制关闭存储。
- 在无保留政策下,应拒绝具有派生日志保留的基础功能。
- 仅元数据日志记录策略应禁止跟踪、日志和错误报告中的提示和完成内容。
- 对于受监管的工作负载,保留未知的提供商能力记录应被拒绝。
- 提供商中断后的回退应保留在符合条件的路由集中。
- 当批处理端点存储输入文件的时间超过策略允许的时间时,批处理应拒绝。
同时测试漂移。当功能记录发生更改时,系统应在更改生效之前显示哪些策略和路由受到影响。
运营所有权
困难的部分不是编写第一个评估器。它使注册表保持最新并防止未记录的异常。
指定所有者:
- 提供商文档审核节奏;
- 帐户级控制的批准状态,例如修改后的滥用监控或零数据保留;
- 区域部署清单;
- 文件、矢量存储、接地、批量和存储响应的功能资格;
- 政策例外工作流程;
- 审核记录保留和访问控制;
- 面向开发者的错误消息和批准的替代方案。
每条能力记录都应有审核日期。如果过期,严格的策略应该停止信任它或需要手动批准。提供商文档和功能行为变化过于频繁,无法实现静态配置。
权衡
严格的保留路由器会减少可用的模型选择。一些预览模型、有状态 API、基础工具和文件工作流程将不可用于敏感工作负载。这就是控制点,但产品团队需要明确的替代方案。
当最快的部署是全球性的但工作负载需要特定的地理位置或数据区域时,区域路由可能会增加延迟或成本。使其在遥测中可见,以便团队了解为什么请求使用更昂贵或更慢的路线。
阻止有状态功能可以促使团队构建自己的内存层。这可能是正确的架构,但它仍然需要存储策略、删除工作流程、加密、访问控制和审核日志。将状态移出提供程序并不会消除治理工作。
及时完成修订可以保护敏感数据,但会削弱调试和质量审核。使用可重现的请求元数据、确定性测试装置、允许的工作负载的受控采样以及在政策允许的情况下记录的打破玻璃访问。
建议
- 在模型路由之前强制保留和驻留,而不是作为后处理检查。
- 提供商、端点、功能、区域和帐户审批级别的模型功能。
- 对受监管或受客户合同约束的工作负载使用默认拒绝行为。
- 将文件上传、矢量存储、网络基础、批处理和存储的对话历史记录视为单独的政策维度。
- 即使必须禁止提示和完成内容,也能保持运行遥测。
- 发出审核记录,其中包括政策、路由、功能证据、区域、存储标志和原因代码。
- 为高风险功能组合和后备行为编写合约测试。
预测:保留路由将成为标准网关层
可能的方向是保留路由成为企业 LLM 平台中的标准层,类似于速率限制、预算控制和可观察性。随着提供商添加更多有状态工具、基础选项、缓存、文件、代理和托管内存功能,安全路径将更少地依赖于模型名称,而更多地依赖于完整的执行路径。
这是一个预测,而不是当前的普遍要求。当前的要求更简单:如果您的团队承诺不保留、不进行区域处理、不进行培训使用或不进行人工审核,则您的网关需要足够的策略逻辑和证据来证明每个请求都遵循这些限制。
可行的结论
将保留路由器构建为提供商选择之前的政策入口。定义规范的保留政策,在路由之前对每个请求进行分类,维护过时的提供商功能注册表,默认拒绝不安全的组合,并记录审核证据而不保留敏感内容。
设计目标不是找到始终安全的提供商。目标是证明特定帐户和区域下使用特定端点和功能集的特定请求在发送之前满足政策。