RuoYi AI 源码分析

RuoYi AI 是一个基于Spring Boot 3.4的企业级AI助手平台,深度集成FastGPT、扣子(Coze)、DIFY等主流AI平台,提供先进的RAG技术和多模型支持。

核心亮点:

项目整体架构

核心模块结构

ruoyi-ai/
├── ruoyi-admin/ # 主启动模块
├── ruoyi-modules/ # 业务模块
│ ├── ruoyi-chat/ # 聊天核心模块
│ ├── ruoyi-system/ # 系统管理模块
│ └── ruoyi-generator/ # 代码生成模块
├── ruoyi-modules-api/ # API接口模块
├── ruoyi-common/ # 公共组件模块
└── ruoyi-extend/ # 扩展功能模块

技术栈

主要依赖

核心功能实现

  1. 多模型AI集成
  1. AI平台深度集成
  1. 本地化RAG方案
  1. 知识库管理

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. 数据模型设计

核心表结构:

聊天消息表

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启动成功 ლ(´ڡ`ლ)゙");
}
}

关键特性:

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>

特点:

Spring 国际化实现
ThingsBoard HTTP Transport 实现方式