# 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、embedding(pgvector)、content_tsv(FTS)、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 写入路径 | 1–1.5 天 | chunker、repo、ingest、END_CONVERSATION 接入 | | Phase 2 异步补齐 | 0.5–1 天 | Celery 任务、embedding 写入 | | Phase 3 读取路径 | 1–1.5 天 | FTS、vector、HybridRetriever、MemoryService.retrieve | | Phase 4 消费端接入 | 1 天 | prompt、MemoirGenerator、Celery 任务 | | **合计** | **约 3.5–5 人天** | 视测试与联调深度而定 |