96SEO 2026-04-21 05:26 41
作为一名Java开发者,你是否也曾感到焦虑?kan着Python社区那些花哨的AI框架,我们只Neng默默羡慕吗?其实大可不必。Spring生态终于迎来了它的原生AI框架——Spring AI 1.0。这不仅仅是一个库,geng是我们连接未来智Neng世界的桥梁。今天我想和大家分享一个非常有意思的实战案例:如何利用Spring AI 1.0,结合国产大模型DeepSeek,从零搭建一个具备RAG和函数调用Neng力的智Neng客服系统。

说实话,DeepSeekZui近的表现真的让人眼前一亮,不仅推理Neng力强,而且对中文语境的理解非常透彻。把它集成到我们的Spring Boot应用里简直就是如虎添翼。别被那些复杂的AI术语吓倒,跟着我的节奏,你会发现,原来构建一个智Neng系统Ke以如此优雅。
一、 技术选型与架构设计:不仅仅是代码在动手敲代码之前,我们得先想清楚这盘棋怎么下。智Neng客服系统不是简单的“你问我答”,它需要记忆、需要知识、还需要Neng够执行具体操作。为了实现这些目标,我们本例采用了一套相当硬核的技术栈。
核心自然是Spring Boot 3.x与Spring AI 1.0,它们构成了系统的骨架。大模型方面我们选择了DeepSeek,通过Spring AI的OpenAI兼容接口进行对接,这招真的hen灵。数据存储层,我们依然信赖MySQL,配合JPA进行ORM映射;为了提升检索性Neng,Redis也是必不可少的。而在前端交互上,WebSocket是Zui佳选择,它Neng保证对话的实时性和流畅感,那种“打字机”式的流式输出体验,绝对Neng提升用户的满意度。
我们的系统架构遵循分层设计原则。用户在前端发起请求,通过WebSocket长连接直达后端。后端的ChatService作为大脑,负责协调各方:它一方面去向量数据库检索相关知识,另一方面判断是否需要调用函数查询业务数据。Zui后DeepSeek模型综合这些信息生成回复,并流式推送给用户。整个数据流转清晰而高效。
二、 第一步:搭建脚手架与依赖引入工欲善其事,必先利其器。我们需要创建一个新的Spring Boot项目。这一步虽然基础,但至关重要。打开你的`pom.xml`,我们需要把以下这些关键的依赖加进去。这就像是给我们的项目注入各种超Neng力。
除了常规的Web启动器外Zui核心的当然是`spring-ai-openai-spring-boot-starter`。虽然我们用的是DeepSeek,但Spring AI目前对OpenAI接口标准的支持Zui为完善,而DeepSeek恰好兼容这套标准,这简直是天作之合。别忘了数据库驱动、Redis支持以及WebSocket依赖,它们dou是支撑系统运行的基石。
org.springframework.boot
spring-boot-starter-web
org.springframework.ai
spring-ai-openai-spring-boot-starter
1.0.0
org.springframework.boot
spring-boot-starter-data-jpa
mysql
mysql-connector-java
org.springframework.boot
spring-boot-starter-data-redis
org.springframework.boot
spring-boot-starter-websocket
三、 第二步:接入DeepSeek大模型
配置文件往往是整个项目Zui容易被忽视,却又Zui关键的地方。要使用DeepSeek,我们需要在`application.yml`中进行一番精心的配置。这里有个小技巧:虽然我们调用的是DeepSeek的API,但在Spring AI的配置中,我们依然使用`openai`作为配置前缀,只需要把`base-url`指向DeepSeek的地址即可。
记得要把API Key配置好,这可是通行证。此外数据库连接、Redis地址这些常规配置也不Neng少。为了让模型输出geng符合我们的客服场景,我们还Ke以在这里预设一些参数,比如`temperature`和`max-tokens`,控制模型的创造性和回答长度。
spring:
ai:
openai:
api-key: ${DEEPSEEK_API_KEY}
base-url: https://api.deepseek.com/v1
chat:
options:
model: deepseek-chat
temperature: 0.7
max-tokens: 2000
datasource:
url: jdbc:mysql://localhost:3306/customer_service
username: root
password: password
driver-class-name: com.mysql.cj.jdbc.Driver
jpa:
hibernate:
ddl-auto: update
show-sql: true
data:
redis:
host: localhost
port: 6379
四、 第三步:数据持久化设计
一个健壮的系统离不开合理的数据库设计。我们的智Neng客服需要记住用户说了什么也需要存储大量的知识库内容。为此,我们设计了几个核心表。
是`conversations`,它记录每一次对话的元数据;然后是`messages`,这里按时间顺序存储了用户和AI的所有交互记录,这对于后续的复盘和优化非常重要。为了实现RAG,我们需要`knowledge_base`,这里存储着向量化的业务文档。Zui后`user_feedback`Neng帮助我们收集用户对回答的满意度,形成闭环优化。
为了提升查询性Neng,特别是向量检索的效率,我们在相关字段上建立索引是必不可少的操作。这就像给图书管理员贴上了标签,找书自然快多了。
五、 第四步:打造“Zui强大脑”——RAG知识库检索Ru果大模型只Neng基于训练数据回答,那它产生的幻觉会让你头疼不Yi。RAG技术就是为了解决这个问题。它的核心思想是:先去知识库里找相关资料,然后把资料“喂”给模型,让它基于资料回答。
在`KnowledgeBaseService`中,我们实现了这一逻辑。当用户提问时我们先将问题转化为向量,然后在数据库中计算余弦相似度,找出Zui匹配的文档片段。这里我们使用了JdbcTemplate直接执行SQL向量运算,虽然kan起来有点硬核,但性Neng相当不错。
@Service
@Slf4j
public class KnowledgeBaseService {
private final JdbcTemplate jdbcTemplate;
private final EmbeddingModel embeddingModel;
@Value
private int embeddingDimension;
/**
* 搜索相关知识内容
*/
public String searchRelevantContent {
// 将查询转换为向量
List queryEmbedding = embeddingModel.embed;
// 在数据库中搜索Zui相似的文档
String sql = """
SELECT content, similarity
FROM knowledge_base,
AS q
WHERE kb_vector IS NOT NULL
ORDER BY kb_vector <=> query_vector
LIMIT 5
""";
List results = jdbcTemplate.query(sql,
new Object{queryEmbedding},
-> {
KnowledgeBase kb = new KnowledgeBase;
kb.setContent);
kb.setSimilarity);
return kb;
});
// 组合返回Zui相关的内容
return results.stream
.map
.collect);
}
/**
* 添加知识到知识库
*/
public void addKnowledge {
// 生成向量表示
List embedding = embeddingModel.embed;
KnowledgeBase kb = new KnowledgeBase;
kb.setTitle;
kb.setContent;
kb.setCategory;
kb.setVector;
kb.setCreatedAt);
knowledgeBaseRepository.save;
}
}
六、 第五步:赋予“双手”——函数调用Neng力
光会说话还不够,智Neng客服还得Neng干活。比如用户想查订单、查余额,大模型本身是不知道这些实时数据的。这时候,Spring AI的函数调用功Neng就派上用场了。我们Ke以把Java方法“注册”给AI,让它在觉得合适的时候自动调用。
我们定义了`CustomerServiceFunctions`组件,里面包含了`queryOrderStatus`和`queryUserBalance`两个方法。通过`@FunctionInfo`注解,我们告诉AI这些方法是干什么的。当用户问“我的订单到了吗?”时AI会自动识别并调用`queryOrderStatus`方法,然后把返回结果组织成自然语言告诉用户。这种体验简直无缝衔接。
@Component
@Slf4j
public class CustomerServiceFunctions {
private final OrderRepository orderRepository;
private final UserRepository userRepository;
/**
* 查询订单状态
*/
@FunctionInfo(
description = "查询用户的订单状态",
name = "queryOrderStatus"
)
public String queryOrderStatus String orderId) {
log.info;
Order order = orderRepository.findById
.orElse;
if {
return "订单不存在";
}
return String.format("订单 %s 的状态是: %s,预计 %s 送达",
orderId, order.getStatus, order.getEstimatedDelivery);
}
/**
* 查询用户余额
*/
@FunctionInfo(
description = "查询用户账户余额",
name = "queryUserBalance"
)
public String queryUserBalance String userId) {
log.info;
User user = userRepository.findById
.orElse;
if {
return "用户不存在";
}
return String.format);
}
}
七、 第六步:核心对话服务与提示词工程
现在到了Zui核心的部分——`ChatService`。这里是所有魔法发生的地方。它负责串联起知识检索、函数调用和模型对话。
我们使用`ChatClient`来与DeepSeek交互。注意到我们使用了`Flux
提示词的设计也是一门艺术。我们在`buildPrompt`方法中,精心构造了系统指令,告诉AI它的角色、它拥有的知识库内容,以及回答时的注意事项。一个好的提示词,Neng让模型的输出质量提升好几个档次。
@Service
@Slf4j
public class ChatService {
private final ChatClient chatClient;
private final ConversationRepository conversationRepository;
private final MessageRepository messageRepository;
private final KnowledgeBaseService knowledgeBaseService;
@Autowired
public ChatService(ChatClient.Builder chatClientBuilder,
ConversationRepository conversationRepository,
MessageRepository messageRepository,
KnowledgeBaseService knowledgeBaseService) {
this.chatClient = chatClientBuilder.build;
this.conversationRepository = conversationRepository;
this.messageRepository = messageRepository;
this.knowledgeBaseService = knowledgeBaseService;
}
/**
* 处理用户消息并返回AI响应
*/
public Flux chat {
log.info;
// 保存用户消息
saveMessage;
// 检索相关知识
String context = knowledgeBaseService.searchRelevantContent;
// 构建提示词
String prompt = buildPrompt;
// 调用AI模型并流式返回
return chatClient.prompt
.user
.stream
.content
.doOnNext(response -> {
log.debug;
})
.doOnComplete -> {
log.info;
})
.doOnError(error -> {
log.error;
});
}
/**
* 构建提示词模板
*/
private String buildPrompt {
return String.format("""
你是一个专业的客服助手,负责回答用户的问题。
%s
%s
请基于上述知识回答用户问题。Ru果知识库中没有相关信息,请诚实地告知用户,并尽可Neng提供建设性的帮助。
注意事项:
1. 回答要准确、专业、友好
2. 避免提供不确定的信息
3. Ru果涉及具体操作,请提供详细步骤
4. 保持对话的连贯性
""", context, userMessage);
}
/**
* 保存消息到数据库
*/
private void saveMessage {
Message message = new Message;
message.setSessionId;
message.setRole;
message.setContent;
message.setTimestamp);
messageRepository.save;
}
}
在ChatService中启用函数调用也非常简单,只需要在调用链中指定函数名称即可:
public Flux chatWithFunctions {
return chatClient.prompt
.user
.functions // 注册函数
.stream
.content;
}
八、 第七步:实时交互——WebSocket集成
HTTP请求一问一答的模式在聊天场景下显得太笨重了。WebSocket才是正解。我们需要配置WebSocket端点,让前端Neng连上来。
`WebSocketConfig`负责注册处理器,而`ChatWebSocketHandler`则是处理具体消息的地方。当收到前端发来的文本消息时我们解析它,然后调用`ChatService`。注意这里我们利用了Reactive编程的特性,将AI返回的流式数据一段一段地发回前端。这种即时反馈的感觉,真的非常棒。
@Configuration
@EnableWebSocket
public class WebSocketConfig implements WebSocketConfigurer {
@Autowired
private ChatWebSocketHandler chatWebSocketHandler;
@Override
public void registerWebSocketHandlers {
registry.addHandler
.setAllowedOrigins;
}
}
@Component
@Slf4j
public class ChatWebSocketHandler extends TextWebSocketHandler {
@Autowired
private ChatService chatService;
@Override
protected void handleTextMessage throws Exception {
String payload = message.getPayload;
ChatRequest request = parseRequest;
// 流式发送AI响应
chatService.chat, request.getSessionId, request.getMessage)
.doOnNext(response -> {
try {
session.sendMessage);
} catch {
log.error;
}
})
.subscribe;
}
}
九、 第八步:前端界面与用户体验
后端再强大,也需要一个像样的前端展示。这里我们用一个简单的HTML页面来演示。界面虽然朴素,但功Neng齐全。包含了消息展示区域和输入框。
JavaScript部分负责建立WebSocket连接,监听消息,并把收到的内容渲染到页面上。我们还加了一些简单的CSS样式,区分用户消息和AI消息的背景色,让对话kan起来geng清晰。按下回车键就Neng发送,交互非常流畅。
十、 第九步:容器化部署与监控
开发完了总得上线吧。使用Docker进行部署是现在的标准操作。我们编写一个简单的`Dockerfile`,基于OpenJDK镜像,把打包好的Jar包扔进去运行。
为了方便管理,我们再用`docker-compose.yml`把应用、MySQL和Redis编排在一起。这样,一条命令就Neng启动整个环境,是不是hen方便?
FROM openjdk:17-jdk-slim
WORKDIR /app
COPY target/customer-service-1.0.jar app.jar
EXPOSE 8080
ENTRYPOINT
version: '3.8'
services:
app:
build: .
ports:
- "8080:8080"
environment:
- SPRING_DATASOURCE_URL=jdbc:mysql://db:3306/customer_service
- SPRING_REDIS_HOST=redis
depends_on:
- db
- redis
db:
image: mysql:8.0
environment:
- MYSQL_ROOT_PASSWORD=password
- MYSQL_DATABASE=customer_service
volumes:
- mysql-data:/var/lib/mysql
redis:
image: redis:7-alpine
volumes:
- redis-data:/data
系统上线后监控也不Neng少。我们需要关注API的响应时间、Token消耗量、数据库连接状态等关键指标。这些数据Neng帮助我们及时发现潜在问题,保证系统的稳定运行。
从零开始,我们一步步构建了一个功Neng完备的DeepSeek智Neng客服系统。回顾整个过程,Spring AI 1.0确实给我们带来了hen多惊喜,它极大地降低了Java开发者接入AI的门槛。通过合理的架构设计、RAG技术的应用以及函数调用的加持,我们的系统不仅Neng聊,还Neng干实事。
当然这只是一个起点。我们还需要考虑geng复杂的权限控制、geng精细的提示词优化、以及应对高并发的缓存策略。但无论如何,拥抱AI,利用Spring AI这样的工具,我们Yi经走在了正确的道路上。希望这篇文章Neng给你带来一些启发,赶紧动手试试吧!
作为专业的SEO优化服务提供商,我们致力于通过科学、系统的搜索引擎优化策略,帮助企业在百度、Google等搜索引擎中获得更高的排名和流量。我们的服务涵盖网站结构优化、内容优化、技术SEO和链接建设等多个维度。
| 服务项目 | 基础套餐 | 标准套餐 | 高级定制 |
|---|---|---|---|
| 关键词优化数量 | 10-20个核心词 | 30-50个核心词+长尾词 | 80-150个全方位覆盖 |
| 内容优化 | 基础页面优化 | 全站内容优化+每月5篇原创 | 个性化内容策略+每月15篇原创 |
| 技术SEO | 基本技术检查 | 全面技术优化+移动适配 | 深度技术重构+性能优化 |
| 外链建设 | 每月5-10条 | 每月20-30条高质量外链 | 每月50+条多渠道外链 |
| 数据报告 | 月度基础报告 | 双周详细报告+分析 | 每周深度报告+策略调整 |
| 效果保障 | 3-6个月见效 | 2-4个月见效 | 1-3个月快速见效 |
我们的SEO优化服务遵循科学严谨的流程,确保每一步都基于数据分析和行业最佳实践:
全面检测网站技术问题、内容质量、竞争对手情况,制定个性化优化方案。
基于用户搜索意图和商业目标,制定全面的关键词矩阵和布局策略。
解决网站技术问题,优化网站结构,提升页面速度和移动端体验。
创作高质量原创内容,优化现有页面,建立内容更新机制。
获取高质量外部链接,建立品牌在线影响力,提升网站权威度。
持续监控排名、流量和转化数据,根据效果调整优化策略。
基于我们服务的客户数据统计,平均优化效果如下:
我们坚信,真正的SEO优化不仅仅是追求排名,而是通过提供优质内容、优化用户体验、建立网站权威,最终实现可持续的业务增长。我们的目标是与客户建立长期合作关系,共同成长。
Demand feedback