Files
memind/docs/architecture/jkriver-sleep-reference.md
T
john 908db04b67 Document Experience schema and JKRiver read-only references.
Map Mi-Memory Structure/Expansion into h5_experience V1 fields and record JKRiver Sleep design lessons under AGPL constraints, plus post-fix MemFuseBench numbers.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-09-02 10:04:44 +08:00

165 lines
6.5 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# JKRiver Sleep Pipeline 只读参考
日期: 2026-09-02
状态: **架构级参考文档**。JKRiverRiverse)源码位于 `~/Project/jkriver`**AGPL-3.0 / 商业双授权**,禁止将其实现移植进 Memind 商业 SaaS。本文只记录可安全采用的**设计决策**与**反面教训**,供 `memory-v2-lifecycle.mjs` 未来填槽时对照。
## 0. 授权边界(必读)
JKRiver `LICENSE`**Dual License**
- 开源:AGPL-3.0(网络服务需开源修改版)
- 商业:需联系 mailwangjk@gmail.com
Memind 103 生产为商业 SaaS → **不得复制** `agent/sleep/*.py``agent/storage/*.py` 的实现。允许:
- 读源码理解事务边界、幂等策略、数据模型取舍
- 在 Memind 内**独立设计**语义等价的 JS 逻辑
- 引用公开概念(Sleep Consolidation、supersede、evidence linking
禁止:
- 逐行翻译 Python → JavaScript
- 嵌入 JKRiver 代码片段
- 在未取得商业授权前声称「基于 JKRiver 移植」
Mi-MemoryMIT)无此限制;JKRiver 有。
## 1. 忽略清单(与 Memind 重叠)
JKRiver 下列模块**不建议**研究或集成——Memind 已有等价或更完整实现:
| JKRiver 模块 | 原因 |
|---|---|
| Agent / Web Chat / Telegram | 重叠 `wechat-mp`, Portal chat |
| Skills / Task Agent | 重叠 `skills-registry`, `chat-skills` |
| MCP 集成 | 重叠 Goose MCP extension |
| Proactive messaging | 重叠 `schedule-reminder-worker`, `notification-dispatcher` |
| Finance / Health 领域 storage | 领域耦合,与 `h5_user_memory_items` 模型不兼容 |
## 2. 值得读的核心:`agent/sleep/`2324 行)
### 2.1 14 步流水线(`orchestration.py`
```
load_initial → extract_sessions → analyze_behavior → classify_and_integrate
→ cross_verify → resolve_disputes → extract_edges → expire_facts
→ maturity_decay → user_model → trajectory → consolidate → snapshot → finalize
```
与 Memind 此前画的 Sleep 图相比,JKRiver **多五步**
| 步骤 | 作用 | Memind 对应空槽 |
|---|---|---|
| `cross_verify` | 交叉验证新 fact | 无 |
| `resolve_disputes` | 争议 fact 仲裁(`disputes.py` 231 行) | 无 |
| `user_model` | 用户模型更新 | `user-memory-profile` 部分覆盖 |
| `trajectory` | 长期轨迹 / key_anchors | 无 |
| `consolidate` + `snapshot` | 预编译快照 | `memory-v2-lifecycle.compact()` 占位 |
Memind V1 只需关注后四个 maintenance 步映射到 lifecycle
| JKRiver 步骤 | `memory-v2-lifecycle.mjs` | 现状 |
|---|---|---|
| `expire_facts` | `expire()` | flag 关,逻辑有 |
| `maturity_decay` | decay(无独立函数) | **未实现** |
| `promote`classify 隐含) | `promote()` | candidate→item INSERT IGNORE |
| `consolidate` | `compact()` | `mode: 'candidate-only'` |
| `reflect`trajectory 隐含) | `reflect()` | `mode: 'observation-only'` |
### 2.2 事务与幂等(**可安全采用的设计**)
`orchestration.py` 核心模式:
```python
with transaction():
_run_sleep_pipeline_inner(...)
# finalize 步才 mark_processed()
# 崩溃 → 整批回滚 → 下次重跑(at-least-once
# embedding / clustering 在事务外,失败只 warning
```
Memind 现状:`expire` / `compact` / `promote` / `reflect` **各自独立调用**,无共同事务边界,无 processed 水位。
**可独立采用的设计决策**(不是代码):
1. Consolidation 批次必须在单 DB 事务内
2. `mark_processed` / 水位标记必须在流水线**最后一步**
3. 非关键后处理(embedding、聚类)放在事务外
4. `LLMPipelineError` 单独处理:LLM 不可用则 abort 整批,不部分提交
### 2.3 Maturity Decay 语义(`_maturity.py`17 行)
```python
_MATURITY_TIERS = [(730, 10, 730), (365, 6, 365), (90, 3, 180)]
# if new_decay > current_decay: update (只增不减)
```
这是 **保留期延长**,不是置信度衰减:
- 跨度 ≥730 天且 evidence ≥10 → `decay_days` 延到 730
- 命中 `key_anchors` 时门槛 ×0.6
与 Memind `experience-service.mjs` 的 **30 天半衰期指数衰减**相反。若 Personal Memory 填 decay 槽,必须先做语义选择,不能混用。
### 2.4 Fact 模型(与 Memind 差距)
JKRiver fact`category`, `subject`, `value`, `start_time`, `supersedes`, `superseded_by`, `decay_days`, `evidence[]`
Memind `h5_user_memory_items``label`, `memory_text`, `confidence`, `status`, `evidence_message_id`
这是**换模型**,不是加字段。JKRiver consolidation 算法 tied to 前者,不能直映射。
## 3. 反面教训:`008_drop_hypotheses.sql`
```sql
-- hypotheses 表一直是 0 行,无生产读写
-- 被 user_profile (layer 'suspected'/'confirmed' + supersedes) 完全取代
DROP TABLE IF EXISTS hypotheses CASCADE;
```
对 Memind 的含义:
1. **不要把 `hypothesis` 做成独立表或必填字段**Experience schema 已采纳:`hypothesis` 可空)
2. 未验证的推断应表达为 `layer=suspected` + `supersedes` 链,而不是平行 hypotheses 存储
3. 建表前先证明有读写路径,否则 0 行表最终被删
## 4. Memind 填槽优先级(JKRiver 启发,自行实现)
`memory-v2-lifecycle` flag 打开 + MemFuseBench 基线稳定后:
| 优先级 | 函数 | JKRiver 启发 | 自行实现要点 |
|---|---|---|---|
| P0 | 事务边界 + 水位 | `orchestration.transaction()` | MySQL 事务包裹 promote+expire |
| P1 | `promote()` supersede | `classify_and_integrate` | candidate 冲突时 supersede 而非 INSERT IGNORE |
| P2 | `expire()` + verify | `expire_facts` + verify strategy | 过期写 verify 候选,不静默删 |
| P3 | decay 延长 | `maturity_decay` | 按 evidence 计数延长 retention,非指数衰减 |
| P4 | `compact()` | `consolidate` + `snapshot` | 保守:只报告 eligible,不覆盖源 |
| P5 | `reflect()` | `trajectory` + disputes | 需 Experience 结构化数据先就绪 |
## 5. 何时启动 JKRiver 填槽
三门(与 `memfuse-bench-baseline.md` 一致):
1. `h5_memory_v2_candidates` 有真实流量
2. lifecycle `rolloutMode` 至少 `canary`
3. MemFuseBench / recall benchmark 有**可对比的**前后基线
当前(2026-09-02):仅第 3 项部分满足(MemFuseBench 已可跑)。lifecycle 仍 `off`**不启动填槽实现**
## 6. 本地材料
```bash
# 已 clone,不在 Memind 仓库内
~/Project/jkriver
~/Project/mi-memory # MIT,含 MemFuseBench 数据集
```
关键路径:
- `agent/sleep/orchestration.py` — 流水线入口
- `agent/sleep/steps_maintain.py` — expire / maturity
- `agent/sleep/disputes.py` — 争议解决
- `migrations/008_drop_hypotheses.sql` — 反面教训