Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
100 changes: 89 additions & 11 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,8 @@
[![License](https://img.shields.io/badge/license-MIT-blue.svg)](LICENSE)
[![Java](https://img.shields.io/badge/Java-21+-orange.svg)](https://www.oracle.com/java/)
[![Spring Boot](https://img.shields.io/badge/Spring%20Boot-3.4.1-brightgreen.svg)](https://spring.io/projects/spring-boot)
[![Spring AI](https://img.shields.io/badge/Spring%20AI-1.0.0--M5-green.svg)](https://spring.io/projects/spring-ai)
[![Spring AI Alibaba](https://img.shields.io/badge/Spring%20AI%20Alibaba-1.0.0--M6.1-orange.svg)](https://java2ai.com)
[![React](https://img.shields.io/badge/React-18.x-61dafb.svg)](https://reactjs.org/)
[![TypeScript](https://img.shields.io/badge/TypeScript-5.x-blue.svg)](https://www.typescriptlang.org/)

Expand All @@ -32,9 +34,9 @@ PaiAgent-one 是一个**企业级的 AI 工作流可视化编排平台**,让 A

- **🎯 零代码编排**:可视化拖拽界面,无需编程即可构建复杂 AI 工作流
- **🚀 高性能引擎**:自研轻量级 DAG 引擎,支持拓扑排序和智能循环检测
- **🔌 多模型统一**:统一接入 OpenAI、DeepSeek、通义千问等主流大模型
- **🔌 多模型统一**:基于 Spring AI 框架,统一接入 OpenAI、DeepSeek、通义千问等主流大模型
- **🛠️ 灵活扩展**:基于插件化设计,轻松开发自定义节点满足个性化需求
- **🐛 实时调试**:内置调试面板,可视化执行过程,快速定位问题
- **🐛 实时调试**:内置调试面板,支持 SSE 流式输出,可视化执行过程
- **📦 开箱即用**:完整的前后端解决方案,快速部署到生产环境

## ✨ 核心特性
Expand All @@ -43,10 +45,14 @@ PaiAgent-one 是一个**企业级的 AI 工作流可视化编排平台**,让 A
基于 ReactFlow 构建的专业流程图编辑器,支持节点拖拽、连线配置、参数编辑等完整功能。

### 多大模型节点支持
- **OpenAI 节点**:GPT-3.5/GPT-4 等模型支持
- **DeepSeek 节点**:国产大模型接入
- **通义千问节点**:阿里云千问系列模型
- **更多模型**:持续集成中...

基于 **Spring AI + Spring AI Alibaba** 框架统一接入:

- **OpenAI 节点**:GPT-3.5/GPT-4 等模型(Spring AI OpenAI 接口)
- **DeepSeek 节点**:国产大模型(OpenAI 兼容接口)
- **通义千问节点**:阿里云千问系列(Spring AI Alibaba DashScope 原生支持)
- **智谱 AI 节点**:GLM 系列模型(OpenAI 兼容接口)
- **AIPing 节点**:第三方模型代理(OpenAI 兼容接口)

### 工具节点生态
- **TTS 音频合成**:超拟人语音生成
Expand Down Expand Up @@ -79,7 +85,7 @@ PaiAgent-one 是一个**企业级的 AI 工作流可视化编排平台**,让 A
│ React 18 + TypeScript + ReactFlow + Ant Design │
│ • 可视化编辑器 • 节点面板 • 调试工具 │
└────────────────────┬────────────────────────────────────┘
│ REST API / WebSocket
│ REST API / SSE
┌────────────────────┴────────────────────────────────────┐
│ 应用层 (Backend) │
│ Spring Boot 3.4.1 + Java 21 │
Expand All @@ -94,6 +100,13 @@ PaiAgent-one 是一个**企业级的 AI 工作流可视化编排平台**,让 A
└────────────────────┬────────────────────────────────────┘
┌────────────────────┴────────────────────────────────────┐
│ AI 模型层 (Spring AI) │
│ • Spring AI: OpenAI/DeepSeek/智谱 等兼容接口 │
│ • Spring AI Alibaba: 通义千问 DashScope 原生支持 │
│ • ChatClientFactory: 统一的 ChatClient 动态工厂 │
└────────────────────┬────────────────────────────────────┘
┌────────────────────┴────────────────────────────────────┐
│ 数据层 (Data & Storage) │
│ • MySQL: 工作流配置、执行记录 │
│ • MinIO: 文件存储 (可选) │
Expand Down Expand Up @@ -157,6 +170,16 @@ PaiAgent-one 是一个**企业级的 AI 工作流可视化编排平台**,让 A
<td>增强版 ORM 框架</td>
</tr>
<tr>
<td>Spring AI</td>
<td>1.0.0-M5</td>
<td>AI 模型统一调用框架</td>
</tr>
<tr>
<td>Spring AI Alibaba</td>
<td>1.0.0-M6.1</td>
<td>通义千问 DashScope 原生支持</td>
</tr>
<tr>
<td>MySQL</td>
<td>8.0+</td>
<td>关系型数据库</td>
Expand All @@ -172,7 +195,7 @@ PaiAgent-one 是一个**企业级的 AI 工作流可视化编排平台**,让 A
<td>对象存储服务</td>
</tr>
<tr>
<td rowspan="3"><b>核心引擎</b></td>
<td rowspan="5"><b>核心引擎</b></td>
<td>自研 DAG 引擎</td>
<td>-</td>
<td>工作流编排核心</td>
Expand All @@ -187,6 +210,16 @@ PaiAgent-one 是一个**企业级的 AI 工作流可视化编排平台**,让 A
<td>-</td>
<td>防止工作流死锁</td>
</tr>
<tr>
<td>Spring AI ChatClient</td>
<td>-</td>
<td>统一 AI 模型调用接口</td>
</tr>
<tr>
<td>ChatClientFactory</td>
<td>-</td>
<td>动态创建不同模型客户端</td>
</tr>
</table>

## 📁 项目结构
Expand All @@ -199,15 +232,22 @@ PaiAgent-one/
│ │ │ ├── engine/ # 🎯 DAG 工作流引擎(核心)
│ │ │ │ ├── WorkflowEngine.java # 工作流编排引擎
│ │ │ │ ├── dag/DAGParser.java # 拓扑排序+循环检测
│ │ │ │ ├── llm/ # LLM 调用层(Spring AI)
│ │ │ │ │ ├── ChatClientFactory.java # ChatClient 动态工厂
│ │ │ │ │ ├── PromptTemplateService.java # 提示词模板处理
│ │ │ │ │ └── LLMNodeConfig.java # LLM 节点配置
│ │ │ │ ├── executor/ # 节点执行器
│ │ │ │ │ ├── NodeExecutor.java # 执行器接口
│ │ │ │ │ ├── NodeExecutorFactory.java # 工厂模式
│ │ │ │ │ └── impl/ # 具体实现
│ │ │ │ │ ├── AbstractLLMNodeExecutor.java # LLM 抽象基类
│ │ │ │ │ ├── InputNodeExecutor.java
│ │ │ │ │ ├── OutputNodeExecutor.java
│ │ │ │ │ ├── OpenAINodeExecutor.java
│ │ │ │ │ ├── DeepSeekNodeExecutor.java
│ │ │ │ │ ├── QwenNodeExecutor.java
│ │ │ │ │ ├── ZhiPuNodeExecutor.java
│ │ │ │ │ ├── AIPingNodeExecutor.java
│ │ │ │ │ └── TTSNodeExecutor.java
│ │ │ │ └── model/ # 数据模型
│ │ │ ├── controller/ # REST API 接口层
Expand Down Expand Up @@ -372,15 +412,23 @@ npm run dev
- ✅ 用户认证系统(Token 认证 + 拦截器)
- ✅ 可视化流程编辑器(ReactFlow 集成)
- ✅ DAG 工作流引擎(拓扑排序 + 循环检测)
- ✅ **Spring AI 框架集成**(v1.0.0-M5)
- 统一的 ChatClient 调用接口
- 支持 OpenAI 兼容协议(OpenAI/DeepSeek/智谱/AIPing)
- ✅ **Spring AI Alibaba 集成**(v1.0.0-M6.1)
- 通义千问 DashScope 原生支持
- 阿里云 Qwen 系列模型接入
- ✅ 多大模型节点支持
- OpenAI 节点(GPT 系列)
- DeepSeek 节点
- 通义千问节点
- 智谱 AI 节点
- AIPing 节点
- ✅ 工具节点实现
- 输入/输出节点
- TTS 音频合成节点
- 音频播放器组件
- ✅ 实时调试功能(调试抽屉 + 日志输出 + 结果展示)
- ✅ SSE 实时流式输出(调试抽屉 + 日志输出 + 结果展示)
- ✅ 工作流 CRUD 管理
- ✅ 执行记录查询

Expand Down Expand Up @@ -451,12 +499,15 @@ npm run dev
public interface NodeExecutor {
Map<String, Object> execute(WorkflowNode node, Map<String, Object> input);
}

// LLM 节点通过 Spring AI ChatClient 统一调用
ChatClient chatClient = chatClientFactory.createClient(nodeType, apiUrl, apiKey, model, temperature);
String response = chatClient.prompt().user(prompt).call().content();
```

### 节点扩展开发

开发自定义节点只需三步:

**方式一:开发普通工具节点**
1. **实现 NodeExecutor 接口**
```java
public class CustomNodeExecutor implements NodeExecutor {
Expand All @@ -473,6 +524,18 @@ public class CustomNodeExecutor implements NodeExecutor {
NodeExecutorFactory.register("custom", new CustomNodeExecutor());
```

**方式二:开发 LLM 节点(推荐)**
```java
// 继承 AbstractLLMNodeExecutor,自动获得 Spring AI 能力
@Component
public class CustomLLMNodeExecutor extends AbstractLLMNodeExecutor {
@Override
protected String getNodeType() {
return "custom_llm";
}
}
```

3. **前端添加节点定义**
```typescript
const customNode = {
Expand All @@ -482,6 +545,21 @@ const customNode = {
};
```

## 💼 项目亮点(简历版)

**项目名称**:PaiAgent - 企业级 AI 工作流编排平台

**项目描述**:基于可视化流程编辑器的 AI Agent 工作流平台,支持用户通过拖拽方式编排多种大模型(DeepSeek、通义千问等)和工具节点,使用自研 DAG 引擎按拓扑顺序执行工作流,实现复杂 AI 任务的自动化编排与执行。

**技术栈**:Java 21、Spring Boot 3.4.1、Spring AI 1.0.0

**核心职责**:

- 基于 Spring AI 框架重构 LLM 通信层,采用工厂模式+模板方法模式设计 ChatClientFactory 动态工厂和 AbstractLLMNodeExecutor 抽象基类,将 5 个 LLM 节点执行器的重复代码从 800+行精简至 75 行
- 设计动态 ChatClient 创建机制,支持运行时根据工作流节点配置(apiKey/apiUrl/model)动态实例化不同厂商的 ChatClient,实现多租户场景下每个节点独立配置的能力
- 抽取 PromptTemplateService 公共服务,统一处理 `{{variable}}` 模板变量替换和上下游节点参数引用映射,支持 input 静态值和 reference 动态引用两种参数类型
- 基于 Spring AI 的 Flux 响应式流实现 LLM 流式输出,通过 SSE 实时推送生成进度到前端,配合现有 ExecutionEvent 事件机制,用户可实时查看 AI 生成过程

## 🤝 贡献指南

我们欢迎所有形式的贡献,包括但不限于:
Expand Down
10 changes: 8 additions & 2 deletions backend/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@
<mybatis-plus.version>3.5.5</mybatis-plus.version>
<springdoc.version>2.3.0</springdoc.version>
<spring-ai.version>1.0.0-M5</spring-ai.version>
<spring-ai-alibaba.version>1.0.0.2</spring-ai-alibaba.version>
<spring-ai-alibaba.version>1.0.0-M6.1</spring-ai-alibaba.version>
</properties>

<dependencyManagement>
Expand Down Expand Up @@ -102,12 +102,18 @@
<artifactId>minio</artifactId>
<version>8.5.7</version>
</dependency>
<!-- Spring AI OpenAI (支持OpenAI、DeepSeek和通义千问的OpenAI兼容接口) -->
<!-- Spring AI OpenAI (支持OpenAI、DeepSeek等OpenAI兼容接口) -->
<dependency>
<groupId>org.springframework.ai</groupId>
<artifactId>spring-ai-openai-spring-boot-starter</artifactId>
<version>${spring-ai.version}</version>
</dependency>
<!-- Spring AI Alibaba DashScope (用于通义千问原生支持) -->
<dependency>
<groupId>com.alibaba.cloud.ai</groupId>
<artifactId>spring-ai-alibaba-starter</artifactId>
<version>${spring-ai-alibaba.version}</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,8 @@
package com.paiagent.engine.llm;

import com.alibaba.cloud.ai.dashscope.api.DashScopeApi;
import com.alibaba.cloud.ai.dashscope.chat.DashScopeChatModel;
import com.alibaba.cloud.ai.dashscope.chat.DashScopeChatOptions;
import lombok.extern.slf4j.Slf4j;
import org.springframework.ai.chat.client.ChatClient;
import org.springframework.ai.chat.model.ChatModel;
Expand All @@ -19,8 +22,8 @@ public class ChatClientFactory {
/**
* 根据节点类型和配置创建ChatClient
*
* @param nodeType 节点类型 (openai/deepseek/qwen)
* @param apiUrl API端点URL
* @param nodeType 节点类型 (openai/deepseek/qwen/zhipu/ai_ping)
* @param apiUrl API端点URL (DashScope模式下忽略)
* @param apiKey API密钥
* @param model 模型名称
* @param temperature 温度参数
Expand All @@ -32,7 +35,8 @@ public ChatClient createClient(String nodeType, String apiUrl, String apiKey,
nodeType, apiUrl, model, temperature);

ChatModel chatModel = switch (nodeType) {
case "openai", "deepseek", "qwen" -> createOpenAICompatibleModel(apiUrl, apiKey, model, temperature);
case "openai", "deepseek", "zhipu", "ai_ping" -> createOpenAICompatibleModel(apiUrl, apiKey, model, temperature);
case "qwen" -> createDashScopeModel(apiKey, model, temperature);
default -> throw new IllegalArgumentException("不支持的节点类型: " + nodeType);
};

Expand All @@ -41,7 +45,7 @@ public ChatClient createClient(String nodeType, String apiUrl, String apiKey,

/**
* 创建OpenAI兼容的ChatModel
* 支持OpenAI、DeepSeek和通义千问(通过OpenAI兼容接口)
* 支持OpenAI、DeepSeek、ZhiPu、AIPing等OpenAI兼容接口
*/
private ChatModel createOpenAICompatibleModel(String apiUrl, String apiKey,
String model, Double temperature) {
Expand All @@ -56,4 +60,39 @@ private ChatModel createOpenAICompatibleModel(String apiUrl, String apiKey,

return new OpenAiChatModel(openAiApi, options);
}
}

/**
* 创建DashScope ChatModel(用于通义千问)
* 使用阿里云 DashScope 原生 API,通过 Spring AI Alibaba 框架调用
*
* @param apiKey 阿里云 DashScope API Key
* @param model 模型名称,如 qwen-turbo, qwen-plus, qwen-max 等
* @param temperature 温度参数,控制输出随机性 (0.0-2.0)
* @return DashScopeChatModel 实例
*
* @apiNote 已知问题: spring-ai-alibaba 1.0.0.2 版本存在 requestOptions bug
* 可能在某些场景下抛出 "requestOptions cannot be null" 异常
* 建议后续升级到更高版本以获得完整修复
* @see <a href="https://github.com/alibaba/spring-ai-alibaba/issues/3300">GitHub Issue #3300</a>
*/
private ChatModel createDashScopeModel(String apiKey, String model, Double temperature) {
log.info("【DashScope模式】创建ChatModel - 模型: {}, 温度: {}", model, temperature);

// 创建 DashScope API 客户端
DashScopeApi dashScopeApi = new DashScopeApi(apiKey);
log.debug("DashScopeApi 实例创建成功");

// 配置模型选项
DashScopeChatOptions options = DashScopeChatOptions.builder()
.withModel(model)
.withTemperature(temperature)
.build();
log.debug("DashScopeChatOptions 配置完成 - model: {}, temperature: {}", model, temperature);

// 创建并返回 DashScopeChatModel
DashScopeChatModel chatModel = new DashScopeChatModel(dashScopeApi, options);
log.info("【DashScope模式】DashScopeChatModel 创建成功");

return chatModel;
}
}
3 changes: 3 additions & 0 deletions backend/src/main/resources/application.yml
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,9 @@ spring:
# 占位配置,实际使用时通过节点配置动态指定
api-key: ${OPENAI_API_KEY:sk-placeholder}
base-url: https://api.openai.com
# DashScope配置(用于通义千问原生支持)
dashscope:
api-key: ${DASHSCOPE_API_KEY:sk-placeholder}

# MyBatis-Plus 配置
mybatis-plus:
Expand Down