《AI Engineering》笔记 CH06 RAG

2026/02/03

RAG 的基础

1. 什么是 RAG?(第一、二页)

  • 定义检索增强生成
    • Retrieve (检索):先去数据库里找相关文档。
    • Augment (增强):把找到的文档塞进 Prompt 里。
    • Generate (生成):让模型根据这些文档回答问题。
  • 为什么需要 RAG?
    1. 知识更新:模型训练完就定型了(比如只知道 2023 年前的事),RAG 可以让它知道今天的新闻。
    2. 私有数据:模型不知道你们公司的内部文档,RAG 可以把文档喂给它。
    3. 减少幻觉:强迫模型“基于提供的上下文回答”,而不是瞎编。
  • 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 工程师的启示:

  1. RAG 是必修课:如果你想做“基于文档的问答”或“企业知识库”,RAG 是唯一解。
  2. 不要迷信向量数据库:向量搜索(Vector Search)很火,但它不是万能的。对于精确匹配(搜名字、ID),老派的关键词搜索(BM25/Elasticsearch)反而更好用。
  3. 架构图 (Figure 6-2)
    • Retriever = ContentProvider / Dao
    • Generator = ViewModel 处理逻辑。
    • Prompt = UI State

工程流程和优化

纯粹从**AI 工程化(AI Engineering)信息检索(Information Retrieval)**的技术角度,详细解析这四块核心内容。

这几页书主要讲述了如何构建一个高性能、高准确率的 RAG(检索增强生成)系统。

第一块:向量数据库与索引 (Vector Database & Indexing)

这一部分解决的是**“在大规模数据中如何快速找到相似向量”**的问题。

当数据量达到百万或亿级时,暴力计算(逐一计算查询向量与库中所有向量的距离)是不可行的。因此,我们需要引入 ANN(Approximate Nearest Neighbor,近似最近邻) 算法,通过牺牲极小精度的代价换取检索速度的数量级提升。

书中重点介绍了以下几种核心索引技术:

  1. HNSW (Hierarchical Navigable Small World)

    • 机制:基于图(Graph)的算法。它构建了一个多层的图结构(类似跳表)。最上层是稀疏的节点,用于快速定位大概区域;越往下层节点越密集,用于精确定位。
    • 特点:这是目前性能最强、最主流的算法。它的查询速度极快,召回率(Recall)很高。
    • 代价:构建索引慢,且内存占用较高。
  2. IVF (Inverted File Index,倒排文件索引)

    • 机制:基于聚类(Clustering)的算法。它使用 K-Means 将向量空间划分为多个“簇”(Voronoi Cells)。
    • 查询流程:查询时,先判断查询向量落在哪一个(或哪几个)簇附近,然后只扫描这几个簇里的向量,忽略其他所有数据。
    • 特点:内存占用比 HNSW 低,构建速度快。
  3. 量化 (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 效果最立竿见影的手段。

  • 两阶段检索架构
    1. 召回 (Retrieval):使用向量搜索(Bi-Encoder)快速从海量数据中捞出 Top 100 个相关文档。这一步速度快但精度一般。
    2. 重排 (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”这个单词的向量距离非常近。
  • 工作流程
    1. 索引:将知识库里的图片和文本都通过 CLIP 转化为向量存入数据库。
    2. 检索
      • 用户输入文本(如“飞屋环游记里的房子”),系统将其转为向量。
      • 在数据库中搜索与该文本向量距离最近的图片向量
    3. 生成:将检索到的图片和用户的文本问题,一起喂给多模态大模型(如 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 模型)处理数据快得多、准得多。

2. 架构图 (Figure 6-7) —— "Tool Use 的雏形"

第二页 的流程图非常关键,它标志着从 RAG 向 Agent (智能体) 的进化。

  • 流程
    1. User Query: "卖了多少个?"
    2. Text-to-SQL: 模型生成 SQL 语句。
    3. SQL Execution: 执行 SQL(这是关键!模型开始调用外部工具了)。
    4. SQL Result: 拿到结果 19
    5. Generative Model: 把 19 包装成一句人话:“过去 7 天共售出 19 个。”
  • 难点 (Schema Selection)
    • 如果你的数据库有 1000 张表,Schema 太大,塞不进 Prompt。
    • 你需要先做一个**“表检索”**步骤:先判断用户问的是哪个业务(订单?库存?用户?),只把相关的 3 张表的 Schema 喂给模型。

全章总结 (Summary)

Chapter 6 结束了。这一章的核心逻辑是:

  1. RAG 是外挂大脑:解决知识更新和幻觉问题。
  2. 检索是关键
    • 非结构化数据(文档):用 Hybrid Search (关键词 + 向量) + Reranking
    • 结构化数据(表格):用 Text-to-SQL
  3. 未来方向
    • RAG 不仅仅是“读”数据,它开始“执行”查询(SQL)。
    • 这为下一章 Chapter 7: Agents (智能体) 埋下了伏笔——如果模型能执行 SQL,那它能不能执行 Python 代码?能不能调用 API 发邮件?

Reranking 技术细节

这是一个非常关键的概念。为了让你彻底理解 Reranking(重排序),我们用一个生活中的场景和一个 Android 开发的场景来类比。

1. 生活类比:海选 vs 面试

想象一下,你们公司要招一名 Android 高级工程师,收到了 10,000 份简历

  • 第一步:召回 (Retrieval) —— "HR 关键词海选"

    • 做法:HR 不懂技术,她只会在系统里搜关键词:“Android”, “Kotlin”, “5年经验”。
    • 结果:系统瞬间甩出来 100 份 简历。
    • 特点速度极快,但精度一般。这 100 个人里,可能混进去了很多“关键词堆砌”的水货,或者其实是做 Java 后端的。
    • 这就是 Bi-Encoder(向量搜索)做的事。
  • 第二步:重排序 (Reranking) —— "技术总监面试"

    • 做法:你(技术总监)没时间看 10,000 份简历,但你有时间仔细读这 100 份。你会逐字逐句看项目经验、GitHub 链接、技术深度。
    • 结果:你给这 100 个人重新打分,挑出了 Top 5 最牛的人来面试。
    • 特点速度慢(你要动脑子读),但精度极高。你排除了那些“只是提到 Kotlin 但其实不会”的人。
    • 这就是 Cross-Encoder(重排序模型)做的事。

2. 技术原理解析

为什么需要分两步?为什么不直接用第二步的方法去搜那 10,000 份简历?

第一步:召回 (Retrieval) - Bi-Encoder

  • 原理“各算各的”
    • 文档的向量是提前算好存数据库的。
    • 用户的搜索词向量是当场算的。
    • 计算相似度时,只是两个向量做个简单的点积(Dot Product),速度飞快(毫秒级)。
  • 缺点:向量是对信息的“有损压缩”。很多细腻的语义(比如“我把猫咬了”和“猫把我咬了”)在压缩成向量后,区别可能变得很模糊。

第二步:重排 (Reranking) - Cross-Encoder

  • 原理“以此为准,重新审视”
    • 它把 “用户的问题”“文档的内容” 拼在一起,作为一个整体喂给模型。
    • 模型会通过 Attention(注意力机制) 逐字逐句地分析:“这个文档里的这句话,是不是真的在回答那个问题?”
  • 缺点计算量大,慢。它不能提前算好,必须实时算。所以你不能对 10,000 个文档都跑一遍这个,只能对前 100 个跑。

3. 为什么要这么做?(给 LLM 省脑子)

这就好比你做 Android App 的 Feed 流

  1. 召回:先从数据库里 SELECT * FROM posts LIMIT 100(快速捞一堆)。
  2. 重排:然后在内存里用一套复杂的推荐算法(考虑用户画像、点击率预测)给这 100 条排序。
  3. 展示:最后只把 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-basems-marco-MiniLM)。
    • Android 类比:它就像是一个 TFLite 模型,甚至可以在高端手机上跑,比云端大模型轻量得多。

2. 它是干嘛的?(Function)

不会说话,也不会生成文本。它只会做一件事:打分

  • 输入:一对文本 (Query, Document)
    • Query: "Android 怎么防止内存泄漏?"
    • Document: "使用 WeakReference 可以避免..."
  • 输出:一个 01 之间的分数(相似度/相关性)。
    • Score: 0.98

3. 它是怎么工作的?(Mechanism)

名字里的 "Cross" (交叉) 是关键。

  • Bi-Encoder (双塔模型 - 用于第一步召回)

    • Query 和 Document 是不见面的。
    • Query 进左边的塔算个向量,Document 进右边的塔算个向量。最后算距离。
    • 缺点:缺乏深度的交互。
  • Cross-Encoder (交叉编码器 - 用于第二步重排)

    • 它把 Query 和 Document 拼接在一起:[CLS] Query [SEP] Document
    • 然后喂给 BERT 模型。
    • 在模型内部,Query 的每一个字都能和 Document 的每一个字进行 Self-Attention (注意力交互)
    • 优点:它能理解非常微妙的逻辑关系(比如否定词、因果关系)。
    • 缺点:因为要两两拼接计算,所以慢。

总结

你可以把 Cross-Encoder 想象成一个**“专职阅卷老师”**:

  • 他不会写作文(不能生成)。
  • 但他读过很多书,专门负责给考生的作文(Document)和题目(Query)的匹配度打分
  • 因为他只负责打分,不需要像 GPT 那样掌握天文地理,所以他的脑容量(模型参数)比较小,跑起来比较快(相对于 GPT 来说)。

目前市面上主流的 Cross-Encoder (Reranker) 模型主要分为开源闭源 API 两大类。

如果你要自己搭建 RAG 系统,通常会从以下这些模型里选:

1. 开源模型 (Open Source) —— 可以私有化部署

这些模型通常基于 BERT 或 RoBERTa 架构,你可以直接在 Hugging Face 上下载。

  • BGE Reranker (智源 BAAI) —— 目前最强、最流行

    • 型号BAAI/bge-reranker-v2-m3, BAAI/bge-reranker-large
    • 特点:中文和英文效果都极好,支持多语言,长文本处理能力强。是目前 RAG 系统的首选。
    • 大小:Large 版本约 560M 参数(显存占用很小)。
  • Jina Reranker (Jina AI)

    • 型号jina-reranker-v1-base-en
    • 特点:针对长上下文(8K)做了优化,适合处理很长的文档。
  • Cohere Rerank (虽有 API,但也有开源竞品)

    • Cohere 是这个领域的领头羊,很多开源模型(如 BGE)都是以打败 Cohere 为目标的。
  • MS MARCO Cross-Encoders

    • 型号cross-encoder/ms-marco-MiniLM-L-6-v2
    • 特点:非常老牌,体积极小(只有 20M 参数),速度飞快,但精度不如 BGE。适合对延迟要求极高的场景。

2. 闭源 API (Commercial API) —— 付费调用

如果你不想自己维护模型服务器,可以直接调 API。

  • Cohere Rerank API

    • 地位行业标准。几乎是 Rerank 界的 GPT-4。
    • 特点:效果极好,支持多语言,很多企业级 RAG 都在用。
    • 代码cohere.rerank(query=..., documents=...)
  • Jina Rerank API

    • 特点:性价比高,对开发者友好。

选型建议 (Android 工程师视角)

  1. 想省事、效果好:直接调 Cohere Rerank API。不用管运维,几行代码搞定。
  2. 数据隐私敏感 / 想要免费:部署 BGE-Reranker-v2-m3
    • 你可以把它部署在一个小的 Docker 容器里(甚至 CPU 都能跑,虽然慢点)。
    • 它能精准理解中文语义,比如“小米手机”和“红米手机”的区别。

总结表

模型名称 类型 优势 适用场景
Cohere Rerank API 效果天花板,省心 企业级应用,不差钱
BGE Reranker 开源 效果接近 Cohere,免费,中文强 私有化部署,中文 RAG
MS MARCO MiniLM 开源 极快,极小 边缘设备,对延迟极敏感

评论和交流请发送邮件到 [email protected]

Wechat Donate QACode
通过微信扫描赞赏码赞助此文