You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

发送大文本至OpenAI API时遭遇400 Bad Request错误求助

解决方案:OpenAI API大文本400 Bad Request问题

问题核心原因

你遇到的400错误本质是模型上下文长度限制:

  • gpt-3.5-turbo默认版本(如gpt-3.5-turbo-0301)的上下文上限为4096 token,约对应3000-4000个英文单词(1字符≈0.75 token),20000字符远超该限制,触发API请求校验失败。
  • 原代码未捕获API返回的具体错误信息,无法直接确认问题根源。

具体解决方案

1. 切换到大上下文模型

最简单的解决方式是改用支持更大容量的模型:

  • 将代码中的model变量改为gpt-3.5-turbo-16k(支持16384 token,约12000个英文单词),足以容纳20000字符的文本。
  • 若需要更大容量,可选择gpt-4-32k(支持32768 token),但成本更高。

修改代码示例:

// 在chatGPT方法中更新model值
String model = "gpt-3.5-turbo-16k";

2. 添加错误信息捕获

原代码仅抛出RuntimeException,无法获取OpenAI返回的具体错误提示。修改代码读取错误流,明确问题:

// 替换chatGPT方法中的try-catch逻辑
try {
    URL openAIUrl = new URL(url);
    HttpURLConnection connection = (HttpURLConnection) openAIUrl.openConnection();
    connection.setRequestMethod("POST");
    connection.setRequestProperty("Authorization", "Bearer " + apiKey);
    connection.setRequestProperty("Content-Type", "application/json");

    chatGptRequest.setModel(model);

    Gson gson = new Gson();
    String body = gson.toJson(chatGptRequest);

    connection.setDoOutput(true);
    OutputStreamWriter writer = new OutputStreamWriter(connection.getOutputStream());
    writer.write(body);
    writer.flush();
    writer.close();

    // 新增:处理非200响应
    int responseCode = connection.getResponseCode();
    BufferedReader br;
    if (responseCode == HttpURLConnection.HTTP_OK) {
        br = new BufferedReader(new InputStreamReader(connection.getInputStream()));
    } else {
        br = new BufferedReader(new InputStreamReader(connection.getErrorStream()));
    }

    String line;
    StringBuffer response = new StringBuffer();
    while ((line = br.readLine()) != null) {
        response.append(line);
    }
    br.close();

    // 非200响应时抛出包含具体错误的异常
    if (responseCode != HttpURLConnection.HTTP_OK) {
        throw new RuntimeException("OpenAI API Error: " + response.toString());
    }

    return response.toString();
} catch (IOException e) {
    throw new RuntimeException(e);
}

3. 文本分块处理(不换模型时)

若坚持使用gpt-3.5-turbo基础版,需将大文本拆分为多个小块,分批处理后汇总结果:

  • 将长文本按段落/固定长度拆分,每次发送一个文本块+用户问题,让模型逐步提取信息。
  • 或先让模型总结每个文本块的关键信息,再合并所有总结结果,最后发送给模型回答最终问题。

示例思路(伪代码):

// 拆分大文本为多个小块
List<String> textChunks = splitLargeText(text, 3000); // 按3000字符拆分
StringBuilder summary = new StringBuilder();

// 分批总结每个文本块
for (String chunk : textChunks) {
    ChatGptRequest summaryRequest = new ChatGptRequest();
    List<Message> summaryMessages = new ArrayList<>();
    Message systemMsg = new Message();
    systemMsg.setRole("system");
    systemMsg.setContent("Summarize key information in this text, especially date-related content: " + chunk);
    summaryMessages.add(systemMsg);
    summaryRequest.setMessages(summaryMessages);
    String chunkSummary = ChatGptClient.chatGPT(summaryRequest);
    summary.append(chunkSummary).append("\n");
}

// 用汇总信息回答原问题
ChatGptRequest finalRequest = new ChatGptRequest();
List<Message> finalMessages = new ArrayList<>();
Message systemMsg = new Message();
systemMsg.setRole("system");
systemMsg.setContent("Based on this summary: " + summary.toString());
finalMessages.add(systemMsg);
Message userMsg = new Message();
userMsg.setRole("user");
userMsg.setContent("What is the start and end date?");
finalMessages.add(userMsg);
finalRequest.setMessages(finalMessages);
String finalResponse = ChatGptClient.chatGPT(finalRequest);

4. 提前校验token长度

在发送请求前计算总token数,超过模型限制时提前处理:

  • 使用Java版tiktoken库(如com.knuddels:tiktoken-java)计算消息的token数量。
  • 若超过限制,直接提示用户或自动触发分块逻辑。

示例代码(依赖tiktoken-java):

import com.knuddels.jtokkit.Encodings;
import com.knuddels.jtokkit.api.Encoding;
import com.knuddels.jtokkit.api.EncodingRegistry;
import com.knuddels.jtokkit.api.ModelType;

// 计算消息总token数
public static int calculateTotalTokens(List<Message> messages) {
    EncodingRegistry registry = Encodings.newDefaultEncodingRegistry();
    Encoding encoding = registry.getEncodingForModel(ModelType.GPT_3_5_TURBO);
    
    int totalTokens = 0;
    for (Message msg : messages) {
        // 每个消息的token数:角色字符数 + 内容字符数 + 固定分隔符token
        totalTokens += encoding.countTokens(msg.getRole()) + encoding.countTokens(msg.getContent()) + 4;
    }
    totalTokens += 2; // 系统额外token
    return totalTokens;
}

// 在sendData方法中添加校验
public Result sendData() {
    ChatGptRequest chatGptRequest = new ChatGptRequest();
    List<Message> messages = new ArrayList<>();

    Message userMessage = new Message();
    userMessage.setRole("user");
    userMessage.setContent("What is the start and end date?");
    messages.add(userMessage);

    Message systemMessage = new Message();
    systemMessage.setRole("system");
    systemMessage.setContent(text);
    messages.add(systemMessage);

    // 校验token数
    int totalTokens = calculateTotalTokens(messages);
    if (totalTokens > 4096) { // gpt-3.5-turbo基础版上限
        return Result.error("Text too long, please reduce content length or use a larger model.");
    }

    chatGptRequest.setMessages(messages);
    String response = ChatGptClient.chatGPT(chatGptRequest);
    return Result.success(response);
}

内容的提问来源于stack exchange,提问作者Shiva Rena

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.25 11:54:53