Files
smartmate/backend/infra/rag/RAG复用接口实施计划.md
LoveLosita fae162162a Version: 0.9.13.dev.260410
后端:
1. Memory Day1 链路打通(chat_history -> outbox -> memory_jobs)
   - 更新 service/events/chat_history_persist.go:聊天消息落库同事务追加 memory.extract.requested 事件(仅 user 消息,失败回滚后由 outbox 重试)
   - 新建 service/events/memory_extract_requested.go:消费 memory.extract.requested 并幂等入队 memory_jobs,补齐 payload 校验、文本截断与 idempotency key
   - 更新 cmd/start.go:注册 RegisterMemoryExtractRequestedHandler
2. Memory 模块骨架落地(先跑通状态机,再接入真实抽取)
   - 新建 memory/model、repo、service、orchestrator、worker、utils 目录与 Day1 mock 抽取执行链
   - 新建 model/memory.go:补齐 memory_items / memory_jobs / memory_audit_logs / memory_user_settings 与事件 payload 模型
   - 更新 inits/mysql.go:接入 4 张 memory 相关表 AutoMigrate
3. RAG 复用基础设施预埋(依赖可替换)
   - 新建 infra/rag:core pipeline + chunk/embed/retrieve/rerank/store/corpus/config 分层实现
   - 默认接入 MockEmbedder + InMemoryStore,预留 Milvus / Eino 适配实现
   - 新增 infra/rag/RAG复用接口实施计划.md
4. 本地依赖与交接文档同步
   - 更新 docker-compose.yml:新增 etcd / minio / milvus / attu 服务与数据卷
   - 删除 newAgent/HANDOFF_工具研究与运行态重置.md、newAgent/阶段3_上下文瘦身设计.md
   - 新增 newAgent/HANDOFF_WebSearch两阶段实施计划.md、memory/HANDOFF-RAG复用后续实施计划.md、memory/README.md
前端:无 仓库:无
2026-04-10 13:07:54 +08:00

6.1 KiB
Raw Blame History

RAG 复用接口实施计划Memory + WebSearch 统一底座)

1. 目标与原则

  1. backend/infra/rag 抽离共享 RAG Core统一 chunk/embed/retrieve/rerank 能力。
  2. 先接入 MemoryCorpusWebCorpus 两个适配器,避免后续重复造轮子。
  3. 保持“并行迁移”策略:新老链路并存,先接入、再灰度、再切流、最后删除旧实现。
  4. 不阻塞现有主链路;任何 RAG 子能力失败都必须可降级。

2. 本轮范围与非目标

2.1 本轮范围

  1. 定义 RAG Core 接口、标准数据结构、错误码和回退语义。
  2. 提供 MemoryCorpusWebCorpus 适配层设计。
  3. 给出分阶段落地步骤、验收标准、风险控制。

2.2 本轮非目标

  1. 不在本轮实现完整生产级向量检索细节Milvus 连接器可先占位)。
  2. 不在本轮统一改造所有调用方,只做首批接入点。
  3. 不在本轮引入多 Provider 工厂(先保证单 Provider 可替换)。

3. 目录与模块规划

建议目录(先建骨架,逐轮填实):

backend/infra/rag/
  core/
    types.go
    interfaces.go
    pipeline.go
    errors.go
  chunk/
    text_chunker.go
  embed/
    eino_embedder.go
  retrieve/
    vector_retriever.go
  rerank/
    eino_reranker.go
  store/
    vector_store.go
    milvus_store.go
  corpus/
    memory_corpus.go
    web_corpus.go
  config/
    config.go

4. 核心接口设计(建议签名)

type Chunker interface {
    Chunk(ctx context.Context, doc SourceDocument, opt ChunkOption) ([]Chunk, error)
}

type Embedder interface {
    Embed(ctx context.Context, texts []string, action string) ([][]float32, error)
}

type Retriever interface {
    Retrieve(ctx context.Context, req RetrieveRequest) ([]ScoredChunk, error)
}

type Reranker interface {
    Rerank(ctx context.Context, query string, candidates []ScoredChunk, topK int) ([]ScoredChunk, error)
}

type VectorStore interface {
    Upsert(ctx context.Context, rows []VectorRow) error
    Search(ctx context.Context, req VectorSearchRequest) ([]ScoredVectorRow, error)
    Delete(ctx context.Context, ids []string) error
    Get(ctx context.Context, ids []string) ([]VectorRow, error)
}

type CorpusAdapter interface {
    Name() string
    BuildIngestDocuments(ctx context.Context, input any) ([]SourceDocument, error)
    BuildRetrieveFilter(ctx context.Context, req any) (map[string]any, error)
}

5. 统一流程约定

5.1 Ingest 流程

  1. CorpusAdapter.BuildIngestDocuments 生成标准文档。
  2. Chunker.Chunk 切块(固定 chunk_size + overlap
  3. Embedder.Embed(action=add/update) 生成向量。
  4. VectorStore.Upsert 写入。
  5. 任一步失败按“可补偿”记录状态,不影响主业务成功返回。

5.2 Retrieve 流程

  1. CorpusAdapter.BuildRetrieveFilter 构建过滤条件。
  2. Embedder.Embed(action=search) 向量化 query。
  3. VectorStore.Search 召回候选。
  4. threshold 过滤。
  5. 可选 Reranker 重排;失败则 fallback 到原排序并记录原因码。

6. 两类 Corpus 适配器设计

6.1 MemoryCorpus

  1. 数据源:memory_items(结构化记忆事实)。
  2. 强约束过滤:user_id + assistant_id + conversation_id
  3. 元数据:memory_type/confidence/sensitivity_level/ttl_at/source_event_id
  4. 注入优先级:constraint/preference 高于 fact/todo_hint

6.2 WebCorpus

  1. 数据源websearch 抓取结果(url/title/snippet/content)。
  2. 强约束过滤:query_id/session_id,避免跨问题污染。
  3. 元数据:domain/published_at/fetched_at/language/source_rank
  4. 检索策略:先向量召回,再结合域名可信度做轻量加权。

7. 与 Eino 的集成方式

  1. embed/eino_embedder.go:封装 Eino embedding 调用。
  2. rerank/eino_reranker.go:封装 Eino 重排调用。
  3. 统一配置入口:rag.enabled/top_k/threshold/reranker_enabled/timeout
  4. 统一日志字段:trace_id/corpus/action/fallback_reason/latency_ms/hit_count

8. 分阶段实施(建议 4 轮)

Round 1基础骨架不切流

  1. infra/rag 目录与接口、类型、错误码。
  2. 提供 NoopRerankerMockEmbedder 兜底实现。
  3. 验收:编译通过,主链路行为不变。

Round 2MemoryCorpus 接入(灰度)

  1. 把记忆检索从“模块内直连”改为调用 RAG Core。
  2. 保留旧路径开关 memory.rag.enabled,默认关闭。
  3. 验收:开启开关后功能等价,失败可自动降级旧链路。

Round 3WebCorpus 接入(灰度)

  1. websearch 召回改走 RAG Core。
  2. 加入 web.rag.enabled 灰度开关。
  3. 验收:检索可复用同一 pipeline质量不低于旧实现。

Round 4统一切流与清理

  1. 默认开启 RAG Core旧链路保留一段观察窗口。
  2. 指标稳定后删除旧实现。
  3. 验收:两条业务链路均通过统一接口,文档与监控齐全。

9. 配置建议

rag:
  enabled: true
  topK: 8
  threshold: 0.55
  reranker:
    enabled: true
    timeoutMs: 1200
  ingest:
    chunkSize: 400
    chunkOverlap: 80
  retrieve:
    timeoutMs: 1500

10. 验收标准DoD

  1. 同一套 Core 能同时服务 Memory 与 WebSearch。
  2. rerank 异常时可观测地降级,不影响主功能可用性。
  3. 支持按 corpus 维度查看命中率、耗时、降级率。
  4. 新老链路可开关切换,回滚路径明确。

11. 风险与应对

  1. 风险:一次性切流影响面大。
    应对:按 corpus 分轮灰度,先 Memory 后 Web。
  2. 风险:向量检索延迟波动。
    应对:超时控制 + fallback + 本地缓存热点 query。
  3. 风险:跨域检索串数据。
    应对:强制 filter 校验,不满足维度直接拒绝检索。

12. 下一步执行清单(紧接实现)

  1. 先补 core/interfaces.go + core/types.go + core/pipeline.go
  2. 再补 corpus/memory_corpus.go(首个适配器)。
  3. 然后给 websearch 接 corpus/web_corpus.go 占位适配器。
  4. 最后补 store/milvus_store.go 与配置接线(当前 docker compose 已准备 Milvus 依赖)。