画像常驻注入自然遗忘曲线(ADR-0009 ADOPTED方案) #127

Closed
opened 2026-08-13 01:37:41 +00:00 by KumaAgent · 0 comments
Member

Parent

#103 第四批清单:31 条实现类落差 + 9 条待拍板(条目 11)

What to build

画像(Profile)常驻注入至今是无条件全量渲染。ADR-0009 已 ADOPTED 的补法是把既有"自然遗忘曲线"(recency×importance 降权,此前只用于事件记忆三因子召回)扩展到画像"是否留在常驻注入的冻结快照里"这个判断上——明文否决了硬条目数上限这个更直接的替代方案。

不要加硬 top-k/字符预算。 这正是原文点名否决的备选——与画像不同,ADR-0008/0015 对关系注入/触发注入是明文允许上限的,两条规则相反,不要把 issue #114(关系网独立封顶)的做法平移过来。

Acceptance criteria

  • ProfileFactModel 新增可空列 importance(本仓不随包分发 alembic 迁移,不需在本仓补迁移文件)
  • _EXTRACT_MEMORIES_TOOLfacts[]importance 属性,_parse_candidate 里复用既有 _resolve_importance(raw) 解析(events/knowledge 已有同名字段用的就是它)
  • ProfileFactimportance 字段;ProfileFactModel.updated_at 列已存在,只是 storage.py::_to_fact 没带出来——把它带出来,不需要另加 created_at(除非下面的 age 锚点裁决选了"距首次写入"这条)
  • 三个写入入口都要穿字段:delta.py::run_delta_compression_cyclereflection.py__init__.py 均经 write_tentative_factsruntime_loop.py::update_profile 工具(用户显式纠正路径)没有 LLM 打标可蹭,须显式定一个默认 importance(按"可变尾部=权威覆盖"语义,合理默认是取高值而非中值)
  • render_profile_snapshot 新增 now 入参,接上 recency × importance 降权判断;三个渲染调用点都要跟(runtime_loop.py 两处 + __init__.py drive-tick 近期摘要一处)
  • delta.pygather_profile_facts 后直接拼 current_profile 喂压缩 prompt 那条路径不经过 render,须显式裁决它要不要同样降权(不降则压缩 prompt 仍无界)

原文(docs/adr/0009-memory-engineering.md「更新(2026-07-11 第三方项目对照 grill 第三轮)」节,第 3 条 ADOPTED):

ADOPTED — 画像"常驻注入"边界改用自然遗忘曲线,而非硬上限:长期陪伴场景下画像(Profile)只增不减,本轮曾考虑给画像加一个类似 SullyOS "Room Plates" 的硬条目数上限,但最终采用更简洁的方案——把本 ADR 已有的"自然遗忘曲线"(recency×importance 降权,此前只用于事件记忆的三因子召回评分)概念扩展到画像"是否保留在常驻注入的冻结快照里"这个判断上:低 importance + 高 age 的画像条目自然跌出常驻注入范围,不需要新造一套硬上限+淘汰机制

  • 两处必须在 AC 里钉死、否则实现期会各自发挥的语义空白
    • age 的锚点_upsert_fact 每次重复提炼同一 key 都会刷新 updated_at,"age" 实为"距上次被重新断言多久",被反复提到的事实永远不会老化。若要"距首次写入多久"需要真正新增 created_at。片内须显式裁定用哪一种
    • 存量条目 importance=None 的缺省:本仓对 EventRecord.mood=None 的先例是"直接判 0、不做历史回填",但那是加法中性项,判 0 无害;画像 importance 判 0 会直接把全部存量条目淘汰掉——只能借"不回填"的精神,不能照抄"判 0"的做法,须显式定义存量条目的缺省行为
  • 不加硬条目数上限、不加字符预算、不加淘汰/物理删除机制。若实现期仍认为需要,须先在 ADR-0009 追加更新节推翻原决策,不能默不作声地做
  • 测试覆盖:tests/test_profile.py/tests/test_profile_storage.py/tests/test_delta_compressor.py/tests/test_delta_compression_cycle.py 均需补断言

Blocked by

  • #126 — 关系网 tension/affinity 双轴驱动 + 文档对齐——两片都要往同一个 _EXTRACT_MEMORIES_TOOL schema 与同一段 Delta 压缩 instruction 字符串加字段,并行改会冲突,需串行
## Parent #103 第四批清单:31 条实现类落差 + 9 条待拍板(条目 11) ## What to build 画像(Profile)常驻注入至今是无条件全量渲染。ADR-0009 已 ADOPTED 的补法是把既有"自然遗忘曲线"(recency×importance 降权,此前只用于事件记忆三因子召回)扩展到画像"是否留在常驻注入的冻结快照里"这个判断上——**明文否决了硬条目数上限**这个更直接的替代方案。 **不要加硬 top-k/字符预算。** 这正是原文点名否决的备选——与画像不同,ADR-0008/0015 对关系注入/触发注入是明文允许上限的,两条规则相反,不要把 issue #114(关系网独立封顶)的做法平移过来。 ## Acceptance criteria - [ ] `ProfileFactModel` 新增可空列 `importance`(本仓不随包分发 alembic 迁移,不需在本仓补迁移文件) - [ ] `_EXTRACT_MEMORIES_TOOL` 的 `facts[]` 加 `importance` 属性,`_parse_candidate` 里复用既有 `_resolve_importance(raw)` 解析(events/knowledge 已有同名字段用的就是它) - [ ] `ProfileFact` 加 `importance` 字段;`ProfileFactModel.updated_at` 列已存在,只是 `storage.py::_to_fact` 没带出来——把它带出来,不需要另加 `created_at`(除非下面的 age 锚点裁决选了"距首次写入"这条) - [ ] 三个写入入口都要穿字段:`delta.py::run_delta_compression_cycle`、`reflection.py`、`__init__.py` 均经 `write_tentative_facts`;`runtime_loop.py::update_profile` 工具(用户显式纠正路径)没有 LLM 打标可蹭,须显式定一个默认 importance(按"可变尾部=权威覆盖"语义,合理默认是取高值而非中值) - [ ] `render_profile_snapshot` 新增 `now` 入参,接上 recency × importance 降权判断;三个渲染调用点都要跟(`runtime_loop.py` 两处 + `__init__.py` drive-tick 近期摘要一处) - [ ] `delta.py` 里 `gather_profile_facts` 后直接拼 `current_profile` 喂压缩 prompt 那条路径**不经过 render**,须显式裁决它要不要同样降权(不降则压缩 prompt 仍无界) 原文(docs/adr/0009-memory-engineering.md「更新(2026-07-11 第三方项目对照 grill 第三轮)」节,第 3 条 ADOPTED): > **ADOPTED — 画像"常驻注入"边界改用自然遗忘曲线,而非硬上限**:长期陪伴场景下画像(Profile)只增不减,本轮曾考虑给画像加一个类似 SullyOS "Room Plates" 的硬条目数上限,但最终采用更简洁的方案——把本 ADR 已有的"自然遗忘曲线"(recency×importance 降权,此前只用于事件记忆的三因子召回评分)概念扩展到画像"是否保留在常驻注入的冻结快照里"这个判断上:低 importance + 高 age 的画像条目自然跌出常驻注入范围,**不需要新造一套硬上限+淘汰机制**。 - [ ] **两处必须在 AC 里钉死、否则实现期会各自发挥的语义空白**: - **age 的锚点**:`_upsert_fact` 每次重复提炼同一 key 都会刷新 `updated_at`,"age" 实为"距上次被重新断言多久",被反复提到的事实永远不会老化。若要"距首次写入多久"需要真正新增 `created_at`。片内须显式裁定用哪一种 - **存量条目 `importance=None` 的缺省**:本仓对 `EventRecord.mood=None` 的先例是"直接判 0、不做历史回填",但那是加法中性项,判 0 无害;画像 `importance` 判 0 会**直接把全部存量条目淘汰掉**——只能借"不回填"的精神,不能照抄"判 0"的做法,须显式定义存量条目的缺省行为 - [ ] **不加硬条目数上限、不加字符预算、不加淘汰/物理删除机制**。若实现期仍认为需要,须先在 ADR-0009 追加更新节推翻原决策,不能默不作声地做 - [ ] 测试覆盖:`tests/test_profile.py`/`tests/test_profile_storage.py`/`tests/test_delta_compressor.py`/`tests/test_delta_compression_cycle.py` 均需补断言 ## Blocked by - #126 — 关系网 tension/affinity 双轴驱动 + 文档对齐——两片都要往同一个 `_EXTRACT_MEMORIES_TOOL` schema 与同一段 Delta 压缩 instruction 字符串加字段,并行改会冲突,需串行
Yushu closed this issue 2026-08-14 05:14:05 +00:00
Sign in to join this conversation.
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set.

Reference
ProjectKuma/arise#127
No description provided.