兼容 OpenAI 的 API 网关背后的多租户 RAG
用于在多模型 API 网关后面构建检索增强生成的实用参考架构:租户范围索引、提供商中立检索适配器、规范化引用、生命周期控制和成本归因。
面向客户的 AI 助理需要检索增强生成,但当请求流经 OpenAI 兼容的 API 网关而不是某个模型提供程序的本机堆栈时,RAG 会变得更加困难。网关必须保持租户数据隔离,保留模型提供者之间的引用,按计划删除索引内容,并将嵌入、检索和生成成本归为正确的客户。
实际的答案是将检索视为一流的网关子系统。不要将其隐藏在一个提供商集成中。将检索与生成分开,为每个请求提供租户范围的检索上下文,在返回引用之前对引用进行规范化,并在分类帐中记录每个计费步骤。
读者问题
为许多客户构建 AI 助手的团队通常从一个简单的流程开始:上传文档、嵌入块、检索最匹配的内容、将这些片段放入提示中,然后要求模型回答。直到产品需要多个模型提供商、客户级计费、下架和可审核性之前,这种方法才有效。
风险不仅仅在于答案不准确。较大的运营风险包括租户命名空间错误、无法验证的引用、文档删除后过时的索引,以及由于检索成本消失在通用基础设施支出中而无法解释的利润。
本文将事实、建议和预测分开。事实是当前提供商和矢量数据库 API 记录的实现能力。这些建议是网关产品的架构选择。据预测,随着提供商检索功能的不断变化,此架构可能需要灵活性。
参考架构
网关级 RAG 设计应包含五个组件:
- 租户解析程序: 将传入的 API 密钥、工作区、客户帐户或合作伙伴 API 客户映射到规范tenant_id.
- 检索配置文件: 定义要搜索的语料库、要使用的嵌入模型、结果计数、过滤器、重新排名选项、引文要求和回退行为。
- 检索适配器层: 通过一个内部调用本机提供程序检索、外部向量数据库或自定义搜索服务接口。
- 提示组装和生成适配器: 将检索到的上下文传递给选定的模型提供程序,而不向调用方公开向量后端详细信息。
- 使用和审核分类帐: 记录嵌入、索引、检索、提示令牌、完成令牌、租户、模型、提供程序和跟踪
最小请求协定可以保持提供者中立:
{
"tenant_id": "tenant_123",
"model": "gpt-compatible-or-claude-compatible-model",
"retrieval_profile": "support_docs_v2",
"citation_required": true,
"messages": [
{"role": "user", "content": "What is our refund policy for annual plans?"}
]
}响应也应该是提供者中立:
{
"answer": "Annual plans can be refunded within the configured policy window...",
"citations": [
{
"source_id": "doc_789",
"title": "Billing Policy",
"url_or_internal_ref": "kb://billing-policy",
"chunk_id": "chunk_044",
"offsets": {"page": 3},
"score": 0.82,
"retrieval_provider": "vector_db",
"model_provider": "openai_compatible",
"provider_payload": {}
}
],
"retrieval_trace_id": "rt_456",
"billable_tenant": "tenant_123",
"embedding_usage": null,
"retrieval_usage": {"queries": 1, "results": 6},
"model_usage": {"input_tokens": 1920, "output_tokens": 180}
}事实:提供者检索功能不相同
OpenAI 的向量存储 API 支持可以创建、搜索、配置分块策略、与文件元数据关联以及删除。矢量存储搜索支持查询、过滤器、最大结果计数、排名选项、分数阈值和查询重写控件。这些控件为网关作者提供了控制延迟、相关性和成本的有用旋钮。
OpenAI 平台数据控件还使生命周期设计变得非常重要:矢量商店中的客户内容将保留直至删除。如果租户离职,或者临时项目过期,则网关不能假设提供商会根据产品的业务计划自动删除索引内容。
Anthropic 会公开不同的引用模式。应用程序可以提供带有源和标题元数据的搜索结果内容块,并且当启用引用时,模型可以将引用引用附加到生成的文本。存在实际限制:搜索结果引用设置在请求中是全有或全无,搜索结果块支持文本内容,引用粒度取决于内容如何分割成块。
含义很直接:网关不应将某个提供程序的检索形状公开为其公共合同,除非它打算使该提供程序成为永久检索机构。
建议:使用检索适配器,而不是检索Lock-In
创建内部检索适配器接口。网关可以支持其背后的多个后端:
- 本地提供程序检索:在客户希望以最快的路径进入某个提供程序的文件搜索或矢量存储功能时非常有用。
- 外部矢量数据库:在产品必须支持多个模型提供程序并具有一致的租户隔离和生命周期时非常有用控件。
- 预取搜索结果块:在网关组装检索到的文本并将其传递给支持显式引用感知上下文的提供程序时很有用。
无论后端如何,适配器都应返回相同的内部结构:
interface RetrievalResult {
retrievalTraceId: string;
tenantId: string;
corpusId: string;
chunks: Array<{
sourceId: string;
title: string;
text: string;
urlOrInternalRef?: string;
chunkId: string;
offsets?: { page?: number; byteStart?: number; byteEnd?: number; tokenStart?: number; tokenEnd?: number };
score?: number;
metadata: Record<string, string | number | boolean>;
providerPayload?: unknown;
}>;
retrievalUsage: {
provider: string;
queryCount: number;
resultCount: number;
billableUnits?: number;
};
}这使生成层可以接收上下文,而无需知道它是否来自 OpenAI 向量商店、Pinecone、Weaviate、数据库全文搜索索引或内部混合检索器。
租户隔离在矢量查询之前开始
租户隔离不得依赖于提示指令。它必须在检索之前在存储边界和查询边界强制执行。
对于 Pinecone 样式的系统,记录的多租户模式是无服务器索引中每个租户一个命名空间。数据平面操作以命名空间为目标,这简化了租户隔离和卸载,因为删除命名空间会删除该租户的记录。 Pinecone 还记录了命名空间和元数据过滤之间的权衡:在大型共享命名空间内进行过滤会扫描更多数据,成本更高,并且比命名空间范围内的查询执行速度更慢。
对于 Weaviate 风格的系统,多租户将每个租户存储在单独的分片上,因此一个租户的数据对另一个租户不可见。租户删除会删除关联的分片。Weaviate 还支持活动、非活动和卸载等租户状态,这为很少使用的租户创建生命周期选项。
实施清单
- 从经过身份验证的网关身份解析 tenant_id,而不是仅从用户提供的正文字段。
- 通过服务器端将 tenant_id 映射到向量命名空间、分片或提供者向量存储标识符注册表。
- 拒绝 API 关键租户与请求的语料库租户不匹配的请求。
- 将共享公共语料库与私有租户语料库分开。
- 在选择租户边界后,对文档类型、语言、产品区域或日期范围使用元数据过滤。
- 记录命名空间、分片、corpus_id、 retrieval_profile 和 retrieval_trace_id 用于审核。
通过单独的授权、单独的索引或受控的聚合路径保留显式管理工作流程的跨租户搜索。不要让跨租户搜索成为元数据过滤器的意外副作用。
将引用规范化为网关对象
引用是产品合同,而不仅仅是装饰。客户支持助理、法律起草工具或内部知识助理需要说明生成答案的原因以及支持文本的来源。
网关应将引文数据标准化为自己的架构:
{
"source_id": "doc_123",
"title": "Refund Terms",
"url_or_internal_ref": "kb://refund-terms",
"chunk_id": "chunk_006",
"offsets": {"page": 2, "byte_start": 4410, "byte_end": 5020},
"score": 0.79,
"retrieval_provider": "weaviate",
"model_provider": "anthropic",
"model_provider_citation_payload": {}
}保持标准化字段稳定并允许特定于提供商的扩展。一些提供商会比其他提供商公开更丰富的引用详细信息。有些人会引用搜索结果块。有些会引用上传的文件。有些不会提供您的应用程序所需的确切偏移格式。网关应保留现有内容,而不是假装每个提供者都具有相同的引用语义。
严格引用模式
当 citation_required 为 true 时,预先定义失败行为。严格模式可以要求每个事实段落至少包含一次引用,或者最终答案包含来自高于最低分数阈值的检索块的引用。如果所选模型提供程序无法满足引文合同,则网关应快速失败、使用兼容的提供程序或返回结构化拒绝。
这是建议,而不是通用规则。严格的引用模式可以提高信任度,但也会增加拒绝、重试和回退的复杂性。对于低风险的创意工作流程,引用可能是可选的。对于面向客户的支持或受监管的内部工作流程,citation_required 通常应成为检索配置文件的一部分。
索引生命周期是一项产品功能
RAG 系统会积累数据。临时上传意外地变成了永久上传。以前的客户留下了嵌入物。产品团队更改分块策略并忘记重建旧索引。网关应明确生命周期控制。
建议的生命周期控制包括:
- 临时语料库过期:为短期会话上传的文档应具有过期时间戳和删除作业。
- 租户卸载:删除租户应将命名空间、分片、提供者向量存储和相关内容的删除排入队列文件对象。
- 冷租户处理: 在支持的情况下,可以将非活动租户标记为非活动或卸载,以减少资源使用。
- 重新索引版本控制: 存储每个块的嵌入模型、分块策略、解析器版本和 indexed_at。
- 删除状态公开:合作伙伴API工作流程应显示文档删除、矢量删除和提供商端删除是否已完成。
重要的事实是,某些矢量存储内容在删除之前会保留。架构建议是使删除操作可见且可测试,而不是将其埋藏在没有面向客户状态的异步作业中。
跟踪三个成本分类帐
单个令牌分类帐对于 RAG 来说是不够的。网关至少需要三个账本:
- 嵌入和索引成本:文档解析、分块、嵌入调用、文件存储、索引写入和重新索引。
- 检索成本:向量数据库读取、本机向量存储搜索、重新排名、查询重写和结果扩展。
- 生成成本: 从用户消息中输入令牌并检索上下文、输出令牌、工具调用、重试和回退。
这对于转售或分配 AI 成本的代理机构、SaaS 供应商和内部平台团队尤其重要。如果没有单独的账本,RAG 利润就很难解释。对于小代使用量的租户,如果不断上传文档、重新索引大型语料库或运行广泛的检索查询,其成本可能仍然很高。
每个分类帐事件应包括 tenant_id、customer_id(如果不同)、API 键 ID、retrieval_profile、corpus_id、模型、提供商、trace_id 和计费单位。这让使用分析可以回答实际问题:哪些租户拥有昂贵的检索配置文件、哪些语料库过时、哪些模型产生引用失败以及哪些客户由于检索返回太多上下文而生成过大的提示。
要测试的故障模式
网关 RAG 子系统应对造成客户可见损坏的故障模式进行测试:
- 缺失引用: citation_required 为 true,但提供商响应不包含可用的引用引用。
- 过时索引: 文档已更新或删除,但旧块仍出现在检索结果中。
- 租户不匹配: 请求解析为租户 A,而语料库或命名空间属于租户B.
- 检索过于宽泛:配置文件返回太多块,增加成本并降低答案质量。
- 块大小不匹配:块太大,导致引用不精确,或者太小,导致上下文失去意义。
- 提供者功能不匹配:一个模型可以以所需的形式发出引用,而另一个则不能。
- 生命周期失败: 请求删除,但提供程序端存储仍处于活动状态或未验证。
这些测试应在网关合同级别运行,而不仅仅是在一个提供程序适配器内运行。目标是证明当检索后端或生成提供程序发生变化时,公共行为保持稳定。
权衡
原生提供程序检索可以减少应用代码并加速第一个版本。需要权衡的是,存储生命周期、引文格式、查询控制和功能可用性可能会与一个提供商联系在一起。
外部矢量数据库增加了操作范围。好处是跨 OpenAI 兼容模型、Anthropic 模型和未来提供程序的可移植性更强。它们还使租户范围的命名空间或分片更容易推断网关何时负责计费和关闭。
细粒度的块可提高引用精度和可审核性。它们还增加了索引大小、检索量和提示组装复杂性。粗块更简单,但它们可能会产生指向宽泛的页面或部分的引用,而不是确切的支持段落。
严格的引用要求模式可以提高用户信任度。它还会强制网关处理无法生成所需引文格式的模型,这可能意味着拒绝请求、更改模型或返回置信度较低的答案。
预测:检索将变得更加原生,但网关仍然需要自己的合同
提供商原生检索功能可能会变得更加强大。更多模型将接受带有结构化源元数据的检索上下文。更多 API 将公开排名控制、查询重写和引文设置。但这并没有消除对网关合同的需要。
网关仍然拥有租户身份、密钥管理、支出限制、使用情况分析、合作伙伴 API 工作流程以及面向客户的删除承诺。提供程序功能可以在适配器层后面使用,但产品不应强制每个租户、模型和计费工作流程进入一个提供程序的检索抽象。
可行的结论
将多租户 RAG 构建为具有明确边界的网关子系统。在检索之前解析租户身份。使用租户范围的命名空间、分片或向量存储。将检索保留在适配器后面。将引用标准化为网关拥有的模式。添加生命周期状态和删除验证。分别跟踪嵌入、检索和生成成本。
此架构使 RAG 保持稳定,而无需将产品锁定到一个检索提供商。当 AI 助手从原型转向面向客户的系统时,它还为团队提供了所需的操作控制:隔离、引文、可移植性、生命周期管理和成本归因。