文章目录
- [1. 关键词检索和语义检索](#1. 关键词检索和语义检索)
-
- [1.1 关键词检索](#1.1 关键词检索)
- [1.2 语义检索](#1.2 语义检索)
- [2. 标准工作链路](#2. 标准工作链路)
- [3. 核心原理](#3. 核心原理)
-
- [3.1 Embedding 向量](#3.1 Embedding 向量)
- [3.2 向量相似度](#3.2 向量相似度)
-
- [3.2.1 欧氏距离](#3.2.1 欧氏距离)
- [3.2.2 原始点积](#3.2.2 原始点积)
- [3.2.3 余弦相似度](#3.2.3 余弦相似度)
- [4. 向量索引检索器 API](#4. 向量索引检索器 API)
-
- [4.1 VectorIndexAutoRetriever (向量存储自动检索器)](#4.1 VectorIndexAutoRetriever (向量存储自动检索器))
- [4.2 VectorIndexRetriever(向量索引标准检索器)](#4.2 VectorIndexRetriever(向量索引标准检索器))
- [5. 案例案例](#5. 案例案例)
-
- [5.1 构建向量索引](#5.1 构建向量索引)
- [5.2 构建向量检索器](#5.2 构建向量检索器)
-
- [5.2.1 方式一:快捷方法 as_retriever()](#5.2.1 方式一:快捷方法 as_retriever())
- [5.2.2 方式二:显式实例化 VectorIndexRetriever](#5.2.2 方式二:显式实例化 VectorIndexRetriever)
- [5.2.3 方式三:智能自动检索器 VectorIndexAutoRetriever](#5.2.3 方式三:智能自动检索器 VectorIndexAutoRetriever)
- [5.3 执行检索](#5.3 执行检索)
1. 关键词检索和语义检索
1.1 关键词检索
BM25、TF‑IDF 都属于关键词检索(词法检索),只做字面词汇匹配:
- 识别不了同义词 :
开心和愉悦语义完全相同,但关键词检索会判定二者不匹配; - 无法处理一词多义:同一个词语放在不同句子里意思不一样,词法检索只会单纯判定词汇命中;
- 用户换一套话术提问,就找不到对应的文档。
关键词检索只在乎单词是否出现过 ,并不读懂文字背后真正的语义。想要解决这个短板,就要依靠语义检索。
1.2 语义检索
语义检索,是不局限于文字表面的词汇匹配 ,去理解用户查询和文档内在含义、意图,基于语义相似度完成内容召回的检索方式。
核心实现原理:
- 通过
Embedding嵌入模型,将问句、文档转换成高维稠密向量; - 在向量空间中,语义相近的文本对应的向量距离更近;
- 使用余弦相似度等方式计算向量相似度,筛选并排序最相似的文档作为检索结果。
语义检索不再依赖字面关键词比对:即便查询和文档用词完全不一样,只要含义相近,就可以成功匹配,捕捉关键词检索识别不到的细微语义差别。
关键词检索与语义检索都会把文本转为向量,再计算相似度打分,差异只在于向量怎么生成:
- 关键词检索 (
TF‑IDF/BM25):通过统计词频构造稀疏向量; - 语义检索 (
Embedding):使用预训练嵌入模型生成稠密向量。
2. 标准工作链路

工作链路说明:
- 文本输入 :准备知识库原始文档
Documents,接收用户查询语句Prompt; - 向量化处理 :将文档与用户提问送入同一个
Embedding Model(嵌入模型),把自然语言转换为计算机可运算的高维向量; - 映射至向量空间 :全部向量落在同一多维向量空间内,语义相近的文本,向量空间距离更近;
- 相似度排序召回 :计算查询向量和文档向量的距离,按照相似度从高到低排序,返回距离最近的
Top‑K相关文档,完成语义检索。
核心逻辑:不再匹配字面词汇,依靠向量空间距离判断文本语义相似度。
3. 核心原理
3.1 Embedding 向量
嵌入模型可以将任意粒度的文本(词语、句子、段落、长文档)映射为高维空间中的坐标点,通过一组数值组成的向量承载文本的语义信息。
- 向量空间核心规则:语义含义越相近的两段文本,在向量空间中的空间距离越近;文本语义差异越大,向量之间的距离也就越远。
- 向量维度说明 :二维、三维坐标仅用于可视化展示。实际工程落地中,向量维度通常在 100 ~ 1000维以上;更高的维度可以捕捉更细粒度的语义差别,提升区分效果。
- 多粒度编码能力:嵌入模型支持对不同长度的文本生成独立向量,无论是单个词汇、短句段落,还是完整长文档,都可以得到唯一对应的语义向量。
示例:
- 句子
1:他在课堂上轻声说话 - 句子
2:上课时他压低声音低语
两句话用词并不完全相同,但表达的含义高度一致,二者生成的向量在空间中距离很近;而和语义无关的文本,向量距离会显著拉大。
3.2 向量相似度
在通过嵌入模型得到查询向量和文档向量之后,我们需要一种量化规则,用来判断两段文本语义的相近程度。
三种向量相似度衡量方式:
| 度量指标 | 取值范围 | 向量同向 | 向量垂直 | 向量反向 | 核心关注点 | 适用场景 |
|---|---|---|---|---|---|---|
| 欧氏距离 | [ 0 , + ∞ ) [0,+\infty) [0,+∞) | 距离很小 | 中等距离 | 距离很大 | 空间绝对直线距离 | 低维向量场景,文本检索极少使用 |
| 原始点积 | ( − ∞ , + ∞ ) (-\infty,+\infty) (−∞,+∞) | 正数 | 0 0 0 | 负数 | 方向 + 向量长度共同打分 | 向量模长携带业务权重的特殊场景 |
| 余弦相似度 | − 1 , 1 -1,1 −1,1 | 1 1 1 | 0 0 0 | − 1 -1 −1 | 仅关注向量方向,忽略模长 | 通用语义检索、RAG知识库问答 |
3.2.1 欧氏距离
欧氏距离计算两个向量在高维空间中的直线几何距离。
- 取值范围: [ 0 , + ∞ ) [0,+\infty) [0,+∞)
- 判定规则:数值越小,向量在空间上越靠近,语义相似度越高;数值越大,语义差异越大。
- 特点:关注向量完整的空间坐标差异,同时兼顾方向与模长。
- 局限:高维场景下距离区分效果变差,RAG 语义检索中并不常用。
欧氏距离,就是高维空间中两个向量点之间的直线长度,用来衡量两点在空间里相隔多远。
公式( n 维向量):
d ( a , b ) = ∑ i = 1 n ( a i − b i ) 2 d(a,b)=\sqrt{\sum_{i=1}^n(a_i-b_i)^2} d(a,b)=i=1∑n(ai−bi)2
- 把两个向量每一维坐标依次相减、平方后全部累加,最后开平方根,得到直线距离。
- 取值范围: [ 0 , + ∞ ) \boldsymbol{[0,+\infty)} [0,+∞)
- d = 0 d=0 d=0:两个点完全重合,向量一模一样
- 数值越小 → 空间位置越近 → 语义相似度越高
- 数值越大 → 空间位置越远 → 语义差异越大
直观理解(二维平面),平面上 3 个点 A 、 B 、 C A、B、C A、B、C:
- A A A 和 B B B 靠得很近,欧氏距离短,语义相似
- A A A 和 C C C 相隔很远,欧氏距离长,语义差别大

3.2.2 原始点积
原始点积 将两个向量对应维度的值逐一相乘后累加求和,最终计算分值同时受向量方向 与向量模长(长度)双重因素共同影响。
- 取值范围: ( − ∞ , + ∞ ) \boldsymbol{(-\infty,+\infty)} (−∞,+∞)
- 判定规则:向量同向时计算结果为正数,互相垂直时值等于
0,方向相反时结果为负数;在方向保持一致的前提下,向量模长越大,最终得分越高。 - 特点:最终分数自带向量长度带来的权重增益,更长文本生成的大模长向量更容易获得更高的匹配分值。
- 局限:相似度评分会被文本长度干扰,无法公平对比长短不一的文本;仅适合向量模长本身具备业务权重含义的特殊场景。
公式( n 维向量):
a ⋅ b = ∑ i = 1 n a i b i \boldsymbol a \cdot \boldsymbol b=\sum_{i=1}^n a_ib_i a⋅b=i=1∑naibi
举例:向量 10 , 10 10,10 10,10 与 100 , 100 100,100 100,100,两个向量的指向方向完全相同,但后者向量模长更大,因此原始点积的计算结果会明显更高。
3.2.3 余弦相似度
余弦相似度 本质计算两个向量之间的夹角,对点积做归一化处理,剔除向量长度带来的影响,只关注向量的方向。
公式:
cos θ = a ⋅ b ∥ a ∥ ∥ b ∥ \cos\theta=\frac{\boldsymbol a \cdot \boldsymbol b}{\Vert a\Vert\Vert b\Vert} cosθ=∥a∥∥b∥a⋅b
- 取值范围: − 1 , 1 -1,1 −1,1
- 判定规则:分值等于
1代表方向完全一致;分值等于0代表向量互相垂直,语义无关;分值等于-1代表语义完全相反。分数越靠近1,语义相似度越高。 - 关键等价关系:当向量执行 L2 归一化 (强制所有向量模长=
1),归一化后的点积 = 余弦相似度。向量数据库底层经常使用该特性加速计算,效果不变,性能更高。 - 适用场景:RAG、语义检索的首选方案,不受句子长短影响,只判断语义是否相近。
示例,二维平面中有两个向量:红色点 10 , 10 \boldsymbol{10,10} 10,10、蓝色点 100 , 100 \boldsymbol{100,100} 100,100
- 两个点从原点出发,在同一条射线上,夹角 θ = 0 \boldsymbol{\theta=0} θ=0,方向完全一致
- 两个向量长度差别巨大: 100 , 100 100,100 100,100 的向量明显更长
- 余弦相似度只看夹角,不关心两点在空间上离得远不远

4. 向量索引检索器 API
向量检索器是 RAG 体系中负责稠密语义召回的核心组件,通过计算查询向量与文档向量的空间相似度,从向量库中召回语义最相关的文档片段。
4.1 VectorIndexAutoRetriever (向量存储自动检索器)
父类:BaseAutoRetriever
面向向量索引的检索组件,依靠大模型自动生成向量查询参数(自动推导过滤条件、召回条数),无需人工硬编码过滤规则。
参数列表:
| 参数 | 类型 | 说明 | 默认值 |
|---|---|---|---|
| index | VectorStoreIndex | 向量存储索引实例 | 必填 |
| vector_store_info | VectorStoreInfo | 描述向量库内容、支持哪些元数据过滤字段;LLM依靠这段自然语言描述自动生成查询条件 | 必填 |
| prompt_template_str | Optionalstr | 自定义LLM提示词模板;传空则使用内置默认模板 | None |
| similarity_top_k | int | 默认召回文档条数 | DEFAULT_SIMILARITY_TOP_K |
| empty_query_top_k | Optionalint | 当LLM推导出来的查询文本为空(仅使用元数据过滤)时,返回的文档数量;为 None 时复用 similarity_top_k |
10 |
| max_top_k | int | top_k 上限值;LLM输出的召回条数不会超过该值 | 10 |
| vector_store_query_mode | str | 向量查询模式,完整取值参考 VectorStoreQueryMode |
DEFAULT |
| default_empty_query_vector | OptionalList\[float] | 空查询时使用的默认向量;查询文本为空时使用该向量检索 | None |
| callback_manager | OptionalCallbackManager | 回调管理器,用于链路追踪与埋点 | None |
| verbose | bool | 是否打印详细调试日志 | False |
4.2 VectorIndexRetriever(向量索引标准检索器)
父类:BaseRetriever
常规向量检索实现,参数由开发者手动固定传入 ,是日常 RAG 最基础的召回组件。
参数列表:
| 参数 | 类型 | 说明 | 默认值 |
|---|---|---|---|
| index | VectorStoreIndex | 向量存储索引实例 | 必填 |
| similarity_top_k | int | 召回相似度最高的前K条文档 | DEFAULT_SIMILARITY_TOP_K |
| vector_store_query_mode | str | 向量查询模式,完整取值参考 VectorStoreQueryMode |
DEFAULT |
| filters | OptionalMetadataFilters | 元数据过滤条件 | None |
| alpha | float | 稀疏/稠密混合检索权重,仅在混合检索模式生效 | None |
| doc_ids | OptionalList\[str] | 限定仅在指定文档ID列表内检索 | None |
| vector_store_kwargs | dict | 查询时透传给向量数据库的自定义扩展参数 | 必填 |
5. 案例案例
5.1 构建向量索引
在LlamaIndex 系列【13】索引存储:SimpleIndexStore中已经介绍过怎么构建向量索引。
直接从之前的持久化目录中加载:
python
loaded_storage_context = StorageContext.from_defaults(persist_dir="./storage")
vector_index = VectorStoreIndex(storage_context=loaded_storage_context)
5.2 构建向量检索器
LlamaIndex 提供了三种构建向量检索器的方式,分别适配快速原型开发、生产级精细化控制、智能动态查询三类典型场景。
5.2.1 方式一:快捷方法 as_retriever()
这是最简洁的构建方式,直接调用 VectorStoreIndex 内置的工厂方法生成检索器,内部自动注入索引实例并封装默认参数,代码量最少,适合快速验证与原型开发。
python
# 最简写法:使用全局默认 top_k 与标准查询模式
vector_retriever = vector_index.as_retriever()
# 带基础参数配置写法
vector_retriever = vector_index.as_retriever(
similarity_top_k=3,
vector_store_query_mode="default"
)
说明
- 内部本质:对
VectorIndexRetriever构造函数的封装,自动传入当前index实例; - 常用可配置项:
similarity_top_k控制召回结果条数,vector_store_query_mode指定向量查询模式; - 适用场景:业务规则简单、无需复杂过滤的标准
RAG场景,以及快速验证检索效果的开发阶段。
5.2.2 方式二:显式实例化 VectorIndexRetriever
手动实例化标准向量检索器,开放完整参数配置能力,支持自定义元数据过滤、混合检索权重、文档范围限定等高级能力,是生产环境做性能调优与业务管控的首选方式。
python
from llama_index.core.indices.vector_store.retrievers.retriever import VectorIndexRetriever
from llama_index.core.vector_stores.types import (
MetadataFilters,
MetadataFilter,
FilterOperator
)
# 定义前置元数据过滤条件
filters = MetadataFilters(
filters=[
MetadataFilter(key="doc_type", value="product", operator=FilterOperator.EQ)
]
)
vector_retriever = VectorIndexRetriever(
index=vector_index, # 绑定目标向量索引实例
similarity_top_k=4, # 召回相似度 Top 4 的文档片段
filters=filters, # 检索前按元数据过滤文档范围
alpha=0.5, # 混合查询模式下稀疏/稠密检索的权重系数
doc_ids=["doc_001", "doc_002"], # 强制限定仅在指定文档范围内检索
vector_store_query_mode="default",# 向量库查询模式
vector_store_kwargs={} # 透传给底层向量数据库的扩展参数
)
说明
- 核心优势:参数完整可控,支持过滤、范围隔离、权重调优等高级配置,满足生产环境的精细化需求;
- 兼容性:输出标准
List[NodeWithScore]结构,与BM25等其他检索器完全对齐,可直接接入混合检索链路; - 适用场景:生产环境性能调优、多租户数据隔离、按业务维度定向检索等场景。
5.2.3 方式三:智能自动检索器 VectorIndexAutoRetriever
基于大语言模型自动解析用户自然语言查询,动态生成元数据过滤条件与召回数量,无需人工硬编码过滤规则,适合元数据维度多、查询条件灵活多变的前台业务场景。
python
from llama_index.core.indices.vector_store.retrievers.auto_retriever.auto_retriever import VectorIndexAutoRetriever
from llama_index.core.vector_stores.types import VectorStoreInfo
# 向 LLM 描述向量库的内容边界与元数据字段定义
vector_store_info = VectorStoreInfo(
content_info="企业内部知识库,涵盖产品手册、运维规范、架构设计三类文档",
metadata_info=[
{"name": "category", "type": "string", "description": "文档分类:product / ops / architecture"},
{"name": "version", "type": "integer", "description": "文档版本号,取值 1、2、3"},
{"name": "department", "type": "string", "description": "负责部门:研发 / 运维 / 产品"}
]
)
vector_retriever = VectorIndexAutoRetriever(
index=vector_index,
vector_store_info=vector_store_info,
similarity_top_k=2, # 默认召回条数基准值
max_top_k=6, # LLM 动态调整召回条数的上限
empty_query_top_k=10, # 纯元数据过滤、无查询文本时的召回条数
verbose=False
)
说明
- 执行链路:用户自然语言提问 →
LLM解析并提取过滤条件、召回数量 → 组装标准向量查询 → 执行检索返回结果; - 适用场景:面向终端用户的开放式检索、多维度智能筛选问答、低代码配置型知识库系统;
- 注意事项:检索过程会额外产生一次
LLM调用,接口延迟与调用成本略高于普通向量检索器。
5.3 执行检索
检索器构建完成之后,统一调用 retrieve() 方法执行召回逻辑。LlamaIndex 对所有继承自 BaseRetriever 的检索组件提供完全一致的调用接口 ,向量检索器、BM25 检索器、图谱检索器、混合检索器均可使用同一套调用方式,返回标准化结果对象 List[NodeWithScore]。
直接传入字符串问句执行检索,是业务开发中最常用的调用形式。
python
# 传入自然语言,执行召回
retrieval_result = vector_retriever.retrieve("简述产品部署流程")
# 遍历打印检索结果
for item in retrieval_result:
print(f"匹配得分:{item.score:.4f}")
print(f"文档内容:{item.node.text}")
print(f"元数据信息:{item.node.metadata}\n")
返回对象说明
List[NodeWithScore]:检索结果列表,按匹配分数从高到低排序item.score:相似度 /BM25匹配分值item.node:原始文档块对象,包含文本text、唯一标识node_id、业务元数据metadata