背景
如果你的项目使用 JDK 17+,推荐学习 Spring AI 框架。本篇以 JDK 8 项目为例,手搓 AI 接口的接入。
依赖引入
1 2 3 4 5 6 7 8 9 10 11 12
| <dependency> <groupId>com.google.code.gson</groupId> <artifactId>gson</artifactId> <version>2.8.9</version> </dependency>
<dependency> <groupId>org.apache.httpcomponents.client5</groupId> <artifactId>httpclient5</artifactId> <version>5.1.3</version> </dependency>
|
AI 配置类
建议单独开一个配置类,后续可通过 Nacos 等方式动态更新:
1 2 3 4 5 6 7 8 9 10 11 12 13
| public class AIConfig { private String apiKey; private String model; private String URL; private Double temperature;
public AIConfig() { URL = "https://dashscope.aliyuncs.com/compatible-mode/v1/chat/completions"; apiKey = "sk-xxx"; model = "qwen-plus"; temperature = 0.8; } }
|
实体类
1 2 3 4 5 6 7 8 9 10
| public class AIMessage { private String role; private String content; }
public class AIRequst { private String model; private List<AIMessage> messages; private double temperature; }
|
核心调用实现
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81
| public ResultBody AIImport(String userId, String issue) { String key = "AI_" + userId; Object cacheObject = redisService.getCacheObject(key); String contextInfo = (cacheObject != null) ? (String) cacheObject : "";
AIRequst openaiReq = new AIRequst(); openaiReq.setModel(aiConfig.getModel());
List<AIMessage> messages = new ArrayList<>(); AIMessage systemMessage = new AIMessage(); systemMessage.setRole("system"); systemMessage.setContent("你是一个语音聊天助手,会讲冷笑话、鬼故事等。"); messages.add(systemMessage);
AIMessage userMessage = new AIMessage(); userMessage.setRole("user"); userMessage.setContent(String.format("上下文信息:\n%s\n\n用户问题:%s", contextInfo, issue)); messages.add(userMessage);
openaiReq.setMessages(messages); openaiReq.setTemperature(aiConfig.getTemperature());
Gson gson = new Gson(); String jsonRequest = gson.toJson(openaiReq);
try { URL url = new URL(aiConfig.getURL()); HttpURLConnection connection = (HttpURLConnection) url.openConnection(); connection.setRequestMethod("POST"); connection.setRequestProperty("Content-Type", "application/json"); connection.setRequestProperty("Authorization", "Bearer " + aiConfig.getApiKey()); connection.setDoOutput(true);
try (OutputStream os = connection.getOutputStream()) { byte[] input = jsonRequest.getBytes(StandardCharsets.UTF_8); os.write(input, 0, input.length); }
int responseCode = connection.getResponseCode(); if (responseCode == 200) { try (BufferedReader br = new BufferedReader( new InputStreamReader(connection.getInputStream(), StandardCharsets.UTF_8))) { StringBuilder response = new StringBuilder(); String responseLine; while ((responseLine = br.readLine()) != null) { response.append(responseLine.trim()); }
JsonObject jsonResponse = gson.fromJson(response.toString(), JsonObject.class); if (jsonResponse.getAsJsonArray("choices").isEmpty()) { return ResultBody.error().message("AI 响应超时..."); }
JsonObject choice = jsonResponse.getAsJsonArray("choices").get(0).getAsJsonObject(); JsonObject message = choice.getAsJsonObject("message"); String answer = message.get("content").getAsString().trim();
if (answer.isEmpty()) { return ResultBody.error().message("AI 响应超时"); }
redisService.setCacheObject(key, issue, 300L, TimeUnit.MINUTES); return ResultBody.ok().message(answer); } } else { try (BufferedReader br = new BufferedReader( new InputStreamReader(connection.getErrorStream(), StandardCharsets.UTF_8))) { StringBuilder errorResponse = new StringBuilder(); String errorLine; while ((errorLine = br.readLine()) != null) { errorResponse.append(errorLine.trim()); } System.err.println("错误响应: " + errorResponse); } return ResultBody.error().message("AI 响应超时..."); } } catch (IOException e) { e.printStackTrace(); return ResultBody.error().message("AI 响应超时"); } }
|
小结
- JDK 8 项目可通过 HttpURLConnection 手搓 AI 接口,不需要额外框架
- 注意提取 AI 配置为独立配置类,方便后续热更新
- 结合 Redis 缓存上下文信息,实现简单的对话记忆
参考:CSDN - Java接入AI接口