【大模型統一集成項目】如何封裝多個大模型 API 調用

🌟 在這系列文章中,我們將一起探索如何搭建一個支持大模型集成項目 NexLM 的開發過程,從 架構設計代碼實戰,逐步搭建一個支持 多種大模型(GPT-4、DeepSeek 等)一站式大模型集成與管理平臺,并集成 認證中心、微服務、流式對話 等核心功能。

🔍 從架構設計到代碼實現,一起探討如何應對不同技術挑戰,最終打造出高效、可擴展的大模型平臺,目前項目基礎架構已經搭建完成。

系列目錄規劃:

  1. NexLM:從零開始打造你的專屬大模型集成平臺 ?
  2. Spring Boot + OpenAI/DeepSeek:如何封裝多個大模型 API 調用 ?
  3. 微服務 + 認證中心:如何保障大模型 API 的安全調用
  4. 支持流式對話 SSE & WebSocket:讓 AI 互動更絲滑
  5. 緩存與性能優化:提高 LLM API 響應速度
  6. NexLM 開源部署指南(Docker)

第二篇:Spring Boot + OpenAI/DeepSeek:如何封裝多個大模型 API 調用

🎯 如何讓你的項目支持 OpenAI、DeepSeek、本地大模型等多種 LLM?
🎯 如何封裝 API,做到擴展性強、調用方便?
🎯 這篇文章帶你一步步搭建通用 LLM 調用服務!

為什么要封裝 LLM API?

在大模型開發中,我們往往需要 支持多個模型,例如:

  • GPT-4(OpenAI) :行業最強模型之一,但 API 價格較貴
  • DeepSeek:性價比高,部分場景效果接近 GPT-4
  • 本地大模型(如 ChatGLM) :適合私有化部署,數據安全

如果在代碼里直接寫多個 API 請求,會導致 代碼冗余、擴展性差。我們需要一個 統一封裝的 LLM API 調用層,讓項目可以隨時切換模型,甚至同時支持多個模型。

效果展示

在這里插入圖片描述
DeepSeek API 調用交互稍微有點點耗時…目前還沒有支持流式輸出效果(下一期優化),代碼倉庫地址:https://github.com/pitt1997/NexLM

代碼實現

實現簡單的 AI 接口調用還是比較簡單,定義接口和具體接口的調用邏輯即可,下面是代碼演示。

在這里插入圖片描述

1)Controller 層

ChatController 定義一個頁面的路由地址

@RestController
public class ChatController {/*** chat頁面*/@GetMapping("/auth/chat")public ModelAndView chat(ModelAndView modelAndView) {modelAndView.setViewName("ftl/chat");return modelAndView;}
}

ChatApiController 定義一個 API 交互接口。

@RestController
@RequestMapping("/api/ai")
public class ChatApiController {@Autowiredprivate ChatService chatService;@Autowiredprivate JwtTokenProvider jwtTokenProvider;@PostMapping("/chat")public ResponseEntity<String> chat(@RequestBody ChatRequest request, @RequestHeader("Authorization") String token) {// TODO 測試放行(后續加上JWT票據認證)if (token.startsWith("Bearer ")) {return ResponseEntity.ok(chatService.callAIModel(request.getMessage(), request.getModelType()));}// 認證中心解析 JWT 驗證權限SessionUser sessionUser = jwtTokenProvider.validateUserToken(token);if (sessionUser == null) {return ResponseEntity.status(HttpStatus.UNAUTHORIZED).body("Unauthorized");}return ResponseEntity.ok(chatService.callAIModel(request.getMessage(), request.getModelType()));}
}
2)VO 層

請求對象,主要定義輸入的消息和模型的類型。

@Data
public class ChatRequest {private String message;   // 用戶輸入的消息private String modelType; // 選擇的大模型,例如 "chatgpt" 或 "local"
}
3)Service 層

這里封裝不同模型的調用實現。

@Service
public class ChatService {@Autowiredprivate OpenAIClient openAIClient;@Autowiredprivate DeepSeekClient deepSeekClient;@Autowiredprivate LocalLLMClient localLLMClient;public String callAIModel(String prompt, String modelType) {if ("chatgpt".equalsIgnoreCase(modelType)) {return openAIClient.chat(prompt);} else if ("deepseek".equalsIgnoreCase(modelType)) {return deepSeekClient.chat(prompt);} else if ("local".equalsIgnoreCase(modelType)) {return localLLMClient.chat(prompt);}return "Invalid Model Type";}
}
4)調用大模型接口 API

實現具體大模型的 API 調用邏輯。以 DeepSeek 為例,注意 DeepSeek 需要提前在官網注冊密鑰。(注:按照官網要求的請求參數格式進行請求即可,注意需要正確解析返回結果中的內容)。

@Component
public class DeepSeekClient {private static final String API_URL = "https://api.deepseek.com/chat/completions"; // DeepSeek API 地址private static final String API_KEY = "你的 DeepSeek API Key"; // 替換為你的 API Keyprivate static final String MODEL = "deepseek-chat"; // deepseek-v3 / deepseek-r1public String chat(String prompt) {RestTemplate restTemplate = new RestTemplate();HttpHeaders headers = new HttpHeaders();headers.setContentType(MediaType.APPLICATION_JSON);headers.add("Authorization", "Bearer " + API_KEY);Map<String, Object> body = new HashMap<>();body.put("model", MODEL); // deepseek-v3 / deepseek-r1body.put("temperature", 0.7); // 可調整溫度body.put("max_tokens", 2048); // 控制回復長度List<Map<String, String>> messages = Arrays.asList(new HashMap<String, String>() {{put("role", "user");put("content", prompt);}});body.put("messages", messages);HttpEntity<Map<String, Object>> request = new HttpEntity<>(body, headers);ResponseEntity<String> response = restTemplate.exchange(API_URL, HttpMethod.POST, request, String.class);return extractContent(response.getBody());}// 解析一下大模型返回結果的json參數。private String extractContent(String responseBody) {try {ObjectMapper objectMapper = new ObjectMapper();JsonNode root = objectMapper.readTree(responseBody);return root.path("choices").get(0).path("message").path("content").asText();} catch (Exception e) {e.printStackTrace();return "Error parsing response";}}
}

OpenAI 調用邏輯基本一致。

@Component
public class OpenAIClient {private static final String API_URL = "https://api.openai.com/v1/chat/completions";private static final String API_KEY = "你的 OpenAI API Key"; // 請替換為你的 API Keypublic String chat(String prompt) {RestTemplate restTemplate = new RestTemplate();HttpHeaders headers = new HttpHeaders();headers.setContentType(MediaType.APPLICATION_JSON);headers.add("Authorization", "Bearer " + API_KEY);Map<String, Object> body = new HashMap<>();body.put("model", "gpt-4");List<Map<String, String>> messages = Arrays.asList(new HashMap<String, String>() {{put("role", "user");put("content", prompt);}});body.put("messages", messages);HttpEntity<Map<String, Object>> request = new HttpEntity<>(body, headers);ResponseEntity<String> response = restTemplate.exchange(API_URL, HttpMethod.POST, request, String.class);return response.getBody();}
}
5)調用本地模型

也可以調用本地部署的大模型(需要提前部署本地大模型,可以看我之前的文章部署方法)。

@Component
public class LocalLLMClient {private static final String LOCAL_MODEL_URL = "http://localhost:5000/api/chat";public String chat(String prompt) {RestTemplate restTemplate = new RestTemplate();Map<String, String> requestBody = new HashMap<>();requestBody.put("prompt", prompt);ResponseEntity<String> response = restTemplate.postForEntity(LOCAL_MODEL_URL, requestBody, String.class);return response.getBody();}
}

3. 前端頁面(HTML + JavaScript)

一個簡單的 HTML 頁面,輸入問題后,調用后端 API 獲取大模型的回答(暫時使用 HTML 做一個演示)。

<!DOCTYPE html>
<html lang="zh">
<head><meta charset="UTF-8"><title>AI 聊天</title><style>body {font-family: Arial, sans-serif;background: #f4f4f4;margin: 0;padding: 0;display: flex;justify-content: center;align-items: center;height: 100vh;}.chat-container {width: 500px;background: #fff;padding: 20px;border-radius: 10px;box-shadow: 0 4px 10px rgba(0, 0, 0, 0.1);}h1 {text-align: center;color: #333;}.input-group {margin: 15px 0;}input, select, button {width: 100%;padding: 10px;margin-top: 5px;border: 1px solid #ccc;border-radius: 5px;}button {background: #007bff;color: white;cursor: pointer;}button:hover {background: #0056b3;}.response {margin-top: 20px;background: #eef;padding: 10px;border-radius: 5px;min-height: 50px;}</style>
</head>
<body>
<div class="chat-container"><h1>大模型 AI 聊天</h1><div class="input-group"><label>輸入你的問題:</label><input type="text" id="message" placeholder="請輸入問題"></div><div class="input-group"><label>選擇模型:</label><select id="modelType"><option value="chatgpt">ChatGPT</option><option value="deepseek">DeepSeek</option><option value="local">本地模型</option></select></div><button onclick="sendMessage()">發送</button><div class="response" id="response">AI 回復將在這里顯示...</div>
</div><script>async function sendMessage() {const message = document.getElementById('message').value;const modelType = document.getElementById('modelType').value;// 你的 JWT 令牌const token = getCookie('JSESSIONID'); // 這里應從登錄系統獲取console.log('JWT Token:', token); // 打印 token 值const response = await fetch('/web/api/ai/chat', {method: 'POST',headers: {'Content-Type': 'application/json','Authorization': `Bearer B6FC7391D7856A16391F9860DA5DA3B8}`},body: JSON.stringify({ message, modelType })});const text = await response.text();document.getElementById('response').innerText = text;}function getCookie(name) {const cookies = document.cookie.split(';');for (let cookie of cookies) {const [cookieName, cookieValue] = cookie.trim().split('=');if (cookieName === name) {return decodeURIComponent(cookieValue);}}return null;}
</script>
</body>
</html>

4. 認證中心(JWT 解析示例)

接口調用時應當校驗當前用戶的票據(登錄時會存儲用戶會話票據信息)。

        // 認證中心解析 JWT 驗證權限SessionUser sessionUser = jwtTokenProvider.validateUserToken(token);if (sessionUser == null) {return ResponseEntity.status(HttpStatus.UNAUTHORIZED).body("Unauthorized");}

5. 效果測試

🔥 現在,你的 AI 聊天前后端已完成!

  1. 直接訪問登錄 http://localhost:8080/web/auth/login 頁面
  2. 輸出用戶名/密碼:admin/123456
  3. 跳轉大模型頁面,選擇對應大模型,開始對話

6. 總結

  • 架構:微服務 + 認證中心 + API 網關 + 本地/遠程大模型
  • Java 代碼:完整的 Controller、Service、API 調用示例
  • 前端:簡單 HTML + JS 渲染
  • 認證:JWT 校驗

這樣,你的系統可以支持用戶認證,并調用本地或第三方大模型進行 AI 交互。

結語

本篇文章,我們介紹了 如何封裝多個 LLM(大模型) API 調用

但是,目前的 對話是一次性返回的,后續我們將完善 微服務 + 認證中心:如何保障大模型 API 的安全調用, 并且支持流式對話(SSE)增加 WebSocket 實時消息實現 實時輸出 AI 回復!敬請期待!

📌 下一章預告:SSE + WebSocket 實現流式對話!


📢 你對這個項目感興趣嗎?歡迎 Star & 關注! 📌 GitHub 項目地址

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

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

相關文章

AI4CODE】3 Trae 錘一個貪吃蛇的小游戲

【AI4CODE】目錄 【AI4CODE】1 Trae CN 錐安裝配置與遷移 【AI4CODE】2 Trae 錘一個 To-Do-List 這次還是采用 HTML/CSS/JAVASCRIPT 技術棧 Trae 錘一個貪吃蛇的小游戲。 1 環境準備 創建一個 Snake 的子文件夾&#xff0c;清除以前的會話記錄。 2 開始構建 2.1 輸入會…

【簡答題002】Java變量簡答題

博主會經常補充完善這里面問題的答案。希望可以得到大家的一鍵三連支持&#xff0c;你的鼓勵是我堅持下去的最大動力&#xff01;謝謝&#xff01; 001 什么是Java變量&#xff1f; Java變量是用來存儲數據并在程序中引用的命名空間。 002 Java變量有哪些類型&#xff1f; J…

從零開發Chrome廣告攔截插件:開發、打包到發布全攻略

從零開發Chrome廣告攔截插件&#xff1a;開發、打包到發布全攻略 想打造一個屬于自己的Chrome插件&#xff0c;既能攔截煩人的廣告&#xff0c;又能優雅地發布到Chrome Web Store&#xff1f;別擔心&#xff0c;這篇教程將帶你從零開始&#xff0c;動手開發一個功能強大且美觀…

基于騰訊云高性能HAI-CPU的跨境電商客服助手全鏈路解析

跨境電商的背景以及痛點 根據Statista數據&#xff0c;2025年全球跨境電商市場規模預計達6.57萬億美元&#xff0c;年增長率保持在12.5% 。隨著平臺規則趨嚴&#xff08;如亞馬遜封店潮&#xff09;&#xff0c;更多賣家選擇自建獨立站&#xff0c;2024年獨立站占比已達35%。A…

maven的項目構建

常用構建命令 命令說明mvn clean清理編譯結果&#xff08;刪掉target目錄&#xff09;mvn compile編譯核心代碼&#xff0c;生成target目錄mvn test-compile編譯測試代碼&#xff0c;生成target目錄mvn test執行測試方法mvn package打包&#xff0c;生成jar或war文件mvn insta…

定時任務和分布式任務框架

文章目錄 一 Spring Task1.@Scheduled注解介紹2 基本用法(1)使用@EnableScheduling修飾啟動類(2)創建定時任務的類(3)fixedDelay(4)fixedRate(5)cron3 執行多個任務4 設置異步執行5 @Async使用自定義線程池6 缺點二 xxl-job介紹架構圖與其他任務調度平臺的比較運行調…

git安裝,配置SSH公鑰(查看版本、安裝路徑,更新版本)git常用指令

目錄 一、git下載安裝 1、下載git 2、安裝Git?&#xff1a; 二、配置SSH公鑰 三、查看安裝路徑、查看版本、更新版本 四、git常用指令 1、倉庫初始化與管理 2、配置 3、工作區與暫存區管理 4、提交 5、分支管理 6、遠程倉庫管理 7、版本控制 8、其他高級操作 一…

[Web]ServletContext域(Application)

簡介 Web應用的Application域的實現是通過ServletContext對象實現的。整個Web應用程序的所有資源共享這個域。生命周期與Web應用程序相同&#xff0c;即當前Web應用程序啟動時&#xff08;以服務器視角而非訪客視角&#xff09;出生&#xff0c;Web應用服務程序關閉時停止。 通…

qt c++ 進程和線程

在Qt C開發中&#xff0c;進程&#xff08;Process&#xff09;和線程&#xff08;Thread&#xff09;是兩種不同的并發模型&#xff0c;各有適用場景和實現方式。以下是詳細對比和實際開發中的用法總結&#xff1a; 一、進程&#xff08;Process&#xff09; 進程是操作系統資…

【鴻蒙開發】OpenHarmony調測工具hdc使用教程(設備開發者)

00. 目錄 文章目錄 00. 目錄01. OpenHarmony概述02. hdc簡介03. hdc獲取04. option相關的命令05. 查詢設備列表的命令06. 服務進程相關命令07. 網絡相關的命令08. 文件相關的命令09. 應用相關的命令10. 調試相關的命令11. 常見問題12. 附錄 01. OpenHarmony概述 OpenHarmony是…

手寫簡易Tomcat核心實現:深入理解Servlet容器原理

目錄 一、Tomcat概況 1. tomcat全局圖 2.項目結構概覽 二、實現步驟詳解 2.1 基礎工具包&#xff08;com.qcby.util&#xff09; 2.1.1 ResponseUtil&#xff1a;HTTP響應生成工具 2.1.2 SearchClassUtil&#xff1a;類掃描工具 2.1.3 WebServlet&#xff1a;自定義注解…

【Java開發指南 | 第三十四篇】IDEA沒有Java Enterprise——解決方法

讀者可訂閱專欄&#xff1a;Java開發指南 |【CSDN秋說】 文章目錄 1、新建Java項目2、單擊項目名&#xff0c;并連續按兩次shift鍵3、在搜索欄搜索"添加框架支持"4、勾選Web應用程序5、最終界面6、添加Tomcat 1、新建Java項目 2、單擊項目名&#xff0c;并連續按兩次…

在MATLAB中實現PID控制仿真

在MATLAB中實現PID控制仿真可以通過代碼編程或Simulink圖形化建模兩種方式完成。以下是兩種方法的詳細操作步驟和示例&#xff1a; 方法1&#xff1a;使用MATLAB腳本編程&#xff08;基于控制系統工具箱&#xff09; 步驟1&#xff1a;定義被控對象的數學模型 假設被控對象是…

Conda常用命令匯總

Conda 是一個流行的包管理器和環境管理工具&#xff0c;廣泛應用于數據科學、機器學習等領域。它可以幫助我們管理 Python 包以及不同版本的環境&#xff0c;避免包沖突&#xff0c;提升項目的可復現性。以下是一些常用的 Conda 命令&#xff0c;涵蓋環境創建、管理、包安裝等常…

大數據實時分析:ClickHouse、Doris、TiDB 對比分析

1. 引言 在大數據分析領域,實時分析需求越來越重要。ClickHouse、Doris 和 TiDB 作為當前流行的實時分析數據庫,各自針對不同的應用場景和數據特性進行了優化。本文將對比它們的核心架構、適用場景以及查詢優化方法,幫助數據開發人員選擇合適的工具。 2. 核心架構對比 2.…

藍橋杯歷年真題題解

1.軌道炮&#xff08;數學模擬&#xff09; #include <iostream> #include <map> using namespace std; const int N1010; int x[N],y[N],v[N]; char d[N]; int main() {int n;int ans-100;cin>>n;for(int i1;i<n;i)cin>>x[i]>>y[i]>>v…

Pytorch的一小步,昇騰芯片的一大步

Pytorch的一小步&#xff0c;昇騰芯片的一大步 相信在AI圈的人多多少少都看到了最近的信息&#xff1a;PyTorch最新2.1版本宣布支持華為昇騰芯片&#xff01; 1、 發生了什么事兒&#xff1f; 在2023年10月4日PyTorch 2.1版本的發布博客上&#xff0c;PyTorch介紹的beta版本…

嵌入式硬件篇---手柄控制控制麥克納姆輪子

文章目錄 前言1. 變量定義2. 搖桿死區設置3. 模式檢查4. 搖桿數據處理4.1 右搖桿垂直值&#xff08;psx_buf[7]&#xff09;4.2 右搖桿水平值&#xff08;psx_buf[8]&#xff09;4.3 左搖桿水平值&#xff08;psx_buf[5]&#xff09;4.4 左搖桿垂直值&#xff08;psx_buf[6]&am…

阿里千問大模型(Qwen2.5-VL-7B-Instruct)部署

參考鏈接 知乎帖子 B站視頻 huggingface 鏡像網站&#xff08;不太全&#xff0c;比如 Qwen/Qwen2.5-VL-7B-Instruct就沒有&#xff09; huggingface 5種下載方式匯總 通過huggingface-cli下載模型 不一樣的部分是預訓練權重的下載和demo 首先安裝huggingface_hub pip insta…

Jenkins在Windows上的使用(二):自動拉取、打包、部署

&#xff08;一&#xff09;Jenkins全局配置 訪問部署好的Jenkins服務器網址localhost:8080&#xff0c;完成默認插件的安裝后&#xff0c;接下來將使用SSH登錄遠程主機以實現自動化部署。 1. 配置插件 選擇dashboard->Manage Jenkins->plugins 安裝下面兩個插件  …