Naive RAG(经典 RAG)
RAG 的最基础形态。所有 RAG 变体的底子,先吃透它,再看其他范式都是在这之上做优化。
一、核心思想
LLM 不知道的事(实时信息、私有文档),先从文档库里检索相关内容,拼进 prompt,让 LLM 基于检索结果回答。
用户问题 → 检索相关文档 → 拼进 prompt → LLM 生成回答
二、完整流程(两阶段)
阶段一:入库(离线,提前做)
文档 → 切片 → 每片 embedding → 向量存入向量库
这一步提前做好,文档向量预先算好存着。
阶段二:检索生成(在线,用户提问时)
用户问题 → embedding → 和库里文档向量比相似度 → 取 top-k → 拼进 prompt → LLM 生成
三、逐步拆解
1. 切片(Chunking)
把长文档切成小块。
为什么切:
- embedding 对短文本效果更好(长文本语义被稀释)
- 检索要精准(返回最相关的一段,而非整篇)
- LLM context 有限
常见切法:
| 方法 | 说明 |
|---|---|
| 固定长度 | 每 N 字符切一块 |
| 递归字符切分 | 按段落→句子→字符递归切,尽量在自然边界切 |
| 按标题切分 | Markdown 按 #/## 切,保留语义结构 |
关键参数:
chunk_size:每块字符数(如 800~1600)chunk_overlap:相邻块重叠(如 100),避免切断上下文- 小块合并:太小的合并到上一块,避免碎片
2. Embedding(向量化)
把文本转成定长向量,让语义相近的文本向量也相近。
"禅院飞鸟介绍" → [0.12, -0.34, ..., 0.78] (1024维)
"禅院飞鸟的背景" → [0.11, -0.32, ..., 0.77] (向量很接近)
"CPU排查方法" → [-0.45, 0.23, ..., 0.02] (向量差很远)
embedding 模型是 bi-encoder(双编码器):单条文本输入,输出向量。
3. 向量库
存文档向量,支持高效相似度检索。常见:Milvus、Faiss、Chroma、Pinecone。
入库时文档向量预先算好存着,检索时只算 query 向量,所以快。
相似度度量:
- 余弦相似度:算向量夹角,越接近 1 越像
- L2 距离:算直线距离,越小越像
4. 检索
query → embed → query向量
↓
和库里所有文档向量算相似度
↓
取相似度最高的 top-k 个文档
对比只有一次:query 向量 vs 文档向量。检索结果(挑出的文档)是对比的产物,不是再拿去对比的输入。
top-k:取最相似的 k 个(如 top-3)。注意 top-k 是检索参数,和生成的 top-p 无关。
5. 拼 prompt
把检索到的文档直接拼进 prompt 的 context 部分:
prompt:
系统: 基于以下资料回答问题
资料:
[文档1] ...
[文档2] ...
[文档3] ...
用户: <用户原话>
LLM → 基于资料生成回答
6. 生成
LLM 看到 context 里的文档,基于它生成回答。答案有据可查(可溯源到文档)。
四、特点
- 每次必检索:不管问什么,都去检索
- 检索词用原话(或简单改写):直接用用户问题向量化去检索
- 结果拼进 context:检索到的文档作为 prompt 上下文,LLM 充分可见
五、优缺点
优点:
- 简单直接,流程清晰
- 可控(每次都检索,结果拼 context,LLM 一定能看到)
- 适合问题明确的场景
缺点:
- 问题不明确时检索差(用户原话未必是好的检索词)
- 每次都检索,即使不需要(如"你好"也去检索,浪费)
- 无精度优化(无 query 改写、无 rerank)
六、适用场景
- 简单 QA(问什么就检索什么)
- 问题明确、和文档语言一致
- 对检索精度要求不高
七、关键认知
- Naive RAG 是基础:检索 → 拼 prompt → 生成。
- 两阶段:入库(离线预计算文档向量)+ 检索生成(在线)。
- 向量检索是 query 向量 vs 文档向量,对比一次出结果。
- 检索结果拼进 prompt context,LLM 充分使用。
- 简单可控,但无优化、每次必检索、检索词用原话。
Naive RAG 的问题(检索差、无脑检索)催生了 Agentic RAG(智能判断)和 Advanced RAG(优化质量)两个方向。
评论区