RAG是一种范式全链路拆解(个人观点)
个人观点整理:市面上用 Claude Code 的 grep、Karpathy 的 LLM Wiki 来论证 RAG 已死,往往既没理解 RAG 的本质,也没说清这些技术和 RAG 的区别与联系。
市面上存在
claude code 使用 grep,或者以 Karpathy 的 llm wiki 为引子,公式化地讲解技术原理,然后开始说 RAG 怎么怎么样弱势,RAG 已死!这样的文章,既没有理解 RAG 的本质,也不理解他所提的这些技术和 RAG 的区别和联系。
| 判断维度 | 优先选 LLM Wiki | 优先选 传统 RAG |
|---|---|---|
| 知识生命周期 | 长期(数月~数年),持续维护 | 短期(数天~数月),临时使用 |
| 数据规模 | 中小规模(百~千级词条) | 大规模(万~百万级文档) |
| 更新频率 | 低频稳定,定期迭代 | 高频动态,实时新增 |
| 核心诉求 | 体系化、可解释、可编辑 | 全覆盖、快上线、忠于原文 |
| 知识形态 | 概念、方法论、规则、经验 | 原始文档、条款、记录、数据 |
| 交互模式 | 系统学习、深度研究 | 单点问答、事实查询 |
- 长期沉淀、体系化的知识用 Wiki;海量、动态、原始的资料用 RAG。
- 它和 RAG、LLM Wiki 不在一个赛道。在代码场景下,精确的符号匹配远比语义检索可靠,Claude Code 的核心创新是把搜索的控制权交给 LLM 自主迭代,而非提前建好向量索引喂给模型。
RAG的本质
RAG 的本质并不是某一套固定工作流,而是一种更抽象的工程范式。RAG 是 Retrieval-Augmented Generation 的缩写,核心是检索—增强—生成:只要系统能够先获取外部信息,再将其用于增强模型上下文,并最终完成生成,就可以被归入 RAG 的范畴。比如说,skills 的渐进式披露、Agent Memory,都可以算是一种 RAG。

Chunking
我们一般会同时将 chunk 的所处章节信息作为 chunk 内容和正文拼接在一起进行向量化,并作为筛选过滤条件单独存储。这样一来,既避免了一次 chunk 中混杂不同章节的信息导致关键信息被隐藏;也因为一 chunk 限制在一章节内,避免了上下文被中断;同时,当缺少证据时,可以依据当前检索到的 chunk 的章节信息,依此作为过滤条件筛选 chunk 进行检索以补充证据,避免了指代、条件、结论不明确的问题;我们还可以先让模型依据问题判断信息可能所处的章节,以此为过滤条件进行检索,有效地提高了检索效率,降低检索成本。真是一举多得啊!
看到这里的佬友可能会想到一个东西,skills 的渐进式披露:当 skills 过多时,将各 skills 的简要功能介绍和所处位置集成为一个菜单,模型阅读这个菜单选择具体 skill 后再将具体的 skill.md 展示给模型。这和我们这里的结构化 chunking 是不是很像?skills 的渐进式披露本质上也是一种 RAG!当然这是我的个人观点,没有官方背书。
层 RAG(Hierarchical RAG)+ 元数据过滤的典型工程实践,核心是利用文档原生的章节结构,解决纯文本暴力分块的固有缺陷。
核心设计:双轨存储机制
- 向量化侧:将章节标题 / 层级路径与 chunk 正文拼接后共同向量化,让向量本身携带结构上下文,避免孤立分块导致的语义漂移;
- 过滤侧:章节信息作为独立元数据字段单独存储,支持检索前置过滤、检索后补全两种使用方式。
解决的四个核心痛点
- 消除跨章节语义混杂:强制 chunk 边界对齐章节边界,避免单个 chunk 混入多个无关主题的内容,大幅降低召回噪声。
- 保留上下文连贯性:分块被限制在单一章节内,语义场景统一,不会出现上下文断裂,提升后续生成的逻辑一致性。
- 支持证据动态补全:当已召回 chunk 信息不完整时,可通过章节标签定向召回同章节其他 chunk,补充指代、前提、条件等缺失信息,解决半截话导致的答案模糊。
- 前置缩小检索范围:可先让模型预判答案所属章节,再限定范围检索,显著缩小检索空间,既提升准确率,也降低向量检索的计算成本。
Embedding稠密与稀疏同样重要
稠密和稀疏 embedding 基本上是同时需要的,它们各自优缺点鲜明,结合使用才能优势互补。假如只有稠密向量,可能会导致专有名词或少见名词的遗漏,比如说中药石刁柏,如果稠密 embedding 模型没有进行过专业的中药材方面的训练,在没有上下文的情况下,它很难想到石刁柏其实就是我们平常吃的芦笋。在具体 chunk 中 embedding 模型尚且可以根据上下文使得该 chunk 向量与芦笋靠近,但是在用户的提问中,没有上下文补充,用户提问的向量会偏向于石头、柏树之类的东西。最终导致模型无法检索到有用信息,导致回答质量下降。如果只有稀疏向量,面对同义词、模糊描述会导致检索不完全,而面对同名不同义的词,又会检索错误。因此,在普通的问答模型的 RAG 中,稠密与稀疏 embedding 都会使用。
索引算法
学过数据库的佬友都知道,索引是一种优化技术,旨在提高数据检索的速度。索引的核心作用类似于书籍的目录,它允许系统快速定位到数据的存储位置,而无需遍历整个数据库。同样的,为了提高模型检索效率,我们在进行向量存储时,也会用到一些专门的索引算法。包括 HNSW、IVF、倒排索引等等,其实这一块不用太深究,大致知道有哪些索引即可。大家就当看个乐吧。
查询优化
检索部分最重要的其实是这个
查询优化的本质是在将用户原始问题发送给检索器之前,对其进行一系列处理、改写或增强的技术。因为不是所有模型使用者都是那么聪明(笨笨),说话都那么清楚明白的,这时候就需要 LLM 提前帮用户把话说明白,这样才方便后续的检索。你在使用大模型的过程中,模型 Thinking 时就是在做这个哦。
查询优化主要包括改写、扩写、重写、多查询、子查询和 HyDE。
重排(Rerank)
说了这么多,但我们之前的检索其实还是相当于一遍粗筛,根本原因还是在于语义相似不等于问题相关:检索找的是语义上相似的文档,但它们可能并没有直接回答用户的具体问题。同时,模型为了保证不漏掉任何信息,在检索阶段会带回大量文档(如 Top 50-100)。这其中混杂着大量不相关的内容,如果全部塞给 LLM,不仅会浪费其上下文窗口,增加成本,还可能让模型被错误信息干扰,降低回答质量。因此我们还需要进行重排。
我所熟知的重排方法包括两种,一种是 Cross-Encoder(交叉编码器),一种是基于 LLM 的重排。
- Cross-Encoder(交叉编码器)模型:这是目前精度最高的方法。它将查询和文档拼接在一起,输入到一个模型中进行深度联合分析,从而输出一个精确的相关性分数。其代价是计算开销大、速度慢,通常需要对每个查询-文档对做一次独立的推理。典型代表有 bge-reranker 系列和 Cohere Rerank。
- 基于 LLM 的重排:直接利用强大的 LLM 进行重排。通过设计特定的提示词(Prompt),让 LLM 对候选文档列表进行阅读、比较和排序。这种方法能利用 LLM 强大的推理能力,但成本更高、速度更慢。某种意义上和其目的背道而驰了吗?
总结观点
首先一个就是目前 code agent 最常用的 grep,grep 命令本身不就是一种关键词检索吗?code agent 利用 grep 命令获取所需的代码片段用于执行任务,这正是 RAG 的定义啊。其次是 Karpathy 的 llm wiki,用这个来踩 RAG 更是诡异。Karpathy 的 LLM Wiki 指的是 Karpathy 在 2026 年 4 月提出的一种个人/团队知识库模式:让 LLM 不只是临时检索资料并回答,而是持续把资料编译成一个可维护、可链接、会累积的 Wiki。这个本质就是个会增量更新的 RAG 啊。用本质 RAG 的东西来贬低 RAG,是典型的自我反驳。
RAG 早就从传统文档进化成了一种范式,Agent Memory 需要 RAG,skills 的渐进式披露需要 RAG,自我反思与进化也需要 RAG……RAG 从来都没死过,它到处都是!
补充:定制化需求与细节优化
需要定制化需求和细节优化,可以看这里。
一、Embedding 模型选择
选择维数多且支持最大上下文大的模型。
二、Reranker 模型选择
选择支持最大上下文大的模型。
三、权限管控
在项目中搜 todo 权限 有注释的代码用。
- 使用 RBAC 模型,文档分配给角色,角色分配给用户。
- 入库流程:公用文档存入 Metadata 字段
public,私有文档 Metadata 字段添加关系型数据库的文档 ID。 - 提问流程:用户搜索时查询到自己权限的文档 ID,查询向量数据库时添加 Metadata 过滤字段(public、文档)。
四、向量数据库 Milvus
- 注意 dimension 字段要和 embedding 维度对应。
- 可以使用混合搜索,通过稠密向量 + 稀疏向量进行匹配,得到结果更精准。
五、上下文入关系型库
- Redis 过期事件监听(整条存;由于我的项目 Redis 存上下文只存最新的 10 条对话,所以如果要用这个方案得自己改一下)。
- 每次 LLM 生成完之后异步添加(单条存,通过 sessionId + userId 查询)(推荐)。
六、文件解析
通过 OCR 将扫描版 PDF 转为文本(图片同理)。
向量数据库选型对照
| 数据库 | 类型 | 适合场景 |
|---|---|---|
| LangChain4j In-Memory | 索引库 / 内存库 | Java 技术栈的 RAG 原型验证;中小型项目中追求极致低延迟的检索场景(生产不要用) |
| Chroma | 开源 | 个人开发者、原型验证(PoC)、小型项目 |
| Milvus | 开源 | 超大规模、企业级生产系统;有专业运维团队 |
| Pinecone | 商业 | 追求极简运维、快速上线的商业项目 |
| Qdrant | 开源 | 高并发、低延迟检索;自托管且注重性价比 |
| Weaviate | 开源 | 知识库、智能问答等需结合语义与结构化关系 |
| Pgvector | 扩展 | 数据已在 PG 的轻量级 RAG 或 MVP 项目 |
| Elasticsearch | 混合引擎 | 已有 ES 技术栈,需要文本 + 向量一体化搜索 |
| 腾讯云 VectorDB | 商业 | 企业级 RAG、智能客服;尤其适合腾讯云生态的企业 |
补充:RAG 技术栈用法与召回优化
RAG 技术栈的用法
- 典型用法:上传 PDF → MinIO 存原件 → 解析、切分 → 向量进 Milvus、元数据进 Mongo【存文档元信息】
RAG 召回优化方法
HyDE
| 维度 | 传统语义检索 | HyDE |
|---|---|---|
| 检索源 | 用户原问题 | LLM 生成的假想答案 |
| 适合场景 | 关键词明确的问题 | 短问/口语化/抽象问法 |
| 一次检索成本 | 1 次 Embedding | 1 次 LLM 调用 + 1 次 Embedding |
| 延迟 | 几十 ms | 增加 1~3 秒(LLM 生成) |
| 准确率提升 | 基准 | 短问场景提升 10~30%(论文数据) |
复杂多跳/对比 → 子查询分解

需先讲背景 → 回溯提示

FAQ 类 + 文档稳定 → 假设问题法(离线)

Neo4j【知识图谱】



为什么节点上要存 chunk_id?
因为图谱本身只存结构(实体 + 关系),不存原文。原文在 Milvus 的 kb_chunks 集合里。
Milvus chunk 回填
目标:把 chunk_id 列表批量去 Milvus 取回真实文本——到这里才拿到能喂给 LLM 的原始材料。
一个直观的对比
用户问:iPhone 15 Pro Max 用了什么基带芯片?5G 表现怎么样?
| 方案 | 召回内容 | 完整度 |
|---|---|---|
| 纯 Milvus | iPhone 评测文 + 基带介绍文 | ⭐⭐ 分散在不同文档 |
| Neo4j 一跳 | X70 → 高通 → 5G → 实测速率 | ⭐⭐⭐⭐ 直接给链路 |
| 二者结合 | 图谱定锚 + 向量取原文 | ⭐⭐⭐⭐⭐ 既精准又丰富 |


多路召回融合打分加权 RRF
在多路召回融合时,最朴素的 RRF 给每路检索源同等权重 1.0。但在企业级 RAG 中,不同检索路径的可靠性是不同的——向量检索直接拿相似度,链路短、命中精度高;HyDE 检索虽然多一次 LLM 调用,但中间没有对齐失败这种强误差;而知识图谱链路长(LLM 抽取→实体对齐→图查询→chunk 反查),每一步都引入潜在噪音。加权 RRF 就是为了给不同源信任度打分——这条路更可靠,就多给它一点权重。
误差出现

| 场景 | 是否需要 Rerank |
|---|---|
| 多路召回后候选 < 20 个,且都已 RRF 融合 | ❌ 不需要,RRF 足够 |
| 多路召回后候选 50~200 个 | ✅ 强烈需要 |
| 有网络搜索等独立源参与 | ✅ 必须,否则网络结果永远靠后 |
| 最终答案质量有答非所问问题 | ✅ 加 Rerank 很可能立竿见影 |
| 延迟极敏感场景(< 200ms) | ⚠️ 慎用,BGE-Reranker 一次 50 文档约 100~200ms |
LangGraph 核心组件:Node(节点)、Edge(边)、State(状态)、Checkpoint(检查点)
- **支持循环、条件分支、并行、回跳,**任意图结构
- 全文检索(倒排):基于词,关心文本里面有什么词,可以做精确短语匹配;【分词匹配,不是绝对匹配】
- 向量检索:基于语义,关心意思像不像,没有绝对词这个概念。
PEFT(高效微调技术)库
- LoRA:低秩适配的奠基性工作,证明了模型微调时权重更新本质是低秩的,用极少量参数即可逼近全量微调效果,彻底改变了 PEFT 的技术格局。【一个矩阵的秩越大,它的信息含量就越大】
- QLoRA:量化 + LoRA 的突破性工作,将基座模型量化到 4bit 再做 LoRA 微调,使消费级显卡即可微调 7B/13B 级大模型,大幅降低了微调的硬件门槛。
LoRA 本质是:输出 = 原始权重计算 + LoRA 增量计算。 合并就是把增量直接加到原始权重矩阵里面,把两步加法,变成一个新矩阵,推理恢复成标准单层矩阵运算,因此没有额外开销。
QLoRA 核心:把底座大模型4bit 量化压缩,冻结底座,只训练 LoRA 小矩阵,普通消费显卡就能微调 7B/13B 大模型。
通用训练都要面对
| 事项 | 是否通用 | 说明 |
|---|---|---|
| 训练要跑多久 | ✅全部需要 | CV 叫 epoch/max_steps;控制什么时候停止训练,防止欠拟合 / 过拟合。 |
| 每次喂多少数据(batch) | ✅全部需要 | batch size + 梯度累积;硬件显存的第一道关卡。 |
| 优化器、学习率策略 | ✅全部需要 | AdamW / SGD;学习率衰减、warmup;决定参数怎么更新,调参重中之重。 |
| 怎么省显存、提速度 | ✅全部需要 | 混合精度、梯度检查点、分布式、量化;硬件不够就必须做。 |
| 多久打日志、评估、存 checkpoint | ✅全部需要 | 定期验证、保存断点;防止程序崩溃,方便看收敛情况。 |
| 数据怎么截断、打包、算 loss | ✅全部需要 | CV:图片 resize、aug、loss 权重;NLP:截断 /padding、loss mask;不同任务最大差异在这里。 |
Unsloth:大模型训练 & 推理加速库,主打跑的更快、显存占用更低,兼容 HuggingFace 整套流程。
- TRL 和 Unsloth 不是竞争二选一,经常搭配一起用:TRL 定训练的算法范式,Unsloth 做底层加速。
Accelerate 是 HuggingFace 做的分布式硬件适配工具库
torch.distributed 是原生底层接口,API 复杂,要手动处理:模型放哪张卡、梯度通信、多卡同步、混合精度、进程管理。 Accelerate 把这些繁琐底层细节全部包起来。
Ragas(Retrieval-Augmented Generation Assessment),开源 RAG 检索增强生成自动评估框架
MCP:给大模型用来获取上下文、调用外部能力的通信协议


RAG 检索加速策略
检索分召回和重排两段,优化方向就三件事:减轻向量库压力、少召回、少算。
- 向量侧优化
- 向量量化:FP32 → FP16 / INT8 / INT4,降内存、提检索速度(如 FAISS IVF_PQ);
- 向量索引选型:海量数据用 IVF、HNSW;小数据集直接暴力搜索;
- 向量分片 / 分区:按业务、时间、租户分区,检索只打对应分片,缩小扫描范围。
- 混合检索(Sparse + Dense)
- BM25(关键词)+ 向量召回,用 RRF 融合;召回少量候选(top-k 别太大,比如 top-20),再进重排。
- 过滤先行
- metadata 元数据过滤(时间、租户 ID、文档类型)先跑,再做向量检索,候选池能小一大截。
- 缓存热点 Query
- 高频查询把召回 + 重排结果缓存住,命中就直接返回,跳过向量库。
- 文档预处理
- 优化 chunk 策略,chunk 别又小又碎;向量预计算、离线入库;
- 文档分层:摘要粗召回,原文细召回。
- 工程层面
- 向量库独立部署、负载均衡;异步预加载索引;吃满向量库原生并发能力。
核心原则:能提前过滤就别进向量检索;能少召回就少召回;重排放在小候选集上。








