1. 项目概述
最近在电商客服系统升级项目中,我们基于Spring Boot 3和LangChain4j实现了一套企业级RAG(检索增强生成)架构。这个系统上线后,客服工单处理效率提升了40%,新人培训周期缩短了60%。今天就来分享下这套生产级RAG架构的设计思路和落地经验。
RAG技术本质上是通过"知识检索+大模型生成"的方式来解决传统问答系统的局限性。但真正要落地到企业生产环境,远不是调通几个API那么简单。我们需要考虑知识版本管理、多租户隔离、服务治理等工程问题,这也是本文要重点讨论的内容。
需要模型API调用? 免费领10W Token,多模型网关一键接入 Claude、DeepSeek 等主流模型。
2. 架构设计思路
2.1 企业级RAG的核心挑战
在电商客服场景中,我们遇到了几个典型问题:
- 商品政策和售后规则每周都在更新
- 不同商家(租户)的知识库需要严格隔离
- 高峰期需要支持500+ QPS的并发查询
- 回答必须附带依据来源供客服复核
这些需求导致我们无法直接使用开箱即用的RAG方案,必须进行深度定制。
2.2 分层架构设计
最终采用的架构分为五层:
- 接入层:处理鉴权、限流和协议转换
- 服务层:
- 查询服务(低延迟优先)
- 摄入服务(高吞吐优先)
- 会话服务(状态管理)
- 存储层:
- PostgreSQL + PGVector(向量存储)
- Redis(缓存和会话)
- 对象存储(原始文档)
- 模型层:
- Embedding模型
- Rerank模型
- 对话模型
- 治理层:监控、评估和知识管理
2.3 核心设计原则
- 查询与摄入分离:避免长任务阻塞在线查询
- 无状态设计:方便水平扩展
- 异步化处理:文档解析和向量化通过Kafka异步处理
- 多级缓存:查询改写、热门问题、向量结果都做缓存
- 分级降级:模型不可用时自动降级到关键词检索
3. 关键技术实现
3.1 知识摄入流水线
文档处理流程经过多次迭代优化:
java复制// 伪代码展示核心处理流程
public void processDocument(Document doc) {
// 1. 文件解析
String text = parseFile(doc);
// 2. 结构化切块
List<TextChunk> chunks = chunker.chunk(text);
// 3. 元数据增强
chunks.forEach(chunk -> {
chunk.addMetadata("tenantId", doc.getTenantId());
chunk.addMetadata("effectiveDate", doc.getEffectiveDate());
});
// 4. 批量向量化(优化吞吐关键)
List<Embedding> embeddings = embeddingModel.embedAll(chunks);
// 5. 批量写入
embeddingStore.addAll(embeddings, chunks);
}
关键优化点:
- 批量处理:16个chunk为一批进行向量化和写入
- 结构化元数据:保留业务关键字段用于过滤
- 异步重试:失败任务进入DLQ等待重试
3.2 混合检索策略
单一向量检索在业务场景下效果有限,我们实现了四路混合召回:
| 召回类型 | 适用场景 | 实现方式 |
|---|---|---|
| 向量召回 | 语义相似问题 | PGVector的HNSW索引 |
| 关键词召回 | 精确术语匹配 | Elasticsearch BM25 |
| 规则召回 | 强规则类问题 | 预配置的规则引擎 |
| 元数据过滤 | 租户隔离 | PostgreSQL条件查询 |
检索结果经过融合排序后,再使用Rerank模型进行精细排序。
3.3 查询链路优化
典型查询链路耗时分布(经过优化后):
| 阶段 | P99耗时 | 优化手段 |
|---|---|---|
| Query Rewrite | 120ms | 本地缓存 |
| 向量检索 | 80ms | HNSW索引 |
| Rerank | 150ms | 并行处理 |
| LLM生成 | 800ms | 流式输出 |
| 总计 | 1150ms | - |
关键优化:
- 预热高频问题的Embedding缓存
- 对长回答采用流式输出改善体验
- 设置分段超时和熔断机制
4. 生产环境问题与解决方案
4.1 知识更新延迟问题
现象:商品价格更新后,系统仍返回旧价格
根因:答案缓存未关联知识版本
解决方案:
java复制// 缓存键增加版本标识
String cacheKey = String.join("::",
request.getTenantId(),
request.getKnowledgeBaseId(),
request.getDatasetVersion(), // 新增版本号
request.getQuestion()
);
4.2 高峰期性能下降
现象:大促期间响应时间从1s飙升到5s+
排查过程:
- 发现Embedding模型API达到限流阈值
- 查询线程被阻塞在模型调用上
- 线程池队列积压导致整体延迟上升
解决方案:
- 增加本地Embedding缓存
- 实现分级降级策略:
java复制if (isDegradeMode()) {
// 降级到关键词检索
return keywordSearch(query);
} else {
// 正常向量检索
return vectorSearch(query);
}
4.3 表格数据召回差
现象:商品参数表格召回效果不理想
原因:普通切块会破坏表格结构
改进方案:
- 识别文档中的表格区域
- 将表格转换为Markdown格式
- 作为特殊chunk单独处理
- 检索时优先保留表格完整性
5. 部署与扩展
5.1 Kubernetes配置要点
yaml复制# query-service的HPA配置
apiVersion: autoscaling/v2
kind: HorizontalPodAutoscaler
metadata:
name: rag-query-hpa
spec:
scaleTargetRef:
apiVersion: apps/v1
kind: Deployment
name: rag-query
minReplicas: 4
maxReplicas: 20
metrics:
- type: Resource
resource:
name: cpu
target:
type: Utilization
averageUtilization: 60
最佳实践:
- Query和Ingest服务分开部署
- 根据CPU使用率自动扩缩容
- 设置合理的资源限制(避免OOM)
5.2 监控指标设计
我们通过Micrometer暴露了关键指标:
code复制# 业务指标
rag_questions_total
rag_cache_hit_rate
rag_no_answer_count
# 性能指标
rag_retrieval_latency
rag_llm_latency
rag_total_latency
# 质量指标
rag_reference_accuracy
rag_user_feedback
Grafana监控看板包含:
- 实时QPS和延迟
- 模型调用成功率
- 知识覆盖率
- 缓存命中率
6. 演进方向
当前系统仍在持续迭代,重点方向包括:
-
多模态支持:
- 商品图片解析
- 客服通话录音转文本
- 视频说明书处理
-
Agent集成:
java复制// 伪代码展示Agent集成 @AgentService public class RefundAgent { @Tool("查询订单状态") public OrderStatus checkOrder(String orderId) { return orderService.getStatus(orderId); } @Tool("发起退款") public RefundResult createRefund(RefundRequest request) { return paymentService.refund(request); } } -
评估体系:
- 自动化AB测试框架
- 基于用户反馈的持续优化
- 知识漏洞自动识别
这套基于Spring Boot和LangChain4j的RAG架构,经过半年多的生产验证,已经支持日均20万+的客服问答。其核心价值在于将AI能力自然地集成到企业现有的Java技术栈中,既利用了大模型的能力,又符合企业的工程规范要求。
