大模型统一集成项目如何封装多个大模型-API-调用
【大模型统一集成项目】如何封装多个大模型 API 调用
🌟 在这系列文章中,我们将一起探索如何搭建一个支持大模型集成项目 NexLM 的开发过程,从 架构设计 到 代码实战 ,逐步搭建一个支持 多种大模型(GPT-4、DeepSeek 等) 的 一站式大模型集成与管理平台 ,并集成 认证中心、微服务、流式对话 等核心功能。
🔍 从架构设计到代码实现,一起探讨如何应对不同技术挑战,最终打造出高效、可扩展的大模型平台,目前项目基础架构已经搭建完成。
系列目录规划:
- NexLM:从零开始打造你的专属大模型集成平台 ✅
- Spring Boot + OpenAI/DeepSeek:如何封装多个大模型 API 调用 ✅
- 微服务 + 认证中心:如何保障大模型 API 的安全调用
- 支持流式对话 SSE & WebSocket:让 AI 互动更丝滑
- 缓存与性能优化:提高 LLM API 响应速度
- 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 调用交互稍微有点点耗时…目前还没有支持流式输出效果(下一期优化),代码仓库地址:
代码实现
实现简单的 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 {
@Autowired
private ChatService chatService;
@Autowired
private 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 {
@Autowired
private OpenAIClient openAIClient;
@Autowired
private DeepSeekClient deepSeekClient;
@Autowired
private 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 Key
private static final String MODEL = "deepseek-chat"; // deepseek-v3 / deepseek-r1
public 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-r1
body.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 Key
public 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 聊天前后端已完成!
- 直接访问登录
http://localhost:8080/web/auth/login
页面 - 输出用户名/密码:admin/123456
- 跳转大模型页面,选择对应大模型,开始对话
6. 总结
- 架构 :微服务 + 认证中心 + API 网关 + 本地/远程大模型
- Java 代码 :完整的 Controller、Service、API 调用示例
- 前端 :简单 HTML + JS 渲染
- 认证 :JWT 校验
这样,你的系统可以支持 用户认证 ,并 调用本地或第三方大模型 进行 AI 交互。
结语
本篇文章,我们介绍了 如何封装多个 LLM(大模型) API 调用 。
但是,目前的 对话是一次性返回的 ,后续我们将完善 微服务 + 认证中心:如何保障大模型 API 的安全调用 , 并且 支持流式对话(SSE)增加 WebSocket 实时消息 实现 实时输出 AI 回复 !敬请期待!
📌 下一章预告:SSE + WebSocket 实现流式对话!
📢 你对这个项目感兴趣吗?欢迎 Star & 关注! 📌