如何在Java中调用ChatGPT聊天补全API实现上下文关联对话
Java调用ChatGPT聊天补全API实现上下文对话与摘要生成
原API调用示例(中文说明)
用户提供的基础curl调用对应ChatGPT聊天补全API的核心请求格式:
curl https://api.openai.com/v1/chat/completions \ -H "Content-Type: application/json" \ -H "Authorization: Bearer $OPENAI_API_KEY" \ -d '{ "model": "gpt-3.5-turbo", "messages": [{"role": "user", "content": "Hello!"}] }'
其中messages字段为对话消息数组,每个元素包含role(角色:user/assistant/system)和content(消息内容),是实现上下文对话的核心参数。
响应示例(中文翻译)
{ "id": "chatcmpl-76eCdoZ4qHySmqBTsX0e97NqTOLgs", "object": "chat.completion", "created": 1681818863, "model": "gpt-3.5-turbo-0301", "usage": { "prompt_tokens": 16, "completion_tokens": 29, "total_tokens": 45 }, "choices": [ { "message": { "role": "assistant", "content": "作为AI语言模型,没有具体上下文我无法检查条款。请提供更多信息或上下文,以便我准确协助你。" }, "finish_reason": "stop", "index": 0 } ] }
核心实现逻辑
要实现带历史上下文的对话并生成摘要,关键是维护完整的对话消息列表:每次发起请求时,将所有历史对话(用户提问、AI回复)与新问题一起传入messages参数,同时在新问题中明确要求AI基于所有上下文生成回答并附带摘要。
Java代码实现
1. 定义消息实体类
封装对话中的角色与内容:
import com.fasterxml.jackson.annotation.JsonProperty; public class ChatMessage { @JsonProperty("role") private String role; @JsonProperty("content") private String content; public ChatMessage(String role, String content) { this.role = role; this.content = content; } // Getters and Setters public String getRole() { return role; } public void setRole(String role) { this.role = role; } public String getContent() { return content; } public void setContent(String content) { this.content = content; } }
2. 定义请求体与响应体类
请求体:
import com.fasterxml.jackson.annotation.JsonProperty; import java.util.List; public class ChatCompletionRequest { @JsonProperty("model") private String model; @JsonProperty("messages") private List<ChatMessage> messages; public ChatCompletionRequest(String model, List<ChatMessage> messages) { this.model = model; this.messages = messages; } // Getters and Setters public String getModel() { return model; } public void setModel(String model) { this.model = model; } public List<ChatMessage> getMessages() { return messages; } public void setMessages(List<ChatMessage> messages) { this.messages = messages; } }
响应体(简化版,可按需扩展):
import com.fasterxml.jackson.annotation.JsonProperty; import java.util.List; public class ChatCompletionResponse { @JsonProperty("id") private String id; @JsonProperty("choices") private List<Choice> choices; @JsonProperty("usage") private Usage usage; // Getters and Setters public String getId() { return id; } public void setId(String id) { this.id = id; } public List<Choice> getChoices() { return choices; } public void setChoices(List<Choice> choices) { this.choices = choices; } public Usage getUsage() { return usage; } public void setUsage(Usage usage) { this.usage = usage; } public static class Choice { @JsonProperty("message") private ChatMessage message; @JsonProperty("finish_reason") private String finishReason; // Getters and Setters public ChatMessage getMessage() { return message; } public void setMessage(ChatMessage message) { this.message = message; } public String getFinishReason() { return finishReason; } public void setFinishReason(String finishReason) { this.finishReason = finishReason; } } public static class Usage { @JsonProperty("prompt_tokens") private int promptTokens; @JsonProperty("completion_tokens") private int completionTokens; @JsonProperty("total_tokens") private int totalTokens; // Getters and Setters public int getPromptTokens() { return promptTokens; } public void setPromptTokens(int promptTokens) { this.promptTokens = promptTokens; } public int getCompletionTokens() { return completionTokens; } public void setCompletionTokens(int completionTokens) { this.completionTokens = completionTokens; } public int getTotalTokens() { return totalTokens; } public void setTotalTokens(int totalTokens) { this.totalTokens = totalTokens; } } }
3. 核心调用逻辑
使用Java 11+内置HttpClient发起请求,维护历史对话列表:
import com.fasterxml.jackson.databind.ObjectMapper; import java.net.URI; import java.net.http.HttpClient; import java.net.http.HttpRequest; import java.net.http.HttpResponse; import java.util.ArrayList; import java.util.List; public class ChatGPTClient { private static final String API_URL = "https://api.openai.com/v1/chat/completions"; private static final String API_KEY = "你的OPENAI_API_KEY"; // 替换为个人API密钥 private static final ObjectMapper objectMapper = new ObjectMapper(); private final List<ChatMessage> historyMessages = new ArrayList<>(); public String chatWithContext(String newQuestion) throws Exception { // 添加新问题到历史列表,附带摘要生成要求 historyMessages.add(new ChatMessage("user", newQuestion + "\n请基于上述所有历史上下文生成回答,并附上对话摘要")); // 构建请求体 ChatCompletionRequest request = new ChatCompletionRequest( "gpt-3.5-turbo", historyMessages ); String requestBody = objectMapper.writeValueAsString(request); // 构建并发送HTTP请求 HttpRequest httpRequest = HttpRequest.newBuilder() .uri(URI.create(API_URL)) .header("Content-Type", "application/json") .header("Authorization", "Bearer " + API_KEY) .POST(HttpRequest.BodyPublishers.ofString(requestBody)) .build(); HttpClient client = HttpClient.newHttpClient(); HttpResponse<String> response = client.send( httpRequest, HttpResponse.BodyHandlers.ofString() ); // 解析响应并更新历史列表 ChatCompletionResponse completionResponse = objectMapper.readValue(response.body(), ChatCompletionResponse.class); if (!completionResponse.getChoices().isEmpty()) { ChatMessage assistantReply = completionResponse.getChoices().get(0).getMessage(); historyMessages.add(assistantReply); return assistantReply.getContent(); } return "无有效响应"; } public static void main(String[] args) throws Exception { ChatGPTClient client = new ChatGPTClient(); // 第一轮对话 String firstReply = client.chatWithContext("我正在学习Java的HttpClient,能给我讲讲基本用法吗?"); System.out.println("AI回复:\n" + firstReply); // 第二轮对话,自动携带历史上下文 String secondReply = client.chatWithContext("刚才说的内容里,如何处理响应体的JSON解析?"); System.out.println("\nAI回复:\n" + secondReply); } }
关键注意事项
- 上下文维护:每次对话后,必须将用户提问和AI回复都加入历史消息列表,确保后续请求包含完整对话链。
- Token限制:
gpt-3.5-turbo默认token上限为4096,若历史对话过长,需对上下文进行截断或预总结,避免超出限制。 - 依赖要求:需添加Jackson依赖(
com.fasterxml.jackson.core:jackson-databind:2.15.2)用于JSON序列化与反序列化。
内容的提问来源于stack exchange,提问作者khushbu shah
相关产品推荐
相关产品推荐

