RAG 的基础
1. 什么是 RAG?(第一、二页)
- 定义:检索增强生成。
- Retrieve (检索):先去数据库里找相关文档。
- Augment (增强):把找到的文档塞进 Prompt 里。
- Generate (生成):让模型根据这些文档回答问题。
- 为什么需要 RAG?
- 知识更新:模型训练完就定型了(比如只知道 2023 年前的事),RAG 可以让它知道今天的新闻。
- 私有数据:模型不知道你们公司的内部文档,RAG 可以把文档喂给它。
- 减少幻觉:强迫模型“基于提供的上下文回答”,而不是瞎编。
- Android 类比:WebView vs Native。
- 纯模型 = Native App。发布后很难更新内容,包体积大。
- RAG = WebView。内容在服务器上(数据库),随时更新,App 只是一个展示壳。
2. 检索算法大比拼:关键词 vs 向量(第三至六页)
这是 RAG 的核心引擎。作者对比了两种检索方式。
A. Term-based Retrieval (关键词检索) —— "SQL LIKE 查询"
- 代表算法:TF-IDF, BM25。
- 原理:数单词。
- 用户搜 "AI Engineering"。
- 系统找包含 "AI" 和 "Engineering" 这两个词最多的文档。
- 优点:精准匹配。搜人名、型号(如 "Pixel 8 Pro")非常准。
- 缺点:不懂同义词。搜 "小狗",找不到包含 "汪星人" 的文档。
- Android 类比:
String.contains() 或 FTS (Full Text Search)。
B. Embedding-based Retrieval (向量检索) —— "语义搜索"
- 代表算法:Dense Retrieval (HNSW, FAISS)。
- 原理:算距离。
- 把 "小狗" 转成向量
[0.1, 0.9]。
- 把 "汪星人" 转成向量
[0.12, 0.88]。
- 算出它俩距离很近,所以能搜出来。
- 优点:懂语义。搜 "怎么做披萨",能找到 "意大利面食烹饪指南"。
- 缺点:不精确。搜 "Python 3.8",可能会给你 "Python 3.9" 的文档,因为它觉得这俩很像。
- Android 类比:图片相似度搜索。
3. 混合检索 (Hybrid Search) —— "最佳实践"
第七、八页 提出了终极方案。
- 问题:
- 关键词检索不懂语义。
- 向量检索不懂专有名词(比如错误码
EADDRNOTAVAIL)。
- 解决:Hybrid Search (混合检索)。
- 同时跑一遍 BM25(关键词)和 FAISS(向量)。
- 把两边的结果加权合并(Rerank)。
- Android 类比:多级缓存策略。
- 先查内存缓存(快但少),再查磁盘缓存(慢但多),最后查网络。把所有结果整合后展示给用户。
总结
这一节给 Android 工程师的启示:
- RAG 是必修课:如果你想做“基于文档的问答”或“企业知识库”,RAG 是唯一解。
- 不要迷信向量数据库:向量搜索(Vector Search)很火,但它不是万能的。对于精确匹配(搜名字、ID),老派的关键词搜索(BM25/Elasticsearch)反而更好用。
- 架构图 (Figure 6-2):
- Retriever =
ContentProvider / Dao。
- Generator =
ViewModel 处理逻辑。
- Prompt =
UI State。
工程流程和优化
纯粹从**AI 工程化(AI Engineering)和信息检索(Information Retrieval)**的技术角度,详细解析这四块核心内容。
这几页书主要讲述了如何构建一个高性能、高准确率的 RAG(检索增强生成)系统。
第一块:向量数据库与索引 (Vector Database & Indexing)
这一部分解决的是**“在大规模数据中如何快速找到相似向量”**的问题。
当数据量达到百万或亿级时,暴力计算(逐一计算查询向量与库中所有向量的距离)是不可行的。因此,我们需要引入 ANN(Approximate Nearest Neighbor,近似最近邻) 算法,通过牺牲极小精度的代价换取检索速度的数量级提升。
书中重点介绍了以下几种核心索引技术:
-
HNSW (Hierarchical Navigable Small World)
- 机制:基于图(Graph)的算法。它构建了一个多层的图结构(类似跳表)。最上层是稀疏的节点,用于快速定位大概区域;越往下层节点越密集,用于精确定位。
- 特点:这是目前性能最强、最主流的算法。它的查询速度极快,召回率(Recall)很高。
- 代价:构建索引慢,且内存占用较高。
-
IVF (Inverted File Index,倒排文件索引)
- 机制:基于聚类(Clustering)的算法。它使用 K-Means 将向量空间划分为多个“簇”(Voronoi Cells)。
- 查询流程:查询时,先判断查询向量落在哪一个(或哪几个)簇附近,然后只扫描这几个簇里的向量,忽略其他所有数据。
- 特点:内存占用比 HNSW 低,构建速度快。
-
量化 (Quantization)
- 目的:压缩向量体积,减少内存占用并加速计算。
- Product Quantization (PQ):将高维向量切分成多个低维子向量,分别进行聚类压缩。
- Scalar Quantization (SQ):将 32 位浮点数(float32)压缩为 8 位整数(int8)。这通常能将内存占用减少 4 倍,且精度损失在可接受范围内。
第二块:检索优化三板斧 (Retrieval Optimization)
仅仅有了向量数据库是不够的,为了让检索结果更准确,工程上通常采用以下三种策略:
1. Chunking (切片策略)
大模型无法一次性处理整本书,且长文本会导致检索精度下降(向量被稀释)。因此需要将文档切分为小块(Chunks)。
- Fixed-size Chunking:按固定 Token 数(如 512 tokens)切分。简单但容易切断语义。
- Overlap (重叠):在切片之间保留重叠部分(如 50 tokens),防止一句话被切成两半导致语义丢失。
- Recursive Chunking:按文档结构(段落 -> 句子 -> 词)递归切分,尽可能保持语义完整性。
- 权衡:
- 块太小:检索精准,但缺乏上下文(模型不知道这句话的前因后果)。
- 块太大:包含太多无关噪音,导致检索准确率下降。
2. Query Rewriting (查询重写)
用户的原始提问往往是不完整的或指代不明的。
- 问题:在多轮对话中,用户可能会问“它多少钱?”。如果直接拿“它多少钱”去检索,搜不到任何有用信息。
- 解决:利用 LLM 将用户的最新提问 + 历史对话上下文,重写为一个独立、完整的查询语句。
- 重写后:“iPhone 15 Pro Max 256GB 版本多少钱?”
- HyDE (Hypothetical Document Embeddings):一种高级重写技术。先让 LLM 生成一个“假设的答案”,然后用这个假设答案去检索文档。这通常比直接用问题检索效果更好。
3. Reranking (重排序)
这是提升 RAG 效果最立竿见影的手段。
- 两阶段检索架构:
- 召回 (Retrieval):使用向量搜索(Bi-Encoder)快速从海量数据中捞出 Top 100 个相关文档。这一步速度快但精度一般。
- 重排 (Reranking):使用 Cross-Encoder 模型对这 100 个文档与查询进行逐一精细比对打分,重新排序,只取 Top 5 给大模型。
- 优势:Cross-Encoder 能理解复杂的语义关系,极大地提升了最终喂给大模型的信息质量。
第三块:Contextual Retrieval (上下文检索)
这是 Anthropic 在 2024 年提出的解决“切片导致上下文丢失”的高级技术。
- 痛点:
当文档被切成小块后,很多块失去了独立存在的意义。
- 例子:一个切片内容是“公司营收增长了 50%”。
- 检索失效:如果用户搜“苹果公司 2023 年财报”,这个切片可能因为没有“苹果”和“2023”这两个关键词而被漏掉。
- 解决方案:
在建立索引阶段(Indexing),利用 LLM 为每一个切片生成一段简短的上下文说明,并将其拼接到切片内容的前面。
- 处理后的切片:“【背景:这是苹果公司 2023 年 Q4 财务报告的营收部分】 公司营收增长了 50%。”
- 结果:
这个切片现在包含了关键的元数据(Metadata),无论用户搜细节还是搜背景,都能被精准命中。这显著提升了检索的召回率(Recall)。
第四块:多模态 RAG (Multimodal RAG)
RAG 不仅仅局限于文本,它正在向图像、音频扩展。
- 核心技术:CLIP (Contrastive Language-Image Pre-training)
- CLIP 是一个能将文本和图像映射到同一个向量空间的模型。
- 在这个空间里,“一只狗的照片”的向量和“a dog”这个单词的向量距离非常近。
- 工作流程:
- 索引:将知识库里的图片和文本都通过 CLIP 转化为向量存入数据库。
- 检索:
- 用户输入文本(如“飞屋环游记里的房子”),系统将其转为向量。
- 在数据库中搜索与该文本向量距离最近的图片向量。
- 生成:将检索到的图片和用户的文本问题,一起喂给多模态大模型(如 GPT-4V 或 Gemini),让模型看着图片回答问题。
- 应用:电商搜图、图表分析、视频内容检索。
Text-to-SQL (结构化数据检索)
我为你拆解为两个核心模块:
1. 结构化数据 RAG (Tabular RAG) —— "AI DBA"
第一页 (Table 6-3) 展示了一个典型的电商订单表。
- 问题:
- 用户问:“过去 7 天卖了多少个 Fruity Fedora?”
- 如果你用传统的 RAG(向量搜索),你会把整个表格切成文本块。
- 模型可能会读到:“订单1卖了1个,订单3卖了1个...”。
- 痛点:大模型极不擅长做算术(加减乘除)。让它自己去数数,大概率会数错。
- 解决:Text-to-SQL。
- 不要让模型去读数据,让模型写 SQL。
- 模型输出:
SELECT SUM(units) FROM Sales WHERE product_name = 'Fruity Fedora' AND timestamp >= DATE_SUB(CURDATE(), INTERVAL 7 DAY);
- 数据库执行 SQL,返回结果
19。
- 模型回答:“卖了 19 个。”
- Android 类比:Room @Query。
- 你不会把数据库里所有 User 对象读到内存里,然后用
for 循环去过滤。
- 你会写一个
@Query("SELECT * FROM users WHERE age > 18"),让 SQLite 引擎去处理数据,因为数据库引擎比 Java 代码(或 AI 模型)处理数据快得多、准得多。
第二页 的流程图非常关键,它标志着从 RAG 向 Agent (智能体) 的进化。
- 流程:
- User Query: "卖了多少个?"
- Text-to-SQL: 模型生成 SQL 语句。
- SQL Execution: 执行 SQL(这是关键!模型开始调用外部工具了)。
- SQL Result: 拿到结果
19。
- Generative Model: 把
19 包装成一句人话:“过去 7 天共售出 19 个。”
- 难点 (Schema Selection):
- 如果你的数据库有 1000 张表,Schema 太大,塞不进 Prompt。
- 你需要先做一个**“表检索”**步骤:先判断用户问的是哪个业务(订单?库存?用户?),只把相关的 3 张表的 Schema 喂给模型。
全章总结 (Summary)
Chapter 6 结束了。这一章的核心逻辑是:
- RAG 是外挂大脑:解决知识更新和幻觉问题。
- 检索是关键:
- 非结构化数据(文档):用 Hybrid Search (关键词 + 向量) + Reranking。
- 结构化数据(表格):用 Text-to-SQL。
- 未来方向:
- RAG 不仅仅是“读”数据,它开始“执行”查询(SQL)。
- 这为下一章 Chapter 7: Agents (智能体) 埋下了伏笔——如果模型能执行 SQL,那它能不能执行 Python 代码?能不能调用 API 发邮件?
Reranking 技术细节
这是一个非常关键的概念。为了让你彻底理解 Reranking(重排序),我们用一个生活中的场景和一个 Android 开发的场景来类比。
1. 生活类比:海选 vs 面试
想象一下,你们公司要招一名 Android 高级工程师,收到了 10,000 份简历。
2. 技术原理解析
为什么需要分两步?为什么不直接用第二步的方法去搜那 10,000 份简历?
第一步:召回 (Retrieval) - Bi-Encoder
- 原理:“各算各的”。
- 文档的向量是提前算好存数据库的。
- 用户的搜索词向量是当场算的。
- 计算相似度时,只是两个向量做个简单的点积(Dot Product),速度飞快(毫秒级)。
- 缺点:向量是对信息的“有损压缩”。很多细腻的语义(比如“我把猫咬了”和“猫把我咬了”)在压缩成向量后,区别可能变得很模糊。
第二步:重排 (Reranking) - Cross-Encoder
- 原理:“以此为准,重新审视”。
- 它把 “用户的问题” 和 “文档的内容” 拼在一起,作为一个整体喂给模型。
- 模型会通过 Attention(注意力机制) 逐字逐句地分析:“这个文档里的这句话,是不是真的在回答那个问题?”
- 缺点:计算量大,慢。它不能提前算好,必须实时算。所以你不能对 10,000 个文档都跑一遍这个,只能对前 100 个跑。
3. 为什么要这么做?(给 LLM 省脑子)
这就好比你做 Android App 的 Feed 流:
- 召回:先从数据库里
SELECT * FROM posts LIMIT 100(快速捞一堆)。
- 重排:然后在内存里用一套复杂的推荐算法(考虑用户画像、点击率预测)给这 100 条排序。
- 展示:最后只把 Top 5 显示在屏幕首屏。
对于 RAG 系统来说:
- 大模型(LLM)的窗口有限(比如只能看 4000 字)。
- 如果你直接把第一步捞出来的 Top 5 给它,可能里面有 3 个是错的(因为第一步不够准)。
- 加上 Reranking,就是为了确保喂给大模型的这 4000 字,是含金量最高、最相关的精华。
总结:
Reranking 就是在“海量粗搜”之后,加了一个“精细筛选”的环节,用少量的计算时间,换取最终结果准确率的大幅提升。
Cross-Encoder 通常不是像 GPT-4 那样巨大的生成式大模型(LLM),而是一个专门用于“打分”的中小型模型(BERT 类模型)。
为了让你彻底搞懂,我们从大小、功能、工作方式三个维度来拆解。
1. 它有多大?(Size)
- LLM (GPT-4, Llama-3):通常是 70亿 (7B) 到 万亿 参数。它们像是一个博学的教授,能写诗、写代码、聊天。
- Cross-Encoder (Reranker):通常只有 3亿 (300M) 到 5亿 参数(比如
bge-reranker-base 或 ms-marco-MiniLM)。
- Android 类比:它就像是一个 TFLite 模型,甚至可以在高端手机上跑,比云端大模型轻量得多。
2. 它是干嘛的?(Function)
它不会说话,也不会生成文本。它只会做一件事:打分。
- 输入:一对文本
(Query, Document)。
- Query: "Android 怎么防止内存泄漏?"
- Document: "使用 WeakReference 可以避免..."
- 输出:一个
0 到 1 之间的分数(相似度/相关性)。
3. 它是怎么工作的?(Mechanism)
名字里的 "Cross" (交叉) 是关键。
总结
你可以把 Cross-Encoder 想象成一个**“专职阅卷老师”**:
- 他不会写作文(不能生成)。
- 但他读过很多书,专门负责给考生的作文(Document)和题目(Query)的匹配度打分。
- 因为他只负责打分,不需要像 GPT 那样掌握天文地理,所以他的脑容量(模型参数)比较小,跑起来比较快(相对于 GPT 来说)。
目前市面上主流的 Cross-Encoder (Reranker) 模型主要分为开源和闭源 API 两大类。
如果你要自己搭建 RAG 系统,通常会从以下这些模型里选:
1. 开源模型 (Open Source) —— 可以私有化部署
这些模型通常基于 BERT 或 RoBERTa 架构,你可以直接在 Hugging Face 上下载。
2. 闭源 API (Commercial API) —— 付费调用
如果你不想自己维护模型服务器,可以直接调 API。
-
Cohere Rerank API
- 地位:行业标准。几乎是 Rerank 界的 GPT-4。
- 特点:效果极好,支持多语言,很多企业级 RAG 都在用。
- 代码:
cohere.rerank(query=..., documents=...)
-
Jina Rerank API
选型建议 (Android 工程师视角)
- 想省事、效果好:直接调 Cohere Rerank API。不用管运维,几行代码搞定。
- 数据隐私敏感 / 想要免费:部署 BGE-Reranker-v2-m3。
- 你可以把它部署在一个小的 Docker 容器里(甚至 CPU 都能跑,虽然慢点)。
- 它能精准理解中文语义,比如“小米手机”和“红米手机”的区别。
总结表
| 模型名称 |
类型 |
优势 |
适用场景 |
| Cohere Rerank |
API |
效果天花板,省心 |
企业级应用,不差钱 |
| BGE Reranker |
开源 |
效果接近 Cohere,免费,中文强 |
私有化部署,中文 RAG |
| MS MARCO MiniLM |
开源 |
极快,极小 |
边缘设备,对延迟极敏感 |