向量存储与 RAG 检索架构设计
一、整体架构概览
LangChat 的 RAG 系统分为两条核心链路:文档入库(Ingestion) 和 检索增强生成(Retrieval),共享同一套工厂层基础设施。二、向量存储设计
2.1 多后端支持
| 后端 | SEMANTIC | FULLTEXT | HYBRID | 特点 |
|---|---|---|---|---|
| PgVector | ✓ | ✗(回退 SEMANTIC) | ✓(RRF 融合) | 向量 + PostgreSQL 全文检索,开箱即用 |
| Elasticsearch | ✓ | ✓ | ✓(kNN + BM25) | 向量 + 全文检索,需企业版许可 |
| Milvus | ✓ | ✗(回退 SEMANTIC) | ✗(回退 SEMANTIC) | 纯向量检索,适合大规模数据集 |
2.2 检索模式(SearchMode)
系统通过SearchMode 枚举定义三种检索模式,在向量库构建阶段即生效:
- SEMANTIC(默认):纯向量检索,通过 Embedding 余弦相似度匹配,所有向量库均支持
- FULLTEXT:纯关键词检索,基于 BM25 / 倒排索引匹配,仅 Elasticsearch 原生支持
- HYBRID:混合检索,同时使用向量和关键词两路搜索后融合排序
SearchMode 影响向量库实例的构建方式。以 PgVector 为例:
2.3 实例缓存策略
向量存储实例通过 Caffeine 本地缓存管理,缓存键由连接参数(provider、host、port、username、password、database、dimension、tableName)和 searchMode 的 MD5 哈希生成。- 相同配置参数 + 相同 searchMode 的请求共享同一个连接实例
- 不同 searchMode 使用不同实例(因为 HYBRID 模式需额外全文索引配置)
- 每个知识库使用
knowledgeId作为表名/集合名,实现数据隔离 - 配置变更时通过
clearCache()失效所有 searchMode 的缓存
2.4 KnowledgeFactory — 门面层
KnowledgeFactory 是获取向量库和 Embedding 模型的统一入口,屏蔽了 VectorStore 配置查询细节:
2.5 Hybrid 搜索与 minScore 适配
PgVector Hybrid 模式采用 RRF(Reciprocal Rank Fusion)算法融合两路排序:minScore(如 0.69)是基于余弦相似度(0~1)的语义,直接用于 RRF 会过滤掉全部结果。
解决方案:HYBRID 模式不使用 minScore 过滤 RRF 分数(传 minScore=0 给向量库),而是通过余弦相似度后置过滤保证结果质量:
/search接口:EmbeddingSearchService.search()中直接后置过滤- RAG 对话:
SegmentAwareContentRetriever中通过 embeddingModel 计算余弦相似度后置过滤
三、检索配置系统(RetrievalConfig)
3.1 配置数据结构
3.2 三个使用场景
3.3 参数优先级
- 应用对话:
RetrievalConfig的值优先于知识库默认配置。若retrievalConfig为 null,回退到AigcKnowledge.maxResults / minScore,searchMode 回退到 SEMANTIC - 手动测试 / 工作流:直接使用请求参数,null 值回退到默认值(SEMANTIC, rrfK=80)
四、文档入库链路(Ingestion)
关键数据流
五、检索链路(Retrieval)
系统提供两条检索路径:5.1 直接搜索(知识库搜索 UI)
5.2 RAG 对话检索(Chat with RAG)
六、段落启用/禁用机制
向量库中的数据不会被删除。运行时通过 MySQL 的aigc_segment_index 表控制可见性:
status=true AND enabled=true 的索引条目,收集 indexHash 集合,注入 MetadataFilter 过滤。这样用户禁用某个段落时,无需操作向量库,只需修改 MySQL 字段即可生效。
七、多路检索融合
当一次对话关联多个知识库时,系统会创建多个检索器实例。LangChain4j 的DefaultQueryRouter 将同一查询发送给所有检索器,各自独立返回结果,最终由 ContentAggregator 合并:
| 场景 | 聚合策略 |
|---|---|
| 未启用 Rerank | 按各检索器返回的原始分数排序 |
| 启用 Rerank | 所有结果送入 ScoringModel 重新打分排序 |
八、可观测性
| 组件 | 职责 |
|---|---|
| ConsumptionRecorder | 记录 Embedding Token 消耗(入库 + 检索) |
| ChatListener / ChatTrace | 记录对话生命周期(推理、RAG 来源、Tool 调用、Token 用量) |
| 日志 | 各层关键节点均有结构化日志,包含 knowledgeId、searchMode、resultCount、score 等字段 |
九、核心类索引
| 类 | 所在包 | 职责 |
|---|---|---|
VectorStoreFactory | factory.vectorstore | 向量库实例创建与缓存,支持动态 SearchMode |
KnowledgeFactory | factory.knowledge | 知识库门面,统一获取 EmbeddingStore 和 EmbeddingModel |
EmbeddingModelFactory | factory.model | Embedding 模型实例创建与缓存 |
RerankModelFactory | factory.model | Rerank 模型实例创建与缓存 |
RagRetrieverBuilder | builder | RAG 检索器总调度,聚合知识库 + SQL 检索器 + Rerank |
KnowledgeRetrieverBuilder | builder | 知识库检索器构建,从 RetrievalConfig 读取参数 |
SegmentAwareContentRetriever | builder | 包装层,索引文本 → 原始 chunk 内容替换;HYBRID 模式下通过余弦相似度后置过滤 |
SqlRetrieverBuilder | builder | Text2SQL 检索器构建 |
AiServiceBuilder | builder | AI Service 总构建器(RAG + Tools + Memory) |
EmbeddingSearchService | embedding | /search 接口的独立搜索服务 |
SearchMode | common.ai.consts | 检索模式枚举(SEMANTIC / FULLTEXT / HYBRID) |
RetrievalConfig | common.ai.dto | 检索配置 DTO |

