基于 Spring AI 的智能客服系统,支持 RAG 知识库、多轮对话、会话管理和工具调用。
- 后端框架: Spring Boot 3.5.5
- AI 框架: Spring AI (集成 DeepSeek)
- 数据库: MySQL 8.0
- ORM: Spring Data JPA
- 开发语言: Java 17
| 模块名称 | 描述 |
|---|---|
| ai-service | 基于 RAG 和 Agent 的智能客服系统,支持会话记录、向量检索和工具调用 |
graph TD
A[用户] --> B[登录认证]
B --> C[进入聊天页面]
C --> D[AI 高级开发工程师 Agent]
D --> E{Agent 决策}
E --> F[RAG 知识库检索]
E --> G[工具调用]
F --> H[构造 Prompt]
G --> H
H --> I[调用 DeepSeek AI]
I --> J[返回结果并保存会话]
ai-service
├── controller
│ ├── AuthController // 用户登录认证
│ ├── ChatController // 聊天接口 (简单/会话模式)
│ ├── SessionController // 会话管理 (CRUD)
│ └── KnowledgeController // 知识库管理 (CRUD + 搜索)
│
├── service
│ ├── AiChatService // AI 核心编排 (RAG+ 历史上下文 + 工具)
│ ├── KnowledgeService // 知识库服务 (向量相似度搜索)
│ ├── OpenAIEmbeddingsService // Embedding 向量生成
│ └── SessionService // 会话管理业务逻辑
│
├── ai
│ ├── prompt
│ │ ├── CustomerPrompt // 客服 Prompt 模板 (支持历史对话)
│ │ └── AgentPrompt // Agent 系统 Prompt
│ ├── agent // Agent 逻辑 (待扩展)
│ └── tool
│ └── OrderTool // 订单查询工具
│
├── repository
│ ├── UserRepository // 用户数据访问
│ ├── ChatMessageRepository // 聊天消息数据访问
│ ├── SessionRepository // 会话数据访问
│ └── KnowledgeRepository // 知识库数据访问
│
├── entity
│ ├── User // 用户实体
│ ├── ChatMessage // 聊天消息实体
│ ├── Session // 会话实体
│ ├── Knowledge // 知识库文档实体
│ ├── ChatRequest // 聊天请求 DTO
│ └── CreateSessionRequest // 创建会话请求 DTO
│
└── config
├── AiConfig // AI 配置
└── CorsConfig // 跨域配置
-
用户认证
- POST
/auth/login- 用户登录 (返回 UUID token)
- POST
-
聊天对话
- GET
/chat/simple?msg=xxx- 简单聊天 (无会话记录) - POST
/chat- 带会话管理的聊天 (自动保存历史记录) - 支持多轮对话上下文理解
- 自动生成会话标题
- GET
-
会话管理
- GET
/session/list?userId={userId}- 获取用户会话列表 - GET
/session/history?sessionId={sessionId}- 获取会话历史消息 - POST
/session/create- 创建新会话 - DELETE
/session/{id}- 删除会话及消息
- GET
-
RAG 知识库
- POST
/knowledge/add- 添加知识文档 (自动生成向量) - POST
/knowledge/batch-add- 批量添加文档 - GET
/knowledge/list- 获取所有文档 - GET
/knowledge/{id}- 获取单个文档详情 - GET
/knowledge/search?keyword=xxx- 向量相似度搜索 - DELETE
/knowledge/{id}- 删除文档
- POST
-
AI 能力
- 基于 DeepSeek 的文本生成
- 向量嵌入 (Embedding) 生成
- 余弦相似度语义检索
- 工具调用 (OrderTool)
- Prompt 模板引擎
-
数据持久化
- MySQL 数据库存储
- JPA 自动建表
- 完整的 CRUD 操作
- Agent 复杂任务规划
- 更多工具集成 (物流查询、库存管理等)
- 向量数据库集成 (Milvus/Pinecone)
- Redis 缓存优化
- 用户权限管理
- 对话质量评估
POST /auth/login
// 请求
POST /auth/login?username=admin&password=123456
// 响应
"550e8400-e29b-41d4-a716-446655440000"GET /chat/simple?msg={message}
# 简单聊天 (无会话记录)
curl "http://localhost:8080/chat/simple?msg=你好"POST /chat
// 请求
POST /chat
Content-Type: application/json
{
"userId": 1,
"sessionId": 1,
"msg": "怎么退货?"
}
// 响应
"您好,退货流程如下:\n1. 在订单页面申请退货\n2. 将商品寄回\n3. 等待仓库验收后退款"GET /session/list?userId={userId}
// 响应
{
"code": 200,
"message": "success",
"data": [
{
"id": 1,
"userId": 1,
"title": "退货咨询",
"createdAt": "2026-03-29T10:00:00",
"updatedAt": "2026-03-29T10:30:00"
}
]
}GET /session/history?sessionId={sessionId}
// 响应
{
"code": 200,
"message": "success",
"data": [
{
"id": 1,
"sessionId": 1,
"userId": 1,
"role": "user",
"content": "怎么退货?",
"createdAt": "2026-03-29T10:00:00"
},
{
"id": 2,
"sessionId": 1,
"userId": 1,
"role": "ai",
"content": "您好,退货流程如下...",
"createdAt": "2026-03-29T10:00:05"
}
]
}POST /session/create
// 请求
POST /session/create
Content-Type: application/json
{
"userId": 1,
"title": "订单咨询"
}POST /knowledge/add
// 请求
POST /knowledge/add
Content-Type: application/json
{
"title": "退货流程",
"content": "1. 申请退货 2. 寄回商品 3. 等待退款"
}GET /knowledge/search?keyword={keyword}&limit={limit}
// 响应 (基于向量相似度)
{
"code": 200,
"message": "success",
"data": [
{
"id": 1,
"title": "退货流程",
"content": "1. 申请退货 2. 寄回商品 3. 等待退款",
"similarity": 0.92
}
]
}CREATE TABLE users (
id BIGINT PRIMARY KEY AUTO_INCREMENT,
username VARCHAR(255) NOT NULL UNIQUE,
password VARCHAR(255) NOT NULL,
email VARCHAR(255) NOT NULL UNIQUE,
created_at TIMESTAMP,
updated_at TIMESTAMP
);CREATE TABLE sessions (
id BIGINT PRIMARY KEY AUTO_INCREMENT,
user_id BIGINT NOT NULL,
title VARCHAR(200),
created_at TIMESTAMP,
updated_at TIMESTAMP,
INDEX idx_user_id (user_id)
);CREATE TABLE chat_messages (
id BIGINT PRIMARY KEY AUTO_INCREMENT,
session_id BIGINT NOT NULL,
user_id BIGINT NOT NULL,
role VARCHAR(50) NOT NULL, -- user/assistant/system
content TEXT,
created_at TIMESTAMP,
INDEX idx_session_id (session_id),
INDEX idx_user_id (user_id)
);CREATE TABLE knowledge_base (
id BIGINT PRIMARY KEY AUTO_INCREMENT,
title VARCHAR(200) NOT NULL,
content TEXT NOT NULL,
embedding_json LONGTEXT, -- 向量 (JSON 格式)
created_at TIMESTAMP,
updated_at TIMESTAMP,
INDEX idx_title (title),
FULLTEXT INDEX idx_content (content)
);工作流程:
用户问题 → Embedding 向量化 → 知识库检索 →
余弦相似度计算 → Top N 相关知识 →
构造 Prompt → AI 生成回复
向量搜索算法:
- 使用 DeepSeek text-embedding-3-small 模型
- 1536 维向量空间
- 余弦相似度计算 (0-1 范围)
- 阈值过滤 (>0.3)
实现机制:
// 加载最近 10 条历史对话
List<String> history = loadHistoryContext(sessionId);
// 构造包含历史对话的 Prompt
String prompt = buildWithHistory(context, history, question);Prompt 结构:
你是优秀的高级 ai 开发工程师:
规则:
- 不要编造
- 简洁回答
- 优先使用知识库
- 结合历史对话理解上下文
知识库:
{相关知识内容}
历史对话:
user: 我想退货
assistant: 请提供订单号
user: SF123456
当前问题:
什么时候能到?
触发条件: 会话的第一次对话
生成规则:
- 截取用户第一个问题前 20 个字符
- 超过 20 字添加省略号
- 自动更新到 sessions.title 字段
OrderTool 示例:
@Component
public class OrderTool implements Function<OrderRequest, String> {
@Override
public String apply(OrderRequest request) {
// 查询订单状态
return "订单号:" + request.orderId() + ",状态:已发货";
}
public record OrderRequest(String orderId) {}
}spring:
datasource:
url: jdbc:mysql://localhost:3306/monkey
username: admin
password: 123456
driver-class-name: com.mysql.cj.jdbc.Driver
jpa:
hibernate:
ddl-auto: update # 自动建表
show-sql: true
properties:
hibernate:
dialect: org.hibernate.dialect.MySQLDialect
ai:
openai:
api-key: ${deepseek.apikey} # 环境变量
base-url: https://api.deepseek.com
chat:
options:
model: deepseek-chat
server:
port: 8080# 设置 DeepSeek API Key
export deepseek.apikey=sk-xxxxxxxxxxxxxxxx# 安装 MySQL 8.0+
# 安装 JDK 17+
# 获取 DeepSeek API KeyCREATE DATABASE monkey CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;export deepseek.apikey=sk-xxxxxxxxxxxxxxxxcd ai-service
./mvnw spring-boot:run# 添加知识文档
curl -X POST http://localhost:8080/knowledge/add \
-H "Content-Type: application/json" \
-d '{"title": "退货流程", "content": "1.申请 2.寄回 3.退款"}'
# 创建会话
curl -X POST http://localhost:8080/session/create \
-H "Content-Type: application/json" \
-d '{"userId": 1, "title": "测试会话"}'
# 发起聊天
curl -X POST http://localhost:8080/chat \
-H "Content-Type: application/json" \
-d '{"userId": 1, "sessionId": 1, "msg": "怎么退货?"}'- 当前方案: 适合 < 10,000 条文档
- 大规模方案: 集成向量数据库 (Milvus/Pinecone)
// 建议:缓存热门搜索的向量
@Cacheable(value = "embeddings", key = "#query")
public List<Double> createEmbedding(String query) {
// ...
}-- 已配置的索引
CREATE INDEX idx_sessions_user_id ON sessions(user_id);
CREATE INDEX idx_chat_messages_session_id ON chat_messages(session_id);
CREATE INDEX idx_chat_messages_user_id ON chat_messages(user_id);
CREATE FULLTEXT INDEX idx_content ON knowledge_base(content);建议监控以下指标:
- API 响应时间: P99 < 2s
- 向量生成耗时: < 500ms
- 知识库检索耗时: < 100ms (1000 条以内)
- AI 生成耗时: < 1.5s
- 数据库连接数: HikariCP 池使用情况
Q: 如何切换 AI 模型?
A: 修改 application.yml 中的 spring.ai.openai.chat.options.model
Q: 知识库搜索不准确怎么办?
A: 调整相似度阈值 (searchByKeyword 方法中的 > 0.3)
Q: 如何清空所有会话数据?
A: 执行 SQL: TRUNCATE TABLE chat_messages; TRUNCATE TABLE sessions;
Q: 支持并发聊天吗? A: 支持,每个会话独立,互不影响
- 项目名称: monkey
- 模块: ai-service
- 版本: 0.0.1-SNAPSHOT
- JDK 版本: 17+
- Spring Boot: 3.5.5
- Spring AI: 1.0.0
Last Updated: 2026-03-29