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平台,通过工厂模式统一管理:
@Componentpublic 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集成:
@Overridepublic 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集成:
@Overridepublic 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集成:
@Overridepublic 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集成配置
@Configurationpublic 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@EnableAsyncpublic 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聊天、代码生成等核心业务模块