Retrieval-augmented generation 通常以一张简洁的示意图开场:

documents -> embeddings -> vector database -> LLM

Enter fullscreen mode Exit fullscreen mode

这是一条有用的起点,但它可能会把架构中的一小部分误当作整个系统。

优秀的 RAG 数据库设计需要覆盖的远不止向量存储。

一个生产级的 RAG 应用可能还需要存储原始文档、强制租户隔离、精确匹配产品名称、按日期过滤、记住对话、失效过时内容、组合多个数据源,并将最终 prompt 控制在 token 预算内。

仅仅因为存储了 embedding,数据库并不会自动变成“RAG 数据库”。不同的数据库模型解决检索的不同环节。

本文将探讨关系数据库、文档数据库、缓存、全文搜索引擎和向量数据库在 RAG 中的角色。随后再讨论一个仅靠相似度难以表达的检索难题:当应用已知中心、却不知答案确切边界时,如何找到有用的上下文邻域。

在实际的 AI 用例中,这一模式出现在客户支持、销售效率工具、内部知识助手、AI 编程自动化以及 AI Agent 开发中。同样的问题也适用于基于内部数据的 AI 助手开发——此时访问控制和数据新鲜度与生成答案同样重要。

RAG 的工作原理及其与微调的区别

RAG 在收到请求时检索外部信息,再把选定的证据放入模型上下文。微调则改变模型权重。因此,RAG 与微调的实际区别在于知识何时、何地被引入。

由于知识保存在模型外部,RAG 通常更容易更新、引用、过滤或移除。微调可以改变行为、风格或学习到的模式,但它并不是频繁变化的文档存储的便捷替代方案。

RAG 的主要优缺点由此分离而来:RAG 可以使用最新、私有数据源而无需重新训练模型,但它增加了摄取、检索、权限、评估、延迟和运维工作。仅理解 AI 生成原理并不足够:一个流畅的模型仍可能基于弱旧或未授权的证据作答。

数据库类型与如何构建 RAG

一个更完整的 RAG 流水线如下:

source data
  -> ingestion and normalization
  -> document and metadata storage
  -> candidate selection
  -> lexical or vector ranking
  -> reranking and context assembly
  -> LLM
  -> answer and citations

Enter fullscreen mode Exit fullscreen mode

数据库可在多个阶段参与。

Responsibility Typical data
Source of truth Documents, records, revisions, users, permissions
Ingestion state Jobs, checksums, parser versions, failures
Exact filtering Tenant, category, status, language, date
Lexical retrieval Keywords, names, identifiers, error codes
Semantic retrieval Embeddings and similarity scores
Session state Recent messages, selected sources, cached results
Context assembly Related records, projections, token-bounded payloads

一个数据库可以承担其中多项职责。小型应用并不需要因为表格中有六行就使用六个数据库。关键在于在选择存储引擎之前先明确检索任务。有效的数据库比较应从这些任务出发,而非单纯的功能数量对比。

团队在研究如何构建 RAG 时,往往从 embedding 模型或 RAG 向量数据库入手。更安全的顺序是先确定真实来源、访问规则、更新流程、精确过滤、候选检索方法和评估计划。向量索引只是该设计中的一个组件。

为了具体化差异,我们假设正在构建一个京都旅行助手。它存储关于地标、餐厅、文化设施、活动、交通、营业时间、预订以及用户行程的信息。

PostgreSQL 与 MySQL:结构化真相与精确关系

关系数据库通常是保存 RAG 系统权威应用状态最不意外的选择。

对于旅行助手,关系数据库可以存储:

  • 用户与账号;
  • 预订与预约;
  • 收藏地点与行程;
  • 租户或组织边界;
  • 文档版本与摄取状态;
  • 权限与可见性规则;
  • 结构化的营业时间与无障碍字段。

当正确性依赖于精确关系时,SQL 尤其有用。如果私人行程仅属于某一用户,或文档不得跨越租户边界,该规则不应依赖 embedding 分数。

关系查询可以先选出允许的 document ID,RAG 流水线随后仅对这些文档进行排序。

SELECT document_id
FROM travel_documents
WHERE city = 'Kyoto'
  AND language = 'en'
  AND published = true
  AND valid_from <= CURRENT_TIMESTAMP
  AND valid_until > CURRENT_TIMESTAMP;

Enter fullscreen mode Exit fullscreen mode

PostgreSQL 还支持 JSON、全文搜索和扩展。pgvector 扩展可以将向量与关系数据并存,这通常足以支撑早期或中等规模的 RAG 应用。

重要的是:添加向量列并不会消除设计权限、文档生命周期、元数据、候选选择和 prompt 构建的需求。

MongoDB 与文档数据库:灵活的内容记录

当摄取项已呈现为 JSON 对象,且不同类型拥有不同字段时,文档数据库是自然的选择。

地标记录可能包含历史、图片、坐标和营业时间。餐厅可能包含菜系、价格区间、预订规则和饮食选项。活动可能包含开始时间、场馆、票务链接和天气政策。

{
  "kind": "restaurant",
  "name": "Example Cafe",
  "area": "Higashiyama",
  "cuisine": ["Japanese", "Cafe"],
  "features": {
    "indoor": true,
    "vegetarianOptions": true
  }
}

Enter fullscreen mode Exit fullscreen mode

MongoDB documents 可以 表示这种结构,而无需将每种类型强制放入同一列。元数据与源文本可以共存,嵌套字段在已知访问模式时也可以被索引。

然而,灵活性并不消除检索设计。应用仍需决定哪些集合、字段、过滤器和记录应成为模型的候选。

经典的 RDB 与 NoSQL 差异在此依然重要。关系系统以精确关系和约束为中心;文档数据库以灵活的记录形状和面向聚合的访问为中心。对于业务系统,NoSQL 数据库选型应考虑一致性、授权、运维技能、备份和迁移,而不仅仅是传入数据是否为 JSON。

Redis:短生命周期状态与重复工作

即使不是主文档存储,Redis 在 RAG 场景中也很有用。

常见用途包括:

  • 对话会话状态;
  • 缓存的检索结果;
  • 速率限制;
  • 短生命周期 Agent 状态;
  • 任务队列;
  • 去重键;
  • 频繁重用的上下文片段。

若许多用户对同一景点提出相似问题,缓存已验证的检索结果可能比再次运行完整流水线更省成本。

Redis 支持持久化和多种数据结构,但缓存仍需失效策略。旅行信息使这一点显而易见:关于活动、临时关闭或营业时间的答案即使在缓存文本内部一致,也可能已过时。

Redis 文档
将其描述为远不止简单的键值缓存,但在 RAG 架构中的角色仍应被明确选择。

OpenSearch:词语、字段与过滤器依然重要

embedding 搜索并非全文搜索的替代品。

用户会搜索精确的地名、线路、产品代码、法律术语、错误消息和引号短语。模型可能会为相关文本生成相似的 embedding,但精确标识符通常仍需要词法匹配。

OpenSearch 可组合:

  • 全文查询;
  • BM25 风格的词法相关性;
  • 字段过滤;
  • 聚合;
  • 地理查询;
  • 向量搜索;
  • 面向搜索的仪表板与运维工具。

对于旅行助手,它可以回答如下问题:

Find pages containing "Kiyomizu-dera" in English,
published in the Kyoto corpus, with an opening-hours field updated this month.

Enter fullscreen mode Exit fullscreen mode

该查询包含精确文本、元数据和新鮮度要求。这些信号不应被简化为单一向量距离。

OpenSearch 文档
涵盖词法与面向向量的搜索,使其成为需要同时支持这两种检索模式的潜在单引擎选择。

Qdrant 与向量数据库:语义相似度

向量数据库围绕一个不同的问题设计:

Which stored items are closest to this query in embedding space?

当用户与文档不共享相同词汇时,这很有价值。

例如,访客可能问:

Where can I spend a quiet indoor afternoon learning about local history?

Enter fullscreen mode Exit fullscreen mode

有用的博物馆描述可能不包含该确切句子。语义检索仍可将其纳入候选集。

Qdrant 存储带 payload 元数据的向量,并支持带过滤的相似度搜索。典型请求先限制合格点,再按向量距离对剩余点排序。

metadata filter
  -> approximate nearest-neighbor search
  -> top candidates
  -> optional reranker
  -> LLM context

Enter fullscreen mode Exit fullscreen mode

这是一种有效模式,但留下一个架构问题:应用如何在相似度排序开始前决定正确的过滤器和搜索命名空间?

向量数据库的相似度搜索算法、索引类型、过滤行为、内存使用和更新模式都会影响结果。RAG 向量数据库对比(Pinecone、Qdrant、pgvector 或 OpenSearch)应使用应用自身语料和过滤器进行。推荐向量数据库的列表无法替代针对工作负载的评估。

RAG 混合搜索:BM25、向量与重排序

关键词与语义检索是互补的。RAG 混合搜索流水线可结合 BM25 与向量分数,使精确名称和标识符保持可见,同时仍能发现语义相关的文档。

metadata and permission filters
  -> BM25 lexical candidates
  + vector similarity candidates
  -> merge and deduplicate
  -> reranker
  -> token-bounded context

Enter fullscreen mode Exit fullscreen mode

对于提升 RAG 准确率,重排序集成通常比单纯增加第一阶段结果数量更有用。重排序器可更仔细地检查小型候选集,而第一阶段仍以召回率优化。

RAG chunk size 优化技术也很重要。小块可提升匹配精度但可能丢失上下文;大块保留上下文但消耗更多 token 并可能稀释相关性。合适的块大小取决于文档结构、检索方法以及需要被引用的单元。

LangChain 和 LlamaIndex 等 RAG 框架可连接加载器、embedding、retriever 和模型。LangChain RAG 设置示例可展示接线,但框架无法为应用决定正确的授权边界、新鲜度规则或候选范围。

内部搜索的开源 RAG 设置可结合 PostgreSQL、OpenSearch 或 Qdrant、本地模型以及编排框架。自托管改变了运维和隐私边界,但并未消除相同的检索与评估决策需求。

RAG 准确率提升与评估指标

检索质量与答案质量应分开衡量。实用的 RAG 评估指标包括:

  • recall 和 precision at k
  • mean reciprocal rank 或 nDCG;
  • context relevance 和 context precision;
  • groundedness 或 faithfulness;
  • citation correctness;
  • answer completeness;
  • retrieved tokens、latency 和 cost per request。

Ragas 等工具可帮助自动化评估的部分工作,但任何 RAG 评估工具或教程都无法为每个业务流程定义正确的预期答案。来自真实问题的小型人工审核测试集仍然有价值。

RAG 幻觉预防措施应不止于添加更多文档。更强的措施包括当前来源、显式引用、权限检查、冲突检测、弃权选项,以及针对知识库中不存在答案的问题的测试。

RAG 知识库自动更新也需要版本控制和失效策略。流水线应知道哪个源修订产生了 chunk、何时必须重建 embedding,以及已删除或过期信息如何离开缓存和索引。

RAG 安全措施与实施成本

RAG 安全措施始于检索之前。租户隔离、源授权、秘密移除、加密、审计轨迹以及针对检索文档中 prompt 注入的防御都应纳入设计。即使数据库被描述为 AI 组件,通用的数据库安全措施依然适用。

组织可能还需要使数据的收集与使用符合隐私规则、行业义务、AI 法律监管以及自身 AI 伦理准则。检索使数据对模型可用;它并不创造使用该数据的权限。

完整的 RAG 成本对比包括摄取、embedding 生成、数据库存储、缓存、网络传输、重排序、LLM 输入 token、监控、备份和工程时间。对于小企业,平均 AI 实施成本不能仅从模型 API 价格推断。

RAG 成本降低与 token 节省与候选范围密切相关。

通过检索和重排序传递更少无关记录,可同时减少数据库工作和 LLM 输入。对于本地部署,本地 LLM 设置和 PC 要求是单独的容量决策,但更小的检索上下文仍可降低下游内存和计算压力。

许多 AI 实施失败是因为 demo 仅在少数成功问题上被评估。当系统也能处理过时数据、缺失答案、访问边界、成本限制和故障恢复时,实际的 AI 实施收益才会显现。

困难的部分往往是候选范围

考虑这个问题:

I am at Kiyomizu-dera. It is raining, and I have two hours. What should I do
next?

几种检索方法都可以提供帮助:

  • 词法搜索可找到提及 Kiyomizu-dera 的页面;
  • 地理搜索可找到半径范围内的坐标;
  • 向量搜索可找到语义相似的旅行建议;
  • SQL 可强制执行营业时间、权限和预订约束;
  • 重排序器可对结果候选重新排序。

挑战不在于其中任何一种方法不好。挑战在于决定哪些内容应进入候选集。

有用的答案可能需要:

  • 附近地标;
  • 室内博物馆或画廊;
  • 当前营业的餐厅;
  • 今日举办的临时活动;
  • 交通信息;
  • 无障碍信息;
  • 用户行程中已存在的地点。

应用已知中心:访客、Kiyomizu-dera、当前日期和当前情况。它尚不知道有用答案的确切边界。

语义相似度并非运维相关性

语义最相似的文档不一定是当前请求最有用的文档。

一篇关于另一座日本寺庙的精美文章可能在 embedding 空间中接近,但在两小时内无法使用。一条简短的交通通知可能在语义上远离旅游问题,但对答案至关重要。餐厅记录可能几乎不包含用户请求中的任何词,但因其附近、营业且与行程兼容而相关。

RAG 系统通常用元数据过滤器解决此问题:

{
  "city": "Kyoto",
  "area": "Higashiyama",
  "openNow": true,
  "weather": "rain",
  "categories": ["restaurant", "museum", "landmark"]
}

Enter fullscreen mode Exit fullscreen mode

这很合理。但随着产品增长,过滤器会变成应用级检索计划。必须有人维护为每个请求重建上下文所需的规则、命名空间、连接和扇出读取。

地理距离也不是完整的边界

如果问题仅仅是“1 公里内有什么?”,PostGIS 或 OpenSearch 地理搜索等地理索引是直接解决方案。

然而,有用的旅行上下文并不总是圆形。

  • 河流、山丘或铁路可能使两个近点不便到达。
  • 下雨会改变哪些设施有用。
  • 家庭与独自旅行者可能需要不同邻域。
  • 营业时间和活动日期改变可用上下文。
  • “雨天京都”等编辑分组不是地理区域。
  • 一个地点可同时属于区域指南、车站指南和个人行程。

距离仍然是重要信号。它只是不是定义视野的唯一关系。

应用持续重建上下文

传统技术栈可以解决此问题。它可能使用 SQL 连接、地理索引、搜索过滤器、图、应用维护的 ID 列表和向量排序。

重复的工作是重建相同的 locality:

start from the current place
  -> identify the area
  -> find allowed categories
  -> join today's events
  -> add relevant transit
  -> add itinerary items
  -> build candidates
  -> rank candidates

Enter fullscreen mode Exit fullscreen mode

这里缺少的操作不是另一个打分算法,而是一种可复用的方式来回答这个更早的问题:

What belongs in the neighborhood of this known center for this kind of
request?

将可复用邻域视为数据

一种设计选择是将该邻域存储起来,而不是每次请求都从头重建。

这并不自动需要新数据库。应用可以使用 SQL 连接表、图边、物化视图、搜索文档或维护的 ID 列表来建模该关系。重要的概念转变是:候选范围成为具有自身生命周期的数据,而不是在排序前临时组装的查询逻辑。

对于旅游示例,可复用邻域需要几个属性:

  • 每个地点应保留一条规范记录;
  • 同一地点应能出现在多个上下文中;
  • 将地点添加到指南不应复制其 payload;
  • 读取应受类别、深度、过滤器、限制和 token 成本约束;
  • 在邻域选定后仍应可进行词法或向量排序。

如果这种关系是偶发的,应用代码可能已足够。如果同一模式在用户、地点、项目、产品或时间窗口中反复出现,则将 locality 作为一等检索原语可能很有用。

KoutenDB 如何表示这种检索模式

KoutenDB 是围绕该模式设计的一种数据库。它使用类坐标的 ring 放置规范记录,并使用 stellar 可见性透镜在这些坐标上创建可复用视图。

导入器或应用可将旅游数据保存在规范 ring 中:

landmarks/kyoto/kiyomizudera
landmarks/kyoto/yasaka-pagoda
restaurants/kyoto/gion
culture/kyoto/national-museum
events/kyoto/2026-07-23
transit/kyoto/higashiyama

Enter fullscreen mode Exit fullscreen mode

然后可将有用坐标附加到以区域为中心的视图:

kouten stellar attach \
  --stellar=travel/kyoto/higashiyama \
  --ring=landmarks/kyoto/kiyomizudera

kouten stellar attach \
  --stellar=travel/kyoto/higashiyama \
  --ring=restaurants/kyoto/gion

kouten stellar attach \
  --stellar=travel/kyoto/higashiyama \
  --ring=culture/kyoto/national-museum

kouten stellar attach \
  --stellar=travel/kyoto/higashiyama \
  --ring=events/kyoto/2026-07-23

Enter fullscreen mode Exit fullscreen mode

应用可从已知中心读取周围上下文:

kouten get --stellar=travel/kyoto/higashiyama

Enter fullscreen mode Exit fullscreen mode

或将同一视野缩小到某一类别:

kouten get --stellar=travel/kyoto/higashiyama --subring=restaurants
kouten get --stellar=travel/kyoto/higashiyama --subring=culture

Enter fullscreen mode Exit fullscreen mode

同一餐厅也可通过雨天指南、车站为中心指南或用户行程可见,而无需复制其规范 payload。

KoutenDB 不会从路径名推断地理或编辑相关性。

应用、导入器或策展流程仍需决定哪些坐标属于每个邻域。数据库保留该决策,以便后续读取无需从头重建。

这不仅仅是路径前缀

ring 名称故意看起来像可读路径。当父子数据自然属于一起时,层级很有用。

然而,路径前缀本身仅表示一棵树。真实记录同时参与多个视图:

canonical catalog: restaurants/kyoto/gion/example-cafe
area guide:        travel/kyoto/higashiyama
weather guide:     travel/kyoto/rainy-day
personal plan:     travel/users/123/today

Enter fullscreen mode Exit fullscreen mode

在每条路径下复制餐厅会产生同步工作。将其移动到一条路径会削弱其他视图。stellar 透镜则在现有坐标上存储可见性关系。

调用方提供中心和成本边界。深度、分支预算、subring、过滤器、投影、排序和限制控制返回多少上下文。调用方无需枚举答案中的每条记录。

Locality 可先于向量排序

Locality-aware 检索与向量搜索并不互斥。

组合流水线可如下:

known center: user + place + time
  -> retrieve the configured local neighborhood
  -> apply current constraints
  -> vector-rank the smaller candidate set if needed
  -> rerank and enforce a token budget
  -> LLM

Enter fullscreen mode Exit fullscreen mode

向量数据库询问哪些候选在语义上接近。locality 层询问数据中哪些部分应首先被考虑。

这可减少加载的 payload 数量、比较的向量数量、重排序的记录数量、传输的字节数以及下游考虑的 token 数量。它并不保证每个查询都更快。只有当应用能够表达有意义的 locality 时,该模型才有用。

将数据库与检索问题匹配

当从问题而非当前 RAG 趋势出发时,数据库决策会变得更清晰。

Retrieval question Natural starting point
Which exact record or relationship is valid? Relational query and indexes
Which JSON documents match known fields? Document database or SQL/JSON
Which result can be reused briefly? Cache or session store
Which documents contain these words? Full-text search engine
Which documents are semantically similar? Vector search
Which places are inside a literal radius? Geographic index
Which context is useful around this known user, place, project, or time? Locality-aware neighborhood retrieval

这些并非互斥选择。PostgreSQL 可保留真实来源,OpenSearch 处理词法检索。向量数据库可对语义相似的 chunk 排序。KoutenDB 可作为 locality-aware 文档与检索存储,或作为更早的候选选择阶段。

较小的系统可选择覆盖足够角色的单一数据库。较大的系统可将其分离。只有当它解决了经过测量的检索、正确性或运维问题时,额外基础设施才合理。

因此,RAG 的实用数据库设计步骤是:

  1. 识别权威来源和更新所有者;
  2. 定义租户、用户和文档访问边界;
  3. 列出精确、词法、语义、地理和 locality-aware 查询;
  4. 选择覆盖这些查询的最小数据库类型集合;
  5. 衡量检索质量、token、延迟和失败案例;
  6. 记录无法重建数据的数据库备份方法和数据库迁移步骤;
  7. 仅在候选和访问模型正确后才进行数据库性能调优。

最终问题是应用已知什么

RAG 架构通常从询问使用哪个 embedding 模型或向量数据库开始。

另一个有用的先决问题是:

What does the application already know before retrieval begins?

它可能已经知道已认证用户、租户、订单、项目、文档组、当前位置、时间窗口或活动任务。这些信息可以定义一个比完整语料库小得多、也更相关的起始区域。

如果请求以无有意义中心开始,全局词法或向量搜索可能完全正确。如果请求以已知中心但不确定上下文边界开始,保留 locality 可在排序和 prompt 构建开始前保持更小的检索问题。

重要的选择不是 SQL 还是向量,也不是一个数据库产品还是另一个。而是决定应用需要精确真相、词法匹配、语义相似度、地理邻近还是可复用的上下文邻域——然后为每个检索阶段提供它实际需要的数据模型。

这是 RAG 数据库设计能够超越 demo 的基础。