全程拆解C|从文档入库到检索、回答、记忆更新和遗忘
本例使用虚构的“项目A日志保留规则”,不是任何公司的真实制度。日期、文档和检索排名均为教学数据。目的是跟踪信息在每个对象中的变化,尤其解释为什么“检索到了相关文档”仍不足以正确回答。[BM25][DPR][RRF][LONGMEM]
用户在2026年10月17日问:“项目A的错误日志应该保留多久?配置项怎么写?”
本章目录
沿着对象与状态理解本章
记忆必须回答两个时间问题:事实什么时候生效,系统什么时候知道。下图用超时配置30秒变20秒追踪来源、有效时间和过期,避免把旧知识以熟悉的口吻重复出来。
下方图解的固定输入在“输入与适用条件”中声明。它用于解释本章机制,不与本章其他独立例子的数值暗中接续。
长期记忆不是永远正确的小纸条
新事实出现后,旧记忆怎样更新而不毁掉历史?
记忆要同时回答:这条信息说的是什么范围、何时有效、系统何时得知、依据在哪里。最新写入的记录不一定描述最新生效的事实。保留时间和来源,才能既回答当前问题,也准确解释过去。
输入与适用条件:独立配置案例;月份只用于展示时间顺序,不涉及真实产品当前参数。30秒与20秒属于不同有效期。
1 / 5 · 1月1日 生效
窄屏可左右滑动图形,或点击“放大图形”。文字解释紧随图后。
配置超时30秒
保留作用域与来源默认静止。用“下一步”看完解释再继续;播放到最后一步自动停止。键盘聚焦播放器后,可用左右键逐步查看、空格播放/暂停。图中颜色辅助区分,含义同时用文字注明。
为什么需要
跨会话复用有效知识,减少重复查找和重复错误。
怎样实现
保存范围、来源与两个时间;使用前核验;过期、冲突与撤销显式处理。
可能的代价与误解
把一次模型猜测写成通用规则,会在后续检索中放大错误。
如何判断是否做对
同时测试当前查询、历史查询、错误范围查询和来源已失效查询。
C.1|先给出原始资料,不急着生成向量
| 文档 | 内容摘要 | 生效范围 | 可见范围 |
|---|---|---|---|
| D1@v1 | 普通项目日志默认90天 | 2026-01-01至10-09 | 全体研发 |
| D1@v2 | 普通日志默认30天;敏感字段日志7天 | 10-10起 | 全体研发 |
| D2@v3 | 项目A错误日志含敏感字段,应使用7天规则 | 10-12起 | 项目A成员 |
| D3@v1 | 配置项retention_days接受整数天数 |
09-01起 | 全体研发 |
| D4@v1 | 项目B某日志获批保留90天 | 10-15起 | 仅项目B成员 |
| D5@v1 | 旧迁移记录:曾将A保留期设为90天 | 历史记录,不是现行政策 | 项目A成员 |
原始资料已经包含几类易混淆关系:同一文档的新旧版本、一般规则与项目例外、规范与历史执行记录、内容相关但用户无权读取的其他项目资料。
如果入库时只保留正文文本,删除生效日期、权限和文档类型,后续向量再精确也无法可靠恢复这些条件。深度检索工程从数据建模开始,不是从选择哪款向量数据库开始。
C.2|解析后的对象应该保留哪些语义
D1@v2可能被表示为:
{
"document_id":"D1","revision":"v2","kind":"policy",
"valid_from":"2026-10-10","valid_to":null,
"recorded_at":"2026-10-10T09:00:00+08:00",
"acl":"engineering",
"sections":[
{"id":"general","text":"普通日志默认保留30天"},
{"id":"exception","text":"包含敏感字段的日志保留7天","depends_on":"general"}
]
}
valid_from表达规则何时适用,recorded_at表达系统何时知道;二者不一定相同。若10月17日才录入一个10月12日生效的修正,历史问答需要区分“当时实际上适用什么”和“系统当时知道什么”。
解析还应保存来源位置,方便最终引用和人工核查。网页标题、章节标题、表头与脚注不是装饰,它们可能决定段落适用范围。把“除敏感字段外”截到另一个片段,会让剩余正文产生相反含义。
C.3|Chunk如何划分,为什么要有父子关系
一种可行教学划分是:C1一般规则、C2敏感例外、C3项目A分类、C4配置语法。每块携带来源文档、版本、有效期和权限;C2指向C1,C3指向所适用的规则族。
检索时可以先命中小片段,提高定位精度,再读取所属章节或关联例外,避免答案缺条件。不是所有关系都必须构建成大图数据库:小规模项目用文档ID与父段落引用即可。只有跨文档关联复杂且有收益证据时,再增加图结构。
Chunk边界必须与任务有关。太小容易失去条件,太大稀释词项和语义并消耗上下文。所谓“固定500字最优”没有普遍保证;需要在自己的问题集上测关键证据召回和最终正确率。
版本变化时,要更新受影响块和索引;不能只追加新版本、永不失效旧块。否则同一个文档越改越多,检索可能同时返回多份互相冲突的规定。
C.4|查询进入时,先确定查询条件
问题包含项目A、错误日志、保留时长和配置方式。用户身份通过认证系统得到项目A成员权限,不由模型从措辞猜测。问题未指定历史日期,应用可采用当前日期,但应在内部明确这项解释。
{
"principal":"user_in_project_A",
"project":"A",
"as_of":"2026-10-17",
"claims_needed":["日志分类","适用保留时长","配置项语法"],
"read_scope":["engineering","project_A"]
}
D4虽然提到90天、日志、项目,词面上很相关,但用户没有读取权限,应在外发给模型或第三方reranker之前排除。检索系统内部能扫描哪些元数据取决于权限设计,但不应把不可见正文先发出去再靠最终答案遮盖。
查询改写可以增加“retention”“retention_days”等术语,但改写是搜索辅助,不是事实证据。模型生成的“项目A应为30天”绝不能因进入查询扩展就变成已确认前提。
C.5|BM25和向量检索各自提供什么
BM25对“项目A”“retention_days”等具体词项可能很有效;向量检索能把“留多久”与“保留时长”联系起来。两条路径生成候选,不直接决定事实真伪。
为了演示融合,假设在已通过权限过滤的候选上得到如下人工设定排名,不是实际Embedding测试结果:
关键词排名:C4配置语法、C3项目A分类、C1普通规则、C2敏感例外
语义排名: C3项目A分类、C2敏感例外、C1普通规则、C4配置语法
RRF对每个候选计算Σ1/(k+rank)。它解决不同评分尺度不可直接相加的问题,但不理解“项目A含敏感字段”这个逻辑条件,也不保证排名靠前的片段能单独回答完整问题。
若只取最高一块C3,能知道日志分类,却可能不知道配置语法;只取C4,知道怎么写字段,却不知道值应该是多少。检索目标应是覆盖所需主张的最小充分证据集,而不只是选一个最高分片段。
C.6|Reranking后为什么仍要做适用性检查
重排模型可能将C3与C2排得更高,但还要检查:D1@v2是否当前生效?D2@v3是否针对项目A错误日志而非访问日志?D5是否只是历史记录?不同证据是否互相支持?
构造一个证据矩阵:
| 待回答主张 | 支持片段 | 是否充分 | 需要补读 |
|---|---|---|---|
| A错误日志属于敏感类别 | C3 | 当前版本且项目匹配 | 无 |
| 敏感类别保留7天 | C2及其父规则 | 条件完整 | 一般规则上下文 |
| 配置键与值类型 | C4 | 语法充分 | 无 |
| 修改是否已部署 | 无 | 不充分 | 需运行环境工具 |
最后一行很重要。知识库能说明应怎样配置,不能证明生产环境已经改好。若用户只问“怎么写”,不需要自动操作;若用户要修改,还需明确资源、授权与核验。
C.7|模型最终接收的上下文不应是一袋相似段落
一种教学上下文包可以是:
任务:回答项目A错误日志的保留时长及配置方式;不执行修改。
时间范围:2026-10-17当前有效规则。
证据E1:D2@v3,项目A,10-12起生效。
内容:项目A错误日志含敏感字段,应使用敏感日志规则。
证据E2:D1@v2,10-10起生效。
内容:普通日志30天;含敏感字段日志7天。
证据E3:D3@v1,配置语法。
内容:retention_days为整数天数。
排除说明:D1@v1已过期;D5是历史执行记录,不能覆盖现行规则。
未确认:线上当前配置;本任务未授权修改。
这包信息不仅有内容,还有角色、时间、排除原因与边界。模型据此生成:在所给教学资料下,项目A错误日志应保留7天,可配置retention_days: 7;该回答未核验线上现状,也未执行修改。
如果模型输出30天,检查它是否忽略了C3到C2的条件关系;如果输出90天,检查过期版本是否未过滤或历史记录被误当规范;如果声称“已修改”,检查任务边界与动作事实混淆。不同错误指向不同层,不应统一用“换更强模型”处理。
C.8|回答之后,应该记忆什么
不应直接保存“所有项目日志7天”。可保存更窄的条目:项目A错误日志在相应有效期按敏感类别处理,来源D2@v3与D1@v2;用途是后续同类问题的检索线索,使用前检查来源是否仍有效。
{
"memory_id":"M17","kind":"semantic",
"scope":{"project":"A","log_type":"error"},
"claim":"按敏感日志规则保留7天",
"sources":["D2@v3","D1@v2"],
"valid_from":"2026-10-12","status":"active",
"review_on":["D1变更","D2变更","项目A日志字段变更"]
}
记忆不是另一个无条件权威。下一次问题涉及项目B或访问日志时,M17不适用。若只是复述了当前知识库信息,保存它的价值在于减少重复定位,不在于让模型永久相信一个数字。
程序性经验则是另一条:“日志保留问题先确认类别与有效日期,再找一般规则和例外。”它可以适用于多项目,但也不应写成必须使用某个固定数据库或强制多Agent流程。
C.9|修正规则:不覆盖历史,怎样表达新旧事实
假设10月20日收到新资料D2@v4,说明项目A从10月18日起已移除敏感字段,新的错误日志改用普通30天规则。系统10月20日才知道这一变化,因此:
旧条目:业务有效 [10-12,10-18),系统曾在10-17确认
新条目:业务有效 [10-18,∞),系统在10-20录入
用户问“10月17日当时该保留多久”,答案仍是7天;问“10月19日规则是什么”,根据当前已知资料是30天;问“系统10月19日当时会怎么回答”,则可能仍依据尚未更新的7天记录。这三种问题不同,不能只用“最后更新时间最新”解决。
原条目M17不应简单删除到无历史可追溯,也不应一直active。可以关闭有效区间、保留来源,建立替代关系。动态工程事实的记忆需要更新与失效语义,而不是不断追加自然语言。
C.10|删除与权限撤销怎样传播
若项目A文档权限撤销,相关缓存、摘要、记忆、搜索结果和引用预览都可能继续暴露旧内容。删除原文只解决一层;需要识别派生对象及其来源关系,按权限与保留策略失效。
并非所有系统都必须追踪复杂的细粒度数据血缘,但至少应知道哪些记忆来自哪些受控来源。没有来源ID的摘要很难安全撤回,也难以解释为什么某条经验还在被使用。
对于执行结果日志,保留策略还可能与审计需求冲突,应依据真实组织要求处理,本例不提供法律判断。技术上应把“不可再用于回答”和“为了受控审计保留”分开,而不是把它们混成一个delete布尔值。
C.11|怎样设计反例证明系统不是只会答这一题
构造相邻问题:项目A普通运行日志、项目A10月5日错误日志、项目B的例外、未授权用户、缺失分类资料、D2与D1版本冲突、配置键拼写变化。对每个问题写出预期证据和可接受的不确定性。
如果把D2删掉,系统不应仍自信断言项目A错误日志必为敏感类别;若仍答7天,可能是记忆未失效或模型猜测。如果把D2改成普通类别,答案应随证据改变,而不是受之前Few-shot影响固定输出7。
这类反事实测试检查数据依赖是否真的发挥作用。只给一题并看到正确答案,不足以证明RAG、记忆或权限工程有效。
C.12|从本例提炼一个可复述的运行答案
先认证与确定时间,解析保留条件与来源,建立可更新索引,检索候选并在外发前过滤权限,融合和重排,补全关联例外,形成主张证据矩阵,再生成和核验引用。回答后只保存有范围、来源和有效期的必要记忆;源更新时同步处理索引、缓存和派生记忆。
这个答案之所以比“RAG就是先检索再生成”更深入,是因为每一步都解释了对象、约束和失败。如果某一环缺失,能指出具体后果,而不是泛泛说“准确率可能下降”。