检索增强生成(RAG)系统正成为企业级AI应用的核心架构,Spring AI提出的模块化RAG架构通过清晰的阶段划分和标准化接口,为开发者提供了高度灵活的实现框架。本文将深入剖析该架构的核心设计,并详细讲解预检索、检索和后检索三个阶段的具体职责与技术实现。
1. 模块化RAG架构全景图
Spring AI的模块化RAG架构采用管道过滤器模式,将整个流程分解为三个明确定义的阶段,每个阶段包含多个可插拔组件:
graph LR
A[用户提问] --> B(预检索阶段)
B --> C(检索阶段)
C --> D(后检索阶段)
D --> E[最终回答]
subgraph 预检索阶段
B1[查询重写]
B2[查询扩展]
B3[查询路由]
end
subgraph 检索阶段
C1[向量检索]
C2[关键词搜索]
C3[混合检索]
end
subgraph 后检索阶段
D1[结果重排序]
D2[证据合成]
D3[生成控制]
end
2. 预检索阶段:查询优化引擎
2.1 核心职责
- 意图澄清:解析用户问题的潜在意图
- 查询优化:提升检索命中率的关键改造
- 路由决策:确定最合适的检索路径
2.2 关键组件实现
2.2.1 查询重写器(Query Rewriter)
public interface QueryRewriter {
String rewrite(String originalQuery, RewriteContext context);
}
@Service
public class AISemanticRewriter implements QueryRewriter {
private final ChatClient chatClient;
@Override
public String rewrite(String query, RewriteContext ctx) {
String prompt = """
请重写以下查询以优化检索效果:
原始查询: %s
用户上下文: %s
只返回重写后的查询
""".formatted(query, ctx.getUserProfile());
return chatClient.call(prompt).getResult().getOutput().getContent();
}
}
2.2.2 查询扩展器(Query Expander)
public class HybridQueryExpander {
private final SynonymExpander synonymExpander;
private final VectorExpander vectorExpander;
public String expand(String query) {
// 基于同义词的扩展
String synonymExpanded = synonymExpander.expand(query);
// 基于向量相似的扩展
String vectorExpanded = vectorExpander.expand(query);
return mergeExpansions(query, synonymExpanded, vectorExpanded);
}
}
2.2.3 路由决策器(Router)
public class ContentTypeRouter {
public RouteDecision route(String query) {
String prompt = """
判断查询最适合的检索类型:
1. VECTOR - 语义搜索(如概念性问题)
2. KEYWORD - 精确匹配(如产品代码)
3. HYBRID - 混合模式
查询: %s
只返回类型名称
""".formatted(query);
String routeType = chatClient.call(prompt).getResult().getOutput().getContent();
return new RouteDecision(routeType);
}
}
3. 检索阶段:知识获取引擎
3.1 核心职责
- 多模态检索:支持文本、向量、结构化数据等多种形式
- 混合搜索:结合传统关键词与向量搜索优势
- 初步过滤:应用基础相关性阈值
3.2 关键组件实现
3.2.1 混合检索器(HybridRetriever)
public class HybridRetriever implements Retriever {
private final VectorStore vectorStore;
private final KeywordSearchEngine keywordEngine;
@Override
public List<Document> retrieve(String query) {
// 并行执行两种检索
List<Document> vectorResults = vectorStore.similaritySearch(query);
List<Document> keywordResults = keywordEngine.search(query);
// 融合排序
return new ReciprocalRankFusion()
.fuse(vectorResults, keywordResults);
}
}
3.2.2 元数据过滤器(MetadataFilter)
public class TemporalFilter implements Filter {
@Override
public List<Document> filter(List<Document> docs, FilterContext ctx) {
return docs.stream()
.filter(doc -> {
Instant docTime = doc.getMetadata().get("timestamp");
return docTime.isAfter(ctx.getTimeThreshold());
})
.collect(Collectors.toList());
}
}
4. 后检索阶段:答案精炼引擎
4.1 核心职责
- 结果精排:基于多维度特征重新排序
- 证据组织:构建生成阶段的参考依据
- 生成控制:约束LLM的输出形式
4.2 关键组件实现
4.2.1 神经排序器(NeuralReranker)
public class CrossEncoderReranker implements Reranker {
private final CrossEncoderModel model;
@Override
public List<Document> rerank(String query, List<Document> docs) {
List<Pair<String, String>> queryDocPairs = docs.stream()
.map(doc -> Pair.of(query, doc.getContent()))
.collect(Collectors.toList());
float[] scores = model.predict(queryDocPairs);
// 组合文档与得分
return IntStream.range(0, docs.size())
.mapToObj(i -> new ScoredDocument(docs.get(i), scores[i]))
.sorted(Comparator.reverseOrder())
.map(ScoredDocument::getDocument)
.collect(Collectors.toList());
}
}
4.2.2 证据合成器(EvidenceSynthesizer)
public class TreeBasedSynthesizer implements EvidenceSynthesizer {
@Override
public String synthesize(String query, List<Document> docs) {
String prompt = """
基于以下文档提取关键证据:
问题: %s
文档:
%s
要求:
1. 去除矛盾信息
2. 保留数据来源
3. 输出Markdown格式
""".formatted(query, joinDocuments(docs));
return chatClient.call(prompt).getResult().getOutput().getContent();
}
}
5. 三阶段协同工作流
5.1 完整处理流程示例
sequenceDiagram
participant User
participant PreRetrieval
participant Retrieval
participant PostRetrieval
participant LLM
User->>PreRetrieval: "如何预防感冒?"
PreRetrieval->>PreRetrieval: 重写为"感冒预防措施"
PreRetrieval->>PreRetrieval: 扩展为"感冒预防 增强免疫力方法"
PreRetrieval->>Retrieval: 优化后的查询
Retrieval->>Retrieval: 向量搜索(0.8权重)
Retrieval->>Retrieval: 关键词搜索(0.2权重)
Retrieval->>Retrieval: 混合结果(FRF算法)
Retrieval->>PostRetrieval: 20篇相关文档
PostRetrieval->>PostRetrieval: 基于时效性重排序
PostRetrieval->>PostRetrieval: 提取关键证据
PostRetrieval->>LLM: 问题+结构化证据
LLM->>User: "预防感冒的5个科学方法..."
5.2 Spring AI配置示例
spring:
ai:
rag:
pre-retrieval:
rewriters:
- type: semantic
temperature: 0.3
- type: spelling
routers:
- type: content-based
retrieval:
type: hybrid
vector:
similarity-threshold: 0.7
keyword:
boost-fields: ["title^2", "content"]
post-retrieval:
reranker:
type: cross-encoder
model: cross-encoder/ms-marco-MiniLM-L-6-v2
synthesizer:
type: tree-summary
6. 高级优化策略
6.1 动态阶段跳过机制
public class SmartPipeline extends DefaultRagPipeline {
@Override
public RagResponse run(RagRequest request) {
// 检测是否可跳过检索(如FAQ直接匹配)
if (preRetrievalAnalyzer.canSkipRetrieval(request)) {
return generateDirectResponse(request);
}
// 正常执行三阶段流程
return super.run(request);
}
}
6.2 反馈驱动优化
@EventListener
public void onUserFeedback(FeedbackEvent event) {
// 根据用户正负反馈调整各阶段参数
optimizationEngine.adjustParameters(
event.getQuery(),
event.getFeedback(),
event.getResponse()
);
}
7. 生产环境考量
7.1 性能监控指标
阶段 | 关键指标 | 预警阈值 |
---|---|---|
预检索 | 平均延迟 | >200ms |
检索 | 召回率@10 | <0.6 |
后检索 | 精排NDCG | <0.7 |
7.2 容错设计
public class FallbackRagPipeline implements RagPipeline {
private final List<RagPipeline> pipelines;
@Override
public RagResponse run(RagRequest request) {
for (RagPipeline pipeline : pipelines) {
try {
return pipeline.run(request);
} catch (Exception e) {
log.warn("Pipeline failed", e);
}
}
return basicFallbackResponse(request);
}
}
Spring AI的模块化RAG架构通过标准化的阶段划分和接口设计,使开发者能够灵活组合最新技术组件。这种架构特别适合需要快速迭代的AI应用场景,三个阶段的明确分工也使得性能优化和问题排查更加有的放矢。随着RAG技术的演进,该架构可无缝集成诸如动态检索、多跳推理等高级能力。