Files
smartmate/docs/backend/legacy-infra-rag-from-backend/RAG复用接口实施计划.md
Losita 3b6fca44a6 Version: 0.9.77.dev.260505
后端:
1.阶段 6 CP4/CP5 目录收口与共享边界纯化
- 将 backend 根目录收口为 services、client、gateway、cmd、shared 五个一级目录
- 收拢 bootstrap、inits、infra/kafka、infra/outbox、conv、respond、pkg、middleware,移除根目录旧实现与空目录
- 将 utils 下沉到 services/userauth/internal/auth,将 logic 下沉到 services/schedule/core/planning
- 将迁移期 runtime 桥接实现统一收拢到 services/runtime/{conv,dao,eventsvc,model},删除 shared/legacy 与未再被 import 的旧 service 实现
- 将 gateway/shared/respond 收口为 HTTP/Gin 错误写回适配,shared/respond 仅保留共享错误语义与状态映射
- 将 HTTP IdempotencyMiddleware 与 RateLimitMiddleware 收口到 gateway/middleware
- 将 GormCachePlugin 下沉到 shared/infra/gormcache,将共享 RateLimiter 下沉到 shared/infra/ratelimit,将 agent token budget 下沉到 services/agent/shared
- 删除 InitEino 兼容壳,收缩 cmd/internal/coreinit 仅保留旧组合壳残留域初始化语义
- 更新微服务迁移计划与桌面 checklist,补齐 CP4/CP5 当前切流点、目录终态与验证结果
- 完成 go test ./...、git diff --check 与最终真实 smoke;health、register/login、task/create+get、schedule/today、task-class/list、memory/items、agent chat/meta/timeline/context-stats 全部 200,SSE 合并结果为 CP5_OK 且 [DONE] 只有 1 个
2026-05-05 23:25:07 +08:00

6.1 KiB
Raw Permalink 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 依赖)。