diff --git a/README.md b/README.md
index 041a9e5..226c2e1 100644
--- a/README.md
+++ b/README.md
@@ -9,6 +9,8 @@
[](LICENSE)
[](https://www.oracle.com/java/)
[](https://spring.io/projects/spring-boot)
+[](https://spring.io/projects/spring-ai)
+[](https://java2ai.com)
[](https://reactjs.org/)
[](https://www.typescriptlang.org/)
@@ -32,9 +34,9 @@ PaiAgent-one 是一个**企业级的 AI 工作流可视化编排平台**,让 A
- **🎯 零代码编排**:可视化拖拽界面,无需编程即可构建复杂 AI 工作流
- **🚀 高性能引擎**:自研轻量级 DAG 引擎,支持拓扑排序和智能循环检测
-- **🔌 多模型统一**:统一接入 OpenAI、DeepSeek、通义千问等主流大模型
+- **🔌 多模型统一**:基于 Spring AI 框架,统一接入 OpenAI、DeepSeek、通义千问等主流大模型
- **🛠️ 灵活扩展**:基于插件化设计,轻松开发自定义节点满足个性化需求
-- **🐛 实时调试**:内置调试面板,可视化执行过程,快速定位问题
+- **🐛 实时调试**:内置调试面板,支持 SSE 流式输出,可视化执行过程
- **📦 开箱即用**:完整的前后端解决方案,快速部署到生产环境
## ✨ 核心特性
@@ -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 音频合成**:超拟人语音生成
@@ -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 │
@@ -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: 文件存储 (可选) │
@@ -157,6 +170,16 @@ PaiAgent-one 是一个**企业级的 AI 工作流可视化编排平台**,让 A
增强版 ORM 框架 |
+| Spring AI |
+1.0.0-M5 |
+AI 模型统一调用框架 |
+
+
+| Spring AI Alibaba |
+1.0.0-M6.1 |
+通义千问 DashScope 原生支持 |
+
+
| MySQL |
8.0+ |
关系型数据库 |
@@ -172,7 +195,7 @@ PaiAgent-one 是一个**企业级的 AI 工作流可视化编排平台**,让 A
对象存储服务 |
-| 核心引擎 |
+核心引擎 |
自研 DAG 引擎 |
- |
工作流编排核心 |
@@ -187,6 +210,16 @@ PaiAgent-one 是一个**企业级的 AI 工作流可视化编排平台**,让 A
- |
防止工作流死锁 |
+
+| Spring AI ChatClient |
+- |
+统一 AI 模型调用接口 |
+
+
+| ChatClientFactory |
+- |
+动态创建不同模型客户端 |
+
## 📁 项目结构
@@ -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 接口层
@@ -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 管理
- ✅ 执行记录查询
@@ -451,12 +499,15 @@ npm run dev
public interface NodeExecutor {
Map execute(WorkflowNode node, Map 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 {
@@ -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 = {
@@ -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 生成过程
+
## 🤝 贡献指南
我们欢迎所有形式的贡献,包括但不限于:
diff --git a/backend/pom.xml b/backend/pom.xml
index 48d45ce..4e7d684 100644
--- a/backend/pom.xml
+++ b/backend/pom.xml
@@ -31,7 +31,7 @@
3.5.5
2.3.0
1.0.0-M5
- 1.0.0.2
+ 1.0.0-M6.1
@@ -102,12 +102,18 @@
minio
8.5.7
-
+
org.springframework.ai
spring-ai-openai-spring-boot-starter
${spring-ai.version}
+
+
+ com.alibaba.cloud.ai
+ spring-ai-alibaba-starter
+ ${spring-ai-alibaba.version}
+
org.springframework.boot
spring-boot-starter-test
diff --git a/backend/src/main/java/com/paiagent/engine/llm/ChatClientFactory.java b/backend/src/main/java/com/paiagent/engine/llm/ChatClientFactory.java
index 0a456b8..e6d57b6 100644
--- a/backend/src/main/java/com/paiagent/engine/llm/ChatClientFactory.java
+++ b/backend/src/main/java/com/paiagent/engine/llm/ChatClientFactory.java
@@ -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;
@@ -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 温度参数
@@ -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);
};
@@ -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) {
@@ -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 GitHub Issue #3300
+ */
+ 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;
+ }
+}
\ No newline at end of file
diff --git a/backend/src/main/resources/application.yml b/backend/src/main/resources/application.yml
index f46caea..a1687a6 100644
--- a/backend/src/main/resources/application.yml
+++ b/backend/src/main/resources/application.yml
@@ -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: