Spring AI 多模型智能協作工作流實現指南

Spring AI 多模型智能協作工作流實現指南

說明

本文檔旨在指導開發者基于 Spring AI 框架,在 Spring Boot 2 環境下集成多種主流大語言模型(如 OpenAI ChatGPT、Deepseek、阿里云通義千問等),并提供從環境配置、模型調用、流式輸出到提示模板與異常處理的完整使用示例。文中示例適配 Spring AI 進行開發。本教程適用于對 LLM 應用開發有一定基礎的 Java 工程師,亦可作為企業多模型接入與管理的實現參考。

1. 系統架構概述

本方案基于 Spring AI 框架,構建了一個多模型協作的工作流系統,通過 ChatGPT、Deepseek 和通義千問三大模型的優勢互補,實現從原始輸入到高質量輸出的完整處理流程。

以下是基于Mermaid語法的工作流架構圖,您可以直接復制到支持Mermaid的Markdown編輯器(如Typora、VS Code插件等)中查看:

異常處理
模型協作工作流
成功
失敗
JSON格式
生成草稿
降級處理
使用默認關鍵詞
解析JSON結果
ChatGPT關鍵詞提取
通義千問文本潤色
Deepseek內容生成
用戶輸入文本
最終輸出結果

架構圖說明:

  1. 流程圖元素

    • 矩形框:表示處理步驟
    • 菱形框:表示判斷/解析節點
    • 子圖:標識不同處理階段
    • 樣式:區分輸入/輸出節點
  2. 工作流步驟

    A
    B
    C
    D
    F
    G
    E
  3. 帶詳細說明的版本

原始文本
JSON格式
成功
失敗
初稿內容
用戶輸入
ChatGPT處理器
解析結果?
提取關鍵詞+意圖
使用默認值
Deepseek生成器
通義千問潤色器
最終輸出

關鍵路徑說明:

  1. 正常流程

    用戶輸入 → ChatGPT提取 → 解析JSON → Deepseek生成 → 通義千問潤色 → 輸出
    
  2. 異常流程

    解析失敗 → 使用默認關鍵詞 → 繼續后續流程
    
  3. 組件職責

    • ChatGPT:結構化理解輸入文本
    • Deepseek:基于結構化數據生成內容
    • 通義千問:優化表達質量

部署架構圖(補充)

云服務
HTTP請求
API調用
API調用
API調用
OpenAI Cloud
Deepseek API
阿里云通義千問
客戶端
Spring Boot API
Redis緩存
數據庫

2. 環境配置

2.1 Maven 依賴配置

<dependencies><!-- Spring Boot Starter --><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-web</artifactId><version>2.7.18</version></dependency><!-- Spring AI Core --><dependency><groupId>org.springframework.ai</groupId><artifactId>spring-ai-core</artifactId><version>0.8.1</version></dependency><!-- OpenAI Starter --><dependency><groupId>org.springframework.ai</groupId><artifactId>spring-ai-openai-spring-boot-starter</artifactId><version>0.8.1</version></dependency><!-- 阿里云通義千問 --><dependency><groupId>com.alibaba.cloud.ai</groupId><artifactId>spring-ai-alibaba-starter</artifactId><version>1.0.0-M2</version></dependency><!-- JSON 處理 --><dependency><groupId>com.fasterxml.jackson.core</groupId><artifactId>jackson-databind</artifactId></dependency><!-- 日志記錄 --><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-logging</artifactId></dependency>
</dependencies>

2.2 應用配置 (application.yml)

spring:ai:openai:api-key: ${OPENAI_API_KEY}model: gpt-4-turbotemperature: 0.7max-tokens: 1000alibaba:dashscope:api-key: ${TONGYI_API_KEY}model: qwen-maxtemperature: 0.8deepseek:api-key: ${DEEPSEEK_API_KEY}base-url: https://api.deepseek.com/v1model: deepseek-chatapp:workflow:max-retries: 3retry-delay: 1000timeout: 30000

3. 核心組件實現

3.1 模型任務定義

@Data
@AllArgsConstructor
@NoArgsConstructor
public class ModelTask {private String taskId;private TaskType type;private String input;private Map<String, Object> params;public enum TaskType {KEYWORD_EXTRACTION, // 關鍵詞提取CONTENT_GENERATION, // 內容生成TEXT_POLISHING      // 文本潤色}
}

3.2 模型執行器接口

public interface ModelExecutor {/*** 執行模型任務* @param task 模型任務* @return 執行結果* @throws ModelExecutionException 模型執行異常*/String execute(ModelTask task) throws ModelExecutionException;/*** 支持的模型類型*/ModelTask.TaskType supportedType();
}

3.3 ChatGPT 執行器實現 (關鍵詞提取)

@Service
@Slf4j
public class ChatGPTExecutor implements ModelExecutor {@Autowiredprivate OpenAiChatClient chatClient;@Overridepublic String execute(ModelTask task) throws ModelExecutionException {try {String prompt = buildExtractionPrompt(task.getInput());log.info("Executing ChatGPT task with prompt: {}", prompt);String response = chatClient.call(prompt);log.info("ChatGPT response: {}", response);return parseJsonResponse(response);} catch (Exception e) {log.error("ChatGPT execution failed", e);throw new ModelExecutionException("ChatGPT processing failed", e);}}private String buildExtractionPrompt(String input) {return """請從以下文本中提取結構化信息,按JSON格式返回:{"keywords": ["關鍵詞1", "關鍵詞2", ...],  // 5-10個核心關鍵詞"intent": "用戶意圖描述",              // 用戶的主要目的"sentiment": "positive/neutral/negative" // 情感傾向}輸入文本:""" + input;}private String parseJsonResponse(String response) {// 簡化的JSON解析,實際項目中應使用Jackson等庫if (response.startsWith("{") && response.endsWith("}")) {return response;}// 處理非標準JSON響應return response.replaceFirst(".*?(\\{.*\\}).*", "$1");}@Overridepublic ModelTask.TaskType supportedType() {return ModelTask.TaskType.KEYWORD_EXTRACTION;}
}

3.4 Deepseek 執行器實現 (內容生成)

@Service
@Slf4j
public class DeepseekExecutor implements ModelExecutor {@Value("${deepseek.api-key}")private String apiKey;@Value("${deepseek.base-url}")private String baseUrl;@Value("${deepseek.model}")private String model;private final RestClient restClient;public DeepseekExecutor() {this.restClient = RestClient.builder().baseUrl(baseUrl).defaultHeader("Authorization", "Bearer " + apiKey).build();}@Overridepublic String execute(ModelTask task) throws ModelExecutionException {try {Map<String, Object> requestBody = buildRequest(task);log.info("Sending request to Deepseek: {}", requestBody);ResponseEntity<Map> response = restClient.post().uri("/chat/completions").body(requestBody).retrieve().toEntity(Map.class);return extractContent(response.getBody());} catch (Exception e) {log.error("Deepseek API call failed", e);throw new ModelExecutionException("Deepseek processing failed", e);}}private Map<String, Object> buildRequest(ModelTask task) {return Map.of("model", model,"messages", List.of(Map.of("role", "system", "content", "你是一個專業的內容生成助手"),Map.of("role", "user", "content", task.getInput())),"temperature", 0.7,"max_tokens", 2000);}private String extractContent(Map<String, Object> response) {// 簡化處理,實際項目需要更健壯的解析return ((Map)((List)response.get("choices")).get(0)).get("message").toString();}@Overridepublic ModelTask.TaskType supportedType() {return ModelTask.TaskType.CONTENT_GENERATION;}
}

3.5 通義千問執行器實現 (文本潤色)

@Service
@Slf4j
public class TongyiExecutor implements ModelExecutor {@Autowiredprivate TongyiChatClient chatClient;@Overridepublic String execute(ModelTask task) throws ModelExecutionException {try {String polishPrompt = buildPolishPrompt(task.getInput());log.info("Executing Tongyi polishing with prompt: {}", polishPrompt);String response = chatClient.call(polishPrompt);log.info("Tongyi polished response: {}", response);return response;} catch (Exception e) {log.error("Tongyi polishing failed", e);throw new ModelExecutionException("Tongyi polishing failed", e);}}private String buildPolishPrompt(String input) {return """請對以下文本進行專業的中文潤色,要求:1. 保持原意不變2. 優化表達流暢度3. 使用更專業的詞匯4. 適當調整句式結構5. 確保語法正確需要潤色的文本:""" + input;}@Overridepublic ModelTask.TaskType supportedType() {return ModelTask.TaskType.TEXT_POLISHING;}
}

4. 工作流協調器

@Service
@Slf4j
public class WorkflowCoordinator {@Autowiredprivate List<ModelExecutor> executors;@Value("${app.workflow.max-retries}")private int maxRetries;@Value("${app.workflow.retry-delay}")private long retryDelay;@Value("${app.workflow.timeout}")private long timeout;private final Map<ModelTask.TaskType, ModelExecutor> executorMap = new HashMap<>();@PostConstructpublic void init() {executors.forEach(executor -> executorMap.put(executor.supportedType(), executor));}@Retryable(maxAttempts = 3, backoff = @Backoff(delay = 1000))public String processWorkflow(String userInput) throws WorkflowException {long startTime = System.currentTimeMillis();String taskId = UUID.randomUUID().toString();try {// 階段1: 關鍵詞提取ModelTask extractionTask = new ModelTask(taskId, ModelTask.TaskType.KEYWORD_EXTRACTION,userInput,Map.of("format", "json"));String extractionResult = executeWithTimeout(executorMap.get(ModelTask.TaskType.KEYWORD_EXTRACTION),extractionTask);// 階段2: 內容生成String generationPrompt = buildGenerationPrompt(extractionResult);ModelTask generationTask = new ModelTask(taskId,ModelTask.TaskType.CONTENT_GENERATION,generationPrompt,Map.of("length", "medium"));String generatedContent = executeWithTimeout(executorMap.get(ModelTask.TaskType.CONTENT_GENERATION),generationTask);// 階段3: 文本潤色ModelTask polishingTask = new ModelTask(taskId,ModelTask.TaskType.TEXT_POLISHING,generatedContent,Map.of("style", "professional"));String finalResult = executeWithTimeout(executorMap.get(ModelTask.TaskType.TEXT_POLISHING),polishingTask);log.info("Workflow completed in {} ms", System.currentTimeMillis() - startTime);return finalResult;} catch (TimeoutException e) {throw new WorkflowException("Workflow timed out", e);} catch (Exception e) {throw new WorkflowException("Workflow execution failed", e);}}private String executeWithTimeout(ModelExecutor executor, ModelTask task) throws Exception {ExecutorService executorService = Executors.newSingleThreadExecutor();Future<String> future = executorService.submit(() -> executor.execute(task));try {return future.get(timeout, TimeUnit.MILLISECONDS);} finally {executorService.shutdown();}}private String buildGenerationPrompt(String extractionResult) {try {JSONObject json = new JSONObject(extractionResult);String keywords = String.join(", ", json.getJSONArray("keywords").toList());String intent = json.getString("intent");return String.format("根據以下關鍵詞和意圖生成專業內容:\n關鍵詞: %s\n意圖: %s", keywords, intent);} catch (Exception e) {log.warn("Failed to parse extraction result, using raw input");return "根據以下信息生成專業內容:\n" + extractionResult;}}
}

5. REST 控制器

@RestController
@RequestMapping("/api/ai-workflow")
@Slf4j
public class WorkflowController {@Autowiredprivate WorkflowCoordinator workflowCoordinator;@PostMapping("/process")public ResponseEntity<?> processInput(@RequestBody String userInput) {try {log.info("Received processing request: {}", userInput);String result = workflowCoordinator.processWorkflow(userInput);return ResponseEntity.ok(result);} catch (WorkflowException e) {log.error("Workflow processing error", e);return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).body(Map.of("error", "Processing failed","message", e.getMessage()));}}@GetMapping("/status")public ResponseEntity<?> getStatus() {return ResponseEntity.ok(Map.of("status", "operational","models", List.of("ChatGPT", "Deepseek", "Tongyi")));}
}

6. 異常處理

@ControllerAdvice
@Slf4j
public class GlobalExceptionHandler {@ExceptionHandler(WorkflowException.class)public ResponseEntity<?> handleWorkflowException(WorkflowException ex) {log.error("Workflow error occurred: {}", ex.getMessage());return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).body(Map.of("error", "AI Workflow Error","message", ex.getMessage(),"timestamp", Instant.now()));}@ExceptionHandler(ModelExecutionException.class)public ResponseEntity<?> handleModelException(ModelExecutionException ex) {log.error("Model execution failed: {}", ex.getMessage());return ResponseEntity.status(HttpStatus.BAD_GATEWAY).body(Map.of("error", "Model Execution Error","message", "One of the AI models failed to process the request","timestamp", Instant.now()));}
}

7. 測試用例

@SpringBootTest
@ActiveProfiles("test")
@Slf4j
public class WorkflowIntegrationTest {@Autowiredprivate WorkflowCoordinator workflowCoordinator;@Testpublic void testFullWorkflow() {String input = "用戶反饋:新版App的語音識別功能很準確,但耗電量較大,希望優化電池使用效率";try {String result = workflowCoordinator.processWorkflow(input);log.info("Workflow result:\n{}", result);assertNotNull(result);assertTrue(result.length() > 50);assertTrue(result.contains("語音識別") || result.contains("耗電"));} catch (WorkflowException e) {fail("Workflow execution failed: " + e.getMessage());}}@Testpublic void testTimeoutHandling() {// 模擬超時場景的測試assertThrows(WorkflowException.class, () -> {workflowCoordinator.processWorkflow("test timeout");});}
}

8. 部署與監控建議

8.1 Prometheus 監控配置

# application.yml 添加監控配置
management:endpoints:web:exposure:include: health,info,metrics,prometheusmetrics:export:prometheus:enabled: truetags:application: ai-workflow

8.2 關鍵指標監控

  1. 工作流執行時間
  2. 各模型調用成功率
  3. API響應時間
  4. 錯誤率統計
  5. Token使用量

9. 性能優化建議

  1. 緩存層:對常見查詢結果實現緩存

    @Cacheable(value = "aiResponses", key = "#userInput.hashCode()")
    public String processWorkflow(String userInput) { ... }
    
  2. 批量處理:支持批量輸入處理

  3. 異步處理:對耗時任務實現異步API

    @Async
    public CompletableFuture<String> processAsync(String input) { ... }
    
  4. 連接池配置:優化HTTP連接池

    spring:ai:openai:rest:connection-timeout: 5000read-timeout: 30000max-connections: 100
    

10. 安全建議

  1. API密鑰輪換:定期更新各模型API密鑰

  2. 輸入過濾:防止Prompt注入攻擊

    public String sanitizeInput(String input) {return input.replaceAll("[<>\"']", "");
    }
    
  3. 訪問控制:實現API訪問認證

  4. 請求限流:防止濫用

總結

本實現方案展示了如何利用 Spring AI 框架構建一個多模型協作的智能工作流系統,具有以下特點:

  1. 模塊化設計:各模型執行器相互獨立,易于擴展
  2. 彈性處理:完善的錯誤處理和重試機制
  3. 性能可控:超時管理和異步支持
  4. 可觀測性:完善的日志和監控支持
  5. 生產就緒:包含安全、緩存等生產環境所需功能

通過這種架構,您可以靈活地替換或添加新的AI模型,同時保持業務邏輯的一致性,為構建企業級AI應用提供了可靠的基礎框架。

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/diannao/84841.shtml
繁體地址,請注明出處:http://hk.pswp.cn/diannao/84841.shtml
英文地址,請注明出處:http://en.pswp.cn/diannao/84841.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

C語言中清空緩存區到底寫到哪里比較好

文章目錄 問題背景%d和%c讀取緩沖區的差別清空緩存區 問題背景 在寫C語言的命令行程序時&#xff0c;我們經常會用到用戶輸入和標準輸出&#xff0c;特別的&#xff0c;當用戶輸入后&#xff0c;我們發現程序運行不是我們要的樣子&#xff0c;這個時候&#xff0c;很可能就是輸…

計算機視覺與深度學習 | 基于 YOLOv8 + BeautyGAN + CodeFormer + Face Parsing 實現簡單的人臉美顏

人臉美顏 **一、算法流程圖****二、完整代碼實現**1. 環境準備2. 完整代碼(face_beautify.py)**三、核心算法公式**1. YOLOv8檢測損失函數2. BeautyGAN損失函數3. CodeFormer圖像重建公式**四、關鍵實現細節**1. 多尺度人臉處理2. 顏色校正策略**五、模型下載清單****六、性能…

如何在WordPress中選擇最佳Elementor主題:專家指南

當你在WordPress建站過程中逐步積累了經驗&#xff0c;你可能會發覺&#xff0c;基礎和進階主題已難以完全滿足你的需求。如果你需要更復雜的功能、更靈活的布局設計&#xff0c;甚至高級定制效果&#xff0c;那么就需要選擇更加專業的主題。在這篇文章中&#xff0c;我將為你推…

FPGA高速接口 mipi lvds cameralink hdml 千兆網 sdi

mipi: https://blog.csdn.net/SDJ_success/article/details/146541776 cameralink CameraLink協議 CameraLink協議是一種專門針對機器視覺應用領域的串行通信協議&#xff0c;它使用低壓差分信號(LVDS)進行數據的傳輸和通信。CameraLink標準是在ChannelLink標準的基礎上多加了…

手機收不到WiFi,手動輸入WiFi名稱進行連接不不行,可能是WiFi頻道設置不對

以下是電腦上分享WiFi后&#xff0c;部分手機可以看到并且能連接&#xff0c;部分手機不行&#xff0c;原因是&#xff1a;頻道設置為5GHz&#xff0c;修改成&#xff0c;任何可用頻率&#xff0c;則可

12.Java 對象冷凍術:從用戶登錄到游戲存檔的序列化實戰

目錄 一、引言 二、用戶登錄存檔&#xff1a;讓賬號信息「凍齡」不變 1. 給對象貼「冷凍標簽」&#xff1a;實現 Serializable 2. 冷凍與解凍實戰&#xff1a;把用戶存進文件 3. 演示場景 三、游戲存檔復活&#xff1a;讓角色進度「穿越時空」 1. 復雜對象冷凍&#xff…

conda 環境中opencv 報錯以及其他報錯

如題&#xff0c;通過 conda install opencv 然后遇到 ImportError: DLL load failed while importing cv2: 找不到指定的模塊。 參考網絡相關答案 通過conda 卸載 然后通過 pip3 安裝opencv-pyhton https://stackoverflow.com/questions/75387197/anaconda-importerror-dll-…

(已開源-CVPR2024) RadarDistill---NuScenes數據集Radar檢測第一名

本文介紹一篇Radar 3D目標檢測模型&#xff1a;RadarDistill。雷達數據固有的噪聲和稀疏性給3D目標檢測帶來了巨大挑戰。在本文中&#xff0c;作者提出了一種新的知識蒸餾(KD)方法RadarDistill&#xff0c;它可以通過利用激光雷達數據來提高雷達數據的表征。RadarDistill利用三…

創建型設計模式之Singleton(單例)設計模式

創建型設計模式之Singleton&#xff08;單例&#xff09;設計模式 摘要&#xff1a; Singleton&#xff08;單例&#xff09;設計模式確保一個類僅有一個實例&#xff0c;并提供全局訪問點。其結構包含一個靜態方法getInstance()用于獲取唯一實例&#xff0c;構造方法私有化防…

C++11:系統類型增強

C11&#xff1a;系統類型增強 強枚舉類型作用域限定隱式類型轉換指定類型前置聲明 類型別名 using模板別名復雜指針別名 auto限制性 auto注意事項 nullptrdecltype 強枚舉類型 在C98的枚舉設計中&#xff0c;存在很多缺陷&#xff0c;為此C11推出了強枚舉來代替舊版的枚舉&…

linux 內核warn_on/Bug_on

1,warn_on() warn_on() 是 Linux 內核中用于報告潛在問題或警告的宏。與 bug_on() 不同&#xff0c;bug_on() 通常用于報告嚴重錯誤&#xff0c;其觸發往往會導致內核Oops或panic&#xff0c;而 warn_on() 則用于報告不太嚴重的、可能只是潛在問題或預期外情況的情況。它的觸…

SQL輸出20個9

在SQL Server中要輸出20個連續的9&#xff0c;可以使用以下幾種方法&#xff1a; 使用REPLICATE函數重復生成字符&#xff1a; SELECT REPLICATE(9, 20) AS Result 2. 使用UNION ALL聯合查詢生成多行&#xff1a; SELECT 9 AS Number FROM (VALUES (1),(1),(1),(1),(1),(1),…

懶人云電腦方案:飛牛NAS遠程喚醒 + 節點小寶一鍵喚醒、遠程控制Windows!

后臺高頻問題解答&#xff1a; “博主&#xff0c;飛牛NAS能定時開關機了&#xff0c;能不能讓它順便把家里Windows電腦也遠程喚醒控制&#xff1f;最好點一下就能連&#xff0c;不用記IP端口那種&#xff01;” 安排&#xff01;今天這套方案完美實現&#xff1a; ? 飛牛NAS…

Linux特殊符號

1 管道符| 管道符號 | 用于將一個命令的輸出作為另一個命令的輸入。這種機制允許將多個命令組合在一起&#xff0c;形成一個數據處理鏈&#xff0c;每個命令處理前一個命令的輸出&#xff0c;從而實現復雜的數據處理任務。示例 # 查詢/var/log目錄下所有的log文件,并進行分頁…

初識Docker:容器化技術的入門指南

初識Docker&#xff1a;容器化技術的入門指南 一、Docker是什么&#xff1a;容器化技術的核心概念二、Docker的核心優勢2.1 環境一致性2.2 高效部署與快速迭代2.3 資源利用率高 三、Docker的安裝與基本使用3.1 安裝Docker3.2 Docker基本概念3.3 第一個Docker容器體驗 四、Docke…

商務風企業公司推廣培訓計劃PPT模版分享

商務風企業公司推廣培訓計劃PPT模版分享&#xff1a;商務培訓推廣計劃PPT模版https://pan.quark.cn/s/063282eaf739 第1套PPT模版&#xff0c;綠橙配色&#xff0c;幾何圖形拼接背景&#xff0c;有中英文標題和占位文本。 第2套PPT模版是黑金高端商務風格&#xff0c;有匯報人…

深入理解Nginx:詳盡配置手冊

Nginx是一款高性能的HTTP和反向代理服務器&#xff0c;廣泛應用于負載均衡、緩存和Web服務器等場景。隨著互聯網應用的快速發展&#xff0c;掌握Nginx的配置和優化技巧顯得尤為重要。在本篇文章中&#xff0c;我們將深入探討Nginx的配置&#xff0c;幫助你更好地理解和使用這款…

每日leetcode

1572. 矩陣對角線元素的和 - 力扣&#xff08;LeetCode&#xff09; 題目 給你一個正方形矩陣 mat&#xff0c;請你返回矩陣對角線元素的和。 請你返回在矩陣主對角線上的元素和副對角線上且不在主對角線上元素的和。 示例 1&#xff1a; 輸入&#xff1a;mat [[1,2,3], …

Server 9 ,在 VMware 虛擬機上安裝 Windows 系統完整指南

目錄 前言 一、準備工作 1.1 準備安裝文件 1.2 安裝VMware軟件 1.3 創建新的虛擬機 1.4 開啟虛擬機 二、注意事項 2.1 調整硬件設置 2.2 啟動順序配置 2.3 固件類型選擇 2.4 安全啟動配置 三、安裝優化 3.1 安裝VMware Tools 3.2 系統更新與激活 四、更多操作 ?…

最終章:終焉之塔 · 前端之道

第一章&#xff1a;HTML基石現實的骨架 第二章&#xff1a;CSS秘典 色彩與布局的力量 第三章&#xff1a;JavaScript引擎 行為之火 第四章&#xff1a;DOM迷宮 掌控頁面之心 第五章&#xff1a;異步幻境 時間與數據的秘密 第六章&#xff1a;事件風暴 用戶的意志 第七章&a…