生产级 RAG:将自托管检索从演示打造成可靠服务

RAG 的演示版和服务版是两码事。缓存、可观测性、数据新鲜度、安全性和 CI——这些是教程里从来不会展示的部分。

Aquila 团队 更新于 2026年6月19日

将自托管 RAG 投入生产意味着加强教程跳过的七个方面:缓存,避免重复计算相同的工作;可观测性,让你了解检索和生成实际做了什么;延迟和成本控制,确保服务在高负载下保持快速和可负担;访问控制,用户只能看到他们被允许看到的内容;数据新鲜度,防止索引腐烂;CI 中的评估,确保变更不会悄然降低质量;以及扩展计划,用于随着语料库增长扩展向量存储。一个演示只能证明一次想法可行;而生产环境能让每个人、每一天都可靠运行,且不会泄露数据或超出预算。本指南涵盖每个方面,并在最后附有一份清单。

这是 RAG 集群的生产收官指南。它假设你已经拥有来自自托管 RAG 完全指南的有效流水线,并且已在一台机器上搭建起来,例如通过在 VPS 上搭建私有 RAG

缓存:不再为重复工作买单

缓存是最高杠杆的生产优化,因为 RAG 会不断重复自身。有三个层面,你应该全部使用。

  • 嵌入缓存。 两次嵌入相同的查询文本纯属浪费。缓存以标准化查询字符串为键的查询嵌入。在索引时,缓存以内容哈希为键的文档嵌入,以便未更改的块在重新索引时永远不会被重新嵌入。仅此一项就能大幅缩短重新索引时间。
  • 检索缓存。 对于重复的查询,给定固定索引,检索到的块 ID 集是确定性的。缓存它(使用较短的 TTL 或索引版本键,以便在重新索引时失效)。常见问题会频繁命中此缓存。
  • 生成/语义缓存。 节省最大的部分。缓存以查询为键的完整答案——更进一步,使用语义缓存:嵌入传入查询,如果它与之前回答过的查询几乎相同,则直接返回缓存的答案,完全不用调用 LLM。“如何重置密码?”和“密码重置步骤”不应都为生成付费。

简单的进程内或 Redis 后端缓存即可覆盖前两层;语义缓存复用你现有的嵌入模型。始终以索引版本为键来缓存,以便重新索引使过期条目失效——一个提供来自上周已删除文档答案的缓存是正确性错误,而非优化。

可观测性:你看不到的东西就无法修复

RAG 答案经过检索和生成两个阶段,每一阶段都可能失败。在演示中你可以直接观察;但在生产环境中,你需要记录它。对于每个请求,捕获:

  • 原始查询、检索到的块 ID 及其得分,以及(采样的)块文本。
  • 所使用的重新排序器顺序(如果有),以及最终发送给 LLM 的块。
  • 提示词 token 数量、答案以及答案引用的来源。
  • 各阶段的延迟——嵌入、检索、重排、生成——以及总延迟。
  • 每个阶段的错误和超时。

这种阶段级追踪可以让你在无需猜测的情况下回答“这个答案为什么不好?”。如果检索返回了错误的块,那是召回率/分块问题;如果检索到了正确的块但答案忽略了它,那是生成/提示词问题。这种划分与评估方法相呼应:你必须能够将失败归因于正确的部分。像 OpenTelemetry 追踪,或框架和开源工具(Langfuse、Phoenix)中的 RAG 特定追踪,都能提供这一点;关键在于你能够端到端地重建任何一个糟糕的答案。

同时记录反馈信号——点赞/点踩,或者用户是否重新措辞并再次提问(这是一个强烈的隐含信号“之前错了”)。通过这种方式捕获的实际失败会成为你黄金测试集中的新用例。

负载下的延迟和成本控制

对于单个用户工作正常的流水线在数百个用户时可能崩溃。兼顾两者:

策略效果备注
语义答案缓存完全跳过重复查询的生成过程成本和延迟方面最大的单一优势
限制检索 k 和候选数量减少重新排序和 prompt token 成本根据你的评估集调整,不要猜测
流式输出答案降低感知延迟即使完整答案很慢,首 token 也能快速返回
批量嵌入提高索引时的吞吐量重新索引完成更快
选择合适大小的生成模型主要成本杠杆较小的本地模型通常足够;将更大的模型留给困难查询
并发限制/队列保护服务器免受过载有界队列优于崩溃的 GPU

关于自托管的两条生产特有的成本注意事项:首先,你的“token 成本”实际上是 GPU 和 CPU 时间——保持提示词简短(良好的检索,而非填充;参见 RAG 与长上下文)直接保持服务器的响应性并稳定你的开销。其次,生成 LLM 主导计算,因此分层方法——使用小型本地模型回答简单查询,仅升级困难查询——通常优于运行一个大模型处理所有请求。

安全与访问控制

这是自托管真正体现价值的地方,也是团队容易偷工减料的地方。两个不同的关注点:

基础设施安全。 标准的服务卫生习惯,但在内部工具上容易忽视:将 API 置于身份验证之后,不要将向量存储或 Ollama/vLLM 端口暴露给公网,使用 TLS,轮换密钥,并对每个客户端进行速率限制。自托管的 RAG 服务器通常在一个地方保存你最敏感的文档——请相应对待。

基于用户的访问控制(难点)。 如果不同用户可能看到不同的文档,你不能从一个共享索引中检索并信任 LLM 会忽略禁止的内容——那是一个等待发生的信息泄露。在检索时强制权限:

  • 在摄取时为每个块标记访问元数据(所有者、团队、分类、允许的角色)。
  • 个查询上应用元数据过滤器,以便向量搜索仅返回请求用户被授权查看的块。
  • 永远不要依赖提示指令(“不要透露 X”)进行访问控制——过滤检索是强制措施;提示只是一个建议。

这也是检索优于填充巨大上下文的强有力论据:使用 RAG,用户的权限决定了哪些内容可以被检索,因此未经授权的内容根本不会到达模型。大多数可自托管的向量存储(pgvector、Qdrant、Weaviate)都支持在相似性查询内部进行元数据过滤——见什么是向量数据库。并且因为整个栈都在你的基础设施上,查询和文档永远不会穿越你无法控制的网络边界。

数据新鲜度与重新索引

一个不更新的知识库会变成一个自信满满却错误百出的知识库。从第一天开始就为变更做好计划:

  • 增量更新,而非完全重建。 当文档发生变化时,仅对该文档重新分块和嵌入,并使用稳定的块 ID 进行更新。对块进行内容哈希处理,以便跳过未更改的块——这与上面的嵌入缓存完美配合。
  • 处理删除。 当源文档被移除或访问被撤销时,删除其向量。一个“已删除”的文档仍能回答问题,这既是一个过时性错误,也是一个安全事件。
  • 调度任务。 使用 cron 作业或事件驱动作业(文件更改时、通过 webhook、每晚)保持索引更新。跟踪每个源的“上次索引”时间戳,以便发现陈旧角落。
  • 为索引添加版本。 为索引打上版本标签;在重新索引时提升版本,以便缓存失效,并且如果糟糕的索引过程破坏了检索,你可以回滚。
  • 模型变更时重新嵌入。 如果你更换嵌入模型,你必须重新嵌入整个语料库——来自不同模型的向量不可比较。将嵌入模型更换视为一次完全重建,并在切换前根据评估集进行验证。

CI 中的评估:护栏

一个持续改进的 RAG 系统与一个悄然退化的系统之间的区别在于,质量是否被严格地把关,而不仅仅是度量。将你的黄金测试集接入 CI:

  1. 在版本控制中保存一个黄金测试集(问题、预期来源、参考答案)——参见如何评估 RAG
  2. 每次更改分块策略、嵌入模型、重新排序器、提示词或模型时,在 CI 中重新运行测试集。
  3. 如果 recall@k、MRR 或 faithfulness 降至你设定的阈值以下,构建失败。一个修复了某个问题的更改通常会破坏其他五个问题;只有质量把关能在用户发现之前捕捉到这些。
  4. 同时也保持评估自托管——使用本地嵌入模型进行检索指标,使用本地评判模型(通过 Ollama 或 vLLM)进行忠实度评估——这样评分“隐私”本身就不会泄露数据。

这会将“我们认为新的分块器更好”转化为一个数字,它要么达标,要么没有。这是最能区分生产 RAG 系统与脆弱系统的单一实践。

扩展向量存储

向量存储通常是迫使你在成长过程中做出架构决策的组件。大致阶段如下:

  • 数万个块。 几乎任何东西都能在单台机器上胜任——pgvector、Chroma、Qdrant。通常,内存而非磁盘是内存 HNSW 索引的第一个瓶颈。一个 768 维 float32 向量大约 3 KB 原始数据;为每个块预留几千字节加上文本,你就不会感到意外。
  • 数百万个块。 迁移到为此构建的引擎——QdrantWeaviate 作为专用存储,或者如果你希望向量与关系数据共存且共享一个备份方案,则使用 pgvector。调整 HNSW 参数(构建时 m/ef_construction,查询时 ef),以在召回率和延迟之间进行权衡。添加量化以减少内存占用。
  • 数千万个及以上。 现在你需要关心分片、复制以实现高可用性,以及分布式部署。Qdrant 和 Weaviate 支持集群;Milvus 专为此规模而构建。这也是过滤搜索性能(ANN 搜索内部的快速元数据过滤)最为重要的地方——与上面的访问控制故事相关。

根据你的实际语料库大小和增长情况选择引擎,而不是根据基准测试标题。最佳自托管向量数据库对比 详述了取舍;概念基础请参见什么是向量数据库。并实际估算存储——在确定硬件规模之前,重新阅读自托管成本分解

生产清单

  • 缓存 —— 查询嵌入、检索和语义答案缓存;全部以索引版本为键。
  • 可观测性 —— 每个请求的阶段级追踪(嵌入、检索、重排、生成),包含块 ID、得分、token 数、延迟和错误。
  • 反馈捕获 —— 点赞/点踩或隐式重新提问信号,反馈到黄金测试集。
  • 延迟控制 —— 流式输出、限制 k、选择合适大小的生成模型、并发限制。
  • 成本控制 —— 语义缓存、分层模型、批量嵌入;通过良好检索实现简短提示词。
  • 基础设施安全 —— API 认证、无公共数据库/LLM 端口、TLS、密钥轮换、速率限制。
  • 访问控制 —— 块级权限元数据,作为每个查询的检索时过滤器强制执行。
  • 数据新鲜度 —— 按内容哈希增量更新、硬删除、计划性重新索引、索引版本化。
  • 嵌入变更计划 —— 任何嵌入模型更换时,完全重新嵌入 + 评估重新验证。
  • CI 中的评估 —— 每次变更重新运行黄金测试集,回归时构建失败,评判模型本地运行。
  • 扩展计划 —— 向量存储根据实际语料库增长调整大小,调整 HNSW,在需要时进行量化/分片。

你不需要第一天就实现所有内容。缓存、可观测性、访问控制和 CI 中的评估是最先重要的四项——它们能将一个能工作的演示转变为人们可以信赖的服务。

常见问题

将 RAG 投入生产时,最重要的添加内容是什么? CI 中的评估。一个能把关每次变更的黄金测试集可以阻止悄然退化——这种故障模式会悄悄毁掉 RAG 系统。缓存和每请求可观测性紧随其后。

如何让 RAG 在负载下保持快速? 语义答案缓存(对重复或近乎相同的查询跳过生成)是最大的赢手。然后流式输出答案以获得低感知延迟,限制检索 k 和重排序候选数量,选择合适大小的生成模型,并在服务器前放置一个有界并发队列。

如何在 RAG 中强制实现基于用户的权限? 在摄取时为每个块标记访问元数据,然后在每次检索时应用元数据过滤器,以便向量搜索仅返回请求用户可以看到的块。永远不要使用提示指令进行访问控制——过滤检索是强制措施;提示不是。

文档变更时是否需要重新索引所有内容? 不需要。仅对变更的文档重新分块和嵌入,并使用稳定的块 ID 更新;对块进行内容哈希处理,以便跳过未更改的块。例外情况是更换嵌入模型,这需要完全重新嵌入,因为来自不同模型的向量不可比较。

何时需要从 pgvector 或 Chroma 迁移? 大约在达到数百万个块时,或者当内存压力和延迟恶化时。迁移到 Qdrant 或 Weaviate 作为专用存储(或者如果你希望向量与关系数据共存,则继续使用 pgvector),并在数千万级别时考虑 Milvus。根据你的实际语料库大小和评估测得的延迟来做决定,而不是基准测试标题。


Aquila 是私有、自托管 AI 搜索的独立指南——基于一个信念:你应该拥有自己的索引,而不是租赁它。生产级 RAG 主要是平淡无奇的纪律:缓存、观察、把关、保持数据新鲜和访问受控——所有这一切都在你控制的基础设施上。探索更多指南 或订阅新闻通讯,获取关于 RAG、向量数据库和语义搜索的诚实且供应商中立的分析。掌控你自己的搜索。

继续学习

更多关于自托管 AI 搜索、RAG 和向量数据库的指南。