1.common-openai-starter
1.目录结构
2.OpenAiProperties.java 新增apiUrl
package com.sunxiansheng.openai.config.properties;
import lombok.Data;
import org.springframework.boot.context.properties.ConfigurationProperties;
/**
* Description: OpenAI配置属性类
*
* @Author sun
* @Create 2024/12/14 11:44
* @Version 1.0
*/
@Data
@ConfigurationProperties(prefix = "openai")
public class OpenAiProperties {
/**
* OpenAI API Key
*/
private String apiKey;
/**
* OpenAI API URL 有默认值
*/
private String apiUrl = "https://api.openai.com/v1/chat/completions";
}
- 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
3.OpenAIAutoConfiguration.java
package com.sunxiansheng.openai.config;
import com.sunxiansheng.openai.client.OpenAiClient;
import com.sunxiansheng.openai.config.properties.OpenAiProperties;
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
/**
* Description: OpenAI自动配置类
*
* @Author sun
* @Create 2024/12/14 11:39
* @Version 1.0
*/
@Configuration
@EnableConfigurationProperties({OpenAiProperties.class}) // 启用配置类
public class OpenAIAutoConfiguration {
/**
* 创建 OpenAiClient
*
* @return
*/
@Bean
@ConditionalOnMissingBean
public OpenAiClient openAiClient() {
return new OpenAiClient();
}
}
- 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
4.OpenAiClient.java 使用gson重构
package com.sunxiansheng.openai.client;
import com.google.gson.JsonArray;
import com.google.gson.JsonObject;
import com.google.gson.JsonParser;
import com.sunxiansheng.openai.config.properties.OpenAiProperties;
import okhttp3.*;
import javax.annotation.Resource;
import java.io.IOException;
import java.nio.charset.StandardCharsets;
import java.util.Base64;
import java.util.concurrent.TimeUnit;
import java.util.logging.Level;
import java.util.logging.Logger;
/**
* Description: OpenAI 客户端类
*
* @Author sun
* @Create 2024/12/14 11:56
* @Version 1.1
*/
public class OpenAiClient {
@Resource
private OpenAiProperties openAiProperties;
private static final OkHttpClient CLIENT = new OkHttpClient.Builder()
.connectTimeout(120, TimeUnit.SECONDS)
.readTimeout(120, TimeUnit.SECONDS)
.writeTimeout(120, TimeUnit.SECONDS)
.build();
private static final Logger LOGGER = Logger.getLogger(OpenAiClient.class.getName());
/**
* 向 AI 提问通用方法
*
* @param model 使用的 AI 模型,如 "gpt-4o"
* @param prompt 提示内容
* @param base64Encode 是否对内容进行 Base64 编码
* @return AI 的响应内容
*/
public String askAI(String model, String prompt, boolean base64Encode) {
try {
// 处理 Base64 编码
String encodedPrompt = base64Encode ? encodeBase64(prompt) : prompt;
// 构造请求体
RequestBody body = RequestBody.create(
createJsonRequest(model, encodedPrompt), MediaType.get("application/json; charset=utf-8")
);
// 构建请求
Request request = new Request.Builder()
.url(openAiProperties.getApiUrl())
.header("Authorization", "Bearer " + openAiProperties.getApiKey())
.header("Content-Type", "application/json")
.post(body)
.build();
// 发送请求并获取响应
try (Response response = CLIENT.newCall(request).execute()) {
if (!response.isSuccessful()) {
throw new IOException("Unexpected response: " + response);
}
// 解析 JSON 响应
return parseResponse(response.body().string());
}
} catch (IOException e) {
LOGGER.log(Level.SEVERE, "Error occurred during API request: " + e.getMessage(), e);
throw new RuntimeException("API request failed", e);
}
}
/**
* 对输入内容进行 Base64 编码
*
* @param prompt 输入内容
* @return 编码后的字符串
*/
private String encodeBase64(String prompt) {
return Base64.getEncoder().encodeToString(prompt.getBytes(StandardCharsets.UTF_8));
}
/**
* 构建请求的 JSON 数据
*
* @param model 使用的 AI 模型
* @param encodedPrompt 编码后的输入内容
* @return 构建好的 JSON 字符串
*/
private String createJsonRequest(String model, String encodedPrompt) {
JsonObject jsonRequest = new JsonObject();
jsonRequest.addProperty("model", model);
JsonArray messages = new JsonArray();
// 添加 system 信息
JsonObject systemMessage = new JsonObject();
systemMessage.addProperty("role", "system");
systemMessage.addProperty("content", "请根据以下内容提供问题的解决方案。使用中文回答,不要使用markdown语法和特殊符号**之类的,注意,内容可能经过 Base64 编码。");
messages.add(systemMessage);
// 添加 user 信息
JsonObject userMessage = new JsonObject();
userMessage.addProperty("role", "user");
userMessage.addProperty("content", encodedPrompt);
messages.add(userMessage);
jsonRequest.add("messages", messages);
return jsonRequest.toString();
}
/**
* 解析 API 响应内容
*
* @param responseBody 响应的 JSON 内容
* @return 解析后的结果
*/
private String parseResponse(String responseBody) {
JsonObject jsonObject = JsonParser.parseString(responseBody).getAsJsonObject();
JsonArray choices = jsonObject.getAsJsonArray("choices");
if (choices != null && choices.size() > 0) {
JsonObject choice = choices.get(0).getAsJsonObject();
JsonObject message = choice.getAsJsonObject("message");
return message.get("content").getAsString();
}
throw new RuntimeException("Invalid response: No choices found.");
}
}
- 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
- 82
- 83
- 84
- 85
- 86
- 87
- 88
- 89
- 90
- 91
- 92
- 93
- 94
- 95
- 96
- 97
- 98
- 99
- 100
- 101
- 102
- 103
- 104
- 105
- 106
- 107
- 108
- 109
- 110
- 111
- 112
- 113
- 114
- 115
- 116
- 117
- 118
- 119
- 120
- 121
- 122
- 123
- 124
- 125
- 126
- 127
- 128
- 129
- 130
- 131
- 132
- 133
- 134
- 135
- 136
2.common-openai-starter-demo
1.目录结构
2.application.yml 新增api-url
openai:
api-key: guest # 必填,OpenAI API Key
api-url: https://api.openai.com/v1/chat/completions # 可选,有默认值,为了防止以后 URL 变化
- 1
- 2
- 3
3.OpenAiController.java
package com.sunxiansheng.openai.controller;
import com.sunxiansheng.openai.client.OpenAiClient;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import javax.annotation.Resource;
/**
* Description: OpenAI 控制器类
*
* @Author sun
* @Create 2024/12/14 12:27
* @Version 1.0
*/
@RestController
public class OpenAiController {
@Resource
private OpenAiClient openAiClient;
@RequestMapping("/ask")
public String ask(String question) {
String res = openAiClient.askAI("gpt-4o", question, false);
return "AI回答:" + res;
}
}
- 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
4.OpenAiApplication.java
package com.sunxiansheng.openai;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
/**
* Description: OpenAI启动类
*
* @Author sun
* @Create 2024/12/14 12:23
* @Version 1.0
*/
@SpringBootApplication
public class OpenAiApplication {
public static void main(String[] args) {
SpringApplication.run(OpenAiApplication.class, args);
}
}
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
5.测试

一起学习,一起进步!
微信名片


评论记录:
回复评论: