主题
语言
·2 分钟阅读

Responses API 与 Chat Completions:有哪些区别,应该使用哪个

介绍 OpenAI 兼容 API 中 /v1/responses 与 /v1/chat/completions 的实际差异:请求结构、对话历史、工具、流式事件,以及如何选择。每个示例都在 GetVibe API 上实时运行。

Responses API 与 Chat Completions:有哪些区别,应该使用哪个

如今,兼容 OpenAI 的 API 主要有两种请求格式:长期使用的 /v1/chat/completions,以及较新的 /v1/responses。GetVibe API 使用同一个密钥和基础 URL https://getvibeapi.com/v1 同时支持这两种格式。下面介绍它们在实际使用中的区别、该如何选择,以及在两者之间切换时需要注意的一个陷阱。

简要结论

Chat CompletionsResponses
端点POST /v1/chat/completionsPOST /v1/responses
输入一个 messages 数组input:字符串或项目数组
系统提示词使用 system 角色的消息instructions 字段
回答choices[0].message一个 output 数组:推理、消息、函数调用
输出限制max_tokensmax_output_tokens
使用者大多数 SDK、框架和聊天应用Codex CLI 和较新的智能体 SDK

格式不会改变模型、价格或 token 数量:无论使用哪种格式,都会按照模型的输入和输出 token 计费。

两种格式中的相同请求

Chat Completions:

curl https://getvibeapi.com/v1/chat/completions \
  -H "Authorization: Bearer $GETVIBE_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "model": "gpt-6-luna",
    "messages": [
      {"role": "system", "content": "用一句话回答。"},
      {"role": "user", "content": "HTTP 429 表示什么?"}
    ],
    "max_tokens": 300
  }'

Responses:

curl https://getvibeapi.com/v1/responses \
  -H "Authorization: Bearer $GETVIBE_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "model": "gpt-6-luna",
    "instructions": "用一句话回答。",
    "input": "HTTP 429 表示什么?",
    "max_output_tokens": 300
  }'

在 Chat Completions 中,文本位于 choices[0].message.content。在 Responses 中,文本位于 output 内:对于推理模型,第一个项目是 reasoning 项,回答则是类型为 message 的项目。你不必手动遍历数组;Python SDK 提供了 output_text 属性。

import os
from openai import OpenAI

client = OpenAI(base_url="https://getvibeapi.com/v1", api_key=os.environ["GETVIBE_API_KEY"])

chat = client.chat.completions.create(
    model="gpt-6-luna",
    messages=[{"role": "system", "content": "用一句话回答。"},
              {"role": "user", "content": "HTTP 429 表示什么?"}],
)
print(chat.choices[0].message.content)

resp = client.responses.create(
    model="gpt-6-luna",
    instructions="用一句话回答。",
    input="HTTP 429 表示什么?",
)
print(resp.output_text)

Responses 并不局限于 OpenAI 模型。在发布前,我们将相同的 Responses 请求分别发送给 gpt-6-luna、claude-sonnet-5.5 和 deepseek-v4.1-flash,三个模型都给出了回答。DeepSeek 在其 message 之前返回了一个 reasoning 项,与上面的说明完全一致。

对话历史:需要自行发送

这是切换前需要了解的唯一事项。OpenAI 自己的 Responses API 可以在服务器上保存对话,因此下一次请求可以通过 previous_response_id 指向上一次请求。GetVibe API 不会存储你的对话,因此不支持 previous_response_id,而 store 会被忽略。我们尝试使用它时,请求因 400 错误而被拒绝。

可行的模式与 Chat Completions 相同:将完整历史记录放入 input 中发送。

history = [{"role": "user", "content": "我叫 Ana。记住这个名字。"}]
first = client.responses.create(model="gpt-6-luna", input=history)

history.append({"role": "assistant", "content": first.output_text})
history.append({"role": "user", "content": "我叫什么名字?用一个词回答。"})
second = client.responses.create(model="gpt-6-luna", input=history)
print(second.output_text)  # Ana

工具:形状有所不同

两种格式都支持函数调用,但工具定义的形式不同。在 Chat Completions 中,函数字段嵌套在 function 对象内;在 Responses 中,这些字段直接位于工具上。调用会作为单独的 function_call 项返回,而你需要使用具有相同 call_id 的 function_call_output 项返回结果。

import json

tools = [{
    "type": "function",
    "name": "get_weather",
    "description": "某个城市的当前天气",
    "parameters": {
        "type": "object",
        "properties": {"city": {"type": "string"}},
        "required": ["city"],
        "additionalProperties": False,
    },
}]

items = [{"role": "user", "content": "丹佛的天气怎么样?"}]
resp = client.responses.create(model="gpt-6-luna", input=items, tools=tools)

for item in resp.output:
    if item.type == "function_call":
        result = {"city": "Denver", "temp_f": 54, "sky": "overcast"}  # 你的函数
        items.append({"type": "function_call", "call_id": item.call_id,
                      "name": item.name, "arguments": item.arguments})
        items.append({"type": "function_call_output", "call_id": item.call_id,
                      "output": json.dumps(result)})

final = client.responses.create(model="gpt-6-luna", input=items, tools=tools)
print(final.output_text)

在我们的运行中,模型使用 {"city":"Denver"} 调用了 get_weather,第二个请求回答丹佛的气温为 54°F,天气阴天。相同循环的 Chat Completions 版本请参阅我们的函数调用指南。

流式传输

两种格式都支持 "stream": true,但事件有所不同。Chat Completions 发送统一的 data: 行,每一段新增文本位于 choices[0].delta.content 中。Responses 发送带名称的事件:首先是 response.created,然后是包含文本片段的 response.output_text.delta,最后是 response.completed。如果你不是通过 SDK,而是自行解析流,就需要针对具体格式编写解析器。

该如何选择

  • 如果你已经在使用 Chat Completions,或者使用某个框架、聊天应用或无代码平台,就选择它。几乎所有工具都支持这种格式,没有必要仅仅为了更换格式而重写可正常运行的代码。
  • 如果某个工具要求使用 Responses,就选择它。主要例子是 Codex CLI,它通过 /v1/responses 进行通信;配置方法请参阅 Codex CLI 文档和我们的 Codex CLI 指南。

无论选择哪种格式,模型列表和价格都相同。所有字段请参阅 API 参考,实时价格请参阅模型页面。

Responses API 与 Chat Completions 对比OpenAI Responses API/v1/responsesChat Completions APIprevious_response_idCodex CLI Responses API

免费试用 GetVibe API

通过一个 OpenAI 兼容的 API 接入 GPT、Claude、Gemini 等模型,支持信用卡或加密货币支付。

相关文章

Responses API 与 Chat Completions:有哪些区别,应该使用哪个 | GetVibe API