在程序员节翻旧笔记,很容易问出一个大问题:“这些年,我的技术判断变了吗?”检索系统却可能只找到几段措辞相近的文字,再由模型补出一条顺畅的成长故事。故事动人,未必属于笔记的主人。
个人知识库要做的是把原始记录摆到一起,让读者看见判断变化的依据。下面的年份和文本都是合成示例,不代表作者的履历。
同一个问题,需要跨时间的证据
只有相似度排序,某一年写得多的主题会占满结果。先按年份或阶段取候选,再挑每个阶段能回答问题的片段,可以减少这种偏斜。不过“早期、中期、成熟期”是解释标签,不能替代真实日期。若早年的记录没有提到测试,就应写“未找到相关记录”,不能写“那时不重视测试”。
NVIDIA 在 2026 年 10 月 21 日介绍的新一代检索模型,将嵌入检索、重排序和文档结构提取分开讨论。它提醒我们:找到相关材料、判断材料是否支持问题、保留材料出处,是不同环节。本文只验证证据整理,不把厂商基准成绩当成个人知识库的成绩。官方说明
图中的 A、B、C 是来源编号,答案中的同名编号必须能回到记录。连线表达资料关联,不代表年份之间存在因果关系。
一个可运行的证据时间轴
保存为 timeline.py,用 Python 3 运行。示例采用 SQLite 精确筛选;它是 RAG 的元数据与引用层,没有伪装成向量召回。
import sqlite3 db = sqlite3.connect(":memory:") db.execute("""CREATE TABLE notes( id TEXT PRIMARY KEY, day TEXT NOT NULL, topic TEXT NOT NULL, body TEXT NOT NULL)""") db.executemany("INSERT INTO notes VALUES(?,?,?,?)", [ ("A", "2016-10-24", "testing", "先用几个输入检查脚本。"), ("B", "2020-10-24", "testing", "修复回归前补一个失败用例。"), ("C", "2026-10-24", "testing", "把来源和未测场景写入变更说明。"), ("D", "2026-10-23", "cooking", "今天记下了菜谱。"), ]) def evidence(topic, start, end): return db.execute( """SELECT id, day, body FROM notes WHERE topic=? AND day>=? AND day<? ORDER BY day, id""", (topic, start, end) ).fetchall() rows = evidence("testing", "2016-01-01", "2027-01-01") assert [r[0] for r in rows] == ["A", "B", "C"] assert evidence("missing", "2016-01-01", "2027-01-01") == [] for note_id, day, body in rows: print(f"[{note_id}] {day} {body}")这里用左闭右开的日期区间,避免“截至某天”到底含不含当天的歧义。真实笔记还应保存文件路径、段落位置、内容哈希和时区;修改原文后,旧引用不能悄悄指向一段新文字。
模型可以解释到哪里
给模型的任务可以很窄:“比较三段记录中明确出现的做法,逐点标注编号;没有证据的心理动机不要推断。”输出后再检查引用编号是否存在,以及每句话是否被引用片段支持。编号存在只解决可追溯性,不能自动证明推论正确。
这段代码的本地运行只证明筛选、排序和空结果行为成立。真实嵌入模型、重排序、长文分块和生成回答尚未在本文环境中运行。若要扩展全文检索,可从 SQLite FTS5 官方文档 开始;中文分词、检索质量与备份恢复仍需独立评估。
一份诚实的时间轴可以有空白。保留空白,比替过去的自己写一段漂亮却查不到出处的话,更值得珍惜。