通八洲科技

如何正确向 OpenAI Chat API 传递消息数组(避免 400 错误)

日期:2025-12-26 00:00 / 作者:心靈之曲

当向 openai 的 `createchatcompletion` 接口传入消息数组时,若动态修改数组(如 `push()`)后出现 http 400 错误,根本原因并非数组操作本身,而是**错误地对已为对象的 message 项再次序列化(如误用 `json.stringify`)**,导致消息结构被破坏,违反 api 要求的严格 json schema。

在你提供的代码中,问题并不出在 data.push(...) 这一操作——它本身完全合法且常用。真正引发 400 Bad Request 的根源是:你在注释解除后错误地执行了 data.push(JSON.stringify({...})),将一个字符串而非对象推入了 messages 数组

OpenAI Chat API 的 messages 字段必须是一个由标准 JavaScript 对象组成的数组,每个对象必须严格符合 { "role": "string", "content": "string" } 结构(role 仅允许 "system"、"user" 或 "assistant")。当你写:

data.push(JSON.stringify({ role: 'sytem', content: 'Hola GPT' }));

你实际向数组中添加的是一个字符串(例如 {"role":"sytem","content":"Hola GPT"}),而非对象。API 接收后尝试解析整个 messages 数组时,会发现其中一项是字符串而非对象,立即拒绝请求并返回 400 —— 这正是 Axios 报错 “Request failed with status code 400” 的真实原因。

✅ 正确做法是直接推送合法对象:

// ✅ 正确:推送对象(注意拼写修正:'system' 而非 'sytem')
data.push({ role: 'system', content: 'Hola GPT' });

⚠️ 同时请注意两个关键细节:

  1. role 值拼写必须准确:'sytem' 是无效值,会导致 400;应为 'system'、'user' 或 'assistant';
  2. 无需手动 JSON.stringify:openai SDK(v3.x+)内部已自动序列化请求体,传入纯对象即可;手动序列化只会破坏结构。

完整修复后的示例代码如下:

const { Configuration, OpenAIApi } = require('openai');

const configuration = new Configuration({
  apiKey: process.env.OPENAI_API_KEY || 'your-api-key-here',
});
const openai = new OpenAIApi(configuration);

const chatGPTProvider = async () => {
  try {
    const messages = [
      { role: 'system', content: 'You are a helpful assistant.' },
      { role: 'user', content: 'Act as an intelligent AI.' },
    ];

    // ✅ 安全追加:直接推入合法对象,修正 role 拼写
    messages.push({ role: 'system', content: 'Hola GPT' });

    const response = await openai.createChatCompletion({
      model: 'gpt-3.5-turbo',
      messages, // ← 传入对象数组,SDK 自动处理序列化
    });

    return {
      status: 'SUCCESS',
      result: response.data.choices[0].message,
    };
  } catch (error) {
    console.error('OpenAI API Error:', error.response?.status, error.message);
    return { status: 'ERROR', result: null };
  }
};

? 总结与最佳实践

只要确保数组内每一项都是格式正确的对象,无论静态定义还是动态 push/unshift,API 均可正常接收并响应。