RAG 怎样按文档版本过滤检索候选
RAG 同时保留 v1、v2、v3 时,不能指望向量距离自动理解“只回答 v2”。更稳的做法是:入库时把版本写进每个 chunk 的元数据,请求进入检索链路后先解析允许版本,再把版本条件和租户、文档条件一起放进向量库过滤器。这样候选集从源头就不会混入不应使用的旧内容。
- 版本字段是检索约束,不是提示词里的软要求。
- 优先在向量检索阶段预过滤,避免 top-k 被旧版本占满后再丢弃。
- 用有效候选率、版本命中率、p95 延迟和空结果率同时评估,别只看向量相似度。
先把版本语义从向量相似度里拿出来
建议每个切片至少保存 tenant_id、doc_id、version、version_rank、effective_from 和 superseded_at。其中 version 用于精确选择,时间字段用于“回答某个历史时点”的查询,version_rank 只适合排序或回退,不应单独充当访问边界。
| 字段 | 检索用途 | 常见边界 |
|---|---|---|
| doc_id | 限定同一份文档 | 文档拆分后所有 chunk 必须一致 |
| version | 精确匹配 v2 | 不要混用字符串和数字格式 |
| effective_from | 按生效时间筛选 | 时区和闭区间必须固定 |
| superseded_at | 排除已被替代的内容 | 回滚时不能直接物理删除旧版本 |
例如知识库允许用户指定“产品手册 v2”,检索请求应先得到 allowed_version = "v2"。如果请求没有版本,才按产品的默认发布策略解析出一个明确版本;不要把“最新”留给生成模型猜。

把版本条件放进检索过滤器
以 Qdrant 为例,payload 过滤器的 must 表示条件全部满足。官方资料也建议为经常过滤的 payload 字段建立索引。下面的代码只演示“先锁定版本,再做相似检索”的关键关系,向量生成和客户端初始化省略。
官方地址:https://qdrant.tech/documentation/search/filtering/
from qdrant_client import models
def build_version_filter(tenant_id: str, doc_id: str, allowed_version: str):
# 租户、文档和版本必须同时满足,防止旧版本或其他租户混入候选。
return models.Filter(must=[
models.FieldCondition(
key="tenant_id",
match=models.MatchValue(value=tenant_id), # 先隔离租户
),
models.FieldCondition(
key="doc_id",
match=models.MatchValue(value=doc_id), # 再限定文档
),
models.FieldCondition(
key="version",
match=models.MatchValue(value=allowed_version), # 精确版本约束
),
])
query_filter = build_version_filter("tenant-a", "pricing", "v2")
result = client.query_points(
collection_name="knowledge_chunks",
query=query_vector,
query_filter=query_filter, # 过滤发生在候选检索阶段
limit=8,
with_payload=True,
)
如果版本不是离散标签,而是按时间回放,可以把 version 换成 effective_from 与 superseded_at > query_time 的范围条件。两种语义不要混在一个字段里,否则回滚和审计时很难解释“为什么这段内容被选中”。
多版本系统还要处理索引和写入的一致性:先写入带完整元数据的 chunk,再把该版本标记为可检索;删除或替代旧版本时保留可追溯标记。Qdrant 的分支检索示例也采用 payload 条件和覆盖标记来解析某个分支可见的版本。

用基线和压测指标判断是否真的改善
不要只比较平均耗时。先记录“混合版本召回后再过滤”的基线,再记录“带版本条件的预过滤”结果。下面是一个用于设计压测报表的示例,数字是说明格式的原创假设,不是某个向量库的固定承诺。
| 方案 | 有效候选率 | p95 延迟 | 空结果率 |
|---|---|---|---|
| 先召回 20 个再丢旧版本 | 84% | 310 ms | 8.6% |
| 版本字段预过滤后召回 8 个 | 96% | 190 ms | 3.1% |
这里的有效候选率指 top-k 中真正满足版本约束的比例,版本命中率则要单独核对最终上下文。生产压测至少固定:同一批问题、同一 embedding 模型、同一 top-k、版本分布、索引状态和冷/热缓存。否则一次换模型或换缓存状态,就无法判断收益来自过滤还是来自别的变化。
如果版本过滤后空结果率反而升高,不要立刻放宽到所有版本。先确认请求解析出的版本是否存在、过滤字段类型是否一致、索引是否覆盖该字段,以及当前版本是否完成了“可检索”发布。只有业务明确允许回退时,才按 v2 → v1 的顺序做第二次查询,并在答案中记录实际命中的版本。
版本过滤失效时按这张清单排查
- 结果混入旧版本:检查过滤器是否真的传给 query 接口,而不是只写进提示词;再抽样打印返回 payload 的
doc_id和version。 - 过滤后没有结果:检查版本值的大小写、类型、租户字段和索引构建状态;不要用“版本不存在”掩盖写入延迟。
- 回滚难以解释:保留版本和替代关系,用明确的发布状态控制可检索性,不要覆盖原 chunk。
- 性能忽高忽低:同时记录过滤命中数量、索引命中情况、top-k 和 p95,避免只看平均耗时。
常见问题
只在生成提示词里写“使用最新版本”可以吗?
不建议。提示词约束是软规则,无法阻止旧版本进入上下文;版本字段应在检索阶段过滤,提示词只负责解释已选上下文。
文档版本和 chunk 版本必须都保存吗?
至少要让每个 chunk 能追溯到文档版本。通常保存 doc_id 与 version 最清楚,必要时再加生效时间和替代关系。
过滤后候选太少怎么办?
先提高该版本的切片覆盖率或调整切片策略,再考虑有审计记录的版本回退;不要直接取消版本过滤来换取表面上的召回数量。
OpenTelemetry AI 怎样把模型调用耗时纳入 trace
- 上一篇
- OpenTelemetry AI 怎样把模型调用耗时纳入 trace
- 下一篇
- Kubernetes Gateway API 进入新阶段后怎样理解迁移影响
-
- 科技周边 · 人工智能 | 1小时前 | 模型评估 AI evaluation 事实性评分 格式评分
- AI evaluation 怎样区分事实性与格式性评分
- 119浏览 收藏
-
- 科技周边 · 人工智能 | 1小时前 | GenAI 可观测性 耗时 OpenTelemetry 模型调用 trace
- OpenTelemetry AI 怎样把模型调用耗时纳入 trace
- 101浏览 收藏
-
- 科技周边 · 人工智能 | 1小时前 |
- ONNX Runtime 怎样选择 CPU 与 CUDA provider
- 246浏览 收藏
-
- 科技周边 · 人工智能 | 1小时前 |
- Hugging Face Datasets 怎样用 cast_column 统一字段类型
- 118浏览 收藏
-
- 科技周边 · 人工智能 | 1小时前 |
- Hugging Face tokenizer 怎样按 special tokens 判断截断边界
- 489浏览 收藏
-
- 科技周边 · 人工智能 | 1小时前 |
- Hugging Face pipelines 怎样为批量推理设置 batch size
- 469浏览 收藏
-
- 科技周边 · 人工智能 | 1小时前 |
- OpenAI embeddings 怎样选择维度缩减参数
- 439浏览 收藏
-
- 科技周边 · 人工智能 | 1小时前 | 人工智能 · 结构化输出 · 结构化输出 JSON Schema OpenAI Responses API strict json_schema
- OpenAI Responses API 怎样用结构化输出约束 JSON 形状
- 168浏览 收藏
-
- 科技周边 · 人工智能 | 1小时前 | 人工智能 · 工具调用 · SSE 工具调用 OpenAI Responses API 流式事件 文本增量
- OpenAI Responses API 怎样区分文本增量与工具事件
- 239浏览 收藏
-
- 科技周边 · 人工智能 | 1天前 |
- AI 流式输出怎样区分文本增量和工具事件
- 491浏览 收藏
-
- 科技周边 · 人工智能 | 1天前 |
- AI 工具调用怎样设计幂等键避免重复执行
- 319浏览 收藏
-
- 前端进阶之JavaScript设计模式
- 设计模式是开发人员在软件开发过程中面临一般问题时的解决方案,代表了最佳的实践。本课程的主打内容包括JS常见设计模式以及具体应用场景,打造一站式知识长龙服务,适合有JS基础的同学学习。
- 543次学习
-
- GO语言核心编程课程
- 本课程采用真实案例,全面具体可落地,从理论到实践,一步一步将GO核心编程技术、编程思想、底层实现融会贯通,使学习者贴近时代脉搏,做IT互联网时代的弄潮儿。
- 516次学习
-
- 简单聊聊mysql8与网络通信
- 如有问题加微信:Le-studyg;在课程中,我们将首先介绍MySQL8的新特性,包括性能优化、安全增强、新数据类型等,帮助学生快速熟悉MySQL8的最新功能。接着,我们将深入解析MySQL的网络通信机制,包括协议、连接管理、数据传输等,让
- 500次学习
-
- JavaScript正则表达式基础与实战
- 在任何一门编程语言中,正则表达式,都是一项重要的知识,它提供了高效的字符串匹配与捕获机制,可以极大的简化程序设计。
- 487次学习
-
- 从零制作响应式网站—Grid布局
- 本系列教程将展示从零制作一个假想的网络科技公司官网,分为导航,轮播,关于我们,成功案例,服务流程,团队介绍,数据部分,公司动态,底部信息等内容区块。网站整体采用CSSGrid布局,支持响应式,有流畅过渡和展现动画。
- 485次学习
-
- PubMedQA
- 深入了解PubMedQA生物医学问答数据集,涵盖其核心功能、使用方法及在临床决策、药物研发等场景的应用,助力提升NLP模型性能。
- 662次使用
-
- H2O EvalGPT
- H2O EvalGPT是H2O.ai推出的开源LLM评估平台,提供详细的大模型性能排行榜、行业特定基准测试及A/B测试功能,助您快速选择最适合项目的高性能大语言模型。
- 682次使用
-
- LMArena
- LMArena是加州大学伯克利分校推出的AI模型匿名评测平台。通过盲测投票机制,用户可对比不同大模型回答并生成实时排行榜,助力开发者优化模型及用户选择最佳AI工具。
- 727次使用
-
- HELM
- 深入了解斯坦福推出的HELM(Holistic Evaluation of Language Models)大模型评测体系。本文解析其核心功能、安装配置步骤及应用场景,涵盖准确性、公平性、鲁棒性等多维度指标,助力开发者全面优化语言模型性能。
- 696次使用
-
- MMBench
- MMBench是由上海人工智能实验室等机构联合推出的多模态基准测试平台,提供细粒度能力评估、大规模数据集及VLMEvalKit工具。本文详细介绍其核心功能、安装使用方法及应用场景,助力开发者全面评估多模态模型性能。
- 528次使用
-
- 量化模型本地推理的显存估算方法
- 2026-10-17 501浏览
-
- 本地大模型反复输出同一句话怎么调整生成参数
- 2026-09-06 501浏览
-
- Python 调用大模型时如何用结构化输出校验 JSON:从解析失败到可重试
- 2026-08-29 501浏览
-
- AI写作工具免费版安装教程(含豆包Clawdbot)
- 2026-05-30 501浏览
-
- WPS AI能自动生成PPT吗?输入主题一键制作演示文稿
- 2026-05-27 501浏览

