添加多轮上下文调用ChatGPT API时出现400 Bad Request错误
问题分析与解决方案
核心错误原因及修复
1. 缺少必填的model参数
OpenAI Chat Completions API要求请求必须指定使用的模型(如gpt-3.5-turbo),你的代码中Request对象未设置该字段,直接触发400错误。
修复:
创建Request实例时添加模型指定:
Request request = new Request() { Model = "gpt-3.5-turbo" // 可根据需求替换为gpt-3.5-turbo-16k等模型 };
2. 消息角色(Role)序列化格式错误
API要求消息的role字段必须是小写字符串("system"/"user"/"assistant"),如果你的RequestMessage类中Role属性序列化后首字母大写(如"Role":"User"),会导致API识别失败。
修复:
在模型类中添加Json序列化特性,强制输出小写字段名:
public class RequestMessage { [JsonPropertyName("role")] public string Role { get; set; } [JsonPropertyName("content")] public string Content { get; set; } } public class Request { [JsonPropertyName("model")] public string Model { get; set; } [JsonPropertyName("messages")] public RequestMessage[] Messages { get; set; } }
额外优化点
1. 避免冗余上下文
你当前每次调用都会重复添加固定的"How are you?"测试对话,会导致上下文冗余、浪费token,建议将系统消息和初始对话只初始化一次:
// 在类构造函数中初始化系统消息(仅执行一次) public YourChatService(string apiKey) { _apiKey = apiKey; _items.Add(new RequestMessage() { Role = "system", Content = $"You are ChatGPT, a large language model trained by OpenAI. Answer as concisely as possible.\nKnowledge cutoff: 2021-09-01\nCurrent date: {DateTime.Now.ToString("yyyy-MM-dd")}" }); }
2. 复用HttpClient
每次创建新HttpClient会造成资源浪费,建议改为类级别静态变量复用:
private static readonly HttpClient _httpClient = new HttpClient(); // 在构造函数中初始化请求头 public YourChatService(string apiKey) { _apiKey = apiKey; _httpClient.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", _apiKey); _httpClient.DefaultRequestHeaders.Add("Accept", "application/json"); }
修复后的完整代码片段
using System.Text.Json.Serialization; private List<RequestMessage> _items = new(); private static readonly HttpClient _httpClient = new HttpClient(); private readonly string _apiKey; private readonly string _apiUrl = "https://api.openai.com/v1/chat/completions"; public YourChatService(string apiKey) { _apiKey = apiKey; _httpClient.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", _apiKey); _httpClient.DefaultRequestHeaders.Add("Accept", "application/json"); // 初始化系统消息 _items.Add(new RequestMessage() { Role = "system", Content = $"You are ChatGPT, a large language model trained by OpenAI. Answer as concisely as possible.\nKnowledge cutoff: 2021-09-01\nCurrent date: {DateTime.Now.ToString("yyyy-MM-dd")}" }); } async public Task<string> SendMessage(string message) { Request request = new Request() { Model = "gpt-3.5-turbo" }; List<RequestMessage> requestMessages = new List<RequestMessage>(_items); requestMessages.Add(new RequestMessage() { Role = "user", Content = message }); request.Messages = requestMessages.ToArray(); string requestData = JsonSerializer.Serialize(request); StringContent content = new StringContent(requestData, Encoding.UTF8, "application/json"); HttpResponseMessage httpResponseMessage = await _httpClient.PostAsync(_apiUrl, content); if (httpResponseMessage.IsSuccessStatusCode) { string responseString = await httpResponseMessage.Content.ReadAsStringAsync(); Response response = JsonSerializer.Deserialize<Response>(responseString); string responseText = response.Choices[0].Message.Content; _items.Add(new RequestMessage() { Role = "user", Content = message }); _items.Add(new RequestMessage() { Role = "assistant", Content = responseText }); return responseText; } else { // 读取API返回的详细错误信息,便于排查 string errorDetails = await httpResponseMessage.Content.ReadAsStringAsync(); return $"Error: {httpResponseMessage.StatusCode} - {httpResponseMessage.ReasonPhrase}\nDetails: {errorDetails}"; } } // 修正后的模型类 public class Request { [JsonPropertyName("model")] public string Model { get; set; } [JsonPropertyName("messages")] public RequestMessage[] Messages { get; set; } } public class RequestMessage { [JsonPropertyName("role")] public string Role { get; set; } [JsonPropertyName("content")] public string Content { get; set; } } public class Response { [JsonPropertyName("choices")] public Choice[] Choices { get; set; } } public class Choice { [JsonPropertyName("message")] public RequestMessage Message { get; set; } }
排查建议
如果仍出现400错误,务必读取API返回的errorDetails内容,OpenAI会明确标注错误原因(如角色格式错误、上下文长度超限等),帮助快速定位问题。
内容的提问来源于stack exchange,提问作者Jay Croghan
相关产品推荐
相关产品推荐

