Files
life-echo/docs/plans/memory-capability-gap.md

177 lines
7.8 KiB
Markdown
Raw Normal View History

# Memory 能力差距文档
> 面向回忆录生产的素材检索与事实组织系统 — 当前实现状态与待完成项。
---
## 一、定位与目标(来自架构计划)
本项目中的 `memory` 定义为:
- **面向回忆录生产的可检索素材资产**
- **可持续抽取、修正、确认的结构化事实层**
- **为章节生成和追问生成提供 grounding 的 RAG 基础设施**
明确不做:
- 通用「记住这个」的终端用户指令式记忆
- 聊天助手式 persona memory
- 面向终端用户的自然语言 `forget that`
---
## 二、当前已就绪部分
### 2.1 数据模型(`features/memory/models.py`
| 表 | 状态 | 说明 |
|----|------|------|
| `memory_sources` | ✅ | 原始素材主记录,含 source_type、raw_text、conversation_id、speaker、captured_at |
| `memory_chunks` | ✅ | 检索单元,含 content、embeddingpgvector、content_tsvFTS、chunk_index、is_excluded |
| `memory_summaries` | ✅ | 会话/滚动/主题摘要,含 source_chunk_ids 追溯 |
| `memory_facts` | ✅ | 候选/已确认事实,含 fact_type、subject、predicate、source_chunk_id |
| `timeline_events` | ✅ | 时间线事件,含 event_year、source_fact_ids |
| `memory_curation_actions` | ✅ | 操作轨迹exclude/restore/correct/confirm/reject |
### 2.2 接口与依赖
| 组件 | 状态 | 说明 |
|------|------|------|
| `MemoryService` 类 | ✅ | 门面已定义,`ingest_transcript``retrieve` 签名就绪 |
| `MemoirService.get_evidence()` | ✅ | 通过注入 `MemoryService` 调用 retrieve |
| `MemoirService` 注入 `MemoryService` | ✅ | `deps.py` 已配置 |
| `EmbeddingProvider` port | ✅ | OpenAI adapter 已实现 |
| `get_embedding_provider()` | ✅ | `core/dependencies.py` 已注册 |
### 2.3 骨架文件
| 文件 | 状态 | 说明 |
|------|------|------|
| `chunker.py` | 骨架 | `chunk_transcript()` 未实现 |
| `repo.py` | 骨架 | 无具体 CRUD |
| `retriever.py` | 骨架 | `HybridRetriever.retrieve()` 未实现 |
| `extractor.py` | 骨架 | `extract_facts()` 未实现 |
| `summarizer.py` | 骨架 | `generate_session_summary``generate_rolling_summary` 未实现 |
| `timeline.py` | 骨架 | 无具体逻辑 |
| `curation.py` | 骨架 | 无具体逻辑 |
---
## 三、待完成能力(按优先级)
### 3.1 写入路径Ingest
**目标**:对话结束后,将 transcript 沉淀为 memory 资产,并异步补齐 embedding、summary、fact。
| 步骤 | 当前状态 | 待实现 |
|------|----------|--------|
| 1. `MemoryService.ingest_transcript()` | `raise NotImplementedError` | 写入 `memory_sources`、切块写入 `memory_chunks`、提交主事务 |
| 2. 触发异步任务 | 无 | Celery 任务embedding 生成、summary 生成、fact 提取、timeline 构建 |
| 3. `chunker.chunk_transcript()` | `raise NotImplementedError` | 按 max_tokens/overlap 切分,支持 speaker 边界 |
| 4. `memory/repo.py` | 空 | `create_source()``create_chunks()``update_chunk_embedding()` 等 |
| 5. `memory_tasks.py` | 无 | 新增 `enrich_memory_source` 等 Celery 任务 |
**接入点**`conversation/ws/router.py``END_CONVERSATION` 分支,在 `process_conversation_segments` 之后调用 `MemoryService.ingest_transcript()`。需从 segments 聚合 transcript 文本。
### 3.2 读取路径Retrieve
**目标**混合检索metadata + FTS + vector生成 evidence bundle供 memoir 章节生成使用。
| 步骤 | 当前状态 | 待实现 |
|------|----------|--------|
| 1. `HybridRetriever.retrieve()` | `raise NotImplementedError` | metadata filter → FTS 查询 → 向量检索 → score fusion |
| 2. `MemoryService.retrieve()` | 返回空 dict | 调用 `HybridRetriever`,按 token budget 组装 evidence bundle |
| 3. `memory/repo.py` | 空 | `search_chunks_fts()``search_chunks_vector()``get_summaries()``get_facts()` |
| 4. `memory_chunks.content_tsv` | 模型有列 | 需 Alembic 迁移generated tsvector 列 + GIN index |
| 5. `memory_chunks.embedding` | 模型有列 | 需异步任务写入pgvector 索引已由 pgvector 扩展支持 |
**Evidence Bundle 结构**(已定义于 `memory/schemas.py`
```python
{
"relevant_chunks": [...],
"relevant_summaries": [...],
"relevant_facts": [...],
"timeline_hints": [...],
}
```
### 3.3 消费端接入
**目标**:章节生成必须优先使用 evidence bundle规则 26
| 消费端 | 当前状态 | 待实现 |
|--------|----------|--------|
| `process_conversation_segments` | 未调用 ingest | 无ingest 在 END_CONVERSATION 时由 router 触发) |
| `process_memoir_segments`Celery | 未使用 evidence | 在生成章节前调用 `MemoryService.retrieve()` 或通过 MemoirService 传入 |
| `generate_chapter_content`Celery | 未使用 evidence | 同上 |
| `MemoirGenerator.generate_narrative` | 仅用 slots + content | 增加 evidence 参数,拼入 prompt |
| `get_narrative_prompt` | 无 evidence 参数 | 增加 `evidence_bundle: dict` 参数,格式化后注入 prompt |
**注意**Celery 任务为同步,需通过 `get_sync_db()` 获取 session并调用 `MemoryService` 的同步版本或封装。当前 `MemoryService` 为 async需考虑
- 方案 A在 Celery 中 `asyncio.run(memory_service.retrieve(...))`
- 方案 B定义 `MemoryServiceSync``retrieve_sync` 供 Celery 使用
### 3.4 辅助能力(二期可延后)
| 能力 | 文件 | 说明 |
|------|------|------|
| fact extraction | `extractor.py` | LLM 抽取结构化事实 |
| session summary | `summarizer.py` | 会话摘要、滚动摘要 |
| timeline build | `timeline.py` | 按 event_year 组织时间线 |
| curation | `curation.py` | exclude/restore/correct 操作 |
| reranker | `ports/reranker.py` | 可选 cross-encoder 重排 |
---
## 四、实现顺序建议
1. **Phase 1写入路径**
- 实现 `chunk_transcript()`
- 实现 `memory/repo.py``create_source``create_chunks`
- 实现 `MemoryService.ingest_transcript()`
- 在 END_CONVERSATION 时调用 ingest需聚合 segments 的 transcript
2. **Phase 2异步补齐**
- 新增 `memory_tasks.py`Celery 任务embedding 生成、写入 `memory_chunks.embedding`
- 可选summary、fact 提取(可后续迭代)
3. **Phase 3读取路径**
- 实现 `repo.search_chunks_fts()``search_chunks_vector()`(需 FTS 迁移)
- 实现 `HybridRetriever.retrieve()`metadata + FTS + vector + 融合)
- 实现 `MemoryService.retrieve()` 调用 HybridRetriever
4. **Phase 4消费端接入**
- 修改 `get_narrative_prompt` 增加 evidence 参数
- 修改 `MemoirGenerator.generate_narrative` 接收 evidence
- 修改 `process_memoir_segments``generate_chapter_content` 在生成前获取 evidence 并传入
---
## 五、Alembic 迁移待办
| 迁移 | 说明 |
|------|------|
| `memory_chunks` FTS | 需 `content_tsv` 使用 `tsvector` generated column + GIN index或应用层维护 |
| 若已有 `create_all` 建表 | 需 `alembic revision --autogenerate` 生成与当前 models 一致的迁移,或手写等效 DDL |
---
## 六、依赖规则
- `conversation` / `memoir` 不得直接读写 memory 表,只能调用 `MemoryService`
- `agents/` 不得直接读写 memory 表,只能消费 evidence bundle
- `memory` 不得直接 import `adapters`,只依赖 `EmbeddingProvider` port
---
## 七、预估工作量
| 阶段 | 预估 | 说明 |
|------|------|------|
| Phase 1 写入路径 | 11.5 天 | chunker、repo、ingest、END_CONVERSATION 接入 |
| Phase 2 异步补齐 | 0.51 天 | Celery 任务、embedding 写入 |
| Phase 3 读取路径 | 11.5 天 | FTS、vector、HybridRetriever、MemoryService.retrieve |
| Phase 4 消费端接入 | 1 天 | prompt、MemoirGenerator、Celery 任务 |
| **合计** | **约 3.55 人天** | 视测试与联调深度而定 |