LlamaIndex RAG 检索:检索前-检索中-检索后
生产核心原则:
1)能下推向量库的,不要放应用层(metadata 预过滤、hybrid、MMR)
2)能放检索后的精排,不要放检索前的 LLM(Rerank 优于 HyDE 作默认)
3)注意 API 边界:PostProcessor 只在QueryEngine链路生效
特别注意:本文是通用解析,核心是检索行为发生的三个阶段,实际生产方案要还需要考虑存储是走本地还是外部向量库,数据规模是大是小,分布式环境等
检索前(Pre-Retrieval)
检索前处理的是Query 本身和检索范围,发生在第一次向量库调用之前。
Metadata 预过滤
组件:MetadataFilters+MetadataFilter
from llama_index.core.vector_stores.types import MetadataFilters, MetadataFilterfilters = MetadataFilters( filters=[ MetadataFilter(key="type", value="人物"), MetadataFilter(key="chapter", value=3, operator=">="), ], condition="and",)retriever = vector_index.as_retriever( similarity_top_k=10, filters=filters,)原理:过滤条件下推到 Pineconefilter/ Qdrantmust等向量库,在 ANN 搜索时缩小候选集。
建议:
- • 业务维度(租户、文档类型、权限、语言),用 metadata 预过滤
- • 过滤字段在 ingest 阶段标准化(枚举值、统一命名)
- • 高基数动态字段(如用户自定义 tag)谨慎做 filter,避免索引失效
文档 / 节点范围约束
组件:doc_ids、node_ids(VectorIndexRetriever参数)
retriever = vector_index.as_retriever( similarity_top_k=10, doc_ids=["doc_001", "doc_002"], # 限定文档)场景:用户已选定文档、对话上下文已锁定 ref_doc、多轮对话缩小搜索范围。
建议:优先doc_ids+ metadata filter 组合,比检索后再过滤高效得多。
Query Transform
组件:TransformQueryEngine+BaseQueryTransform
HyDE 核心逻辑:
# query_str 不变(给 LLM 合成答案仍用原问题)# custom_embedding_strs 变为 [假文档, 原query] → 检索 embedding 改变hypothetical_doc = llm.predict(hyde_prompt, context_str=query_str)| 优点 | 缺点 |
|---|---|
| 缩短 query 与文档的语义距离 | 每次 +1 次 LLM 调用 |
| 对短 query、口语化问题有帮助 | 假文档幻觉可能带偏检索 |
| 有 hybrid + rerank 后边际收益下降 |
建议:默认关闭;仅在评测数据证明有效后,对特定 query 类型(短、模糊)按需开启。
路由与多 Retriever 选择(检索前编排)
组件:
| 组件 | 作用 |
|---|---|
RouterRetriever/RouterQueryEngine | LLM 或规则选择哪个 retriever |
QueryFusionRetriever | 多 retriever 并行 + RRF 融合 |
VectorIndexAutoRetriever | LLM 自动生成 metadata filters,实验性功能,生产慎用 |
QueryFusionRetriever 参数:
QueryFusionRetriever( retrievers=[dense_retriever, bm25_retriever], mode="reciprocal_rerank", # 生产推荐 RRF num_queries=1, # 生产关闭 LLM query 扩展 similarity_top_k=10,)建议:
- •单一向量库 + native hybrid,不需要 QueryFusionRetriever
- •多数据源(向量 + SQL + 知识图谱), QueryFusionRetriever 有价值
- •
num_queries > 1, 仅 offline / 高价值场景,不作默认
Query 改写(Chat Engine 层)
组件:CondenseQuestionChatEngine等
作用:多轮对话中,把「他后来怎么样了?」改写成带上下文的完整问题。
这发生在 Chat Engine 层,严格说也在「检索前」,但是会话管理而非向量检索配置。
建议:多轮 RAG 必须做 query condensation,否则代词/省略会导致检索失败。
检索中(During Retrieval)
检索中是向量库执行 ANN / Hybrid / MMR的阶段,由VectorIndexRetriever+VectorStore.query()驱动。
核心参数
retriever = vector_index.as_retriever( similarity_top_k=30, # 返回 top-k vector_store_query_mode="default", # 查询模式 alpha=0.5, # hybrid 权重 sparse_top_k=40, # Qdrant 等支持 filters=metadata_filters, # 检索中过滤(下推) embed_model=Settings.embed_model, # query embedding 模型)内部构建的VectorStoreQuery:
VectorStoreQuery( query_embedding=..., similarity_top_k=..., query_str=..., mode=VectorStoreQueryMode.DEFAULT, alpha=..., filters=..., sparse_top_k=...,)查询模式(VectorStoreQueryMode)
| 模式 | 含义 | 生产场景 |
|---|---|---|
DEFAULT | 纯 dense 向量检索 | 最常用默认 |
HYBRID | dense + sparse 融合 | Qdrant/Weaviate/Pinecone(dotproduct) |
SPARSE | 纯 BM25/sparse | 关键词精确匹配 |
MMR | Maximum Marginal Relevance | 增加多样性,不是去重 |
TEXT_SEARCH | 全文检索 | 依赖向量库能力 |
SEMANTIC_HYBRID | 语义 + 关键词混合 | 部分向量库 |
Pinecone hybrid 为例:
- Index metric =
dotproduct - 写入/查询均
add_sparse_vector=True - 数据必须含
sparse_values alpha:dense × α,sparse × (1-α)- LlamaIndex 的
sparse_top_k对 Pinecone 无效:Pinecone 的 sparse 召回数量由统一的top_k参数控制,sparse_top_k在 Pinecone 集成中不生效,无需传入
similarity_top_k 与 hybrid_top_k
推荐:宽召回 + 精排
similarity_top_k = 20~50 (检索中,宽召回) ↓Rerank top_n = 5 (检索后,精排) ↓Synthesizer- •
similarity_top_k太小 ,漏召回 - •
similarity_top_k太大 ,rerank 慢、噪声多 - •
hybrid_top_k:部分向量库 hybrid 专用,见具体 store 文档
MMR(检索中多样性)
retriever = vector_index.as_retriever( similarity_top_k=10, vector_store_query_mode="mmr", vector_store_kwargs={ "mmr_threshold": 0.5, "mmr_prefetch_k": 20, },)作用:在相似结果间引入多样性惩罚,避免 top-k 全是雷同段落。
不是:
- • 内容去重(相同文本不同 node_id 不会去重)
- • 替代 rerank
建议:长文档、章节重复内容多时可尝试;默认链路优先 rerank。
Embedding 模型一致性
Query embedding 模型必须与 ingest 相同:
Settings.embed_model = HuggingFaceEmbedding(model_name="BAAI/bge-small-zh-v1.5")vector_index = VectorStoreIndex.from_vector_store( vector_store=vector_store, embed_model=Settings.embed_model, # 不能省略)不一致会导致分数无意义,SimilarityPostprocessor的 cutoff 失效。
检索中阶段的扩展型 Retriever 组件
以下组件在 LlamaIndex 里属于Retriever 层,逻辑上发生在向量库调用前后,与 PostProcessor 不同,它们在as_retriever()层即可接入:
| 组件 | 阶段 | 说明 |
|---|---|---|
AutoMergingRetriever | 检索中(后段) | 向量检索 + docstore 合并父节点 |
RecursiveRetriever | 检索中 | 递归查引用节点 |
QueryFusionRetriever | 检索中 | 多路检索 + 融合 |
外部向量库 + 无 docstore:AutoMergingRetriever基本不可用(父节点不在 docstore)
检索后(Post-Retrieval)
PostProcessor
过滤类
| PostProcessor | 作用 | 生产建议 |
|---|---|---|
SimilarityPostprocessor | 按 score 阈值丢弃 | cutoff 需实测;Pinecone cosine 与 dotproduct 分数范围不同 |
KeywordNodePostprocessor | 正文 keyword 包含/排除 | 中文生产慎用;优先 metadata + hybrid |
SimilarityPostprocessor(similarity_cutoff=0.62)重排类
| PostProcessor | 类型 | 生产建议 |
|---|---|---|
SentenceTransformerRerank | 本地 cross-encoder | 中文用BAAI/bge-reranker-base;追求更高精度可用bge-reranker-v2-m3(多语言,支持长文本) |
CohereRerank | API | rerank-multilingual-v3.0 |
LLMRerank | LLM choice-select | 成本高,非默认 |
from llama_index.core.postprocessor import SentenceTransformerRerankreranker = SentenceTransformerRerank( model="BAAI/bge-reranker-base", top_n=5,)上下文扩展类
| PostProcessor | 依赖 docstore | 外部向量库 |
|---|---|---|
MetadataReplacementPostProcessor | 否 | 是 SentenceWindow 场景 |
PrevNextNodePostprocessor | 是 | 否 |
AutoPrevNextNodePostprocessor | 是 | 否 |
MetadataReplacementPostProcessor配合 SentenceWindow:
# 检索小句子,送给 LLM 的是 metadata["window"] 大窗口MetadataReplacementPostProcessor(target_metadata_key="window")布局优化
| PostProcessor | 作用 |
|---|---|
LongContextReorder | 缓解 Lost in the Middle,高分 chunk 交替放头尾 |
时效性
| PostProcessor | 前提 |
|---|---|
FixedRecencyPostprocessor | metadata 有date |
EmbeddingRecencyPostprocessor | 去重旧版相似文档 |
TimeWeightedPostprocessor | 访问时间衰减 |
安全合规
| PostProcessor | 作用 |
|---|---|
PIINodePostprocessor | LLM 脱敏 PII |
NERPIINodePostprocessor | NER 脱敏 |
自定义:去重(LlamaIndex core 未内置)
重复 ingest 时必须自行实现(LlamaIndex 官方未提供内置去重 PostProcessor):
from llama_index.core.postprocessor.types import BaseNodePostprocessorfrom llama_index.core.schema import NodeWithScore, QueryBundlefrom typing import List, Optionalclass DedupByContentPostprocessor(BaseNodePostprocessor): def _postprocess_nodes( self, nodes: List[NodeWithScore], query_bundle: Optional[QueryBundle] = None, ) -> List[NodeWithScore]: seen = set() result = [] for n in nodes: key = n.node.get_content().strip() if key not in seen: seen.add(key) result.append(n) return resultPostProcessor 顺序
① SimilarityPostprocessor 去掉明显低分(可选)② DedupByContent(需自定义实现)去重(重复 ingest 场景必加)③ SentenceTransformerRerank 精排(强烈建议)④ MetadataReplacement SentenceWindow场景⑤ LongContextReorder 多chunk喂LLM时原则:
- • 先过滤/去重 ,减少 rerank 输入量
- • Rerank 在扩展/替换之前(对 sentence 做 rerank,再替换成 window)
- •
LongContextReorder放最后
结语
LlamaIndex RAG 的过滤与增强是一个三阶段流水线:
- 检索前:决定搜什么、在哪搜,metadata 预过滤、doc 约束、query 改写。
- 检索中:向量库内完成 ANN/hybrid/MMR,宽召回(top_k 20~50)、模型一致、能力下推向量库。
- 检索后:应用层精加工,Rerank 是生产性价比最高的增强;去重、分数过滤、LongContextReorder 按需叠加。
在此之上,再按实际评估数据决定是否加 hybrid、HyDE 或其他层,每一层都要有指标证明其边际价值,而不是堆参数。
学AI大模型的正确顺序,千万不要搞错了
🤔2026年AI风口已来!各行各业的AI渗透肉眼可见,超多公司要么转型做AI相关产品,要么高薪挖AI技术人才,机遇直接摆在眼前!
有往AI方向发展,或者本身有后端编程基础的朋友,直接冲AI大模型应用开发转岗超合适!
就算暂时不打算转岗,了解大模型、RAG、Prompt、Agent这些热门概念,能上手做简单项目,也绝对是求职加分王🔋
📝给大家整理了超全最新的AI大模型应用开发学习清单和资料,手把手帮你快速入门!👇👇
学习路线:
✅大模型基础认知—大模型核心原理、发展历程、主流模型(GPT、文心一言等)特点解析
✅核心技术模块—RAG检索增强生成、Prompt工程实战、Agent智能体开发逻辑
✅开发基础能力—Python进阶、API接口调用、大模型开发框架(LangChain等)实操
✅应用场景开发—智能问答系统、企业知识库、AIGC内容生成工具、行业定制化大模型应用
✅项目落地流程—需求拆解、技术选型、模型调优、测试上线、运维迭代
✅面试求职冲刺—岗位JD解析、简历AI项目包装、高频面试题汇总、模拟面经
以上6大模块,看似清晰好上手,实则每个部分都有扎实的核心内容需要吃透!
我把大模型的学习全流程已经整理📚好了!抓住AI时代风口,轻松解锁职业新可能,希望大家都能把握机遇,实现薪资/职业跃迁~
