Skip to content

fix(LongMemEval): 让 L2 在保持可检索陈述的同时保留来源证据,避免抽取、分层和向量索引的静默失败,并确保扩大的 L2 不干扰去重。 - #42

Open
openjiuwen-sync-bot[bot] wants to merge 4 commits into
openJiuwen-ai:mem2.0from
openjiuwenai:sync/pr-158

Conversation

@openjiuwen-sync-bot

@openjiuwen-sync-bot openjiuwen-sync-bot Bot commented Jul 29, 2026

Copy link
Copy Markdown

Paired: GitHub #42GitCode !158

What type of PR is this?

/kind

Self-checklist:(请自检,在[ ]内打上x,我们将检视你的完成情况,否则会导致pr无法合入

    • 设计:PR对应的方案是否已经经过Maintainer评审,方案检视意见是否均已答复并完成方案修改
    • 测试:PR中的代码是否已有UT/ST测试用例进行充分的覆盖,新增测试用例是否随本PR一并上库或已经上库
    • 验证:PR描述信息中是否已包含对该PR对应的Feature、Refactor、Bugfix的预期目标达成情况的详细验证结果描述
    • 接口:是否涉及对外接口变更,相应变更已得到接口评审组织的通过,API对应的注释信息已经刷新正确
    • 文档:是否涉及官网文档修改,如果涉及请及时提交资料到Doc仓

本次修改为 infer=true 增加了默认关闭的无损 Source Snapshot:抽取成功后,每份原始输入只额外保存并索引一次,供普通召回补回 LLM 漏抽的信息,但不会参与后续抽取、L0/L1 分层、去重、合并、关联或遗忘;同时通过去重扩窗避免 Snapshot 挤占语义候选,并用确定性 ID 和幂等重试防止重复写入。

@CLAassistant

Copy link
Copy Markdown

CLA assistant check
Thank you for your submission! We really appreciate it. Like many open source projects, we ask that you sign our Contributor License Agreement before we can accept your contribution.
You have signed the CLA already but the status is still pending? Let us recheck it.

@openjiuwen-collaboration-bot

openjiuwen-collaboration-bot Bot commented Jul 29, 2026

Copy link
Copy Markdown

head_sha: 9605580454c80012608285d2514f9277cbfa9e3c

变更摘要

本 PR 引入了一项可选的「无损源快照」(lossless source snapshots)功能:当配置项 preserve_source_snapshots 开启时,Evolver 在处理 infer=true 的语义单元后,会将原始输入内容以一条内部快照(source_snapshot=true)的形式持久化,确保原始证据可被全文/向量检索召回,同时保证快照不会挤占语义去重的 top-k 窗口。核心思路是在 Dedup 中新增 recall_for_evolution() 方法,当快照占用召回结果时自动扩展搜索窗口以获取足够的语义候选,并在所有 Evolver 路径中过滤掉快照,使其不参与语义决策(CONSOLIDATE、ASSOCIATE、FORGET 等)。

主要改动

  • 新增 recall_for_evolution() 去重召回接口:在 Dedup 基类添加默认委托到 recall()recall_for_evolution()KeywordDedupVectorDedup 分别实现快照感知的扩展召回逻辑——当 top-k 被 source snapshot 占据时,逐步倍增 search_ksource_snapshot_scan_limit,确保返回足够语义候选。
  • 新增源快照构建与持久化OrchestratingEvolver 新增 _build_source_snapshots()(基于 UUID5 生成确定性快照 ID、复制 segments/temporal/provenance 等字段并标记 source_snapshot=true)和 _persist_source_snapshots()(幂等插入 KVStore 与 Index),在 EXTRACT 路径末尾调用。
  • 所有 Evolver 路径过滤快照:新增静态方法 _semantic_units() 过滤 source_snapshot=true 的单元,EXTRACT/CONSOLIDATE/ASSOCIATE/FORGET 各路径均先过滤再处理;_recall_for_evolution() 对召回结果二次过滤,确保快照不会作为语义候选进入 LLM 判定或关系关联。
  • messages_key 持久化幂等性增强_persist_and_maintain_messages() 引入 insert_idempotently() 辅助函数,避免重复插入冲突;同时修复本轮新原文被重复添加到 historical 列表的问题。
  • 配置与元数据保留RESERVED_METADATA_KEYS 加入 "source_snapshot" 以阻止外部写入;配置模板新增 preserve_source_snapshotsdedup_source_snapshot_scan_limit 两个可选参数。

@openjiuwen-collaboration-bot

openjiuwen-collaboration-bot Bot commented Jul 29, 2026

Copy link
Copy Markdown

head_sha: 9605580454c80012608285d2514f9277cbfa9e3c

代码审查

审查总结

对全部 18 个变更文件逐一审查完毕。发现 2 个问题,均为 P2 级别,位于 src/construction/evolver_impl/orchestrating_evolver.py

优先级 数量
P0 0
P1 0
P2 2
P3 0

各文件审查结果:

  • docs/features/api/F02-write-infer-extract.md — 无问题(仅新增 F05 引用)
  • docs/features/construction/F05-lossless-source-snapshots.md — 无问题(新特性文档)
  • docs/specs/S02-memory-api.md — 无问题(新增 F05 引用和可选无损证据说明)
  • docs/specs/S03-control.md — 无问题(新增 F05 引用和 snapshot 注释)
  • docs/specs/S05-construction.md — 无问题(新增 F05 引用和隔离规则 11)
  • examples/config_template.yml — 无问题(新增 dedup 段和 evolver params 示例)
  • src/common/type_def/memory.py — 无问题(source_snapshot 加入 RESERVED_METADATA_KEYS
  • src/construction/AGENTS.md — 无问题(新增规则 15 文档)
  • src/construction/common.py — 无问题(新增 is_source_snapshot 辅助函数)
  • src/construction/dedup.py — 无问题(新增 recall_for_evolution 默认兼容方法)
  • src/construction/dedup_impl/keyword_dedup.py — 无问题(新增扩窗召回逻辑)
  • src/construction/dedup_impl/vector_dedup.py — 无问题(新增扩窗召回逻辑)
  • src/construction/evolver_impl/dynamic_evolver.py — 无问题(正确集成 snapshot 支持)
  • src/construction/evolver_impl/orchestrating_evolver.py2 个 P2 问题
  • src/control/AGENTS.md — 无问题(新增 preserve_source_snapshots 说明)
  • tests/unit/api/test_write_reserved_metadata.py — 无问题(新增 reserved key 测试参数)
  • tests/unit/construction/test_dynamic_extraction_consolidation.py — 无问题(新增 snapshot 测试用例)
  • tests/unit/construction/test_evolver_dedup.py — 无问题(新增 TestLosslessSourceSnapshots 测试类)

整体风险判断:中低。 核心 snapshot 功能的逻辑设计合理,_recall_for_evolution 的扩窗算法正确,幂等重试机制完备。两个已报告的问题均为边界场景:消息维护重试时的静默丢数据需要特定条件触发,procedural 路径的 snapshot 泄漏需要异常输入组合。建议优先修复消息维护的静默丢数据问题(影响面更大),procedural 路径的过滤一致性问题可作为防御性加固处理。

类型 数量
🔴 阻塞 0
🟡 建议 1

💬 仅评论

@openjiuwen-collaboration-bot

Copy link
Copy Markdown

head_sha: 58bbcd1892df8324ca65010a72e3143e2897b8d0

任务名称 结果 日志操作
静态检查 ❌FAILED 点此跳转
防投毒检查 ✅SUCCESS 点此跳转
开源合规检查 ✅SUCCESS 点此跳转
UT测试 ✅SUCCESS 点此跳转
ST测试 N/A N/A
build 编译包 N/A N/A
ruff codecheck ✅SUCCESS N/A

@openjiuwen-collaboration-bot

Copy link
Copy Markdown

head_sha: 9605580454c80012608285d2514f9277cbfa9e3c

任务名称 结果 日志操作
静态检查 ✅SUCCESS 点此跳转
防投毒检查 ✅SUCCESS 点此跳转
开源合规检查 ✅SUCCESS 点此跳转
UT测试 ✅SUCCESS 点此跳转
ST测试 N/A N/A
build 编译包 N/A N/A
ruff codecheck ✅SUCCESS N/A

self._kv.insert(scope, messages_key(u.id), dumps(u))
insert_idempotently(u)
evicted = 0
for key, _u in historical[self._recent_originals_limit:]:

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

head_sha: 9605580454c80012608285d2514f9277cbfa9e3c

🟡 Medium Priority

变更行:_persist_and_maintain_messagesinsert_idempotently 内联函数(第 816-822 行)与删除循环(第 863 行)的交互。

证据链:

  1. units 中的某个单元在 KV 已存在(重试场景),其旧条目通过 kv.list 加载到 historical 中(第 836-841 行)。
  2. 由于 existing_keys 集合已包含该 key,该单元不会被再次添加到 historical(第 847 行 if key not in existing_keys 跳过)。
  3. 第 860-861 行先调用 insert_idempotently(u) —— 因内容相同,ConflictError 被捕获,静默成功(no-op)。
  4. 第 863 行 for key, _u in historical[self._recent_originals_limit:] 执行淘汰删除:若该单元的旧条目因 t_ingest 排序落到了保留窗口(默认 10 条)之外,其 key 被 self._kv.delete 删除。

失效模式: 重试时,若该单元原本在 /messages/ 的旧记录因其他新消息的插入被挤出保留窗口,insert_idempotently 的 no-op 不产生新记录,而后续删除循环会删掉唯一的旧记录——导致该消息从 /messages/ 静默丢失。旧代码在此场景会因 kv.insertConflictError 而响亮失败;新代码静默丢数据,更危险。

建议:方案一(最小改动):在删除循环中跳过本轮 unit 的 key。在删除循环前构造 current_keys = {messages_key(u.id) for u in units},循环内 if key in current_keys: continue。方案二(语义更清晰):将 insert 移到删除之后执行,这样即使旧记录被淘汰也会被重新写入。

@openjiuwen-collaboration-bot

Copy link
Copy Markdown

head_sha: 4c702069320eb8a96b6eec88d5b69e9525971f56

任务名称 结果 日志操作
静态检查 ❌FAILED 点此跳转
防投毒检查 ✅SUCCESS 点此跳转
开源合规检查 ✅SUCCESS 点此跳转
UT测试 ✅SUCCESS 点此跳转
ST测试 N/A N/A
build 编译包 N/A N/A
ruff codecheck ✅SUCCESS N/A

@openjiuwen-collaboration-bot

Copy link
Copy Markdown

head_sha: ca5cb78e72871c52cae095fa20bd65dab3f92646

任务名称 结果 日志操作
静态检查 ❌FAILED 点此跳转
防投毒检查 ✅SUCCESS 点此跳转
开源合规检查 ✅SUCCESS 点此跳转
UT测试 ✅SUCCESS 点此跳转
ST测试 N/A N/A
build 编译包 N/A N/A
ruff codecheck ✅SUCCESS N/A

@openjiuwen-collaboration-bot

Copy link
Copy Markdown

head_sha: 35155d237a80c2265db204b9613eeee3f98dc3b8

任务名称 结果 日志操作
静态检查 ✅SUCCESS 点此跳转
防投毒检查 ✅SUCCESS 点此跳转
开源合规检查 ✅SUCCESS 点此跳转
UT测试 ✅SUCCESS 点此跳转
ST测试 N/A N/A
build 编译包 N/A N/A
ruff codecheck ✅SUCCESS N/A

@openjiuwen-sync-bot openjiuwen-sync-bot Bot changed the title feat(memory): preserve optional lossless source snapshots LongMemEval适配优化: Jul 31, 2026
@openjiuwen-sync-bot openjiuwen-sync-bot Bot changed the title LongMemEval适配优化: LongMemEval适配优化让 L2 在保持可检索陈述的同时保留来源证据,避免抽取、分层和向量索引的静默失败,并确保扩大的 L2 不干扰去重。 Jul 31, 2026
@openjiuwen-sync-bot openjiuwen-sync-bot Bot changed the title LongMemEval适配优化让 L2 在保持可检索陈述的同时保留来源证据,避免抽取、分层和向量索引的静默失败,并确保扩大的 L2 不干扰去重。 fix(LongMemEval): 让 L2 在保持可检索陈述的同时保留来源证据,避免抽取、分层和向量索引的静默失败,并确保扩大的 L2 不干扰去重。 Jul 31, 2026
@openjiuwen-collaboration-bot

Copy link
Copy Markdown

head_sha: 3e406e9c3de904d0409f92885399dbf0502a9624

任务名称 结果 日志操作
静态检查 ❌FAILED 点此跳转
防投毒检查 ✅SUCCESS 点此跳转
开源合规检查 ✅SUCCESS 点此跳转
UT测试 ✅SUCCESS 点此跳转
ST测试 N/A N/A
build 编译包 N/A N/A
ruff codecheck ✅SUCCESS N/A

@openjiuwen-collaboration-bot

Copy link
Copy Markdown

head_sha: 5dcf42ff5945ee392f13679d267f4d5d1c19d39b

任务名称 结果 日志操作
静态检查 ❌FAILED 点此跳转
防投毒检查 ✅SUCCESS 点此跳转
开源合规检查 ✅SUCCESS 点此跳转
UT测试 ✅SUCCESS 点此跳转
ST测试 N/A N/A
build 编译包 N/A N/A
ruff codecheck ✅SUCCESS N/A

@openjiuwen-collaboration-bot

Copy link
Copy Markdown

head_sha: 35155d237a80c2265db204b9613eeee3f98dc3b8

任务名称 结果 日志操作
静态检查 ❌FAILED 点此跳转
防投毒检查 ✅SUCCESS 点此跳转
开源合规检查 ✅SUCCESS 点此跳转
UT测试 ✅SUCCESS 点此跳转
ST测试 N/A N/A
build 编译包 N/A N/A
ruff codecheck ✅SUCCESS N/A

@openjiuwen-collaboration-bot

Copy link
Copy Markdown

head_sha: 35155d237a80c2265db204b9613eeee3f98dc3b8

任务名称 结果 日志操作
静态检查 ✅SUCCESS 点此跳转
防投毒检查 ✅SUCCESS 点此跳转
开源合规检查 ✅SUCCESS 点此跳转
UT测试 ✅SUCCESS 点此跳转
ST测试 N/A N/A
build 编译包 N/A N/A
ruff codecheck ✅SUCCESS N/A

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants