AI- RAG笔记03 - 索引构建
1、导读
本文学习来源 all-in-rag
个人学习笔记整理总结,有错误或者遗漏希望大家指正
本章主要讨论
- Embedding 负责把数据变成语义向量
- Vector Store / Vector DB 负责存储和检索向量
- Index Optimization 负责让检索结果更准、更完整、更可控
2、Embedding
What
Embedding 是把数据源(文本、图片、音频等)映射成语义向量的过程,输出结果通常是一个 Vector。
也可以理解为:把原始数据映射到一个固定维度、稠密、可计算的数字空间中,每个数据块对应一个向量。
例子:
文本:"RAG是检索增强生成"
→ 向量:[0.12, -0.03, 0.55, ...] # 高维向量
这些向量捕捉了 语义信息,而不仅仅是字面字符。
Why
- 语义搜索
- 原始文本无法直接比较相似度(字符串相似不等于语义相似)
- 向量空间里可以用 距离度量(cosine similarity / L2) 找语义最接近的数据
- cosine similarity 更关注向量方向,L2 更关注空间距离
- 例子:
- “苹果是水果” 和 “香蕉也是水果” → 语义接近 → 向量距离近
- “苹果是水果” 和 “计算机芯片” → 语义不接近 → 向量距离远
- 高效检索
- 向量可以建索引(FAISS / Milvus / Chroma)
- 支持 Top-K 检索:快速找到最相关的数据块
- 原始文本无法高效做大规模相似度搜索
- 统一处理多模态
- 文本、图像、音频都可以转向量
- 但要注意:跨模态检索需要使用已经做过模态对齐的多模态 Embedding 模型
- 这样才可以在同一个向量空间里进行跨模态检索,并把检索结果提供给后续生成模型使用
- 例子:文本查询 → 找相关图片 → 用 CLIP embedding
How
- 不同模态先做不同预处理:文本通常用 Tokenizer 变成 token,图像/音频会经过对应的视觉或音频编码处理
- Embedding 模型神经网络将输入映射成向量
- 对文档块向量进行处理,并且存储进向量数据库
- 用户查询时,也要用同一个或兼容的 Embedding 模型编码成查询向量
- 最后比较查询向量和文档向量的相似度,返回 Top-K 相关数据块
2.1 向量嵌入
核心理解:
-
Embedding 的本质是语义坐标
- 每个文本块都会被模型映射成一个固定维度的向量
- 这个向量可以理解成文本在语义空间里的坐标
- 语义相近的文本,向量距离更近;语义不相关的文本,向量距离更远
-
RAG 中的向量嵌入流程
- 离线阶段:文档 → 切分 Chunk → Embedding 模型编码 → 文档向量 → 存入向量数据库
- 在线阶段:用户问题 → 同一个 Embedding 模型编码 → 查询向量 → 和文档向量做相似度搜索
- 检索结果:返回 Top-K 最相似 Chunk,作为上下文交给 LLM
-
关键点:文档和问题必须在同一个语义空间
- 建库时用的 Embedding 模型,查询时也要用同一个或兼容模型
- 如果文档向量和查询向量不是同一个模型生成的,相似度比较就不可靠
向量相似度:
- Cosine Similarity:看两个向量方向是否接近,越接近 1 越相似,文本语义检索常用
- Dot Product:点积,向量归一化后可以近似等价于 cosine similarity
- Euclidean Distance / L2:看两个向量在空间中的直线距离,距离越小越相似
Embedding 技术发展:
可以理解成:向量表示从“符号匹配”一步步走向“语义理解”。
-
稀疏表示
- 代表:One-hot、Bag of Words、TF-IDF
- 特点:把词当成离散符号,通常是很长、很稀疏的向量
- 例子:苹果 =
[0, 0, 1, 0, ...],香蕉 =[0, 1, 0, 0, ...] - 问题:机器只知道它们是不同词,不知道“苹果”和“香蕉”都属于水果
- 本质:能做字面统计,但很难理解语义关系
-
静态词嵌入
- 代表:Word2Vec、GloVe
- 特点:每个词对应一个固定的稠密向量
- 怎么学:如果两个词经常出现在相似上下文里,模型就认为它们语义接近
- 优点:开始能表达词语之间的语义关系
- 问题:不能处理一词多义
- 例子:“苹果公司”和“吃苹果”里的“苹果”会共享同一个向量
-
动态上下文嵌入
- 代表:BERT、RoBERTa
- 特点:同一个词在不同上下文中可以得到不同表示
- 怎么做:Transformer 的 Self-Attention 会让词关注句子里的其他词
- 例子:
- “我吃了一个苹果”里的“苹果”会受到“吃了”的影响
- “苹果公司发布了新手机”里的“苹果”会受到“公司、手机”的影响
- 解决的问题:让模型不只理解词本身,还理解词所在语境
-
面向检索的 Embedding
- 代表:SBERT、DPR、E5、BGE 等
- 目标:不只是理解一句话,而是判断“问题”和“文档块”是否匹配
- 例子:
- 问题:FAISS 是做什么的?
- 文档:FAISS 是用于高效相似性搜索和向量聚类的库
- 如果这两段语义相关,它们的向量就应该更近
- RAG 里常用的 Embedding 模型,通常是这种专门为检索优化过的向量模型
嵌入模型训练原理:
核心目标:让模型学会把语义相近的内容放近,把语义不相关的内容推远。
-
自监督预训练:先学语言理解
- 不需要人工标注,模型从大量文本中自己学习语言规律
MLM(Masked Language Model)
- 随机遮住文本中的部分 token
- 让模型根据上下文预测被遮住的词
- 例子:
RAG 是 [MASK] 增强生成,模型要预测[MASK]是“检索” - 作用:学习词和上下文之间的关系
NSP(Next Sentence Prediction)
- 判断句子 B 是否是句子 A 的下一句
- 作用:学习句子之间的连贯性和主题关系
- 注意:后续很多模型不一定继续使用 NSP,比如 RoBERTa 移除了这个任务
-
面向检索的训练:再学匹配关系
- RAG 更关心的是:用户问题和哪个文档块匹配
- 训练数据通常是三元组:
- Anchor:用户问题
- Positive:正确相关文档
- Negative:不相关文档
例子:
- Anchor:FAISS 是做什么的?
- Positive:FAISS 是用于相似性搜索和向量聚类的库
- Negative:Python 是一种编程语言
-
度量学习
- 直接优化向量空间里的距离关系
- 目标是让相关文本更近,不相关文本更远
- 重点不是追求绝对相似度,而是优化排序关系
-
对比学习
- 本质还是“拉近正例,推远负例”
- 训练目标:
sim(query, positive)更高sim(query, negative)更低
- 这对 RAG 很关键,因为检索时就是要把正确文档排到前面
-
Hard Negative(困难负例)
- 指看起来相关,但不是正确答案的负例
- 例子:
- 问题:FAISS 是做什么的?
- 困难负例:Milvus 是一个向量数据库
- 它们都和向量检索有关,但答案并不一样
- 用困难负例训练,可以让模型学会更细粒度地区分“相似但不正确”的内容
RAG 对 Embedding 的要求:
- 领域适配:法律、医疗、金融等专业场景,通用模型可能不够
- 多粒度支持:要能处理短句、段落、长文档、代码、表格等
- 检索效率:向量维度越大,表达能力可能更强,但存储和计算成本也更高
- 多模态支持:真实知识库可能不只是文本
- 混合检索能力:向量检索可以理解语义,但关键词精确匹配也很重要
模型选型:
- 可以先看 MTEB 排行榜,但不能只看总分
- RAG 场景重点看 Retrieval 任务表现
- 中文场景要看中文或多语言支持
- 要关注模型大小、向量维度、最大 token 长度、推理速度、部署成本
- 最终还是要用自己的业务数据做测试,因为公开榜单不等于真实业务效果
向量嵌入是 RAG 检索的语义基础。它决定了问题和文档能不能在向量空间中正确“相遇”。如果 Embedding 模型理解不好,后面的向量数据库再快也只是快速找错内容。
2.2 多模态嵌入
多模态嵌入解决的是:不同类型的数据如何进入同一个语义空间。
为什么需要多模态嵌入:
- 现实世界的信息不只有文本,还有图片、音频、视频、表格、截图等
- 普通文本 Embedding 只能理解文本,不能直接理解图片内容
- 如果文本向量和图片向量不在同一个空间里,它们之间的相似度没有意义
- 多模态嵌入的目标就是打破这堵“模态墙”
核心目标:
- 把文本、图像等不同模态映射到同一个共享向量空间
- 在这个空间中,语义相关的文本和图片应该距离更近
- 例子:
- 文本:“一只奔跑的狗”
- 图片:一张狗正在奔跑的图片
- 这两个向量应该接近
关键难点:跨模态对齐
- 模型要学会哪段文本描述哪张图片
- 也要学会哪些图文只是表面相关,但语义不匹配
- 常用技术:Transformer、视觉 Transformer(ViT)、对比学习
- 本质:让不同模态的数据虽然输入形式不同,但输出向量可以在同一个空间中比较
CLIP 的核心思想:
-
双编码器架构
- 图像编码器:把图片编码成图像向量
- 文本编码器:把文本编码成文本向量
- 两个编码器输出到同一个共享向量空间
-
对比学习训练
- 正确的图文对:向量相似度要更高
- 错误的图文对:向量相似度要更低
- 本质还是“拉近正例,推远负例”
- 例子:
- 图片:一只狗在草地上奔跑
- 正确文本:一只狗在草地上奔跑 → 拉近
- 错误文本:一辆红色汽车 → 推远
- 错误文本:一只猫坐在沙发上 → 推远
-
零样本能力
- CLIP 可以把分类任务转成图文相似度匹配
- 例子:判断一张图是不是猫
- 图片向量 vs “a photo of a cat”
- 图片向量 vs “a photo of a dog”
- 哪个文本相似度更高,就更可能是哪一类
bge-visualized-m3:
- 它是在 BGE-M3 文本嵌入模型基础上加入图像能力的多模态模型
- 目标是让文本和图像可以进入统一向量空间,用于图文检索
- M3 主要继承自 BGE-M3:
- Multi-Linguality:多语言能力
- Multi-Functionality:多功能检索能力,比如密集检索、多向量检索
- Multi-Granularity:多粒度能力,可以处理短文本到长文档
bge-visualized-m3 的大致流程:
- 文本经过 tokenizer,变成文本 token
- 图像经过视觉编码器,提取 patch token
- 图像 token 被映射到和文本 token 相同维度
- 图像 token 和文本 token 一起进入 BGE 的 Transformer 编码器
- 最终得到统一的多模态向量表示
应用场景:
- 以文搜图:输入文字,找相关图片
- 以图搜图:输入图片,找相似图片
- 图文组合检索:输入图片加文本,找更精确的结果
- 多模态 RAG:知识库里有文本、图片、截图、表格等内容时,可以一起检索
多模态嵌入不是简单地“文本也转向量、图片也转向量”,重点是这些向量必须被对齐到同一个语义空间。
只有这样,文本查询和图片内容之间的相似度才有意义。
3、Vector
3.1 向量数据库
向量数据库解决的问题是:Embedding 已经把数据变成向量了,但当向量数量变多以后,怎么快速找到和查询最相似的向量。
为什么需要向量数据库:
- 原始文本、图片、音频不能直接做大规模语义搜索
- Embedding 模型把它们变成向量后,就可以计算相似度
- 但如果有几百万、几千万甚至更多向量,暴力两两计算会很慢
- 向量数据库通过专门的索引结构,让相似性搜索变快
在 RAG 里,向量数据库扮演的是“外部知识库”的角色:
文档 / 图片 / 表格
→ Embedding 模型编码成向量
→ 向量数据库存储向量和元数据
→ 用户问题也编码成向量
→ 向量数据库返回 Top-K 相关内容
→ LLM 根据这些内容生成答案
向量数据库主要能力:
-
高效相似性搜索
- 根据查询向量,找到最相似的 Top-K 向量
- 核心是 ANN(Approximate Nearest Neighbor,近似最近邻)检索
- ANN 不是暴力找绝对最精确结果,而是在速度和召回率之间做平衡
-
存储向量和元数据
- 向量字段:存 Embedding 结果
- 标量字段:存原始文本、图片路径、标题、类别、时间等
- 检索时通常是先找到向量,再通过元数据找回原始内容
-
支持过滤查询
- 不只是“找最相似”,还可以加条件
- 例子:只搜索 2024 年以后的文档,只搜索某个分类下的图片
-
支持索引优化
- 用 HNSW、IVF、PQ、LSH 等索引结构加速检索
- 不同索引适合不同规模和性能要求
-
和 RAG 框架集成
- LangChain、LlamaIndex 都可以接 FAISS、Milvus、Chroma 等向量存储
向量数据库 vs 传统数据库:
传统数据库更擅长:
- 精确查询:
id = 1 - 条件过滤:
year > 2023 - 事务、表关系、结构化数据管理
向量数据库更擅长:
- 相似性搜索
- 高维向量检索
- 语义搜索
- 推荐、RAG、图像检索、多模态检索
两者不是替代关系,而是互补关系:
传统数据库:存业务数据、交易数据、结构化信息
向量数据库:存 Embedding 向量和检索元数据
ANN 的几类常见方法:
-
基于树
- 例子:Annoy 的随机投影树
- 思路:用树结构不断缩小搜索范围
-
基于哈希
- 例子:LSH
- 思路:让相似向量更可能落到同一个桶里
-
基于图
- 例子:HNSW
- 思路:构建邻近图,查询时沿着图快速跳到相似区域
-
基于量化
- 例子:IVF、PQ
- 思路:通过聚类和压缩降低存储与计算成本
主流向量数据库 / 向量存储:
- FAISS:本地向量检索库,轻量、高效,适合学习和原型
- Chroma:轻量级本地向量数据库,适合小项目和快速实验
- Milvus:生产级开源向量数据库,适合大规模、高性能、多索引场景
- Qdrant:Rust 实现,性能好,过滤能力强
- Weaviate:支持 GraphQL 和 AI 模块,集成能力强
- Pinecone:托管型云向量数据库,少运维,适合生产快速接入
FAISS:
FAISS 全称是 Facebook AI Similarity Search,本质上更像是一个本地向量检索库 / 向量索引库,不是完整的数据库服务。
FAISS 负责:
- 存储向量索引
- 构建相似性搜索结构
- 根据查询向量返回最相似的向量
FAISS 不负责完整数据库能力:
- 没有独立服务端
- 没有用户权限系统
- 不主打分布式和高可用
- 元数据管理要依赖框架补充
LangChain + FAISS 示例理解:
02_langchain_faiss.py 的流程:
文本列表
→ Document
→ HuggingFaceEmbeddings 编码成向量
→ FAISS.from_documents 建本地向量索引
→ save_local 保存到本地
→ load_local 重新加载
→ similarity_search 查询 Top-K
跑完后生成了两个文件:
faiss_index_store/
index.faiss
index.pkl
两个文件的作用:
index.faiss:FAISS 的核心向量索引文件,负责相似性搜索index.pkl:LangChain 保存的文档映射和元数据,用来把向量 id 找回原始文本
LlamaIndex 本地索引示例理解:
03_llamaindex_vector.py 的流程:
文本列表
→ LlamaIndex Document
→ HuggingFaceEmbedding 编码
→ VectorStoreIndex 建索引
→ persist 保存到本地 JSON
→ StorageContext 加载
→ load_index_from_storage 恢复索引
→ retriever.retrieve 查询
LlamaIndex 持久化后生成的是更透明的 JSON 文件,例如:
docstore.json:保存原始文档 / 节点内容default__vector_store.json:保存向量和向量对应的节点 idindex_store.json:保存索引结构信息graph_store.json:图关系信息,简单例子里可能很少
和 FAISS 的区别:
FAISS:核心文件是二进制索引,更偏底层相似性搜索
LlamaIndex:持久化结构更透明,更偏 RAG 数据层和索引管理
3.2 milvus
Milvus 是一个开源的生产级向量数据库,用来做大规模向量相似性搜索。它最早由 Zilliz 发起,现在是 LF AI & Data Foundation 的顶级项目。
和 FAISS 的区别:
FAISS:本地向量检索库,适合学习和原型
Milvus:完整向量数据库服务,适合生产和大规模场景
Milvus 更像传统数据库系统:
- 有服务端
- 有 Collection
- 有 Schema
- 有索引
- 有数据持久化
- 有客户端 SDK
- 可以用 Attu 可视化
Milvus 核心概念:
-
Collection
- 类似关系型数据库里的表
- 是存储向量和元数据的顶层容器
-
Entity
- Collection 里的一条数据
- 类似表里的一行记录
-
Field
- Entity 里的字段
-
Schema
- Collection 的结构定义
- 决定有哪些字段、字段类型、向量维度、主键等
-
Partition
- Collection 内部的逻辑分区
- 可以按业务规则把数据分区,比如年份、类别、租户
- 查询时只查部分分区,可以缩小搜索范围
-
Alias
- Collection 的别名
- 常用于线上平滑切换
Milvus 索引:
Milvus 的索引是为了加速向量搜索。
常见向量索引:
-
FLAT
- 暴力搜索
- 结果最准确
- 数据量大时慢
- 适合小数据、追求 100% 召回
-
IVF
- 先把向量聚类成多个桶
- 查询时只查最可能相关的几个桶
- 速度更快,但召回率不是绝对 100%
- 适合大规模通用检索
-
HNSW
- 基于图的索引
- 通过多层邻近图快速找到相似区域
- 查询速度快,召回率高
- 内存占用相对大
-
DiskANN
- 面向磁盘 / SSD 的大规模索引
- 适合数据量大到无法完全放入内存的场景
HNSW 参数:
index_params.add_index(
field_name="vector",
index_type="HNSW",
metric_type="COSINE",
params={"M": 16, "efConstruction": 256}
)
含义:
field_name="vector":给vector字段建索引index_type="HNSW":使用 HNSW 图索引metric_type="COSINE":用余弦相似度衡量语义接近程度M:图中每个节点的最大连接数,越大可能召回越好,但更占内存efConstruction:建索引时搜索范围,越大索引质量可能越好,但构建更慢
查询时:
search_params={"metric_type": "COSINE", "params": {"ef": 128}}
ef:查询时的搜索范围,越大召回可能越高,但查询更慢
Milvus 检索类型:
-
基础 ANN Search
- 输入查询向量
- 返回最相似的 Top-K Entity
-
过滤检索
- 向量相似度 + 标量字段条件
- 例子:只查某个分类、某个年份、某个价格范围的数据
-
范围检索
- 不是固定 Top-K,而是返回相似度在某个范围内的数据
-
多向量混合检索
- 同时查多个向量字段
- 例子:文本向量 + 图片向量 + 稀疏关键词向量
- 再用 reranker 做结果融合
-
分组检索
- 按某个字段分组,避免结果都来自同一个来源
- 适合文档检索时控制结果多样性
多模态 Milvus 示例流程:
04_multi_milvus.py 完整跑通的链路:
启动 Milvus Docker 服务
→ 加载 Visualized-BGE 多模态 Embedding 模型
→ 连接 Milvus: http://localhost:19530
→ 创建 Collection: multimodal_demo
→ 定义 Schema: id / vector / image_path
→ 遍历 dragon 图片
→ 每张图片编码成 768 维向量
→ 插入 Milvus
→ 给 vector 字段创建 HNSW + COSINE 索引
→ load_collection 加载到内存
→ 用 query 图片 + 文本“一条龙”编码成查询向量
→ search 返回 Top-5 相似图片
→ 根据 image_path 找回原图
→ 生成 search_result.png
这个过程说明:
Visualized-BGE 负责理解图文语义
Milvus 负责存储向量和路径
HNSW 负责加速相似性搜索
image_path 负责把检索结果映射回原始图片
4、索引优化
索引优化解决的是:基础向量检索已经能用了,但怎么让它查得更准、上下文更完整、范围更可控。
前面普通 RAG 的流程是:
文档切块
→ Chunk 向量化
→ 向量数据库 Top-K 检索
→ 把召回内容交给 LLM
这个流程能跑,但会遇到几个问题:
- Chunk 太小:检索很准,但上下文不够,LLM 可能答不完整
- Chunk 太大:上下文够,但里面噪声也多,检索不够精准
- 知识库太大:全库 Top-K 容易被无关文档干扰
- 数据有结构:PDF 页码、Markdown 标题、Excel sheet、年份、标签等信息没有被充分利用
所以索引优化的目标不是“再换一个向量库”,而是优化:
怎么切
怎么索引
怎么过滤
怎么扩展上下文
怎么路由到正确数据源
4.1 句子窗口索引
句子窗口索引解决的是:
小块检索准,但上下文不够
大块上下文够,但检索不够准
它的核心思想是:
为检索精确性而索引小块
为生成质量而提供大上下文
也就是:
- 检索时用“单句”做向量匹配
- 生成时不用孤立单句,而是把该句前后窗口一起交给 LLM
适合场景:
- 纯文本
- 长 PDF
- 连续性强的文档
- 段落语义依赖前后文的资料
- 用户问题往往能命中某一句,但回答需要结合上下文
例如气候报告、论文、说明文档、政策文件等。
流程:
原始文档
→ 按句子切分
→ 每个句子变成一个 TextNode
→ 每个句子单独做向量索引
→ metadata 里保存前后 N 个句子的 window
→ 查询时先命中最相关句子
→ 后处理器把单句替换成 window 上下文
→ LLM 根据窗口上下文生成答案
关键组件:
-
SentenceWindowNodeParser- 把文档切成一句一句
- 每个句子作为一个 Node
- 给每个 Node 的 metadata 存入前后窗口
-
window_size- 控制前后取多少句
- 示例里是
window_size=3 - 表示命中句子的前 3 句和后 3 句也会作为窗口上下文
-
window_metadata_key- 窗口上下文存在 metadata 的哪个 key 里
- 示例里是
window_metadata_key="window"
-
original_text_metadata_key- 保存原始单句文本
- 示例里是
original_text_metadata_key="original_text"
-
MetadataReplacementPostProcessor- 检索出来的是单句 Node
- 后处理时读取 Node 的
windowmetadata - 用完整窗口替换原来的单句内容
- 最后交给 LLM 的不是孤立句子,而是一段上下文
一个重要细节:
句子窗口索引不是把整个 window 拿去做 embedding。
它是:
embedding 时:只嵌入单句
生成时:替换成 window 上下文
这样才能同时保证:
- 检索精确:因为向量对应的是一句话
- 回答完整:因为 LLM 看到的是前后窗口
和常规分块索引的对比:
常规分块索引:
文档 → 按 chunk_size 切块 → 每个 chunk 做向量索引 → 直接把 chunk 给 LLM
句子窗口索引:
文档 → 按句子切 → 每句做向量索引 → 命中后替换成前后窗口 → 给 LLM
常规索引简单直接,但 chunk 大小不好拿捏。句子窗口索引更细,适合需要“精准定位 + 补上下文”的场景。
4.2 结构化索引 / 元数据索引
结构化索引解决的是另一个问题:
知识库很大,或者数据本身有结构时,不应该全库无差别 Top-K 搜索
如果一个问题只和某个年份、某个章节、某个 sheet、某个文件相关,应该先缩小范围,再做向量检索。
适合场景:
- PDF:页码、章节、标题、作者、年份
- Markdown:一级标题、二级标题、文档路径
- Excel:sheet 名、年份、表格类别
- 多文档知识库:文件名、数据源、部门、日期、标签
- 企业知识库:权限、租户、产品线、业务分类
注意:不是说 PDF / Markdown / Excel 只能用结构化索引。
同一个 PDF 也可以做句子窗口索引。关键在于:有没有结构化 metadata 可以利用。
核心思想:
先用 metadata 缩小范围
再在小范围内做向量检索
例子:
问题:请总结 2023 年 Q2 财报中关于 AI 的论述
可以先过滤:
document_type == 财报
year == 2023
quarter == Q2
然后只在这个范围内搜索“AI 的论述”。
这比全库 Top-K 更准,也更快。
Metadata 的作用:
metadata 可以理解为给每个文本块或文档打标签。
常见 metadata:
- 文件名
- 页码
- 章节标题
- 作者
- 创建时间
- 年份
- sheet 名
- 分类标签
- 数据来源
这些信息本身不一定参与向量语义匹配,但可以用于过滤、路由和结果解释。
4.3 递归检索
递归检索是结构化索引的一种更复杂形式。
它解决的是:
数据分散在多个来源里,系统要先判断该去哪里查,再在对应来源中查具体内容
它更像“先路由,再查询”。
递归检索的思想:
用户问题
→ 顶层索引判断该进入哪个子数据源
→ 找到对应的子查询引擎 / 子索引
→ 在子数据源内部继续检索或查询
→ 返回最终答案
我的理解:
句子窗口索引和结构化索引解决的是两个不同问题:
句子窗口索引:解决上下文粒度问题
结构化索引:解决检索范围和数据路由问题
句子窗口索引适合连续文本:
先命中最相关句子,再扩展前后上下文
结构化索引适合有属性、有标签、有来源的数据:
先根据 metadata 定位范围,再在范围内检索
两者不是互斥的。生产 RAG 里完全可以结合:
先用 metadata 过滤到某个文档/章节
再在这个文档/章节内部做句子窗口检索
这样既能控制范围,又能保证上下文完整。
5、总结
5.1 Embedding
Embedding 是 RAG 检索的语义基础。
关键理解:
- 向量是语义坐标
- 语义相近,向量距离更近
- 文档和查询必须使用同一个或兼容的 Embedding 模型
- 检索模型通常通过对比学习等方式,让 query 和相关文档靠近
- 多模态 Embedding 的重点是跨模态对齐,不是简单各自转向量
5.2 向量数据库
向量数据库不是理解语义的地方。
它负责:
- 存向量
- 存元数据
- 建索引
- 做相似性搜索
- 返回 Top-K
5.3 索引优化
索引优化不是换模型,而是改变“怎么组织知识”。
句子窗口索引:
检索用小粒度单句
生成用大粒度窗口上下文
结构化索引:
先根据 metadata 缩小范围
再做向量检索或问答
递归检索:
先路由到正确数据源
再进入子数据源查询
最终目标都是:
- 查得准
- 上下文够
- 范围可控
- 噪声更少
- 结果更适合给 LLM 生成答案
AtomGit 是由开放原子开源基金会联合 CSDN 等生态伙伴共同推出的新一代开源与人工智能协作平台。平台坚持“开放、中立、公益”的理念,把代码托管、模型共享、数据集托管、智能体开发体验和算力服务整合在一起,为开发者提供从开发、训练到部署的一站式体验。
更多推荐
所有评论(0)