lzf_0626
9490e5043b
记忆系统演示文档 + 修掉两处会让演示断链的真问题
## 新增:docs/演示用/记忆系统演示文档-2026-09-14.md
按"操作 → 看到什么 → 这体现什么"写,五个场景(探针看存储 / 记住一件事 / 谁能读谁读不到 /
画像版本与投影 / 停 Worker),每个场景配可复现命令与**实测输出**,另附建议顺序与时长、
六条问答话术、演示前自检清单、受控信号词表摘录。
配套两个新工具(都已实跑):
- `tools/memory_demo_chain.py`:一键走完"客户说 → 候选 → 客户确认 → 管理员批准 →
记忆与画像自动收敛",打印演示前后对比(实测 2 秒收敛)。
- `tools/memory_recall_demo.py`:同一客户换六个身份召回,当场看出"客户只读自己 /
员工要权限码+归属 / 运营读不到 / 管理员有权限码但没归属也读不到"。
## 修掉两处会让演示当场断链的问题(都是真机复现的)
1. **候选批准后画像字段不收敛**
`CustomerProfileCandidateService._promote` 只写画像快照、**不投**
`profile.rebuild_requested`,而 `user_facts` 与画像字段是 `ProfileAssemblyService`
的重建链路写的。后果:批准后记忆变 active、快照版本 +1,但**画像字段停在旧值**
(客户说"三年以内",画像里还是"十年以上"),要等一次无关的重建才收敛 ——
而"客户说完 → 批准 → 画像变了"正是演示主线。
现补一条重建事件(走事件而不是就地重建:本方法所在事务还没提交,
另开 session 看不到刚写入的记忆)。
2. **画像快照的唯一键从来没起作用,而且埋雷**
`uk_profile_snapshot_current` 建在列 `current_customer_id` 上(不是 `is_current`),
但 `ProfileAssemblyService._write_snapshot` 旧行只置 `is_current=False`(不清该列)、
新行**不写**该列(实测 13 行该列全 NULL)。
后果:只要客户**先被重建过一次**,旧 current 行仍占着 `current_customer_id=9001`,
下一次"批准画像候选"就会撞 `Duplicate entry '9001' for key
uk_profile_snapshot_current` → **整次批准 500**(本次实测踩到)。
现按唯一键的真实语义写:清旧行的该列、新行显式写客户号。
(`ProfileGenerationService` / 候选路径本来就是这么写的,只有这一处没对齐。)
## 守卫
新增 `tests/integration/test_profile_snapshot_current_invariant_mysql.py`:
按真实顺序"先重建再批准候选",断言 ① 只有一条 current 且它占着唯一键、
② 历史版本已归还该列、③ 批准不再 500、④ 批准投出了重建事件。
修复前这条用例会在第 ② 步失败。
## 验证
- `pytest tests/unit tests/contract` → 1490 passed, 2 skipped, 0 failed
- 新增集成用例通过;真机实测演示主线:候选 → verified → active → **2 秒内**
`user_facts` 与 `fin_customer_profile.investment_horizon` 都变成新值
- `mypy tools/memory_demo_chain.py tools/memory_recall_demo.py` → 0 错;ruff 全绿
## 文档
`docs/44-演示流程.md`:配套文档清单与"记忆链路"备选场景都指向新演示文档。
2026-09-15 00:55:44 +08:00
..
2026-09-12 12:10:10 +08:00
2026-09-12 14:57:17 +08:00
2026-09-10 20:33:13 +08:00
2026-09-14 21:46:29 +08:00
2026-09-11 16:57:47 +08:00
2026-09-11 17:26:18 +08:00
2026-09-13 19:47:10 +08:00
2026-09-12 14:40:53 +08:00
2026-09-10 22:29:23 +08:00
2026-09-10 22:42:17 +08:00
2026-09-12 12:20:01 +08:00
2026-09-14 20:29:54 +08:00
2026-09-12 15:21:34 +08:00
2026-09-14 22:17:39 +08:00
2026-09-13 22:57:59 +08:00
2026-09-15 00:03:23 +08:00
2026-09-10 20:15:09 +08:00
2026-09-12 15:21:34 +08:00
2026-09-10 20:29:12 +08:00
2026-09-11 16:57:47 +08:00
2026-09-11 10:13:48 +08:00
2026-09-15 00:41:59 +08:00
2026-09-13 19:39:16 +08:00
2026-09-10 17:11:52 +08:00
2026-09-11 16:57:47 +08:00
2026-09-11 16:57:47 +08:00
2026-09-10 18:14:03 +08:00
2026-09-14 22:56:42 +08:00
2026-09-12 12:09:55 +08:00
2026-09-15 00:41:59 +08:00
2026-09-14 22:16:29 +08:00
2026-09-14 01:07:43 +08:00
2026-09-12 14:43:05 +08:00
2026-09-13 22:28:42 +08:00
2026-09-11 14:46:40 +08:00
2026-09-11 21:03:58 +08:00
2026-09-11 21:03:58 +08:00
2026-09-09 21:55:37 +08:00
2026-09-12 12:20:01 +08:00
2026-09-10 20:22:53 +08:00
2026-09-10 22:34:20 +08:00
2026-09-12 10:34:28 +08:00
2026-09-14 01:59:46 +08:00
2026-09-11 16:57:47 +08:00
2026-09-15 00:55:44 +08:00
2026-09-15 00:55:44 +08:00
2026-09-11 16:57:47 +08:00
2026-09-12 10:45:40 +08:00
2026-09-09 21:55:37 +08:00
2026-09-09 21:55:37 +08:00
2026-09-14 01:59:46 +08:00
2026-09-13 16:20:39 +08:00
2026-09-14 20:35:46 +08:00
2026-09-11 20:30:27 +08:00
2026-09-11 14:24:45 +08:00
2026-09-11 16:51:52 +08:00
2026-09-14 20:35:46 +08:00
2026-09-14 20:35:46 +08:00
2026-09-11 16:51:52 +08:00
2026-09-11 14:19:05 +08:00
2026-09-11 16:28:19 +08:00
2026-09-12 14:40:53 +08:00
2026-09-13 19:17:56 +08:00
2026-09-13 18:54:09 +08:00
2026-09-11 10:13:48 +08:00
2026-09-14 18:13:10 +08:00
2026-09-11 19:51:44 +08:00
2026-09-13 22:08:04 +08:00
2026-09-11 14:46:40 +08:00
2026-09-10 21:36:23 +08:00
2026-09-10 21:55:03 +08:00
2026-09-11 15:25:45 +08:00
2026-09-11 15:25:45 +08:00
2026-09-11 17:26:18 +08:00
2026-09-11 16:57:47 +08:00
2026-09-14 21:46:29 +08:00
2026-09-11 14:46:40 +08:00
2026-09-14 10:03:07 +08:00
2026-09-14 20:50:55 +08:00
2026-09-13 21:56:27 +08:00
2026-09-11 14:46:40 +08:00
2026-09-12 14:43:05 +08:00
2026-09-13 21:44:08 +08:00
2026-09-14 20:48:18 +08:00
2026-09-13 22:28:42 +08:00
2026-09-15 00:41:59 +08:00
2026-09-12 14:43:05 +08:00
2026-09-11 14:46:40 +08:00
2026-09-12 10:45:40 +08:00
2026-09-11 16:57:47 +08:00
2026-09-12 12:10:10 +08:00
2026-09-11 19:51:51 +08:00
2026-09-13 21:14:13 +08:00
2026-09-11 21:03:58 +08:00
2026-09-13 23:38:13 +08:00
2026-09-11 13:05:33 +08:00
2026-09-11 10:27:29 +08:00
2026-09-11 16:57:47 +08:00