feat(rag): 混合检索融合 — Milvus 向量 + Bleve 全文 + RRF + DashScope rerank

检索从向量单路升级为混合:向量(Milvus) + 全文(Bleve BM25) → RRF 融合 →
可选 rerank(DashScope gte-rerank)。

- rag/bleve.go: Bleve 全文索引(内存,随 ingest 写入;kb 过滤);ingest 同步写 Milvus+Bleve
- rag/fuse.go: RRF(Reciprocal Rank Fusion, k=60, 按文本去重)融合多路排序
- rag/rerank.go: DashScope gte-rerank 客户端(可选,env 配置,失败降级 RRF)
- rag/rag.go: Search 改混合(向量+全文→RRF→可选rerank→topK);main 读 RERANK_* env
- 验证: 全模块 build✓ + e2e PASS; live——入库写双索引;查'NATS'→全文精确命中#1+向量
  →RRF NATS 排首(向量=4 全文=1);接 DashScope gte-rerank(百炼 key 有权限)→relevance
  score 0.19 真重排;retriever 节点端到端→DeepSeek 答 Milvus
- 边界: Neo4j 图路(GraphRAG,需实体抽取)推迟;Bleve 内存索引重启重建;rerank 走 env
  (TODO 同 embedding 搬控制面 kind=rerank)

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
Blizzard
2026-06-11 09:53:37 +08:00
parent 755032c1d8
commit 85a5c2c1e7
8 changed files with 311 additions and 56 deletions
+5 -1
View File
@@ -27,6 +27,9 @@ func main() {
embBase := envOr("EMBED_BASE_URL", "") // OpenAI 兼容 embeddings 端点(空=向量检索降级)
embKey := envOr("EMBED_API_KEY", "")
embModel := envOr("EMBED_MODEL", "")
rerankBase := envOr("RERANK_BASE_URL", "") // DashScope 文本重排端点(空=不启用 rerank)
rerankKey := envOr("RERANK_API_KEY", "")
rerankModel := envOr("RERANK_MODEL", "")
b, err := sharedbus.Connect(natsURL)
if err != nil {
@@ -44,7 +47,8 @@ func main() {
ctx, stop := signal.NotifyContext(context.Background(), syscall.SIGINT, syscall.SIGTERM)
defer stop()
ragEngine := rag.Open(ctx, milvusAddr, embBase, embKey, embModel) // RAG 核心链:embedding(env 初值) + Milvus
// RAG 核心链:embedding(env 初值) + Milvus(向量) + Bleve(全文) + 可选 rerank
ragEngine := rag.Open(ctx, milvusAddr, embBase, embKey, embModel, rerankBase, rerankKey, rerankModel)
defer ragEngine.Close()
// 配置控制面:启动取激活 embedding 配置 + 订阅热更新(覆盖 env,持久化由 Gateway 管)。