Spring AI 实操案例:搭建智能客服系统(含RAG增强版)
——让AI成为你的24小时在线客服
一、项目背景
某电商平台需要一个智能客服系统,要求:
- 支持自然语言问答(如订单查询、退换货政策)
- 能调用外部知识库(如产品说明书、活动规则)
- 高并发场景下保持低延迟
二、技术选型
| 组件 | 选型依据 |
|---|---|
| AI框架 | Spring AI 0.8.1(Java生态友好,支持多模型切换) |
| 大模型 | DeepSeek(兼容OpenAI API,成本低)或Ollama本地模型(数据隐私) |
| 向量数据库 | Redis(内存级检索,适合实时场景) |
| 辅助工具 | FFmpeg(音频预处理)、Lombok(简化代码) |
三、环境准备
- 开发环境
- JDK 17+
- Spring Boot 3.2+
- Maven 3.9+
- 配置文件
spring:
ai:
openai:
api-key: sk-xxx # DeepSeek API密钥
base-url: https://api深基流动.com/v1 # 深基流动API地址
chat:
model: deepseek-chat-v3 # 指定模型
temperature: 0.7 # 控制生成随机性
redlock:
redis:
host: localhost
port: 6379
四、核心代码实现
1. 基础对话功能
@Service
public class AiCustomerService {
private final ChatClient chatClient;
public AiCustomerService ChatClient chatClient) {
this.chatClient = chatClient;
}
// 普通对话接口
public String handleQuery(String userInput) {
String prompt = """
你是一个电商客服专家,请用中文回答用户问题。
系统状态:
- 用户最近订单:OD123456(已发货)
- 产品库版本:v2.1
用户问题:%s
"""
.formatted(userInput);
return chatClient.call(prompt).getResult().getOutput().getContent();
}
}
2. RAG增强版(结合知识库)
@RestController
@RequestMapping("/rag")
public classragController {
@Autowired
private VectorStore vectorStore;
@PostMapping("/ask")
public String askWithRAG(@RequestBody String question) {
// 1. 检索相关文档
List文档> docs = vectorStore simSearch(question, 3);
// 2. 构建上下文
Prompt prompt = new Prompt(
Arrays.asList(
new SystemMessage("你是一个客服,需根据以下资料回答问题:" + docs),
new UserMessage(question)
)
);
// 3. 生成回答
return chatClient.call(prompt). Result(). Content();
}
}
五、高级功能扩展
1. 流式响应(SSE协议)
@GetMapping(value = "/stream", produces = MediaType.APPLICATION Event_STREAM_VALUE)
public Flux streamChat(@RequestParam String prompt) {
return chatClient.stream()
.user(prompt)
.system("请逐步思考并回答:")
.map(response -> "data: " + response + "\n\n");
}
2. 本地模型部署(Ollama版)
@Bean
public VectorStore vectorStore(EmbeddingModel embeddingModel) {
return SimpleVectorStore.builder(embeddingModel).build();
}
六、测试与优化
1. 压力测试
使用JMeter模拟1000并发请求,优化点:
- 启用Redis缓存高频问题
- 异步处理耗时操作(如PDF解析)
2. 模型调优
// 调整生成参数
ChatOptions options = new ChatOptions()
.withTemperature(0.3) // 降低随机性
.withMaxTokens(500); // 限制生成长度
七、避坑指南
- API密钥泄露
- 错误:将密钥硬编码在代码中
- 解决:使用Spring Cloud Config或环境变量
- 向量检索不准
- 错误:未对文本进行分词处理
- 解决:添加停用词过滤(如“的”“了”)
- 模型响应延迟
- 错误:未启用缓存
- 解决:对高频问题缓存结果(Redis缓存30分钟)
彩蛋:尝试在Prompt中添加"假设你是李佳琦",AI会瞬间变成带货模式!
(注:实际效果因模型而异,建议先测试再商用)