RuoYi AI 源码分析
RuoYi AI 是一个基于Spring Boot 3.4的企业级AI助手平台,深度集成FastGPT、扣子(Coze)、DIFY等主流AI平台,提供先进的RAG技术和多模型支持。
核心亮点:
- 多模型接入:支持 OpenAI GPT-4、Azure、ChatGLM、通义千问、智谱AI 等主流模型
- AI平台集成:深度集成 FastGPT、扣子(Coze)、DIFY 等主流AI应用平台
- Spring AI MCP 集成:基于模型上下文协议,打造可扩展的AI工具生态系统
- 实时流式对话:采用 SSE/WebSocket 技术,提供丝滑的对话体验
- AI 编程助手:内置智能代码分析和项目脚手架生成能力
项目整体架构
核心模块结构
ruoyi-ai/
├── ruoyi-admin/ # 主启动模块
├── ruoyi-modules/ # 业务模块
│ ├── ruoyi-chat/ # 聊天核心模块
│ ├── ruoyi-system/ # 系统管理模块
│ └── ruoyi-generator/ # 代码生成模块
├── ruoyi-modules-api/ # API接口模块
├── ruoyi-common/ # 公共组件模块
└── ruoyi-extend/ # 扩展功能模块
技术栈
后端框架:Spring Boot 3.4 + Spring AI + Langchain4j
数据库:MySQL 8.0 + Redis + Weaviate向量数据库
安全认证:Sa-Token + JWT
Java版本:JDK 17
主要依赖
- 后端架构:Spring Boot 3.4 + Spring AI + Langchain4j
- 数据存储:MySQL 8.0 + Redis + 向量数据库(Milvus/Weaviate/Qdrant)
- 安全认证:Sa-Token + JWT 双重保障
- 文档处理:PDF、Word、Excel 解析,图像智能分析
- 实时通信:WebSocket 实时通信,SSE 流式响应
核心功能实现
- 多模型AI集成
支持OpenAI GPT系列、Azure、ChatGLM、通义千问、智谱AI等主流模型
通过工厂模式实现不同AI平台的统一接口
支持流式对话(SSE/WebSocket)
- AI平台深度集成
FastGPT:原生API支持,包括知识库检索和工作流编排
扣子(Coze):集成字节跳动官方SDK
DIFY:使用DIFY Java Client,支持应用编排和知识库管理
- 本地化RAG方案
基于Langchain4j + BGE-large-zh-v1.5中文向量模型
支持Weaviate向量数据库
完全本地部署,保护数据隐私
- 知识库管理
支持PDF、Word、Excel文档解析
智能文档分块和向量化存储
语义检索和上下文增强
AI聊天核心功能
1. 聊天服务接口设计
public interface IChatService {
/**
* 客户端发送消息到服务端
*/
SseEmitter chat(ChatRequest chatRequest,SseEmitter emitter);
/**
* 获取此服务支持的模型类别
*/
String getCategory();
}
2. 多AI平台集成
项目支持多个主流AI平台,通过工厂模式统一管理:
@Component
public class ChatServiceFactory implements ApplicationContextAware {
private final Map<String, IChatService> chatServiceMap = new ConcurrentHashMap<>();
public IChatService getChatService(String category) {
IChatService service = chatServiceMap.get(category);
if (service == null) {
throw new IllegalArgumentException("不支持的模型类别: " + category);
}
return service;
}
}
支持的AI平台实现:
OpenAI集成:
@Override
public SseEmitter chat(ChatRequest chatRequest,SseEmitter emitter) {
ChatModelVo chatModelVo = chatModelService.selectModelByName(chatRequest.getModel());
OpenAiStreamClient openAiStreamClient = ChatConfig.createOpenAiStreamClient(chatModelVo.getApiHost(), chatModelVo.getApiKey());
// MCP工具集成
if (enabled) {
String toolString = mcpChat(chatRequest.getPrompt());
Message userMessage = Message.builder().content("工具返回信息:"+toolString).role(Message.Role.USER).build();
messages.add(userMessage);
}
// 流式响应处理
SSEEventSourceListener listener = new SSEEventSourceListener(emitter,chatRequest.getUserId(),chatRequest.getSessionId(), token);
ChatCompletion completion = ChatCompletion.builder()
.messages(messages)
.model(chatRequest.getModel())
.stream(true)
.build();
openAiStreamClient.streamChatCompletion(completion, listener);
return emitter;
}
FastGPT集成:
@Override
public SseEmitter chat(ChatRequest chatRequest, SseEmitter emitter) {
ChatModelVo chatModelVo = chatModelService.selectModelByName(chatRequest.getModel());
OpenAiStreamClient openAiStreamClient = ChatConfig.createOpenAiStreamClient(chatModelVo.getApiHost(), chatModelVo.getApiKey());
FastGPTChatCompletion completion = FastGPTChatCompletion.builder()
.messages(messages)
.detail(true) // 开启后sse会返回event值
.stream(true)
.build();
openAiStreamClient.streamChatCompletion(completion, listener);
return emitter;
}
Coze集成:
@Override
public SseEmitter chat(ChatRequest chatRequest, SseEmitter emitter) {
ChatModelVo chatModelVo = chatModelService.selectModelByName(chatRequest.getModel());
TokenAuth authCli = new TokenAuth(chatModelVo.getApiKey());
CozeAPI coze = new CozeAPI.Builder()
.baseURL(chatModelVo.getApiHost())
.auth(authCli)
.readTimeout(10000)
.build();
CreateChatReq req = CreateChatReq.builder()
.botID(chatModelVo.getModelName())
.userID(chatRequest.getUserId().toString())
.messages(Collections.singletonList(Message.buildUserQuestionText(chatRequest.getPrompt())))
.build();
}
3. 流式对话实现
// SSE事件监听器
public class SSEEventSourceListener extends EventSourceListener {
@Override
public void onEvent(EventSource eventSource, String id, String type, String data) {
// 处理流式响应
emitter.send(data);
}
}
4. 向量存储服务
// 基于Langchain4j的向量存储
public class VectorStoreServiceImpl implements VectorStoreService {
public List<String> getQueryVector(QueryVectorBo queryVectorBo) {
// 语义检索实现
EmbeddingModel embeddingModel = getEmbeddingModel(...);
Embedding queryEmbedding = embeddingModel.embed(queryVectorBo.getQuery()).content();
// 向量相似度搜索
}
}
5. 聊天控制器
@Controller
@RequestMapping("/chat")
public class ChatController {
private final ISseService sseService;
/**
* 聊天接口
*/
@PostMapping("/send")
@ResponseBody
public SseEmitter sseChat(@RequestBody @Valid ChatRequest chatRequest, HttpServletRequest request) {
return sseService.sseChat(chatRequest,request);
}
/**
* 上传文件
*/
@PostMapping("/upload")
@ResponseBody
public UploadFileResponse upload(@RequestPart("file") MultipartFile file) {
return sseService.upload(file);
}
/**
* 语音转文本
*/
@PostMapping("/audio")
@ResponseBody
public WhisperResponse audio(@RequestParam("file") MultipartFile file) {
return sseService.speechToTextTranscriptionsV2(file);
}
}
6. AI Copilot扩展功能
Spring AI集成配置
@Configuration
public class SpringAIConfiguration {
@Bean
public ChatClient chatClient(ChatModel chatModel,
FileOperationTools fileOperationTools,
SmartEditTool smartEditTool,
AnalyzeProjectTool analyzeProjectTool,
ProjectScaffoldTool projectScaffoldTool,
AppProperties appProperties) {
return ChatClient.builder(chatModel)
.defaultSystem("""
You are an expert software development assistant with access to file system tools.
You excel at creating complete, well-structured projects through systematic execution of multiple related tasks.
""")
.defaultTools(fileOperationTools, smartEditTool, analyzeProjectTool, projectScaffoldTool)
.build();
}
}
项目分析工具
@Tool(name = "analyze_project", description = "Analyzes project structure, type, dependencies and other information")
public String analyzeProject(String projectPath, String analysisDepth, String outputFormat, Boolean includeCodeStats) {
try {
AnalyzeProjectParams params = new AnalyzeProjectParams();
params.setProjectPath(projectPath);
params.setAnalysisDepth(analysisDepth != null ? analysisDepth : "basic");
params.setOutputFormat(outputFormat != null ? outputFormat : "detailed");
params.setIncludeCodeStats(includeCodeStats != null ? includeCodeStats : false);
// 执行项目分析
ProjectContext context = analyzeProject(projectPath, depth, params);
return formatAnalysisResult(context, params);
} catch (Exception e) {
logger.error("Error during project analysis", e);
return ToolResult.error("Project analysis failed: " + e.getMessage());
}
}
7. 数据模型设计
核心表结构:
chat_model:AI模型配置表
chat_message:聊天消息记录表
chat_session:会话管理表
knowledge_info:知识库信息表
knowledge_attach:知识库附件表
chat_config:系统配置表
聊天消息表
CREATE TABLE `chat_message` (
`id` bigint(20) NOT NULL COMMENT '主键',
`session_id` bigint(20) NULL DEFAULT NULL COMMENT '会话id',
`user_id` bigint(20) NOT NULL COMMENT '用户id',
`content` longtext CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL COMMENT '消息内容',
`role` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL COMMENT '对话角色',
`deduct_cost` double(20, 2) NULL DEFAULT 0.00 COMMENT '扣除金额',
`total_tokens` int(20) NULL DEFAULT 0 COMMENT '累计 Tokens',
`model_name` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL COMMENT '模型名称'
) ENGINE = InnoDB CHARACTER SET = utf8mb4 COLLATE = utf8mb4_general_ci COMMENT = '聊天消息' ROW_FORMAT = Dynamic;
聊天消息实体类
@Data
@EqualsAndHashCode(callSuper = true)
@TableName("chat_message")
public class ChatMessage extends BaseEntity {
@TableId(value = "id")
private Long id;
private Long userId; // 用户id
private Long sessionId; // 会话id
private String content; // 消息内容
private String role; // 对话角色
private BigDecimal deductCost; // 扣除金额
private Long totalTokens; // 累计 Tokens
private String modelName; // 模型名称
private String remark; // 备注
}
聊天模型配置
@Data
@EqualsAndHashCode(callSuper = true)
@TableName("chat_model")
public class ChatModel extends BaseEntity {
@TableId(value = "id")
private Long id;
private String category; // 模型分类
private String modelName; // 模型名称
private String modelDescribe; // 模型描述
private Double modelPrice; // 模型价格
private String modelType; // 计费类型
private String modelShow; // 是否显示
private String systemPrompt; // 系统提示词
private String apiHost; // 请求地址
private String apiKey; // 密钥
private String remark; // 备注
}
ruoyi-admin 模块
ruoyi-admin 是RuoYi AI项目的核心启动模块,作为整个应用的Web服务入口,负责整合所有业务模块并提供统一的服务接口。
模块结构
ruoyi-admin/
├── pom.xml # Maven配置文件
├── src/main/
│ ├── java/org/ruoyi/
│ │ ├── RuoYiAIApplication.java # 主启动类
│ │ ├── RuoYiAIServletInitializer.java # Servlet容器初始化
│ │ └── controller/ # 控制器层
│ │ ├── AuthController.java # 认证控制器
│ │ ├── CaptchaController.java # 验证码控制器
│ │ └── IndexController.java # 首页控制器
│ └── resources/
│ ├── application.yml # 主配置文件
│ ├── application-dev.yml # 开发环境配置
│ ├── banner.txt # 启动横幅
│ ├── mcp-server.json # MCP服务器配置
│ └── logback-plus.xml # 日志配置
└── target/ # 编译输出目录
启动类分析
主启动类
@SpringBootApplication
@EnableScheduling
@EnableAsync
public class RuoYiAIApplication {
public static void main(String[] args) {
SpringApplication application = new SpringApplication(RuoYiAIApplication.class);
application.setApplicationStartup(new BufferingApplicationStartup(2048));
application.run(args);
System.out.println("(♥◠‿◠)ノ゙ RuoYiAI启动成功 ლ(´ڡ`ლ)゙");
}
}
关键特性:
@SpringBootApplication
:Spring Boot主配置注解@EnableScheduling
:启用定时任务支持@EnableAsync
:启用异步处理支持BufferingApplicationStartup(2048)
:启用应用启动性能监控从 Spring Boot 2.4 开始,应用启动追踪指标可通过
/actuator/startup
端点获得。为内部缓冲区指定了 2048 的容量。一旦缓冲区中的事件达到这个容量,就不会再记录任何数据。因此,必须根据应用的复杂度和启动过程中执行的各种步骤,使用适当的值来存储事件。
只有按这种方式配置了实现,Actuator 端点
/actuator/startup
才可用。查看端点
# 使用 curl 来调用这个 POST 端点,并使用 jq 来格式化 JSON 输出: curl 'http://localhost:8080/actuator/startup' -X POST | jq
过滤启动事件
BufferingApplicationStartup startup = new BufferingApplicationStartup(2048); startup.addFilter(startupStep -> startupStep.getName().matches("spring.beans.instantiate");
分析启动时间
curl 'http://localhost:8080/actuator/startup' -X POST \ | jq '[.timeline.events | sort_by(.duration) | reverse[] | select(.startupStep.name | match("spring.beans.instantiate")) | {beanName: .startupStep.tags[0].value, duration: .duration}]'
Servlet容器初始化
public class RuoYiAIServletInitializer extends SpringBootServletInitializer {
@Override
protected SpringApplicationBuilder configure(SpringApplicationBuilder application) {
return application.sources(RuoYiAIApplication.class);
}
}
用途: 支持传统Servlet容器(如Tomcat、Jetty)部署
依赖管理
核心依赖
<dependencies>
<!-- 数据库驱动 -->
<dependency>
<groupId>com.mysql</groupId>
<artifactId>mysql-connector-j</artifactId>
</dependency>
<!-- 多数据库支持 -->
<dependency>
<groupId>com.oracle.database.jdbc</groupId>
<artifactId>ojdbc8</artifactId>
</dependency>
<dependency>
<groupId>org.postgresql</groupId>
<artifactId>postgresql</artifactId>
</dependency>
<dependency>
<groupId>com.microsoft.sqlserver</groupId>
<artifactId>mssql-jdbc</artifactId>
</dependency>
<!-- 业务模块 -->
<dependency>
<groupId>org.ruoyi</groupId>
<artifactId>ruoyi-system</artifactId>
</dependency>
<dependency>
<groupId>org.ruoyi</groupId>
<artifactId>ruoyi-chat</artifactId>
</dependency>
<dependency>
<groupId>org.ruoyi</groupId>
<artifactId>ruoyi-generator</artifactId>
</dependency>
</dependencies>
特点:
- 支持多种数据库:MySQL、Oracle、PostgreSQL、SQL Server
- 集成系统管理、AI聊天、代码生成等核心业务模块