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

177 lines
7.8 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.
# 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 人天** | 视测试与联调深度而定 |