2403 字
约 8 分钟
16
S20-A20 · 文档的时效与退场:旧制度怎么从答案里消失

一个知识库问答系统给"差旅住宿标准"答出了 2021 版制度里的 400 元/晚,而现行标准是 600 元。检索同时命中了新旧两份文档,而"旧版"的片段因为"历史点击多"分数更高——于是系统自信地给出了过期答案。

RAG 系统里最危险的不是"没有答案",而是"用过期答案回答了现行问题"。这个判断很关键:模型确实能"看出这是 2021 版",但它不一定会"因此不用它"——因为它的任务是"回答问题",而不是"判断资料时效"。所以"时效"必须变成"检索条件"。
而"过期"这件事必须在"检索"这一层被处理,而不是靠模型"看出来这是旧的"。


1. 三种"过期"的形态

形态 例子
被新版本替代 制度 2021 → 2024
条件失效 某政策暂停执行
完全废弃 部门已撤销

第二项最隐蔽:**文档本身没被替代,只是"暂时不适用"**第二项的"变异"是"局部失效":文档大部分仍有效,只有某一章被新政策覆盖。此时"整篇标记过期"会误删有用内容,而"不标记"又会让那一章继续答错。
——于是它仍在索引里、仍能命中,而"暂停"这件事只写在某份通知里。

第三项最容易被忽略:结构变更后,整类文档都不该再出现,而"删除"这个动作通常没人做。

2. 四种退场机制

机制 效果
检索时过滤(status/effective_to) 最干净
排序降权(旧版降权) 缓解,仍可能出现
索引外移(过期文档不入索引) 彻底,但需重建
标注版本让用户判断 兜底

第一项的"优势"在"候选集":过期文档根本不进入 Top-K,于是"模型看到的就是有效资料"——这比"看到后再判断"可靠得多。
第一项是"首选":在检索查询里加 WHERE status='active',于是过期文档根本不进入候选集。

第三项适合"归档类"语料:过期文档移到单独的"历史"索引,默认不查,需要时才查。

第四项是最低要求:**结果里标注"2021 版"**第四项的"兜底"价值在于"用户可判断":即使过滤漏了,用户看到"2021 版"也会自己去核对——而"无声的过期答案"才是最危险的。
,让用户知道自己在看旧版——它不能替代过滤,但能兜住"过滤漏了"的情况。

// 文档元数据(退场所需的最小字段)
doc:
  id: travel-2021
  status: superseded          # active | superseded | suspended | archived
  effective_from: 2021-01-01
  effective_to: 2024-03-31
  superseded_by: travel-2024  # 指向新版本(可用于"已更新"提示)

3. 检索层怎么用这些字段

做法 说明
过滤 status=active 默认行为
按 effective_to 过滤 需"当前日期"
结果去重(同主题只留最新) 需要"主题聚合"键
显式"历史查询"模式 用户主动选择

第一项与第二项的组合是"标准做法":status=active 且 effective_to 为空或晚于今天。

第三项的"前提"是"入库时打了主题键":同一制度的新旧两版必须共享 topic_key,否则"分组"无从进行——而这件事通常没人管。
第三项处理"同一主题多版本并存"的情况:按 topic_key 分组,只留 effective_from 最新的。而它需要"文档标了同一个主题键"——这是入库时的责任。

"时效权重"可以作为"过滤之后"的补充,但要清楚它治不了根:

// 三种做法的可靠性(从高到低)
1 检索过滤:过期文档不进候选集        → 不会错
2 主题去重:同主题只留最新            → 不会错(前提:topic_key 正确)
3 时效加权:新版分数 +x,旧版 -x       → 仍可能错(分数被点击量主导)
// 结论:1、2 是"保证",3 只是"倾向"

4. "暂停执行"怎么表达

做法 问题
改 status=suspended 需要人记得改
加一条"覆盖文档" 容易被漏看
让模型判断 不可靠

第一项最直接,但它依赖"有人去改"——而"暂停"往往是"发个通知"就结束了。

所以实践中用"有效期管理":给文档设 effective_to,到期自动退出检索。第四项的"自动"很关键:"到期"是时间驱动的,"暂停"是事件驱动的——前者可以被定时任务兜住,后者只能靠人。所以"能写成到期日的,就别用状态标记"。
于是"暂停"= "把到期日改成昨天",动作简单且可审计。

5. 怎么发现"该退场但没退场"

手段 得到
按 effective_to 扫描 到期未处理清单
同主题多版本检测 需要去重
点击/引用分布 旧版是否仍被引用
抽样人工核对 兜底

第三项的诊断方向很重要:它把"该退场"的问题转成"新版可检索性"的问题。而修法完全不同——不是"删旧版",而是"让新版能被搜到"(补标题、补同义词)。
第三项很实用:如果"旧版"的点击量仍然很高,说明"新版没有被找到"——于是问题不在"旧版该退",而在"新版的可检索性"。

-- 到期未退场的文档(每周跑一次)
SELECT id, title, effective_to, status FROM doc_meta
WHERE effective_to < CURDATE() AND status = 'active'
ORDER BY effective_to;
-- 输出应当为空;非空即"待处理清单"

"入库即标注"是最省力的落地方式:在文档入库的流程里强制要求 effective_from 与 status,缺失则拒绝入库。于是"退场"从"事后清理"变成"数据质量约束"。

// 入库校验(三项,缺一拒绝)
1 status ∈ {active, superseded, suspended, archived}
2 effective_from 必填(未知时填"1990-01-01"并标"待确认")
3 superseded_by 在 status=superseded 时必填(指向新版本)
// 收益:从源头保证"能按状态过滤",而不是事后补数据

6. 排错:五种"旧制度仍在答案里"

现象 成因 处理方向
答出过期数字 未按状态过滤 加 status 过滤
新旧都返回 无主题去重 按主题留最新
已暂停的政策仍生效 无有效期管理 设 effective_to
旧版片段分数更高 历史点击多 加时效权重
用户不知道是旧版 无版本标注 结果里标版本

第四项是"排序"问题,而它不该用"调权重"解决:"过滤"比"降权"可靠第四项的"排序"陷阱在于"分数高不等于该被选":历史点击多只说明"它曾经有用",而"现在是否有效"是另一件事——两件事混在同一个分数里,就无法分开调。
,因为降权仍有概率被排上来。

最后一个"用户视角"的设计:当检索到"被替代"的文档时,不要直接丢弃,而是"用新版本替换"——回答里写"该制度已于 2024 年更新,现行标准见《差旅制度 2024》第 3 条"。于是"用户问的是旧概念"也能被安放到正确的资料上。

// 两种处理"命中旧版"的方式
差:直接过滤掉 → 用户问"2021 年标准"时答不出
好:替换为新版 + 说明 → 既回答又纠正
// 实现:superseded 文档保留"重定向"关系(superseded_by)

7. 边界:什么情况不必做退场机制

场景 为什么 做法
语料只增不改(如日志) 无"版本"概念 不做
单一年份(无历史) 无并存 不做
已有强权限/审批流 由流程保证 跟随
用户自己维护的小库 出错可见 不做

最后一条与"成本"有关的边界:退场机制的成本主要在"数据维护"(谁标注有效期、谁复核),而不在"代码"。所以它应当被设计成"入库流程的一部分",而不是"事后清理任务"。
判断口径一句话:"同一个问题"会不会有"多个版本"的答案。会(制度、规范、价格表),就必须有退场机制;不会(技术文档一次性写入),只需"过时提醒"。


8. 自测

  1. 三种"过期"形态里,哪一种最隐蔽?为什么它"仍在索引里仍能命中"?
  2. 四种退场机制里,哪一种最干净?它与"排序降权"的可靠性差别在哪?
  3. "按 effective_to 过滤"需要什么前提?为什么它比"改 status"更可靠?
  4. "同主题多版本"该怎么处理?它需要入库时的什么责任?
  5. "旧版点击量仍很高"说明了什么?问题该往哪修?
  6. 判断"是否需要退场机制"的那个问题是什么?
S20-A20 · 文档的时效与退场:旧制度怎么从答案里消失
https://www.clxhxhhr.top/posts/6573/
作者
clxstart
发布于
2024-12-31
许可协议
CC BY-NC-SA 4.0
评论
0 条
还没有评论,先写一条吧。