RAG 入门学习笔记
学习起点:[[20260522.SearchToolDesign(Private)]] 中的资产语义搜索项目
目标:理解 RAG 原理 → 在本地图片数据上跑通最小 Demo
一、什么是 RAG?
RAG = Retrieval-Augmented Generation(检索增强生成)
用一句话说:先从知识库里找到相关内容,再用这些内容辅助 AI 回答问题。
1.1 为什么需要 RAG?
| 问题 | RAG 如何解决 |
|---|---|
| LLM 训练数据有截止日期,不知道新信息 | 检索阶段可以实时查询最新数据 |
| LLM 不知道私有数据(公司内部资产库) | 把私有数据做成索引,检索后注入给 LLM |
| LLM 会”幻觉”,凭空捏造事实 | 提供检索到的真实文档作为依据 |
| LLM token 窗口有限,无法塞入全部资料 | 只检索最相关的少数文档片段 |
二、RAG 的完整流程
1 | ╔══════════════════════════════════════════════════════════╗ |
资产搜索工具只做前两个阶段——把美术的查询转成向量,找最相似的资产,直接返回结果。这是 RAG 的检索子集,学术上叫 语义检索(Semantic Search) 或 Dense Retrieval。
三、核心概念解释
3.1 Embedding(向量化)
把任意内容(文字、图片)压缩成一个固定长度的数字列表(向量),使得:
- 语义相似的内容 → 向量在空间中相近
- 语义不同的内容 → 向量在空间中远离
1 | "一棵柳树" → [0.12, -0.34, 0.87, ..., 0.05] (768 维) |
常用 Embedding 模型:
| 模型 | 输入类型 | 维度 | 特点 |
|---|---|---|---|
| BGE-M3 (BAAI) | 文字 | 1024 | 中文最强,本地部署友好 |
| CLIP (OpenAI) | 图片 + 文字 | 512 | 图文共享同一向量空间 ⭐ |
| SigLIP (Google) | 图片 + 文字 | 768 | CLIP 改进版,零样本更好 |
| GTE-Qwen2 (阿里) | 文字 | 768 | 多语言,商用 Apache 2.0 |
3.2 FAISS(向量相似度搜索库)
FAISS = Facebook AI Similarity Search(Meta 开源)
为什么需要它?
当你有 20000 个向量,要找和查询向量最相似的 Top-10,如果逐一比较需要 20000 次计算。FAISS 用特殊的数据结构,把这个过程加速几十到几千倍。
类比:
- 暴力搜索 = 图书馆里一本一本翻,找和你兴趣最接近的书
- FAISS = 图书馆按主题分区,直接去”植物类”书架精确查找
三种主要索引类型:
| 类型 | 原理 | 精度 | 速度 | 适合规模 | 我们的选择 |
|---|---|---|---|---|---|
IndexFlatL2 |
精确,逐一比较 | 100% | 中(但绝对够用) | < 100K | ✅ 首选 |
IndexIVFFlat |
先分群,再搜索 | ~98% | 快 | 100K–10M | 将来扩展用 |
IndexHNSWFlat |
图结构导航 | ~99% | 最快 | 任意 | 过度设计 |
精确、代码最简单,单次查询 <1ms,完全满足需求。
3.3 相似度度量
| 度量方式 | 公式含义 | 何时用 |
|---|---|---|
| L2 距离(欧式) | 向量空间中的直线距离,越小越相似 | FAISS 默认,图片检索 |
| 余弦相似度 | 两向量夹角的余弦值,越接近 1 越相似 | 文本检索更常用 |
| 内积(点积) | 方向 + 长度共同决定 | CLIP 官方推荐 |
四、图片 RAG(CLIP 的特殊能力)
CLIP 的核心创新:让图片和文字共享同一个向量空间。
1 | "一棵柳树"(文字)→ CLIP 文本编码器 → 向量 A |
这意味着你可以:
- 文字 → 图片:输入”给我一个流程图”,在图片库里找最相似的
- 图片 → 图片:上传参考图,找风格相近的资产
- 图片 → 文字:输入图片,找最相关的描述文档
这正是资产搜索工具「以文搜图」功能的核心原理。
五、本地 Demo 计划
5.1 目标
用 D:\Project\UGit\MyPicGo\Images\ 里的博客图片(PNG/JPG),跑通一个最小的图片语义检索 Demo:
- 输入:一段文字描述(如”代码截图”、”流程图”、”UI 界面”)
- 输出:图片库里最相似的 Top-5 图片路径
5.2 技术栈
1 | D:\Project\UGit\MyPicGo\Images\ (博客图片,约 100+ 张 PNG/JPG) |
5.3 实战过程
- 建项目目录
D:\Project\UGit\PicGoRAGDemo\+ Python venv - 装依赖:
torch / transformers / faiss-cpu / modelscope / Pillow / numpy - 写
build_index.py(索引阶段)+search.py(查询阶段) - 跑
python build_index.py:225 张图编码成 225 × 512 维向量,建 FAISS 索引落盘(CPU 上 ~15s) - 跑
python search.py "query"验证检索(单次查询 <100ms)
3 个关键踩坑:
- transformers 5.x 改了 CLIP API:
get_image_features(...)现在返回BaseModelOutputWithPooling(不再是裸 Tensor),要.pooler_output取 512 维向量 - HuggingFace 国内连不上:直连超时、镜像也不稳,换 ModelScope(阿里魔搭,国内服务器无障碍)
- ModelScope 命名不同:HF 上的
OFA-Sys/chinese-clip-vit-base-patch16在 MS 上对应AI-ModelScope/chinese-clip-vit-base-patch16(AI-ModelScope是 HF 格式镜像专用命名空间,文件结构和 HF 完全一致,transformers.AutoModel可以直接加载)
5.4 测试发现:中英文 query 效果对比
实测发现英文 query 略准:
| Query | 模型 | 检索效果 |
|---|---|---|
"code screenshot" |
OpenAI CLIP | ✅ Top-3 全是代码截图 |
"flowchart" |
OpenAI CLIP | ✅ Top-3 全是流程图 |
"代码截图" |
Chinese-CLIP | ✅ Top-3 全是代码截图 |
"流程图" |
Chinese-CLIP | ⚠️ Top-3 有流程图但混入少量无关图 |
可能原因:博客图片以英文技术截图为主(代码、终端、UI 文字大多为英文)。OpenAI CLIP 同时识别英文文字 + 视觉特征,命中更稳;Chinese-CLIP 训练数据偏中文生活 / 资讯,对”流程图”这种偏技术的视觉概念边界不够锐利。
这正印证 §6.1 的核心观点:embedding 模型在你领域的表现取决于训练数据分布——选型要看场景。
5.5 完整代码
build_index.py(索引阶段)
1 | """build_index.py — 把 N 张图编成 N 个 512 维向量,建 FAISS 索引 |
search.py(查询阶段)
1 | """search.py — 文字 query → CLIP 文本编码 → FAISS Top-K → 打印路径 |
六、学习资源
6.1 入门文章(由浅入深)
| 资源 | 类型 | 适合阶段 |
|---|---|---|
| IBM Technology: What is RAG? | 5分钟视频 | 零基础入门,概念最清晰 |
| Retrieval-Augmented Generation - LangChain 官方文档 | 图文教程 | 理解流程,有代码示例 |
| Building RAG from Scratch - Towards Data Science | 博客 | 不依赖框架,直接用 FAISS + Python |
| LlamaIndex 官方教程 | 实践 | 工程化框架,生产级 RAG |
| OpenAI Cookbook - RAG | 代码示例 | 进阶,含评估指标 |
6.2 必读论文(可选)
| 论文 | 年份 | 为什么读 |
|---|---|---|
| RAG for Knowledge-Intensive NLP Tasks(Lewis et al.) | 2020 | RAG 概念起源 |
| CLIP: Learning Transferable Visual Models(Radford et al.) | 2021 | 图文对齐的基础原理 |
| SigLIP: Sigmoid Loss for Language Image Pre-Training | 2023 | CLIP 改进版,了解进展 |
6.3 中文资源
- BAAI BGE 系列文档:中文 embedding 模型的官方说明,直接指导模型选型
- 知乎「RAG 实践」:国内工程师踩坑笔记,实用
- B站 @跟李沐学AI:深度学习基础,理解 embedding 原理的必要背景
七、笔记
模块一:RAG Overview
1. RAG体系结构:

在 RAG 系统内部,首先会有可以访问数据库的 retriever,它会发动一次查询(类似数据库)。然后 retriever 会得到一个查询后的 (被认为最相关的一些信息)。接着,它会把这写得到的可能最相关的信息,生成一个增强的提示词。
1 | # ============================================================ |
2. LLMs上理解RAG
LLMs 本质上是在不停地预测下一个即将出现的值的可能性,RAG 是改变了这个可能性的分布。
3. 信息检索:RAG Retrieve vs 搜索引擎 vs 数据库查询
三者都在”找东西”,但底层匹配逻辑完全不同:
| 维度 | 搜索引擎(BM25/TF-IDF) | 数据库查询(SQL) | RAG Retrieve(向量检索) |
|---|---|---|---|
| 匹配方式 | 关键词词频统计 | 精确字段匹配 | 语义相似度(向量距离) |
| 查询语言 | 自然语言词袋 | 结构化 SQL | 任意内容(文字 / 图片 / 音频) |
| 能否理解同义词 | ❌ 部分(需要词典) | ❌ 完全不能 | ✅ 天然支持 |
| 能否跨模态 | ❌ 文字只能找文字 | ❌ | ✅ 文字找图片(CLIP) |
| 结果排序依据 | TF-IDF 分数 | 无排序(精确匹配 / 过滤) | 向量空间距离(余弦 / L2) |
| 数据结构要求 | 需要倒排索引 | 需要严格 Schema | 只需向量,原始结构无要求 |
| 适合的问题 | “找包含这些词的文档” | “找符合这些条件的记录” | “找语义上最相关的内容” |
一句话区分三者本质:
1 | 数据库查询 ── "完全相等吗?" (精确) |
RAG 并非”完美替代”前两者,生产环境常将向量检索 + BM25结合使用,取并集后再用 Re-ranker 重新排序——向量检索负责语义泛化,BM25 负责关键词锚定,两者互补。
模块二:信息检索和搜索技术
1. 检索器架构概述
Metadata Filtering(元数据过滤)
在向量检索前/后,用结构化字段对候选集进行硬性筛选,缩小检索范围。
- 原理:文档在入库时附带元数据字段(如来源、日期、类别),查询时先过滤再做向量相似度排序
- 优势:大幅减少无关文档的干扰,提升精度和检索效率。
- 局限:依赖入库时的元数据质量,字段缺失或分类不准会导致有效文档被误过滤。不会理解内容,且几乎不会单独使用。
Keyword Searching(关键词搜索)
基于精确词语匹配来查找文档,是最经典的搜索方式。主要包含 TF-IDF 和 BM25 两种算法。
- 原理:将查询拆成词条,统计词频(如 BM25 算法),返回包含这些词的文档
- 优势:速度快、结果可解释、对专有名词(代码、ID、型号)命中精准
- 局限:无法理解同义词或语义近似表达,换个说法就可能找不到
两者都用词频打分,但 BM25 是 TF-IDF 的改进版:TF-IDF 词频越高得分线性增长;BM25 加入词频饱和(高频词收益递减)和文档长度归一化,短文档中出现一次与长文档出现多次权重更合理,实际检索效果更好。
Semantic Searching(语义搜索)
将文本编码为向量,通过计算向量相似度来匹配”意思相近”的内容。
- 原理:用 Embedding 模型把查询和文档都映射到高维向量空间,用余弦相似度等方式度量距离
- 优势:能捕捉语义泛化,即使措辞不同也能找到相关内容
- 局限:计算开销更高,对精确词语(如特定 ID)反而不如关键词搜索可靠
2. 两种常见的关键词检索算法详解
TF-IDF
核心公式:Score = TF(词, 文档) × log(文档总数 / 含该词的文档数)
- TF(词频):词在当前文档出现越多,说明越相关
- IDF(逆文档频率):词在越多文档里出现,说明越”废话”,权重越低;罕见词权重越高
- 结果:
"的" "is"等高频虚词接近 0 分,"量子纠缠" "BM25"等专有词得高分
BM25(TF-IDF 的工业级改进版,Elasticsearch 默认算法)
核心改进点:
| 问题 | TF-IDF | BM25 |
|---|---|---|
| 词频线性叠加 | 出现 100 次 = 1 次的 100 倍 | 词频饱和,多了收益递减(参数 k1,默认 1.2–2.0) |
| 长文档天然优势 | 惩罚过重 | 按平均文档长度归一化(参数 b,默认 0.75) |
k1:控制词频饱和速度,越高代表”多说几遍越重要”;越低代表”说 3 遍和说 100 遍差不多”b:控制长度惩罚力度,b=0忽略长度,b=1严格按密度打分,0.75 是工业经验值
3. 语义搜索与关键词搜索的异同
1. 共同点:数字化
- Prompt and documents each get a vector(提示词和文档各获得一个向量):
无论是哪种搜索,计算机都无法直接“读懂”文字。第一步都是将用户的提问和数据库里的文档转化成一串数字列表,这串数字就叫向量。 - Vectors compared to generate scores(对比向量以生成评分):
一旦变成了数字,计算机就可以通过数学公式(如余弦相似度)计算两个向量之间的“距离”。距离越近,分值越高,代表两者越相关。
2. 核心区别:向量是如何生成的?
关键词搜索:统计单词数量
- 原理: 这种方式生成的叫稀疏向量。
- 逻辑: 向量里的每一个位置代表一个特定的单词。如果文档里出现了这个词,就在对应位置标上分数(基于词频,如 BM25)。
- 特点: 字面匹配,它只认“长得一样”的词。
局限: 如果你搜“医生”,它找不到包含“医师”但没写“医生”的文档,因为它不理解词义。
语义搜索:使用嵌入模型
- 原理: 这种方式生成的叫稠密向量 (Dense Vector)。
- 逻辑: 它不直接数单词,而是把文本输入到一个预训练好的深度学习模型(Embedding Model,如 BERT)。模型会把文本“映射”到一个多维的语义空间里。
- 特点: 理解含义,向量里的数字代表的是抽象的“特征”或“概念”。
优势: 它能识别同义词。即使单词不匹配,只要“意思”接近(比如“猫”和“小猫”,“医生”和“医师”),它们的向量在数学空间里的距离就会非常近。
3. RRF 算法(平衡关键词和语义)
它是 混合检索 中的核心技术。当你在 RAG 系统中同时运行”关键词检索”和”语义检索”时,会得到两份完全不同的评分列表。RRF(Reciprocal Rank Fusion,倒数排名融合)的作用就是将这两份列表公正地合并成一份最终的排名列表。
1. 核心问题:”苹果和橙子”的对比困境
混合检索面临一个根本性困难:
- 关键词检索(BM25) 的分数可能是
15.4、12.8等。 - 语义检索(向量搜索) 的分数(余弦相似度)通常在
0.8到0.9之间。 - 问题:这两种分数单位不同,无法直接相加比较。
RRF 的解法:完全忽略原始分数,只看文档在列表中的位次(排名)。
2. 核心机制
- 奖励”共识”文档: 如果一个文档在关键词搜索和语义搜索中都排名靠前,RRF 会给它极高的最终得分。
- 标准化两种搜索的权重: 提供了一种跨策略的公平比较方式,不让任何一种算法因分值范围大而主导结果。
- 得分 = 排名的倒数(算法名称由来):
- 第 1 名 →
1/1 = 1.0分 - 第 2 名 →
1/2 = 0.5分 - 第 10 名 →
1/10 = 0.1分 - 逻辑:名次越靠前分值越高,且名次越往后分值下降越快。
- 第 1 名 →
- 汇总得分: 把同一文档在所有列表中的倒数分数相加,总分最高者赢得最终排名。
3. 公式
$$RRF(d) = \sum_{i=1}^{n} \frac{1}{k + rank_i(d)}$$
rank_i:文档d在第i个检索列表中的排名(从 1 开始)。k:平滑常数,工业界通常默认设为 60。
为什么需要 k?
若不加 k,第 1 名(1.0 分)与第 100 名(0.01 分)差距极大,会导致排名第一的文档拥有统治级权力。k 作为”减震器”,能压缩极端差异,削弱偶然排第一的噪声文档的影响。
| 参数值 | 效果 | 风险 |
|---|---|---|
k = 0(极度敏感) |
第一名拥有绝对统治力 | 某个算法偶然将噪声文档排第一,会干扰整个 RAG 结果 |
k = 60(平滑稳健,工业默认) |
单列表的高排名不再独占优势 | 无明显风险;要求多个检索策略共同认可才能胜出 |
4. RRF 的核心优势:只在乎排名
- 无需分数归一化: 不需要考虑 BM25 的 20 分和向量搜索的 0.9 分如何换算,直接比较位次即可。
- 跨策略无缝合并: 无论是 2 种还是 5 种不同的检索技术,只要各自给出一份排名列表,RRF 就能公平融合。
5. 调节语义 vs 关键词权重的参数
标准 RRF 本身没有直接的”语义 vs 关键词”权重参数——k 只是平滑常数,不控制两者比重。
但加权 RRF(Weighted RRF) 在公式中为每个检索策略引入独立权重 w:
$$RRF(d) = \sum_{i=1}^{n} \frac{w_i}{k + rank_i(d)}$$
- 提高
w_semantic→ 结果更偏向语义理解(找近义、概念相关) - 提高
w_keyword→ 结果更偏向精确字面匹配
在工程实现中,这个权重在哪里调?
以 LangChain 的 EnsembleRetriever 为例,最为直观:
1 | from langchain.retrievers import BM25Retriever, EnsembleRetriever |
weights=[0.3, 0.7]即公式中的w_keyword和w_semantic。调大语义权重 → 更擅长理解意图;调大关键词权重 → 更擅长精确匹配专有名词。
4. 评估指标
用量化数字衡量检索器好不好用,是系统调优的科学基础。
三大核心指标
| 指标 | 核心目标 | 一句话解释 |
|---|---|---|
| 召回率 Recall@K | “找得全” | 前 K 个结果里,成功找到了多少个真正相关的文档 |
| 精确率 Precision & MAP | “找得准 + 排得好” | Precision 衡量返回结果中有多少是噪音;MAP 进一步评估相关文档是否排在最前面 |
| 平均倒数排名 MRR | “首位命中” | 第一个相关文档出现的位置越靠前,得分越高 |
用一个具体例子理解 Precision 和 Recall
场景: 知识库共 100 个文档,其中 10 个真正相关(Ground Truth),检索器返回了 8 个,其中 6 个真正相关。
$$Precision = \frac{\text{返回的且相关的}}{\text{总返回数}} = \frac{6}{8} = 75%$$
$$Recall = \frac{\text{返回的且相关的}}{\text{库中所有相关文档数}} = \frac{6}{10} = 60%$$
Precision:站在”你返回的文档”角度 —— 有多少是真货,有多少是噪音?
Recall:站在”知识库”角度 —— 10 个正确答案,你找到了几个?
Precision 与 Recall 的内在张力
两者天然互相拉扯:
| 操作 | Precision | Recall | 原因 |
|---|---|---|---|
| K 调大(如 8 → 50) | ⬇️ 下降 | ⬆️ 上升 | 捞得多,噪音增多,但遗漏减少 |
| K 调小(如 8 → 3) | ⬆️ 上升 | ⬇️ 下降 | 只选最有把握的,精准但遗漏多 |
指标的实际用途
- 评估基准表现:给当前系统打分,明确现状水平
- 验证优化效果:换 Embedding 模型、调整 Chunking 大小、修改混合检索权重时,通过对比指标前后变化来确认改动是否真的有效
最关键的前提:Ground Truth
所有指标都依赖于”基准真相”数据集
- 什么是 Ground Truth? 人工标注好的数据集。例如:针对问题 A,提前标注知识库里”文档 1”和”文档 5”是唯一正确答案。
- 为什么重要? Recall、Precision、MAP、MRR 的所有计算都需要对比”系统找出的答案”与”标准答案”。没有 Ground Truth,就无法进行科学调优。
5. Embedding model深入探讨
对比训练(Contrastive Training Process)
训练目标:让相似内容的向量靠近,不相似内容的向量远离。
正样本:来自”互联网的自然配对”
人类在互联网上的自然行为,天然就产生了海量配对数据:
| 数据源 | 正样本配对方式 | 谁”标注”的? |
|---|---|---|
网页图片的 alt 属性 |
<img alt="夕阳下的柳树"> → (图片, “夕阳下的柳树”) |
网页作者写 alt 文字时,无意识地创造了配对 |
| 论坛问答(StackOverflow、知乎) | (问题, 最佳答案) | 用户提问和回答时,无意识地创造了配对 |
| 维基百科 | (文章标题, 正文第一段) | 人类写百科,结构天然就是配对 |
| 新闻图片 | (配图, 图说文字) | 编辑写图说时,无意识地创造了配对 |
核心思想:互联网本身就是一个巨大的”隐式标注数据集”。人类日常创作内容时,已经在无意识地为 AI 标注数据了。
负样本:由算法自动生成
| 负样本类型 | 来源 | 需要人工吗? |
|---|---|---|
| In-batch 负样本 | Batch 内其他样本自动充当 | ❌ 完全自动 |
| 随机负样本 | 从数据集随机采样 | ❌ 完全自动 |
| Hard Negatives | 用弱模型先检索”接近但错误”的样本 | ⚠️ 部分需要人工验证 |
| LLM 生成的 Hard Negatives | 让 GPT-4 生成语义相近但不同的句子 | ❌ AI 生成 |
极少数需要人工标注的场景
只有在需要高精度 Benchmark(用来测试模型好不好)时,才会动用人工标注:
1 | STS(Semantic Textual Similarity)数据集: |
训练过程:前向传播生成向量 → 构建相似度矩阵 → InfoNCE Loss 惩罚”正样本排名不靠前”的情况 → 反向传播更新权重。
CLIP 的 4 亿训练对几乎全部自动获取。互联网本身就是隐式标注数据集,人工标注只用于评测 Benchmark,不是主力训练数据。
另外我感觉这个训练的过程很像我个人网站上的节点图,这个节点图会有斥力和吸力,整个节点图系统需要保持一个稳定的状态。因此,需要保持斥力和吸力的稳定,它需要有一个调整的过程。而这个调整的过程,我觉得可能就是 embedding 这个过程。
一个常见的误区——大模型参数 vs Embedding维度:参数是神经网络内部的权重总量(CLIP 约 1.5 亿个),是训练中学到的知识本身;维度是输出向量的长度(如 512 维),是设计时固定的规格。参数是模型学到的知识总量(越多越”聪明”),维度是输出向量的长度(影响表达能力的上限)。两者不是同一回事。
模块三:使用向量数据进行信息检索
1. 从暴力检索到 ANN
向量检索的所有算法,都有一个关键变量 K——指定返回与 query 最相近的向量数量(Top-K)。围绕”如何高效找到这 K 个向量”,演化出了两大流派:精确检索 与 近似检索(ANN)。
最基础的算法:暴力检索(Brute Force / Flat Search / Linear Scan)
最朴素直观的做法——计算 query 向量与数据库中每一个向量的距离(余弦/欧氏),全排序后取 Top-K。
在 FAISS 里它叫
IndexFlatL2,在学术界叫 Exact KNN,在工程上常被称为 Brute Force 或 Linear Scan。本质都是同一件事:不建任何索引,硬算到底。
- 优点:实现极简(一行 numpy 就能写完);Recall = 100%,是所有 ANN 算法的精度天花板与评测基准
- 致命问题:复杂度为 O(N×D)(N=向量数,D=维度)。数据库越大,单次查询越慢——百万向量已经吃力,亿级规模直接不可用
- 适用场景:小数据集(<10万)、离线评测、为 ANN 提供 ground truth
解决方案:ANN(Approximate Nearest Neighbor,近似最近邻搜索)
核心思想:预先建索引,跳过大部分不可能相关的向量,只在小范围内精细比对——通过牺牲极小的精度,换取查询速度数个数量级的提升。
主流实现:
- HNSW(分层可导航小世界图):基于”跳表+小世界网络”,复杂度降至 O(log N),精度高、查询快,工业界主流
- IVF(倒排文件索引):先用 K-means 聚类,查询时只扫描最近的几个簇,适合超大规模
- PQ(乘积量化):把高维向量切段后用聚类编号代替,向量压缩 64 倍以上,显著节省内存
工程上需在 精度(Recall)↔ 速度(QPS)↔ 内存 三者间权衡,常见组合如 IVF+PQ、HNSW+PQ。
2. 向量数据库
向量数据库是专门为存储、管理和检索高维向量设计的数据库系统。普通数据库存的是结构化行列,向量数据库存的是 Embedding 向量——并在其上内置 ANN 索引,让语义检索变成一等公民。
与传统数据库的核心区别
| 维度 | 关系型数据库(MySQL) | 向量数据库(Qdrant/Milvus) |
|---|---|---|
| 核心数据 | 结构化行列 | 高维浮点向量 |
| 查询方式 | SQL 精确匹配 | ANN 近似相似度检索 |
| 索引类型 | B-Tree、Hash | HNSW、IVF、PQ |
| 典型问题 | “找 id=42 的记录” | “找最语义相似的 Top-10” |
向量数据库通常同时存向量 + 元数据,支持先用元数据硬过滤,再做向量检索——即上文提到的 Metadata Filtering 与语义检索的结合。
主流向量数据库对比
- Qdrant:Rust 编写,性能强,REST/gRPC 接口,支持 payload 过滤,开源可自部署
- Milvus:专为超大规模设计(亿级),云原生架构,适合生产级分布式场景
- ChromaDB:最轻量,几行代码启动,开发调试首选,不适合大规模生产
- pgvector:PostgreSQL 插件,已有 PG 数据库直接加向量检索,无需引入新系统
- FAISS:严格来说是库而非数据库——无持久化、无 CRUD,但是所有向量数据库的底层算法来源
创建向量数据库的基础流程
Step 1 — 数据库初始化(Database Setup)
创建集合(Collection)并定义 Schema——指定存哪些字段、向量维度是多少、用什么距离度量(余弦 / L2 / 内积)。这是后续所有操作的容器,相当于建表。
Step 2 — 文档加载(Loading Documents)
将原始数据(文本、PDF、图片等)读入内存,按需做分块(Chunking)——把长文档切成适合 Embedding 的小段,避免单段过长导致语义稀释。
Step 3 — 稀疏向量(Sparse Vectors,关键词检索用)
用 BM25 等算法为每个文档块生成稀疏向量——向量大多数位置为 0,只有出现过的词对应位置有权重值。专为关键词精确匹配设计,是混合检索(Hybrid Search)的关键词侧。
Step 4 — 稠密向量(Dense Vectors,语义检索用)
将文档块送入 Embedding 模型(如 BGE、CLIP),输出每个块的稠密向量——每一维都有值,承载语义信息。这是语义搜索的核心,能理解同义词和意图。
Step 5 — 构建 HNSW 索引(HNSW Index)
在稠密向量上建立 HNSW(分层可导航小世界图)索引。预先在向量之间织好”导航网络”,查询时沿图跳跃定位,将检索复杂度从 O(N) 降至 O(log N),实现毫秒级 ANN 搜索。这个也可以不做,如果不做的话就是暴力检索。
3. Chunk(分块技术)
将长文档切成适合 Embedding 的小段,是 RAG 索引阶段的关键预处理步骤。块太大语义稀释、块太小上下文丢失,切得好不好直接影响检索质量。
为什么要分块?
Embedding 模型有 Token 上限(如 BERT 系列 512 token、BGE-M3 8192 token)。把整本书塞进去只会得到一个模糊的”平均语义”,检索时很难命中具体段落。分块后每段各自有独立向量,检索精度大幅提升。
主要分块策略
- 固定大小(Fixed-size Chunking):按字数 / token 数硬切,简单粗暴。缺点是可能从句子中间截断,损失上下文。常配合 Overlap(重叠) 使用——相邻块共享若干 token,缓解截断问题。
- 语义分块(Semantic Chunking):按句子边界、段落、标题层级切分,保留自然语义完整性。适合结构化文档(Markdown、PDF)。
- 递归字符分割(Recursive Character Splitting):LangChain 默认策略,按
\n\n → \n → 句号 → 空格优先级依次尝试,尽量在自然边界切割,兼顾简单与语义完整。
4. 一些更高级的 chunk 技术
利用 LLM 进行语义分块
传统分块靠规则(段落、标题、固定大小),而”LLM 语义分块”让模型真正理解内容的语义边界后再决定怎么切,质量更高但成本也更高。
① 基于 Embedding 相似度的语义分块(SemanticChunker)
原理:先按句子拆开文本 → 对每个句子计算 Embedding → 计算相邻句子的余弦相似度 → 当相似度骤降时,说明话题发生了转变,在此处切割。
1 | 句1 → 句2 → 句3 ↘↘骤降↘↘ 句4 → 句5 |
- 工具:LangChain 的
SemanticChunker直接封装了这个逻辑 - 优点:无需调用 LLM 推理,成本低;真正按语义断点切,而不是按字数
- 缺点:需要设定相似度阈值,阈值选不好会切太碎或切太少
② 命题分块(Proposition Chunking)
原理:用 LLM 将每个文本段进一步提炼为若干原子命题——每条命题是一个独立、完整、可单独理解的最小事实单元。
例:原文”爱因斯坦于 1905 年发表了狭义相对论,并因光电效应获诺贝尔奖”
→ 命题1:「爱因斯坦于 1905 年发表了狭义相对论」
→ 命题2:「爱因斯坦因光电效应研究获得了诺贝尔奖」
- 优点:检索时 query 与命题一一对应,精准度极高;每条命题自包含,不依赖上下文也能理解
- 缺点:每个 chunk 都要调用 LLM 提炼,token 消耗大、速度慢,索引构建成本高
- 适用:对知识库检索质量要求极高的场景(医疗、法律、精确问答)
③ Agentic 分块
直接将整段文档交给 LLM,让它自主判断语义边界、输出分割点或直接输出分好的块。最灵活,能处理复杂非结构化文档(如对话记录、混排文档),但成本最高,一般只用在离线预处理管道中。
三种方式对比
| 方式 | 是否调用 LLM | 成本 | 精度 | 适用场景 |
|---|---|---|---|---|
| Embedding 相似度 | 只用 Embedding 模型 | 低 | 中 | 通用场景,快速构建 |
| 命题分块 | 是(提炼命题) | 高 | 高 | 精确问答、知识库 |
| Agentic 分块 | 是(理解+切割) | 最高 | 最高 | 复杂非结构化文档 |
实际项目中最常见的折中方案:先用递归字符分割做粗切,再用Embedding 相似度做语义边界校正,只在核心知识库段落上启用命题分块。
5.查询解析
用户的原始问题往往口语化、模糊、包含多个子意图——直接用来检索,向量相似度会偏移,漏掉真正相关的文档。”查询解析”这一步的目标,就是在检索前用 LLM 把问题变得更适合检索。
核心思路:在 Retrieval 之前,先用一次(或多次)LLM 调用对 Query 做变换,再去检索。
Query Rewriting —— 查询改写
原理:直接用 LLM 将用户的原始问题改写为一个(或多个)措辞更精准、更接近知识库文档语言的新 Query。
例:用户问”这个 bug 咋修” → 改写后:”如何修复 IndexError 数组越界异常?”
为什么有效:Embedding 模型是对称相似度——用户说的词和文档里写的词越像,向量越接近。改写填补了”口语 ↔ 文档语言”的词汇鸿沟(Vocabulary Mismatch)。
1 | # 改写 Prompt 示意 |
- 优点:实现简单,一次 LLM 调用;显著改善词汇不匹配问题
- 缺点:改写有可能偏离原意;增加一次 LLM 延迟
Query Decomposition —— 查询分解
原理:遇到包含多个子问题的复杂 Query,让 LLM 将其拆解为若干独立子问题,每个子问题单独去检索,最后汇总答案。
例:用户问 “Python 和 JavaScript 在 Web 开发中各有什么优缺点,该选哪个?”
→ 子问题 1:「Python Web 开发的优点是什么?」
→ 子问题 2:「Python Web 开发的缺点是什么?」
→ 子问题 3:「JavaScript Web 开发的优点是什么?」
→ 子问题 4:「JavaScript Web 开发的缺点是什么?」
每条子问题分别检索,检索结果合并后一起交给 LLM 生成最终答案。
为什么有效:一个复杂问题往往在知识库里对应多处分散的信息。不分解则很难用一条 Query 同时命中所有相关段落;分解后每条 Query 更聚焦,检索精度大幅提升。
- 优点:特别适合多跳推理(Multi-hop)和比较类问题
- 缺点:子问题数量不可控;多次检索成本倍增;汇总逻辑复杂
HyDE —— 假设性文档嵌入(Hypothetical Document Embeddings)
原理:不直接对 Query 做 Embedding,而是先让 LLM 生成一段假设性的”理想答案”,再对这段假设答案做 Embedding 去检索。
1 | 用户 Query → LLM 生成"假设答案" → Embed(假设答案) → 向量检索 |
例:用户问”HNSW 为什么查询速度快?”
→ LLM 生成假设答案:”HNSW 基于分层图结构,查询时从高层稀疏图快速定位大致区域,再逐层精细搜索……”
→ 对这段假设答案做 Embedding → 比直接对问题句做 Embedding,向量更接近知识库里真实文档
直觉理解:问题的 Embedding 和答案的 Embedding 在语义空间里本就不在同一个位置。假设答案更像一段”真实文档”,因此和知识库里的文档向量距离更近,检索 Recall 更高。
- 优点:对”知识密集型问答”效果显著;不依赖关键词,纯语义驱动
- 缺点:假设答案可能包含幻觉,但检索阶段不依赖答案的正确性,只用它的向量,所以幻觉不直接影响结果
- 适用:专业领域问答、文档措辞与问题措辞差异大的场景
Multi-Query —— 多角度提问
原理:让 LLM 从多个角度生成同一问题的 N 种变体,分别检索,再对检索结果去重合并(常与 RRF 联用)。
例:原问题”RAG 的局限性”
→ 变体 1:「RAG 在什么场景下效果不好?」
→ 变体 2:「Retrieval-Augmented Generation 的缺点有哪些?」
→ 变体 3:「RAG 系统的失败案例」
三条 Query 各自检索,合并结果后用 RRF 重排序,最终 Top-K 覆盖面远超单一 Query。
- 优点:弥补单条 Query 的覆盖盲区;与 RRF 天然搭配
- 缺点:N 次 Embedding 检索 + LLM 调用,延迟和成本线性增长
总结/各方案对比
| 方式 | 核心思路 | 适用场景 | 额外 LLM 调用 | 风险 |
|---|---|---|---|---|
| Query Rewriting | 改词,更像文档语言 | 口语/专业词汇不匹配 | 1次 | 改偏原意 |
| Query Decomposition | 拆子问,分别检索 | 多跳/比较类复杂问题 | 1次(拆分)+ N次检索 | 子问题爆炸 |
| HyDE | 先生成假设答案再检索 | 问题与文档措辞差异大 | 1次 | 幻觉影响向量方向 |
| Multi-Query | 生成多变体覆盖盲区 | 召回率不足、覆盖面窄 | 1次(生成)+ N次检索 | 成本高 |
工程实践中:最常见的轻量方案是 Query Rewriting + Multi-Query(N=3)+ RRF——只多 1 次 LLM 调用,检索质量提升明显。HyDE 和 Decomposition 留给对质量要求极高的场景(如法律文书问答)。
6. Reranker 与精排策略
背景:向量检索(常规的编码两次的成为Bi-Encoder)快但粗糙——它把 Query 和 Document 分别压成单个向量再做点积,损失了大量细粒度的交互信息。Reranker 就是在粗检索之后,对 Top-N 候选做精细打分、重新排序的第二阶段模块。
两阶段检(Bi-Encoder)索管道
1 | 用户 Query |
交叉编码器(Cross-Encoder)
原理:把 Query 和 Document 拼在一起输入同一个 Transformer,让两段文字的所有 token 互相做注意力——直接输出一个相关性分数。
1 | 输入: [CLS] Query tokens [SEP] Document tokens [SEP] |
- 优点:全量交互,打分最准确,是精度天花板
- 缺点:Document 向量无法预计算——每次查询都要把每个候选文档和 Query 重新跑一遍,100 个候选 = 100 次模型推理,延迟高
- 适用:候选集不大(Top-100 以内)、对精度要求极高的场景
ColBERT(Contextualized Late Interaction over BERT)

如上图,问题的每一个词都会和文章里的每一个词产生呼应,从而获得更精确的结果。
原理:Query 和 Document 依然分开编码(所以 Document 可预计算),但不压缩成单个向量——保留每个 token 的向量。相关性分数用 MaxSim 计算:对 Query 的每个 token(逐字切分),找 Document 所有 token 里最相似的那个,累加求和。
1 | Query → [q₁, q₂, q₃, ...] 每个 token(逐字切分) 一个向量 |
- 优点:Document 可以离线预计算并存储;交互比单向量 Bi-Encoder 丰富得多
- 缺点:存储开销大(每个 token 存一个向量,文档越长越占空间);比 Bi-Encoder 慢,比 Cross-Encoder 快
- 定位:精度与速度的中间档,适合候选集较大(Top-1000)的场景
三者横向对比
| Bi-Encoder | ColBERT | Cross-Encoder | |
|---|---|---|---|
| 编码方式 | Query/Doc 各一个向量 | Query/Doc 各保留 token 向量 | 拼接后联合编码 |
| Doc 预计算 | ✅ | ✅ | ❌ |
| 交互粒度 | 粗(单向量点积) | 中(token-level MaxSim) | 细(全量注意力) |
| 速度 | 最快 | 中 | 最慢 |
| 精度 | 最低 | 中 | 最高 |
| 典型用途 | 第一阶段粗检索 | 中等规模 Reranking | 小候选集精排 |
7. ReRanking
精排不是一种具体模型,而是一个管道位置的概念——在粗检索之后,对候选集重新打分排序。
具体实现方式有多种,§6 已详解 Cross-Encoder 与 ColBERT,这里补充另外两条路线。
精排的三条路线(概览)
| 路线 | 核心机制 | 详见 |
|---|---|---|
| Cross-Encoder | Query+Doc 拼接联合编码,token 全量交互 | §6 ① |
| ColBERT | 保留 token 向量,MaxSim 延迟交互 | §6 ② |
| RRF | 合并多路检索的排名,无需打分 | 下方 ↓ |
| LLM 直接评分 | 让大模型判断相关性 | 下方 ↓ |
① RRF(互惠排名融合,Reciprocal Rank Fusion)
适用场景:你同时运行了多路检索(如稀疏 BM25 + 稠密 CLIP),需要把两份排名列表合并成一份。
核心公式:
1 | RRF_score(doc) = Σ 1 / (k + rank_i) k 通常取 60 |
对每路检索,用文档的排名位置(而非分数)计算贡献,再累加。
具体例子:
1 | Query: "覆有青苔的石头" |
为什么不直接把两路分数相加?
BM25 分数(词频统计)和 CLIP 余弦相似度的量纲完全不同,直接相加没有意义。
RRF 只关心排名位置,不看具体数值,天然绕开了量纲对齐问题。
② LLM 直接评分
将候选结果的文本描述喂给 LLM,让模型直接判断与 Query 的相关性:
1 | Prompt 示例: |
| 说明 | |
|---|---|
| 优点 | 语义理解能力最强;可自定义评分标准(风格、场景适配度等) |
| 缺点 | 每条候选都要调一次 LLM,成本高、延迟高 |
| 适用 | 候选集极小(Top-5 以内)、或需要可解释的评分理由 |
选型速查
| 候选集规模 | 推荐策略 |
|---|---|
| 全量 10 万+ | 只能 Bi-Encoder(向量检索) |
| Top-1000 | ColBERT 或 RRF 合并多路结果 |
| Top-100 | Cross-Encoder(推荐,精度/延迟最佳平衡) |
| Top-10 | LLM 直接评分(可选,需要极致精度或可解释性时) |
- 已有(M1):FTS5 关键词检索(稀疏)
- 已有(M4):CLIP FAISS 视觉检索(稠密)
- 进行中(M5):Cross-Encoder 精排,Top-100 → Top-10
- 可选升级:将 FTS5 与 CLIP 的结果先用 RRF 合并,再送入 Cross-Encoder——
稀疏路线补精确关键词命中,稠密路线补语义覆盖,两者互补
模块四:大语言模型与文本生成
前三个模块都在讲 Retrieve(检索)——把最相关的内容找出来。本模块进入 RAG 的最后一环 Generate(生成):把检索到的内容交给大语言模型(LLM),生成有据可查的回答。
1 | 用户问题 →【检索】Top-K 相关片段 →【拼装 Prompt】→【LLM 生成】→ 回答 |
我们的资产搜索工具是”只检索不生成”,所以模块四对它是可选项;但本地的 starting-ragchatbot-codebase(问答机器人)是完整 RAG,生成环节由 Claude 承担。
Transformer架构简介
一句话:Transformer 是当今几乎所有 LLM、Embedding 模型、Reranker 的共同底座。本笔记反复出现的 BERT、CLIP、BGE、Cross-Encoder、GPT/Claude——全部是 Transformer 的变体。
1. 为什么是 Transformer?(对比 RNN)
先说命名:为什么叫 Transformer,而不叫 Attention?
- Attention 是零件,Transformer 是整机。 Attention 早在 2014 年(Bahdanau)就作为 RNN 的配件用于机器翻译,到 2017 年已是通用技术——新架构若也叫 Attention,会和”RNN+attention”撞名。
- 论文标题是论点,架构名是产品名。《Attention Is All You Need》的潜台词是”以前 RNN 配 attention,把 RNN 拿掉、只留 attention 就够”;标题负责喊口号,新架构另起名 Transformer 与 RNN 时代切割。
- “Transform” = 逐层变换表示。 模型把 token 的向量表示通过堆叠多层一层层重写,最终把”孤立词向量”变成”饱含上下文语义的向量”。Attention 只描述单层的某个操作(Q·K→加权 V),Transformer 描述整机在做什么——抽象层级不同。
那为什么需要它? 2017 年论文《Attention Is All You Need》之前,处理文本主要靠 RNN/LSTM (RNN(Recurrent Neural Network,循环神经网络)),它按顺序一个词一个词读,有两个硬伤:
| 问题 | RNN/LSTM | Transformer |
|---|---|---|
| 并行能力 | 必须顺序计算,无法并行 | 整句一次性并行处理 ⭐ |
| 长距离依赖 | 距离越远信息衰减越严重 | 任意两词直接建立联系 |
| 训练速度 | 慢 | 快(能吃满 GPU) |
Transformer 用**自注意力(Self-Attention)**一举解决了这两点,这也是 LLM 能”规模化”到千亿参数的前提。
2. 核心机制:自注意力(Self-Attention)
自注意力让句子里的每个词,都去”看”句子里所有其他词,按相关性加权吸收信息。
关键三元组 Q / K / V:
| 符号 | 含义 | 类比(像不像检索?) |
|---|---|---|
| Query(查询) | 我现在想找什么 | 用户的搜索词 |
| Key(键) | 我能提供什么”标签” | 文档的索引 |
| Value(值) | 我实际的内容 | 文档正文 |
计算流程:
1 | 对每个词: |
具体例子——理解句子”它”指代谁:
1 | 句子: 这块石头覆满青苔,因为它很潮湿 |
Query·Key→softmax→对 Value 加权求和——这套机制和模块二、三讲的稠密检索(向量相似度→Top-K→取回内容)是同一个数学思想,只不过它发生在模型内部,对每个 token 实时进行。理解了向量检索,你已经理解了注意力的一半。
3. 多头注意力 + 位置编码 + 整体结构
- 多头注意力(Multi-Head):并行跑多组 Q/K/V,每个”头”关注不同角度(一个头看语法、一个头看指代、一个头看语义……),最后拼接。类比:多个专家从不同维度同时审阅同一句话。
- 位置编码(Positional Encoding):自注意力本身不区分词序(”狗咬人”和”人咬狗”会被看成一样),因此要额外注入每个词的位置信息。
- 残差连接 + 层归一化 + 前馈网络(FFN):每一层的标准配件,保证深层网络(几十上百层)能稳定训练。
4. 三种架构变体(决定模型用途)
| 架构 | 代表模型 | 擅长 | 在本笔记中的角色 |
|---|---|---|---|
| Encoder-only(编码器) | BERT、BGE-M3 | 理解、向量化 | Embedding 模型(§3.1)、Cross-Encoder(§6) |
| Decoder-only(解码器) | GPT、Claude、Qwen、Llama | 生成文本 | 本模块的主角,负责”生成” |
| Encoder-Decoder | T5、BART | 翻译、摘要 | 较少用于聊天 |
- 你用 CLIP/BGE(Encoder)把资产转成向量 → 这是 Transformer
- 你用 Cross-Encoder(Encoder)做精排 → 这是 Transformer
- 你用 Claude/Qwen(Decoder)生成答案 → 还是 Transformer
三者血缘相同,区别只在”怎么搭、用哪半边、怎么训练”。
大语言模型采样策略
检索决定”喂什么内容”,采样策略决定”模型怎么把内容说出来”——同样的上下文,参数不同,输出可以严谨也可以天马行空。对 RAG 来说这一节直接关系到幻觉率。
1. LLM 是怎么”吐字”的?
Decoder 模型每一步只做一件事:预测下一个词的概率分布。
1 | 输入:"覆有青苔的石头通常出现在" |
“采样策略”就是从这个概率分布里挑一个词的规则。挑完接到输入后面,再预测下一个,循环往复。
2. 确定性解码
| 策略 | 做法 | 特点 |
|---|---|---|
| 贪心解码 Greedy | 每步都选概率最高的词 | 稳定但呆板,易陷入重复 |
| Beam Search | 同时保留 N 条候选路径,最后选整体最优 | 质量高但慢,多用于翻译/摘要 |
3. 随机采样(聊天/创作主流)
① Temperature(温度)——调节分布的”陡峭/平缓”:
1 | logits 经过 softmax 前先除以 T: |
② Top-k:只在概率最高的 k 个词里采样(如 k=40),砍掉长尾。
③ Top-p / 核采样(Nucleus):从高到低累加概率,凑够 p(如 0.9)就停,只在这个动态集合里采样。比 Top-k 更聪明——分布陡时候选少、分布平时候选多。
1 | 候选(按概率排序): 潮湿0.45 阴暗0.25 森林0.15 苔藓0.08 ... |
④ min-p(较新):以最高概率词为基准,按比例设一个动态下限,鲁棒性比 Top-p 更好。
⑤ 重复惩罚(repetition / frequency penalty):对已经出现过的词降权,避免”复读机”。
4. RAG 场景该怎么调?
生成阶段如果温度太高,模型容易脱离检索到的事实、自由发挥 → 幻觉。
| 场景 | Temperature | Top-p | 说明 |
|---|---|---|---|
| RAG 事实问答 ⭐ | 0 ~ 0.3 | 0.9 | 最大化忠实度,少编造 |
| 摘要/改写 | 0.3 ~ 0.5 | 0.9 | 略有灵活但不离谱 |
| 创意写作/起名 | 0.8 ~ 1.2 | 0.95 | 鼓励多样性 |
| 代码生成 | 0 ~ 0.2 | — | 要确定性 |
如果将来给资产搜索加一个”自然语言解释为什么推荐这个资产”的生成功能,温度应设到 0.2 左右——让它老老实实根据资产的 metadata 描述说话,而不是脑补不存在的属性。
选择适合的大语言模型
没有”最好”的模型,只有”最适合当前任务+预算+合规要求”的模型。下面是一套可复用的选型框架。
1. 七个评估维度
| 维度 | 关键问题 | 对 RAG 的影响 |
|---|---|---|
| 能力等级 | 推理/复杂指令够不够强 | 决定答案质量上限 |
| 上下文窗口 | 能塞下多少检索片段 | RAG 直接相关,见下 ↓ |
| 成本 | 输入/输出每百万 token 价格 | 高频调用时是主要开销 |
| 延迟/吞吐 | 首字时间、每秒 token 数 | 影响用户体验 |
| 隐私/合规 | 数据能否出本地 | 私有资产/代码的红线 ⭐ |
| 中文能力 | 中文理解与生成 | 中文场景必看 |
| 结构化输出/工具调用 | 能否稳定输出 JSON、调函数 | Agentic RAG 必备 |
2. 闭源 API vs 开源本地
| 闭源 API(Claude / GPT / Gemini) | 开源本地(Qwen / Llama / DeepSeek …) | |
|---|---|---|
| 能力 | 通常最强 | 头部开源已逼近闭源 |
| 部署 | 调 API,零运维 | 自己用 GPU 跑,需运维 |
| 成本 | 按量付费,无前期投入 | 硬件前期投入,边际成本近乎 0 |
| 隐私 | 数据出本地 ⚠️ | 数据不出本地 ✅ |
| 定制 | 有限 | 可微调/量化,完全可控 |
3. 2026 年中主流模型速览
下表数据交叉核对自 Anthropic 官方 claude-api 参考(缓存 2026-06-04)与公开比价站(morphllm LLM API,验证于 2026-06-09、LLM API Pricing 2026)。模型与价格变动极快,以官网为准。
闭源 API(价格=输入/输出,每百万 token):
| 模型 | 定位 | 上下文 | 价格(in/out) |
|---|---|---|---|
| Claude Fable 5 | 最强、长程 Agent | 1M | $10 / $50 |
| Claude Opus 4.8 ⭐ | 旗舰、编码/Agent 强 | 1M | $5 / $25 |
| Claude Sonnet 4.6 | 速度/智能平衡 | 1M | $3 / $15 |
| Claude Haiku 4.5 | 快而省 | 200K | $1 / $5 |
| GPT-5.5(OpenAI) | 推理/数学强 | ~256K | ~$5 / $30 |
| Gemini 3.1 Pro(Google) | 超长上下文、多模态、性价比 | 巨大(≥1M) | ~$2 / $12 |
| DeepSeek V4 | 极致性价比 | 大 | ~$0.14 起 |
开源/可本地部署(适合私有数据):
| 模型族 | 特点 | 备注 |
|---|---|---|
| Qwen 3.5(通义千问) | 中文最强梯队、尺寸齐全 | 小尺寸 8GB 可跑,本地首选 ⭐ |
| Llama 4(Meta) | 生态最大 | 中大尺寸 |
| DeepSeek V4 | 推理强、开源 | 满血版需大显存 |
| GLM-5(智谱) | 中文友好 | |
| Mistral / Gemma / Phi | 欧系/谷歌/微软小模型 | Phi 适合边缘端 |
4. 上下文窗口与 RAG 的关系
RAG 要把 [系统提示] + [Top-K 检索片段] + [对话历史] + [用户问题] 一起塞进上下文。窗口越大,能放的检索证据越多。
- 塞太多无关片段会稀释有用信息、抬高成本、还可能触发”中间遗忘”(见下一节)。
- 正解仍是:先精排取 Top-5~10 高质量片段(模块三 §6/§7 的 Reranker),而不是把 Top-100 全丢进去。好的检索 > 大的窗口。
5. 选型速查
| 你的情况 | 推荐 |
|---|---|
| 私有美术资产 / 私有代码,数据不能出本地 | 本地 Qwen3 系列(用你的 DGX Spark 节点跑,128GB 统一内存可加载量化后的中大模型) ⭐ |
| 追求最高答案质量、可接受 API | Claude Opus 4.8(claude-opus-4-8)或 Fable 5 |
| 高频、对成本敏感 | Claude Haiku 4.5 / Gemini Flash / DeepSeek |
| 需要超长上下文 | Gemini 3.1 Pro / Claude(1M 窗口) |
- 资产库项目(私有美术资产)→ 隐私优先 → 本地 Qwen on DGX Spark
starting-ragchatbot-codebase(课程问答机器人)→ 已用 Claude(Anthropic 官方推荐默认claude-opus-4-8+ 自适应思考thinking:{type:"adaptive"}),调 API 即可,无需运维
提示词工程
模型选定、检索完成后,提示词(Prompt)是你在推理阶段唯一的控制杆——不重新训练,仅靠组织输入就能大幅改变输出质量。对 RAG 而言,提示词工程的核心目标是:让模型严格基于检索内容作答,拒绝幻觉。
1. 提示词的基本结构
1 | ┌── System(系统提示):设定角色、规则、语气、边界 |
2. 通用技巧
| 技巧 | 做法 | 何时用 |
|---|---|---|
| 角色设定 | “你是资深美术指导……” | 几乎总是 |
| Few-shot 少样本 | 给 1~3 个”输入→理想输出”示例 | 输出格式/风格要稳定 |
| 思维链 CoT | “请一步步推理后再给结论” | 复杂推理(注:RAG 事实问答通常不需要太多发散) |
| 结构化输出 | 要求输出 JSON / 指定字段 | 下游程序要解析、Agentic RAG |
3. RAG 专用提示词模板(重点)
一个合格的 RAG 提示词必须包含三道”防幻觉”指令:①只用提供的内容 ②找不到就说不知道 ③标注来源。
1 | 你是游戏资产库的检索助手。请严格遵守: |
缺了第 2 条,模型在检索为空时会”自信地胡说”;缺了第 3 条,用户无法核查,答案不可追溯。
4. “中间遗忘”现象(Lost in the Middle)
研究发现:当上下文很长时,模型对开头和结尾的信息记得最牢,中间的内容最容易被忽略——召回率曲线呈 U 形。
1 | 模型注意力 ▲ |
把 最相关的检索片段放在 Prompt 的最前面或最后面,不要埋在中间一大堆片段里。这也再次印证了精排(Reranking)的价值:与其塞 50 条让关键信息淹没在中间,不如精排出 5 条放在显眼位置。
5. 好 vs 坏 提示词对比
| ❌ 差 | ✅ 好 | |
|---|---|---|
| 角色 | (无) | “你是资产库助手” |
| 防幻觉 | (无,放任发挥) | “只用检索结果,找不到就说没有” |
| 来源 | (不要求) | “用 [资产ID] 标注依据” |
| 片段顺序 | 随便堆 | 最相关的放首/尾 |
| 输出 | “随便答” | 指定格式/字段 |
- 提示词工程:临时、零成本,靠当前输入引导 → 本节
- RAG:动态注入外部知识,知识可实时更新 → 本笔记全篇
- 微调(Fine-tuning):把知识/风格”焊进”模型权重,成本高、更新慢
三者常组合使用:RAG 提供事实 + 提示词约束行为 + (可选)微调统一风格。
幻觉抑制处理(Hallucination Suppression)
前三节讲的是”如何让模型少胡说”,但当幻觉不可避免地出现时,我们还需要事后手段来检测、定位、评估、归因。下面四个概念构成 RAG 系统幻觉治理的完整闭环。
(1) Citation / Context Cite(上下文引用)
Citation 直译”引用”,在 RAG 语境里特指:让模型把答案中每一个事实”钉”回原文的具体片段,让用户能一键追溯到出处。
两种实现层次:
| 层次 | 做法 | 代表 |
|---|---|---|
| 事后归因 (Attribution) | 用 LLM 给答案中的每个事实反查”出处是哪个片段” | Citation Generation / Cite-and-Explain |
| 原生内嵌 (Native Citations) | 让模型在生成的同时直接产出引用,无需二次加工 | Anthropic Citations API、LongCite |
Anthropic Citations API 示例(官方文档)——把文档标记为 citations: {"enabled": True},模型就会自动返回带 char_start / char_end 区间的引用块:
1 | response = client.messages.create( |
它解决什么痛点?
| 没引用 | 有引用 |
|---|---|
| “草是绿的” | “草是绿的”〔引用自《我的文档》§1, char 0–6〕 |
| 模型编造 → 用户无法察觉 | 引用对照 → 用户可秒判真假 |
即便现在只做检索不做生成,将来若加 LLM 总结,把引用机制从一开始就塞进 prompt 是几乎零成本的”防御工事”。
(2) Citation Generation(引用生成)
Citation Generation = 让 LLM 主动”产出”带引用的答案。
它是上面 Citation 的”生成端”实现策略,强调训练/提示模型把”输出 + 引用”打包在一起写出来。
主流做法分两路:
| 路线 | 代表 | 思路 |
|---|---|---|
| 训练式 | LongCite(THU, 2024) | 构造长文 QA 训练对,让模型学会”答到哪句、引到哪段”,产出细粒度句级引用 |
| 提示式 | Anthropic-style Citations | 改用提示词约束输出格式,例如:「请输出 JSON: {answer, citations: [{doc_id, span}]}」 |
LongCite 例子(虚构示意):
1 | 问:CLIP 是什么时候、由谁发布的? |
CiteGuard(2025) 指出:模型可能生成”长得像引用”但实际错位”的引用(recall 只有 16–17%)。所以生成引用本身仍需要被验证——它比无引用强,但不是银弹。
(3) Evaluating Criterion Quality in LLMs
直译:评估 LLM 中”评估标准”的质量。
这一节讲的不是”评估 LLM”,而是评估”用来评估 LLM 的那些打分标准(criterion / rubric)本身靠不靠谱”。
为什么重要? 当我们用 LLM-as-a-Judge(让 LLM 当裁判打分)评价 RAG 输出时,裁判其实只看到了你写的 rubric(评分标准)。rubric 写得糊,裁判打得就糊。
1 | ✅ 好 rubric(一条一维度 + 锚点 + justify): |
量化”rubric 质量”要看几件事:
| 维度 | 含义 | 如何测 |
|---|---|---|
| 判别力 Discriminability | 不同质量的答案能不能拉开档次? | 同 query 多份候选,看分数分布 |
| 一致性 Inter-judge Agreement | 同一份答案,不同裁判(人/LLM)打分是否一致 | Cohen’s κ、% 一致率 |
| 与人类对齐 Human Alignment | 裁判分是否接近真人打分 | 跟人工标注集求 Pearson/Spearman |
| 稳定性 Rubric Drift | 同一 rubric 用久了分数是否漂移 | 定期回测金标集 |
| 抗偏性 Bias Resistance | 不受位置偏差 / 长度偏差 / 自家偏好影响 | ABX 配对测试 |
实操做法(行业主流):
- 先建一个金标集(几百条问题 + 人工标注的”标准答案 + 标准分数”)。
- 多版 rubric 对照打同一份金标,看哪版跟人类分数最接近。
- 定期回测——模型升级、领域变化时重跑金标,看分数曲线是否漂移(rubric drift)。
- 记录 justification——每个分数要求裁判给出理由,方便事后复盘”为什么这个答案拿 4 分不是 3 分”。
模块五要讲的 RAG 评估三大指标——Context Relevance / Groundedness / Answer Relevance(即 TruLens 提出的 RAG Triad)——能否真的衡量质量,完全取决于为这三个指标写的 rubric 写得清不清楚。这一节就是为那块内容做铺垫。
(4) 四个概念如何拧成”幻觉治理闭环”
1 | ┌─────────────────────────┐ |
对 RAG 的总结性建议:
| 阶段 | 用上哪些手段 |
|---|---|
| 离线开发 | Good prompt(§3)+ 精排 Top-K(§模块三)+ Citation Generation(训练/提示) |
| 上线前 | RAG Triad 评估 + Evaluating Criterion Quality(人评对齐) |
| 线上 | 原生 Citations(如 Anthropic API)+ 用户反馈回流 |
| 事后归因 | Context Cite 反查 + 监控 Groundedness 分数 |
好的 RAG 不只”答得对”,还要”答得可以查”——生成(Citation)+ 评估(Criterion)才是完整的幻觉治理。
RAG vs 微调(Fine tuning)
RAG 与微调经常被一起讨论,但其实是两条不同的路线,解决的问题不一样:
| 维度 | RAG(检索增强生成) | Fine-tuning(微调) |
|---|---|---|
| 做什么 | 检索外部知识,拼进 prompt | 改模型权重,让模型”记住”知识 |
| 知识更新 | 改知识库即可,实时生效 | 必须重新训练,耗时耗钱 |
| 适用场景 | 私有数据 / 时效性强 / 要引出处 | 学特定风格 / 固定输出格式 / 注入专业表达 |
| 推理成本 | 每次多一次检索(向量查询) | 训练贵,推理不变 |
| 可解释性 | 答案可追溯到具体文档 | 黑箱,模型说啥就是啥 |
| 幻觉风险 | 低(有据可查) | 仍可能幻觉(遗忘 / 编造) |
| 数据需求 | 文档 + 嵌入索引 | 高质量标注问答对(通常上千条起步) |
- 数据在变、要溯源、合规要求高 → 优先 RAG
- 要改风格、固定输出格式、学特定表达 → 优先 Fine-tuning
- 最难的任务 → RAG + 微调组合(先精调基底,再外挂知识)
RAG 是给模型”开卷考试”,Fine-tuning 是让模型”在家背书”。开卷永远比背书保鲜。
常见微调方式
| 方式 | 一句话说明 | 适合场景 | 数据量级 |
|---|---|---|---|
| 指令微调(SFT) | 用”指令-回答”对训练,让模型听懂人话、学格式 | 教新任务、改语气风格 | 几千~几万条 |
| 持续预训练(Continued Pre-training) | 在专业语料上继续预训练,让模型”懂行” | 法律、医疗、代码、金融等垂直领域 | 大规模无标注语料 |
| LoRA / QLoRA(PEFT) | 只训练少量参数(低秩适配器),冻结原权重 | 资源不够 / 多任务并行 / 快速迭代 | 几百~几千条 |
| DPO(直接偏好优化) | 用”好回答 vs 坏回答”对直接优化策略 | 想要 RLHF 效果但嫌流程复杂 | 几千条偏好对 |
| RLHF | 先训奖励模型,再用 PPO 强化学习对齐人类偏好 | ChatGPT 式的”听话 + 有用 + 安全”对齐 | 几万条人类标注 |
| Prefix / Prompt / Adapter Tuning | 在模型上加一个可训练的小模块/前缀 | 一个基座服务多任务 | 几百条 |
持续预训练(学领域知识)→ 指令微调 SFT(学格式/风格)→ DPO 或 RLHF(对齐偏好)——这也是 Llama、Qwen、DeepSeek 这类开源模型的标准训练流程。
但是课程的老师也说,微调并不是让AI去学习新知识的一种好办法。AI通常经过微调之后,通常它在提示词上会有比较大的变化。但是对于信息面的影响会比较小。
所以这就引出了 RAG 和微调的适合场景:RAG 比较适合于注入新知识,而微调比较适合于为特定领域做适配。
不是所有微调都要”改全量”——LoRA/QLoRA 这类 PEFT 用 1% 的参数就能拿到 90% 的效果,才是工程界的性价比之王。
模块五 生产环境中的RAG系统
1. 生产环境面临哪些挑战?
RAG 走出 demo 后,会撞上一连串 demo 里看不到的”墙”:
| 维度 | Demo 状态 | 生产现实 |
|---|---|---|
| 数据 | 几十条干净文档 | 百万级脏文档(重复、过期、权限敏感) |
| 用户 | 自己人测试 | 真实用户问法千奇百怪、夹带错别字/口语 |
| 召回 | “差不多就行” | 必须可追溯、可解释、有 SLA |
| 成本 | 一张卡跑跑 | QPS、成本、延迟三者拉扯 |
| 反馈 | 没有 | 需要日志、监控、A/B、可观测性 |
Demo 是”能不能答出来“,生产是”答得稳不稳、贵不贵、快不快、安不安全、能不能量化改进“。
2. 实施 RAG 评估策略
评估 = 回答”我的 RAG 现在到底有多好?”。三步走:
1 | 离线评估集(黄金集) → 自动化打分 → 回归对比 |
- 黄金集:人工标注 question + 期望答案 / 相关片段
- 指标:检索(Recall@k、MRR)、生成(忠实度、答案相关性)、端到端(命中率)
- 工具:RAGAS、ARES、LangSmith Evaluation、DeepEval
同一份数据 + 同一份代码 = 同一份分数。否则版本一改,谁也说不清是”模型进步”还是”prompt 改了”。
3. 日志记录、监控与可观测性
生产 RAG 是黑盒流水线,没有日志 = 没有调试能力。三个层面:
| 层面 | 记录什么 | 用来干嘛 |
|---|---|---|
| Trace(链路) | 每次 query 的 retriever / reranker / LLM 调用、入参出参、耗时 | 复现问题 |
| Metric(指标) | QPS、延迟分位、token 用量、命中率、错误率 | 大盘告警 |
| Feedback(反馈) | 用户 👍/👎、人工抽检、显式评分 | 灌回评估集,迭代模型 |
LangSmith / Langfuse / Arize Phoenix / MLflow —— 任选一套,别裸跑。
4. 定制化评估
通用指标(如”语义相似度”)往往对不上业务。业务说答得好,才算真的好。
- 领域专家打分:法务/医生/客服主管按业务标准 1~5 分
- 规则化校验:必须出现某字段、必须引用某类来源、不能出现某些词
- 行为代理指标:点赞率、复制率、追问率(用户继续问 = 没答清)
- LLM-as-a-Judge:用强模型当裁判,但必须用黄金集校准,否则裁判自己也在飘
5. 量化(Quantization)
把模型/向量的”高精度数值”换成”低精度表示”,省显存、省钱、省延迟。
| 对象 | 方法 | 效果 |
|---|---|---|
| Embedding 模型 | int8 / binary | 向量库内存 ↓ 4~32x,召回略降 |
| LLM | GPTQ / AWQ / GGUF | 显存 ↓ 2~4x,速度 ↑,质量微损 |
| 向量存储 | Product Quantization (PQ) | 千万级向量单机可跑 |
召回率/生成质量会有 1~3% 的下降,必须在黄金集上回归,别拍脑袋上生产。
6. 成本 VS 响应质量
1 | 质量 ▲ |
常见省钱策略:
- 模型路由:简单问题 → 小模型/规则,复杂问题 → 大模型
- 缓存:相同 query 命中直接返回,省一次 LLM
- 减 token:精排压到 Top-3、截断长文档、用更小 context
- 批处理 / 异步:非实时任务合并请求
把”质量提升 1% 要多花 10 倍钱”这种点找到,就是工程优化的 ROI 关键。
7. 延迟 VS 响应质量
1 | 首字延迟 ▲ |
生产对延迟的硬要求:
| 场景 | 目标首字延迟 |
|---|---|
| 聊天/搜索 | < 1s |
| 客服自动回复 | < 2s |
| 离线分析 | 不敏感 |
手段:流式输出(SSE)、并行检索(向量+BM25 并发)、精排前置、speculative decoding。
8. 安全性
RAG 的攻击面 = 检索器 + LLM,两头都要防:
| 风险 | 例子 | 防御 |
|---|---|---|
| Prompt Injection | 用户问题里塞”忽略上面所有指令” | 输入清洗 + 指令/数据严格分段 |
| 数据泄露 | 检索返回了别人私有文档 | 元数据 ACL 过滤 + 租户隔离 |
| 越权回答 | 内部 wiki 答给了外部用户 | 权限网关 + 来源水印 |
| 幻觉 | 编造不存在的资产 | 强制引用 + “找不到就说没有” |
| 有毒输出 | 检索到恶意文本被 LLM 复述 | 内容审核 + 输出过滤 |
只能在 输入清洗 + 输出审查 + 权限隔离 三层一起做,单点防御都会被绕。
9. 多模态检索增强生成
RAG 不止能喂文字。能检索/生成的模态越多,应用场景越广:
1 | 文本 ←─────► 文本 (最常见,问答/搜索) |
关键技术:
- 统一 Embedding:CLIP / SigLIP / BGE-M3,把多模态映射到同一向量空间
- 多模态 LLM:GPT-4o、Gemini、Qwen-VL,能看图、能听音、能读文档
- 结构化解析:PDF 表格、扫描件、Chart → 用专用模型转 Markdown/JSON 再进 RAG
先把 PDF/PPT/截图全部 OCR + 结构化 → 转成文本 + 图块 → 进同一个向量库。一个 RAG 系统吃下企业全部知识资产。
生产 RAG = 评估体系 + 可观测性 + 工程权衡 + 安全合规 + 多模态扩展。技术之外,工程化能力决定了它能不能真正”活下去”。
八、参考资料
- [[20260522.SearchToolDesign(Private)]]:资产搜索工具完整设计方案
- [[20260521.ArtPipelineAIIntegration(Private)]]:上层 AI Pipeline 集成文档
- 吴恩达Rag课程 导师Zain
- Zain Rag课程正版链接
我本地的仓库位置 D:\Project\UGit\starting-ragchatbot-codebase