diff --git a/README.md b/README.md index 041a9e5..226c2e1 100644 --- a/README.md +++ b/README.md @@ -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/) @@ -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: