issue #127: 画像常驻注入接入自然遗忘曲线(ADR-0009) #132
Loading…
Add table
Add a link
Reference in a new issue
No description provided.
Delete branch "feat/127-profile-forgetting-curve"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Closes #127
实现内容
把 ADR-0009 已 ADOPTED 的"自然遗忘曲线"概念(此前只用于事件记忆的三因子召回)扩展到画像常驻注入判断上:是否留在冻结快照里,不再是无条件全量渲染。
一、importance 字段全链路穿参
ProfileFactModel新增可空importance列(无迁移文件,符合可空列约定)_EXTRACT_MEMORIES_TOOL的facts[]schema 新增importance属性(未加入required,与 events/knowledge 一致),_parse_candidate复用既有_resolve_importanceProfileFact补上updated_at(ProfileFactModel早有此列,_to_fact之前没带出来)与importance;ProfileCandidate新增importance(不带默认值,强制每个构造点显式决定)delta.py:真实 LLM 值(复用_resolve_importance,未指定时兜底 5)runtime_loop.py::_handle_update_profile(update_profile工具):缺省 10(无 LLM 打标可蹭,"可变尾部=权威覆盖"语义下取高值而非中值)reflection.py:缺省 5(中性)cross_platform_pull.py:缺省 5(中性)二、
render_profile_snapshot接入遗忘曲线降权now/half_life_seconds/threshold入参,判定函数_is_retained:weight = recency_decay(age_seconds, half_life_seconds) + importance/10(加法非乘法)runtime_loop.py的_full_frozen_snapshot与_run_event_driven_turn,entry_drive_tick.py的近期摘要RuntimeLoopConfig新增profile_retention_half_life_seconds/profile_retention_threshold两个字段(沿用max_relationship_lines_per_turn的既有先例:两处调用点各自持有配置读取)config.py新增对应两个配置项:arise_profile_retention_half_life_seconds默认 30 天,arise_profile_retention_threshold默认 0.0(数学上关闭态)gather_profile_facts喂给压缩 prompt 的current_profile不降权——判断逻辑完全放在render_profile_snapshot内部,未触碰gather_profile_facts三、两处 AC 要求显式裁定的语义空白
updated_at(而非新增created_at):ADR-0009 2026-07-10 更新节原文已定性"画像无单条时间戳概念,只有画像级'最后更新时间'",_upsert_fact的重复断言刷新语义(反复被提及的事实不该老化)与这个锚点选择天然吻合importance=None:跳过降权判断、恒渲染,不代入任何具体数值参与计算——不能照抄EventRecord.mood=None→判0的先例,那是加法中性项判 0 无害,画像场景判 0 会直接把全部存量条目淘汰掉未做的事(按 AC 红线)
未加硬条目数上限、字符预算、淘汰/物理删除机制——ADOPTED 决策原样维持,未推翻。
设计决策的对抗校验
实现前用独立三路对抗校验推翻了两处初始倾向:
测试与验证
facts[].importance解析、config 到RuntimeLoop两处调用点的接线)全部可被单独抓住storage.py:2038/2324,不在本次 diff 涉及的行号范围内)docs/adr/0009-memory-engineering.md已补更新节(docs 分支本地提交,按约定不推送)两轴 review
Standards + Spec 双维度审查 + 独立对抗校验,共同确认了同一处问题:新增测试类
TestFactImportanceFlowsThroughToStorage的插入锚点选在TestSingleChatWithPendingDelta第一个方法之后而非类块末尾,导致该类另外两个既有方法被误吞进新类(语义无关,纯组织性问题,不影响执行结果)。已在本 PR 内以单独 fix commit 修正,归还给原类,重跑全量测试+ruff 确认无回归。🤖 Generated with Claude Code