在Llama Index的知识库构建和检索流程中,自定义嵌入模型是优化检索效果的核心环节,而查询向量化和文本向量化作为嵌入流程的两个关键步骤,其实现逻辑和适用场景存在明显差异,理解这些差异才能正确完成自定义嵌入的配置。

查询向量化与文本向量化的核心差异
文本向量化是针对知识库中的原始文档内容进行的处理,目的是将非结构化的文本转换为固定维度的向量,存储到向量数据库中。而查询向量化是针对用户输入的检索问题进行的处理,目的是将问题转换为和文本向量同维度的向量,用于和向量库中的内容做相似度匹配。
处理对象的差异
文本向量化的处理对象是静态的知识库内容,通常在索引构建阶段一次性完成,后续除非文档更新否则不需要重复处理。查询向量化的处理对象是动态的用户输入,每次用户发起检索请求时都需要重新执行。
优化目标的差异
文本向量化更关注对文档核心语义的完整保留,确保文档的关键信息不会在向量转换过程中丢失。查询向量化更关注对问题意图的精准捕捉,需要尽可能对齐问题和相关文档的语义空间,提升匹配准确率。
是否需要特殊标记的差异
部分嵌入模型会为查询文本添加特殊的前缀标记,比如给查询内容添加query:前缀,给文档内容添加passage:前缀,帮助模型区分输入类型,提升向量匹配的准确性。如果自定义嵌入时忽略这个差异,会导致查询向量和文本向量不在同一个语义空间,检索效果大幅下降。
自定义嵌入的实践步骤
下面以自定义HuggingFace的嵌入模型为例,说明如何正确配置查询和文本两种向量化方法。
步骤1:定义自定义嵌入类
首先需要继承Llama Index的BaseEmbedding类,分别实现查询向量化和文本向量化的方法,确保两者使用不同的处理逻辑。
from llama_index.core.embeddings import BaseEmbedding
from transformers import AutoModel, AutoTokenizer
import torch
class CustomHFEmbedding(BaseEmbedding):
def __init__(self, model_name: str):
super().__init__()
# 加载本地或HuggingFace上的嵌入模型
self.tokenizer = AutoTokenizer.from_pretrained(model_name)
self.model = AutoModel.from_pretrained(model_name)
# 设置模型为评估模式
self.model.eval()
def _get_embedding(self, text: str, is_query: bool = False) -> list:
# 如果是查询文本,添加对应前缀
if is_query:
processed_text = f"query: {text}"
else:
processed_text = f"passage: {text}"
# 编码文本
inputs = self.tokenizer(processed_text, return_tensors="pt", truncation=True, padding=True, max_length=512)
# 前向传播获取向量
with torch.no_grad():
outputs = self.model(**inputs)
# 取最后一层隐藏状态的平均值作为句向量
embeddings = outputs.last_hidden_state.mean(dim=1).squeeze().tolist()
return embeddings
def _get_query_embedding(self, query: str) -> list:
# 实现查询向量化方法
return self._get_embedding(query, is_query=True)
def _get_text_embedding(self, text: str) -> list:
# 实现文本向量化方法
return self._get_embedding(text, is_query=False)
async def _aget_query_embedding(self, query: str) -> list:
# 异步查询向量化方法,根据实际需求实现
return self._get_query_embedding(query)
async def _aget_text_embedding(self, text: str) -> list:
# 异步文本向量化方法,根据实际需求实现
return self._get_text_embedding(text)
步骤2:初始化自定义嵌入模型
实例化上面定义的自定义嵌入类,指定使用的模型名称,这里以sentence-transformers/all-MiniLM-L6-v2为例。
# 初始化自定义嵌入模型 embed_model = CustomHFEmbedding(model_name="sentence-transformers/all-MiniLM-L6-v2")
步骤3:配置Llama Index使用自定义嵌入
将自定义嵌入模型传入Llama Index的Settings配置中,后续构建索引和发起检索时都会自动使用自定义的向量化方法。
from llama_index.core import Settings, VectorStoreIndex, SimpleDirectoryReader
# 设置全局嵌入模型
Settings.embed_model = embed_model
# 加载本地文档
documents = SimpleDirectoryReader("data").load_data()
# 构建向量索引,此时文本向量化会使用自定义的_get_text_embedding方法
index = VectorStoreIndex.from_documents(documents)
# 创建查询引擎,此时查询向量化会使用自定义的_get_query_embedding方法
query_engine = index.as_query_engine()
# 发起检索
response = query_engine.query("Llama Index自定义嵌入的配置步骤是什么?")
print(response)
实践注意事项
- 如果使用的嵌入模型不需要区分查询和文本前缀,也需要分别实现两个向量化方法,避免运行时报错。
- 自定义嵌入类的维度需要和向量数据库的维度匹配,比如模型输出是384维,向量数据库也需要配置为384维。
- 测试时可以先单独调用
_get_query_embedding和_get_text_embedding方法,验证输出的向量维度是否一致,避免后续检索无结果。
注意:如果使用的是云端嵌入API,比如OpenAI的嵌入接口,也需要确认是否需要对查询和文本做不同的处理,部分接口已经内部做了适配,不需要额外添加前缀。
Llama_Index自定义嵌入查询向量化文本向量化向量检索修改时间:2026-07-02 01:06:32