Skip to content

长期开启实体抽取后的 entities 表膨胀:归档孤儿残留、包名版本号分裂与单次噪音 #688

Closed

Description

@xueyue33

开了 entityExtractionEnabled 跑了一段时间后看了一眼 SQLite,发现活跃记忆只有 ~1650 条(另有 ~3140 条已归档),但 entities 表已经涨到了 12,700+ 行(配了 38,500+ 条关系边),库体积也跟着涨到了 400MB+。

只读统计了一下这 1.27 万个实体的分布,主要有三块水分:

  1. 记忆归档后留下的孤儿实体占了 41%(5,240+ 行)
    这批实体通过 canonical_memory_id、entity_attrs、entity_relations 关联的所有记忆其实都已经 archived = 1 了,但归档记忆和 sleep 维护时没有回收无活跃引用的实体,节点和边一直留在图谱里。
  2. 全库只提过 1 次的实体占了 72%(mention_count = 1 共 9,170+ 行)
    真正出现 4 次以上的核心实体只有 ~1,390 个(11%)。单次实体里混进了不少命令行参数(如 --preset)、路径片段(如 /root/)、协议报错短语等一次性词,进图谱基本起不到串联作用。
  3. src/store.js:4592 findEntityByName 仅做字面精确匹配(WHERE name = ?),同一对象裂变成十几个节点
    • 纯大小写/空格差异就有近 400 组重复(如 Python / python、Web Profile / web profile);
    • 带上 @scope/ 和版本号后缀更明显:比如光 dsh-mneme 自己在表里就裂成了 16 个独立实体(dsh-mneme、@modusensus/dsh-mneme、dsh-mneme@0.9.4、dsh-mneme 0.9.5、@modusensus/dsh-mneme@0.10.0 等),DSH 也裂成了 9 个。这会导致 entityRecall 和 graphAnchoring 命中其中一个名字时,挂在其它版本分身底下的边串不起来。

几点小建议供参考:

  • 入库归一化:匹配实体时忽略大小写与首尾空白;遇到包名带 @x.y.z / vX.Y 版本后缀时剥离到主包名(具体版本号如果有用更适合落 entity_attrs);
  • 孤儿回收:在 sleep 维护轮加一步轻量清理,把名下已经没有任何活跃记忆引用的孤儿实体(及对应死边)清掉或归档;
  • 抽取收紧:提示词里明确排除命令行 flag、裸路径片段、网段等非命名实体。

Activity

  1. added
    area:storage存储层(SQLite/表/索引)
    in-progress有人在改(Ephor 接手)
    fixed已修并合并进 main
    and removed
    in-progress有人在改(Ephor 接手)
    fixed已修并合并进 main
    on Nov 13, 2026
  2. added a commit that references this issue on Nov 13, 2026
  3. modusensus commented on Nov 13, 2026

    @modusensus
    Member

    写入侧已在 #690 落地(合并 commit eb47f674),存量按评审结论不动:

    1. 查找键归一化:findEntityByName 改为 lower(trim(name)) + type 双键匹配,并加表达式索引;createEntity 落库只去首尾空白、保留原始大小写,不剥版本号后缀(DeepSeek-V3/V4 是两个不同对象)。
    2. 不加类型维度会误并 95 组(实测),所以类型始终参与比较。
    3. 删掉预留列 entities.canonical_memory_id:v0.7.1 引入、从未接过线(sqlite_master 里无 view/trigger/index 引用它,25,474 行全 NULL),走幂等迁移(PRAGMA table_info 判断 + ALTER TABLE ... DROP COLUMN)。迁移成本实测:25,474 行旧 schema 首开 396ms、二次 24ms。

    存量实体不合并:实体 id 是 randomUUID(),合并要重指 59,715 行关系表且无唯一约束,会造出重复边;按报告口径实测,mention_count=1 占 75%、按 entity_relations.memory_id 连接口径的真孤儿是 17.9%(不是 41%),量级不足以支撑一次高风险重写。写入侧归一化会止住新增重复(同类型内 lower+折叠空白 实测可减 173 个实体,0.68%)。

    注意:降级是单向门 —— 旧代码没有 addColumn,把插件降回仍带该列的版本后 UPDATE/INSERT 会报 no such column,实体与关系停止落库(记忆写入不受影响),直到重新升级。降级前请先备份 memory.db。这条已写进 CHANGELOG。

  4. added
    fixed已修并合并进 main
    and removed
    in-progress有人在改(Ephor 接手)
    on Nov 13, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    area:entities实体抽取与图谱area:storage存储层(SQLite/表/索引)fixed已修并合并进 main

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions