Files
life-echo/api/docs/memory-retrieval.md
Kevin e4bf0710c7 feat(memory,conversation): 记忆富化/证据包、时间线幂等字段与对话分段全链路
数据库
- 新增迁移 0003:timeline_events.memory_source_id 外键 → memory_sources,便于按 ingest 源做时间线幂等

后端 - 记忆
- 新增 ingest 后 LLM 富化(摘要/事实/时间线),可配置开关与最大字符数
- 新增证据包组装:合并 chunk、摘要、事实、时间线、故事等检索结果;支持空 query 时是否仍带 rolling 等开关
- repo/retriever/service/router/schemas/summarizer/timeline/extractor 等扩展;文档 memory-retrieval.md 更新

后端 - 对话 WS
- 增加 PING/PONG;分段 ASR 日志与空音频处理;转写失败与「无助手回复」错误提示更明确
- 助手多段回复持久化使用统一分隔符,与分段逻辑一致

后端 - Agent
- reply_limits:按 [SPLIT] 与段落拆段,并保证非空 fallback,供 WS 与 TTS 多段下发

后端 - 回忆录任务
- transcript ingest 记录 source_id;任务成功结?
2026-03-27 16:24:43 +08:00

39 lines
2.6 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.
# 记忆检索:异步 API 与 Celery 同步路径
## 两条路径
| 路径 | 入口 | 检索能力 |
|------|------|----------|
| **异步HTTP / MemoirService | `MemoryService.retrieve` → `HybridRetriever` → `evidence.retrieve_evidence_bundle_async` | **FTS + 向量pgvector**RRF 融合 chunksfacts / timeline 按 **query ILIKE**,无命中则 **fallback** 最近条rolling + ILIKE **摘要****stories**(标题/摘要匹配) |
| **同步Celery | `retrieve_evidence_sync``repo` 薄封装 → `evidence.retrieve_evidence_bundle_sync` | **仅 FTS** chunks其余与上类似无向量 |
证据组装在 `app/features/memory/evidence.py``memory/repo` 仅提供原子查询chunk FTS、facts/timeline 搜索、摘要列表等story 合并在 evidence 层完成。
## 为何 Celery 与 Hybrid 不完全一致
- `ingest_transcript_sync` 仅写入 chunk + **FTS****跳过 embedding**(见 `MemoryService.ingest_transcript_sync` 注释),与异步 ingest 行为对齐策略不同。
- 在 worker 中补齐同步向量检索需注入 `EmbeddingProvider` 与同会话查询,成本与可用性需单独评估。
业务上应假设:**线上章节生成任务**以 FTS 证据为主;**异步 API** 若配置了 embedding检索语义更富。
## 空 query
- 默认:`relevant_*` 均为空(与历史行为一致)。
- 若设置 `memory_evidence_empty_query_include_rolling=true`:返回**无 chunk FTS**,但含 **rolling 摘要**、最近 facts / timeline用于「浏览」模式
## 富化ingest 后 LLM
- `memory_enrichment_enabled`(默认 `true``ingest_transcript` / `ingest_transcript_sync` 后执行摘要、事实、时间线;`false` 时跳过。
- `memory_enrichment_max_chars`:截断送入 LLM 的文本长度。
- 同一 `memory_source_id` 的时间线在重跑富化前会先删后插入,避免重复事件。
## Celery 任务中的顺序
`process_memoir_segments``app/tasks/memoir_tasks.py`)在**同一任务**内先执行 `ingest_transcript_sync`(并 `commit`),再执行 `MemoirOrchestrator``run_story_pipeline_for_category_batch`。因此 `retrieve_evidence_sync` 能看到**本批刚写入**的 memory chunks无竞态
章节分类上,若模型返回 **none** 或命中零散档案启发式Story 侧会统一落入 **`summary` 章节**并继续叙事落库,与「本批 transcript 已进 memory」一致避免误以为内容被丢弃。
## Evidence 与叙事 Prompt
`format_evidence_chunks_for_prompt` 拼接 chunks、**摘要(若有)**、facts、timeline、**故事摘要(若有)**;模型应把摘录视为参考材料,非本段口述。