P1 逻辑与实验计划
目标:以最低读写成本在 LoCoMo / LongMemEval 上达到或超过强基线;保证 As-Recorded 无未来泄漏,可审计可复现。P1 输出为可复现实验包 + 图表 + 通过门槛结论。
总览矩阵
| 模块 | 选项A(默认) | 选项B | 选项C | 何时优先 | 代价 |
|---|---|---|---|---|---|
| 预处理 | 规则句分+正则提取 | 轻量句分模型 | — | 中文/英文混排稳定 | 低/低 |
| NER/节点 | 规则+Flair | RoBERTa-NER微调 | 受限LLM抽取 | 域内人/组织多时用B | 低/中/中高 |
| 别名合并 | exact+Jaro-Winkler | token-set比对 | 上下文判别器 | 名称多样性大用B | 低/低/中 |
| 指代消解 | 规则近邻 | SpanBERT蒸馏 | LLM冲突裁决 | 代词密集用B | 低/中/中 |
| 时间解析 | 规则+词典 | SUTime/Heidel | LLM低置信兜底 | 相对时间多用A+B | 低/低/中 |
| 关系抽取 | 模板+依存 | RoBERTa筛选器 | 受限LLM结构化 | 噪声高用B | 低/中/中高 |
| RBU同化 | AR快照精确匹配 | 模糊匹配扩展 | — | 数据脏时开B | 低/低 |
| 事件生成 | 强触发+评分 | 语义合并(sim≥0.8) | 受限LLM摘要 | 主题漂移多开B | 低/中/中 |
| Episode聚合 | 固定窗+参与者交集 | 话题漂移检测 | — | 会话长开B | 低/中 |
| 检索入口 | BM25 | +E5-small融合 | +ColBERT-lite | 查询难/多针开C | 低/中/中 |
| 重排 | 无/MMR | MonoT5-small | MiniLM蒸馏CE | 预算允许用B | 低/中/低 |
| 跨层扩展 | L1↔L2深度≤2 | 关系类型门控 | 学习式扩展 | 误召回高用B | 低/低/中 |
| 打包 | 事件→最小证据 | +活跃标注 | +统计摘要 | 成本受限用A | 低/低/低 |
| 写入触发 | 强触发 | 显著性阈值 | 周期/回补 | 数据稀疏开C | 低/低/低 |
| 回补策略 | 近K轮抽取 | 失败分析模板 | 受限LLM缺口归纳 | 缺口复杂用C | 低/低/中 |
| QA生成 | 基座LLM | +时间特征提示 | +时间一致性判别头 | 时间错误多用B/C | 中/中/中 |
| 评测 | 基准Runner | 误差分类器 | 成本看板 | 默认全开 | 低 |
细化说明(每模块开关与输出)
预处理(pipelines/memowrite/preprocess.py)
- A: Punkt改良句分、邮箱/URL/电话/金额正则、相对时间规范化。
- B: 轻量句分Transformer(标点异常域)。
- 输出:句子、正则mentions、标准化时间候选。
config.preprocess = {rule:true, tiny_seg:false}
NER/节点(modules/extract/entities.py)
- A: 规则+Flair(人/组织/地名),正则识别账号/邮箱/URL。
- B:
roberta-base-ner微调(1–2k标注)。 - C: 受限LLM(JSON schema,失败回退A/B)。
- 输出:Entity/Literal/TimeInstant/Mention/Document。
config.ner = {mode: A|B|C}
别名/规范化(modules/extract/alias.py)
- A: lower+去标点+exact+Jaro≥0.92。
- B: token-set相似≥0.8。
- C: 上下文判别器对冲突名对打分。
config.alias = {jw:0.92, token_set:0.8}
指代消解(modules/extract/coref.py)
- A: 规则近邻+人物优先。
- B: SpanBERT蒸馏版。
- C: 受限LLM仅在冲突时投票。
config.coref = {mode:A|B|A+C}
时间解析(modules/time/normalize.py)
- A: 规则/词典+tz推断,TIMEX到ISO。
- B: SUTime/Heidel兜底。
- C: LLM校正低置信。
config.time = {rule:true, sutime:true, llm_low_conf:true}
关系抽取(modules/extract/relations.py)
- A: 模板+依存(白名单谓词)。
- B: RoBERTa二分类过滤噪声(A→候选→B过滤)。
- C: 受限LLM抽取JSON,回退A/B。
config.relation = {mode:A|A+B|C}
RBU 同化(modules/assimilation/rbu.py)
- A: AR快照精确匹配
(src,rel)+开放版本。 - B: 模糊匹配(别名展开+近似dst)。
- 输出:
INSERT/REPLACE/CLOSE/SKIP的DSL。config.rbu = {fuzzy:false}
事件生成与合并(modules/events/builder.py)
- A: 强触发必建;显著性阈值建;模板摘要;
t_visible缓存。 - B: 语义合并(sim≥0.8 ∧ 参与者交集≥1 ∧ 时间窗相邻/相交)。
- C: 受限LLM生成可读summary(证据闭包不变)。
config.events = {merge:true, llm_summary:false}
Episode 聚合(modules/events/episode.py)
- A: 固定时间窗+参与者交集。
- B: 话题漂移检测(嵌入余弦<阈值)。
config.episode = {topic_shift:true, cos_th:0.7}
检索入口(modules/retrieval/eagle_v1.py)
- A: BM25。
- B: BM25+E5-small RRF。
- C: +ColBERT-lite(蒸馏)。
config.retrieval.entry = {bm25:true, e5:true, colbert_lite:false}
重排与扩展
- 扩展:A 深度≤2、扇出≤m;B 关系类型门控(schema约束)。
- 重排:A 无/MMR;B MonoT5-small;C MiniLM蒸馏CE。
config.rerank = {mmr:true, monot5:true}
打包(modules/retrieval/packing.py)
- A: Event→最小证据;附
active_at/intervals/evidence_id。 - B: 加统计摘要(token紧张时启用)。
config.pack = {stats:false}
写入触发(modules/triggers/*)
- A: 强触发(更新/纠错/承诺/日程)。
- B: 显著性阈值
$s≥τ_keep$;归档$s≤τ_archive$。 - C: 周期/回补(话题边界/会话结束、检索失败)。
config.triggers = {keep:0.72, archive:0.35, periodic:true, backfill:true}
回补(modules/triggers/backfill.py)
- A: 近K轮模板抽取。
- B: 失败类型模板库(缺实体/关系/时间)。
- C: 受限LLM归纳缺口再结构化。
config.backfill = {k:20, llm:false}
QA 生成与时间一致性
- A: 基座LLM+标准模板。
- B: 时间特征提示(AR/AW切面+intervals)。
- C: 生成后判别头
<IsTemporalConsistent>(轻判别器)。config.qa = {temporal_prompt:true, temporal_checker:true}
评测与看板(pipelines/eval_runner.py)
- A: 基准Runner(EM/Acc-AR/AW/Time-F1/Hit@k/nDCG@k/p95/tokens)。
- B: 误差分类器(抽取/别名/时态/检索/证据/生成)。
- C: 成本看板与Pareto导出。
config.eval = {error_breakdown:true, pareto:true}
配置示例(摘)
ner: {mode: A} # A|B|C
coref: {mode: A} # A|B|A+C
relation: {mode: A+B} # A|A+B|C
time: {rule: true, sutime: true, llm_low_conf: true}
rbu: {fuzzy: false}
events: {merge: true, llm_summary: false}
episode: {topic_shift: true, cos_th: 0.7}
retrieval: {bm25: true, e5: true, colbert_lite: false}
rerank: {mmr: true, monot5: true}
pack: {stats: false}
triggers: {keep: 0.72, archive: 0.35, periodic: true, backfill: true}
backfill: {k: 20, llm: false}
qa: {temporal_prompt: true, temporal_checker: true}默认组合:成本优先 预处理A,NER A,Coref A,关系 A+B,时间 A+B(C兜底),RBU A,事件 A+B,Episode B,检索 B(BM25+E5),重排 B(MonoT5),扩展A,打包A,触发 A+B+C,回补A/B,QA B。
1. 范围与目标
- 范围:抽取 → RBU(Read-Before-Update)同化 → 双时间写入 → 事件生成/合并 → 索引增量 → EAGLE v1 检索+重排 → QA → 评测。
- 硬约束
- 所有读(匹配/检索)在 [email protected] 快照上执行。
- 所有写通过 DSL,事实(L1)版本化,节点不版本化。
- As-Recorded 不得泄漏未来证据(事件以
t_visible控制)。
- 成本目标:写 ≤ 120 tokens/会话(均值),读 ≤ 600 tokens/问答(含证据),p95 不劣化。
2. 总流水线
normalize
→ mention/NER
→ coref/alias
→ relation/time
→ RBU 同化(AR 先读后写)
→ DSL 回放(GraphStore)
→ L2 事件生成/合并(含 t_visible)
→ 索引增量(L1/L2 倒排)
→ EAGLE v1(检索→扩展→重排→打包)
→ QA(AR/AW 双切面)
→ 计费与日志
3. 数据契约(不变)
- FactVersion:
{id, src, rel, dst, valid=[sv,ev), record=[sr,er), source, evidence_id[], confidence} - Event:
{id, summary, time_span, participants[{entity,role}], includes_fact[], status} - DSL:
UPSERT_EDGE / ARCHIVE_EDGE / RETRO_CORRECT / UPSERT_EVENT / LINK
4. 模块 × 备选实现 × 指标 × 门槛
推荐=首选实现;B/C 为对照与兜底。未达门槛不纳入端到端。
4.1 预处理(pipelines/memowrite/preprocess.py)
- 输入/输出:turns → 句子、正则 mentions、标准化时间候选。
- 实现
- A 规则:Punkt 改良句分;邮箱/URL/电话/金额正则;相对时间
now/+N days→绝对时间(含 tz)。 - B 句分器(可选):tiny transformer,域外标点。
- A 规则:Punkt 改良句分;邮箱/URL/电话/金额正则;相对时间
- 指标/门槛:时间解析覆盖≥95%;句分错误≤2%(200 句人工)。
4.2 NER/节点抽取(modules/extract/entities.py)
- 输出:
Entity|Literal|TimeInstant|Mention|Document - 实现选项
- A 规则+Flair(推荐):邮箱/URL/句柄/地名后缀规则;人/组织 Flair NER(CPU 友好)。
- B RoBERTa-NER(对照):在 1–2k 标注 span 上微调。
- C 受限 LLM:few-shot,输出 JSON schema;仅低置信兜底。
- 别名/规范化:lower/去标点/公司后缀裁剪;同回合集合精确合并;跨回合 Jaro-Winkler≥0.92 或 token-set≥0.8 →
alias_of。 - 指标/门槛:人/组织 F1 ≥ 0.90;别名误并 ≤ 3%。
4.3 指代消解(modules/extract/coref.py)
- 实现选项
- A 规则:最近主体优先+人称代词表。
- B SpanBERT e2e-coref 蒸馏。
- C LLM 判别:仅 A/B 冲突时投票。
- 指标/门槛:域内 CoNLL F1 ≥ 0.75;否则仅 A + 冲突过滤。
4.4 关系抽取(白名单,modules/extract/relations.py)
- 谓词 v1
persona.{name,role}lives_inworks_atstudies_athas_contact.{email,phone}
scheduled_for.{datetime,location}prefers.{food,music,activity}
likes/dislikesrelated_to(person)ownsuses - 实现选项
- A 模板+依存(推荐):正则模板 + 依存路径。
- B RoBERTa 过滤器:A 产候选→二分类去噪。
- C 受限 LLM:few-shot 受限 JSON;失败回退 A/B。
- 否定/更正检测:
no longer|not anymore|changed to|correction|actually。 - 时间赋值:句内 TIMEX →
valid=[sv,ev);否则valid=[turn.ts, +∞);record.start=turn.ts。 - 指标/门槛:P≥0.90、R≥0.80;更正检出 ≥ 0.90。
4.5 时间解析(modules/time/normalize.py)
- 实现:A 规则/词典;B SUTime/Heidel 作兜底;C 小 LLM 校正(低置信)。
- 指标/门槛:ISO 对齐 ≥ 0.95;歧义标注并 AW 回退。
4.6 RBU 同化(modules/assimilation/rbu.py)
- 读:在 [email protected] 获取
(src,rel)开放版本、dst倒排、alias_of展开。 - 判定:
- 存在
open.dst==d且valid≈new→ SKIP - 存在
open.dst≠d→ REPLACE(旧RETRO_CORRECT(valid_end=ts, record_end=ts)+ 新UPSERT_EDGE) - 无候选 → INSERT
- 否定/终止 → CLOSE(
RETRO_CORRECT)
- 存在
- 局部更新子图:仅更新受影响
(src,rel)邻域与相关事件。
4.7 事件/集(modules/events/builder.py)
- 强触发:纠错/知识更新、承诺/日程、长期偏好 → 必建 Event(
includes_fact覆盖变更)。 - 软触发:显著性 , 建事件; 归档。
- 合并:与候选事件满足
(sim≥0.8 ∧ 参与者交集≥1 ∧ 时间窗相邻/相交)→ 合并includes_fact与time_span。 - Episode:仅检索容器;可见性=子事件函数,不作证据源。
- AR 可见性:更新缓存 ;缺证据则 AR 隐藏。
- 指标/门槛:事件聚合纯度≥0.9;证据闭包完备率≥0.98;AR 泄漏=0。
4.8 检索 EAGLE v1(modules/retrieval/eagle_v1.py)
- 入口融合:BM25(Whoosh/Lucene) + E5-small 向量 + ColBERT-lite(蒸馏) → RRF。
- 切面先行:AR/AW 快照;新鲜度(AR:
record.start,t_visible;AW:valid.{start|end},time_span)。 - 扩展/重排:
L1↔L2深度≤2,扇出≤m;MMR→MonoT5-small(top-64)(时间特征拼接)。 - 打包:Events → Minimal L1 Evidence;事实携
intervals/evidence_id/active_at,事件携active_fact_count。 - 指标/门槛:nDCG@10 ≥ 基线+5%;p95 ≤ 基线;Hit@k、覆盖率@k 报告。
4.9 写入触发器(modules/triggers/*)
- 强触发:更新/纠错/承诺/日程 → 必写。
- 显著性触发: 写; 归档;其余进 WM。
- 周期触发:话题边界/会话结束,仅写摘要 Event + 最小证据闭包。
- 回补触发:检索空/弃权/时态冲突 → 近 K 轮提炼缺口事实写入。
5. 算法伪代码(核心)
def process_turn(turn, t=turn.ts, view="AR"):
ents = extract_entities(turn)
coref = resolve_coref(turn, context, ents)
triples = extract_relations(turn.sentences, ents, coref)
triples = attach_time(triples, turn, tz=DEFAULT_TZ)
snap = snapshot(view="AR", t=t)
C_fact, C_event = match_candidates(triples, snap)
dsl = []
for tp in triples:
act = diff_decide(tp, C_fact[tp.key], t)
dsl += emit_dsl(act, tp, t, turn.mention_ids)
replay(dsl)
ev_ops = build_or_merge_events(dsl, turn, C_event, t)
replay(ev_ops); update_indexes(ev_ops, dsl)
return6. 配置(configs/p1.yaml 示例)
memory:
stm_window: 12
wm_capacity: 8
write_budget_tokens_per_session_avg: 120
read_budget_tokens_per_qa_avg: 600
strong_writes_quota: 3
periodic_writes_quota: 1
triggers:
tau_keep: 0.72
tau_archive: 0.35
reflect_threshold: 3
write_cooldown_turns: 5
backfill_k_turns: 20
retrieval:
k_l1: 32
k_l2: 16
depth: 2
fanout: 4
rerank_top: 64
use_bm25: true
use_e5: true
use_colbert_lite: true
use_monot5_small: true7. 实验设计
7.1 模块级对照
- NER:A vs B vs C → 人/组织/地名 F1,别名误并率。
- Coref:A vs B vs C → CoNLL F1、误链/漏链。
- 关系抽取:A vs B vs C → P/R/F1,更正/否定检出。
- 时间解析:A vs B vs C → ISO 对齐率、歧义率与兜底占比。
- RBU:重复写入减少率、INSERT/REPLACE/CLOSE 分布、错误更正命中。
7.2 系统级对照(端到端)
-
方案矩阵
- P0 基线
-
- 关系抽取 B(过滤)
-
- NER B + Coref B
-
- 检索融合(BM25+E5)
-
- ColBERT-lite + 轻重排
-
- 触发器全启(强/显著/周期/回补)
-
任务:LoCoMo 长程 QA;LongMemEval 的 Knowledge Updates / Temporal Reasoning / Abstention。
-
指标:EM、Acc-AR/AW、Time-Consistency-F1、Temporal-Conflict-Rate↓、Hit@k/nDCG@k、p50/p95、读/写 tokens、LTM 增速。
7.3 消融
−bitemporal, −t_visible, −temporal-critique(占位), −Episode, −periodic, −backfill, −salience, −ColBERT-lite
8. 数据与标注
-
抽取标注:LoCoMo/LongMemEval 各抽 1–2k 句,标实体/关系/时间/否定,用于 NER/关系/时间模块校准。
-
一致性套件:合成案例
- “先停止相信(record.end)后世界才改变(valid.end)”
- 延迟别名合并
- 跨会话修正
验证 AR 泄漏=0、
t_visible单调。
-
切分:train/dev/test = 8/1/1;跨会话均衡。
9. 指标与门槛(Go/No-Go)
-
系统级
- Acc-AR/AW ≥ 强基线(等模型等 token)。
- Temporal-Conflict-Rate(AR)=0;Time-Consistency-F1 显著↑。
- nDCG@10 ≥ 基线 +5%;p95 ≤ 基线。
-
成本
- 写 ≤ 120 tokens/会话;读 ≤ 600 tokens/问答;事件/事实增长可控。
-
模块级
- NER F1 ≥ 0.90;别名误并 ≤ 3%。
- 关系抽取 P≥0.90、R≥0.80;更正检出 ≥ 0.90。
- 时间解析 ≥ 0.95。
10. 产物清单(可复现实验包)
-
工件:
snapshots/*.jsonl(DSL 回放源)queries/*.jsonl(QA 与检索请求)packed_subgraphs/*.json(证据包)configs/p1.yaml、随机种子reports/*.csv(指标明细)、figs/*.png(图表)
-
图表/表格(必须项)
- 表 A:模块指标(NER/Coref/关系/时间)
- 表 B:RBU 写入分布与重复写减少率
- 表 C:检索融合/重排对照(Hit@k/nDCG@k/p95)
- 表 D:端到端 Acc-AR/AW 与 Time-Consistency-F1
- 图 1:Accuracy–Cost Pareto
- 图 2:读/写 tokens CDF 与 p95
- 图 3:LTM 规模增长 vs 触发器配置
- 图 4:AR 无泄漏对抗集结果
11. 风险与兜底
- 误抽取/过写:白名单+类型约束;写入冷却≥5 轮;低置信仅入 WM。
- 别名漂移:追加式
alias_of;AR 禁未来合并;冲突保留多别名并存。 - 检索退化:RRF 融合自适应;召回不足触发回补写入。
- 成本超标:强触发≤3/会话,周期≤1/会话;超预算早停与降采样。
12. 路线与里程碑
- Gate-A(抽取就绪):NER/关系/时间达门槛;RBU 单测全过(单开放版本、起点单调)。
- Gate-B(检索就绪):nDCG@10≥基线+5%,p95 ≤ 基线。
- Gate-C(端到端):Acc-AR/AW ≥ 强基线;写≤120、读≤600;AR 泄漏=0。
- 提交:实验包 + 图表 + 复现脚本(
scripts/run_p1.sh)+ 报告(reports/p1_summary.md)。
13. 备注(实现入口)
modules/extract/entities.py: extract_entities(turn)->List[...]modules/extract/coref.py: resolve_coref(turn, context, entities)->Mapmodules/extract/relations.py: extract_relations(sentences, entities, coref)->List[Triple]modules/assimilation/rbu.py: diff_and_emit(triples, snapshot_AR, ts)->List[DSL]modules/events/builder.py: build_or_merge_events(dsl, turn, snapshot_AR)->List[DSL]modules/retrieval/eagle_v1.py: search(query, t, view, budget)->PackedSubgraphpipelines/eval_runner.py: run_all(config)->reports/*