Chat Completions API 是 OpenAI 最核心的对话接口,支持 GPT-4、GPT-4o、GPT-3.5-Turbo 等模型。该 API 已成为行业事实标准,被众多第三方服务兼容。
核心特点
- 消息角色系统:通过 system/user/assistant 角色构建对话
- 流式输出:支持 SSE 实时返回生成内容
- 工具调用:支持 Function Calling 扩展模型能力
- 结构化输出:支持 JSON Mode 和 JSON Schema 约束输出格式
- 多模态:GPT-4o 支持图像输入
为什么 Chat Completions API 如此重要?
Chat Completions API 不仅是 OpenAI 的核心接口,更是整个大模型行业的事实标准。理解这一点对于开发者至关重要:
1. 行业标准地位
几乎所有的 LLM 工具和框架(LangChain、LlamaIndex、Semantic Kernel 等)都以 OpenAI 格式作为首选支持。这意味着学会 Chat Completions API,你就掌握了与大多数模型交互的通用方式。
2. 广泛的兼容性
许多第三方模型提供商(如 Azure OpenAI、Groq、Together AI、Anyscale)都提供 OpenAI 兼容的 API。你只需要更换 base_url 和 API key,代码几乎不需要修改。
3. 成熟的生态系统
OpenAI SDK 是最成熟、文档最完善的 LLM SDK。Python 和 Node.js 版本都有完整的类型定义、错误处理和流式支持。
4. 持续演进
OpenAI 不断为 Chat Completions API 添加新功能(如 Structured Outputs、Vision),同时保持向后兼容。这种稳定性对于生产环境至关重要。
端点与认证
端点
POST https://api.openai.com/v1/chat/completions
这是一个标准的 RESTful POST 端点。所有请求参数都通过 JSON 请求体传递,响应也是 JSON 格式。
认证
Authorization: Bearer $OPENAI_API_KEY
OpenAI 使用 Bearer Token 认证方式,这是 OAuth 2.0 规范的标准做法。API Key 以 sk- 开头,需要妥善保管,不要泄露到公开代码库中。
安全建议:
- 使用环境变量存储 API Key,不要硬编码在代码中
- 在服务端调用 API,不要在前端暴露 Key
- 定期轮换 API Key
- 使用 OpenAI 的 Project API Keys 功能限制权限范围
请求参数
请求参数分为必需参数和可选参数。理解每个参数的作用对于优化模型输出至关重要。
必需参数
| 参数 | 类型 | 说明 |
|---|---|---|
model | string | 模型 ID,如 gpt-4o、gpt-4-turbo、gpt-3.5-turbo |
messages | array | 消息数组 |
model 参数说明:
模型 ID 决定了使用哪个模型处理请求。不同模型在能力、速度、价格上有显著差异。模型 ID 通常包含版本信息,如 gpt-4o-2024-08-06 表示 2024 年 8 月 6 日发布的版本。使用不带日期的 ID(如 gpt-4o)会自动使用最新稳定版本。
messages 参数说明:
messages 是对话的核心,包含了完整的对话历史。模型会根据这些消息理解上下文并生成回复。消息顺序很重要,通常是 system → user → assistant → user → assistant… 的模式。
可选参数
| 参数 | 类型 | 默认值 | 说明 |
|---|---|---|---|
temperature | number | 1 | 随机性 0-2,越高越随机 |
top_p | number | 1 | 核采样,与 temperature 二选一 |
n | integer | 1 | 生成几个回复 |
stream | boolean | false | 是否流式输出 |
stop | string/array | null | 停止词 |
max_tokens | integer | - | 最大生成 token 数 |
max_completion_tokens | integer | - | 最大完成 token 数(新版) |
presence_penalty | number | 0 | 存在惩罚 -2.0 到 2.0 |
frequency_penalty | number | 0 | 频率惩罚 -2.0 到 2.0 |
tools | array | - | 工具/函数定义 |
tool_choice | string/object | auto | 工具选择策略 |
response_format | object | - | 响应格式(JSON mode) |
seed | integer | - | 随机种子,用于可复现输出 |
关键参数详解:
temperature(温度)
控制输出的随机性。值越低,输出越确定、越集中;值越高,输出越多样、越有创意。
temperature=0:几乎确定性输出,适合需要一致性的场景(如代码生成、数据提取)temperature=0.7:平衡创意和一致性,适合大多数对话场景temperature=1.5+:高度随机,适合创意写作、头脑风暴
top_p(核采样)
另一种控制随机性的方式。top_p=0.9 表示只从累积概率达到 90% 的 token 中采样。通常建议只调整 temperature 或 top_p 其中之一,不要同时调整。
presence_penalty 和 frequency_penalty
这两个参数用于控制重复:
presence_penalty:惩罚已经出现过的 token,鼓励模型谈论新话题frequency_penalty:根据 token 出现的频率进行惩罚,减少重复用词
正值会减少重复,负值会增加重复。通常设置在 0 到 1 之间。
seed(随机种子)
设置 seed 可以使输出更可复现。相同的 seed + 相同的输入通常会产生相同的输出(但不是 100% 保证)。这对于调试和测试很有用。
消息格式
消息(messages)是 Chat Completions API 的核心概念。每条消息都有一个角色(role)和内容(content),模型根据消息序列理解对话上下文。
角色类型
| 角色 | 说明 |
|---|---|
system | 系统指令,设定 AI 行为 |
user | 用户消息 |
assistant | AI 回复 |
tool | 工具调用结果 |
角色详解:
system(系统角色)
系统消息用于设定 AI 的行为、性格、能力边界。它通常放在消息数组的开头,对整个对话产生影响。好的系统提示可以显著提升模型表现。
系统消息的常见用途:
- 定义 AI 的身份和专业领域
- 设定回复的格式和风格
- 规定 AI 应该做什么和不应该做什么
- 提供背景知识和上下文
user(用户角色)
用户消息代表人类用户的输入。这是对话的驱动力,模型会针对用户消息生成回复。
assistant(助手角色)
助手消息代表 AI 的回复。在多轮对话中,你需要将之前的 AI 回复作为 assistant 消息包含在请求中,这样模型才能理解对话历史。
tool(工具角色)
工具消息用于返回函数调用的结果。当模型请求调用工具后,你执行工具并将结果以 tool 消息的形式返回给模型。
基础消息结构
{
"messages": [
{"role": "system", "content": "You are a helpful assistant."},
{"role": "user", "content": "Hello!"}
]
}
多轮对话示例:
{
"messages": [
{"role": "system", "content": "你是一个友好的中文助手。"},
{"role": "user", "content": "你好!"},
{"role": "assistant", "content": "你好!有什么我可以帮助你的吗?"},
{"role": "user", "content": "今天天气怎么样?"},
{"role": "assistant", "content": "抱歉,我无法获取实时天气信息。你可以查看天气应用或网站获取准确的天气预报。"},
{"role": "user", "content": "好的,谢谢!"}
]
}
多模态消息(图像)
GPT-4o 等视觉模型支持图像输入。图像可以通过 URL 或 Base64 编码传递。
{
"messages": [
{
"role": "user",
"content": [
{"type": "text", "text": "What's in this image?"},
{
"type": "image_url",
"image_url": {
"url": "https://example.com/image.jpg",
"detail": "high"
}
}
]
}
]
}
图像参数说明:
url:图像的 URL 地址,或data:image/jpeg;base64,{base64_data}格式的 Base64 数据detail:图像分析的详细程度low:快速模式,消耗较少 token,适合简单识别high:高清模式,消耗更多 token,适合需要细节的场景auto:让模型自动选择
支持的图像格式: PNG、JPEG、GIF、WebP
图像大小限制: 单张图像最大 20MB,建议压缩到合理大小以节省成本
响应格式
理解响应格式对于正确解析模型输出、处理错误和监控使用量至关重要。
标准响应
{
"id": "chatcmpl-abc123",
"object": "chat.completion",
"created": 1677858242,
"model": "gpt-4o-2024-08-06",
"choices": [
{
"index": 0,
"message": {
"role": "assistant",
"content": "Hello! How can I help you today?"
},
"logprobs": null,
"finish_reason": "stop"
}
],
"usage": {
"prompt_tokens": 13,
"completion_tokens": 9,
"total_tokens": 22
}
}
响应字段详解:
| 字段 | 说明 |
|---|---|
id | 唯一标识符,用于日志追踪和问题排查 |
object | 对象类型,固定为 chat.completion |
created | Unix 时间戳,表示响应创建时间 |
model | 实际使用的模型版本(可能与请求中的不同) |
choices | 回复数组,通常只有一个元素(除非设置 n>1) |
usage | Token 使用统计,用于计费和监控 |
choices 数组说明:
index:回复的索引,从 0 开始message:包含角色和内容的消息对象logprobs:对数概率信息(需要在请求中启用)finish_reason:生成停止的原因
usage 字段说明:
prompt_tokens:输入消息消耗的 token 数completion_tokens:生成回复消耗的 token 数total_tokens:总 token 数(用于计费)
finish_reason 值
| 值 | 说明 |
|---|---|
stop | 正常结束或遇到停止词 |
length | 达到 max_tokens 限制 |
tool_calls | 模型调用了工具 |
content_filter | 内容被过滤 |
finish_reason 处理建议:
stop:正常情况,直接使用回复内容length:回复被截断,可能需要增加 max_tokens 或让用户继续tool_calls:需要执行工具并将结果返回给模型content_filter:内容触发安全过滤,需要检查输入或调整提示词
流式传输 (SSE)
流式传输(Streaming)允许模型在生成过程中实时返回内容,而不是等待完整回复。这对于提升用户体验至关重要,用户可以看到”打字机效果”,而不是长时间等待。
为什么使用流式传输?
| 场景 | 非流式 | 流式 |
|---|---|---|
| 用户等待体验 | 长时间空白等待 | 实时看到生成内容 |
| 首字节时间 | 数秒到数十秒 | 通常 < 1 秒 |
| 长回复处理 | 可能超时 | 持续接收数据 |
| 用户中断 | 无法中断 | 可随时停止 |
请求
启用流式传输只需设置 stream: true:
{
"model": "gpt-4o",
"messages": [{"role": "user", "content": "Hello"}],
"stream": true
}
响应格式
流式响应使用 Server-Sent Events (SSE) 格式。每个事件以 data: 开头,包含一个 JSON 对象:
data: {"id":"chatcmpl-abc","object":"chat.completion.chunk","created":1677858242,"model":"gpt-4o","choices":[{"index":0,"delta":{"role":"assistant"},"finish_reason":null}]}
data: {"id":"chatcmpl-abc","object":"chat.completion.chunk","created":1677858242,"model":"gpt-4o","choices":[{"index":0,"delta":{"content":"Hello"},"finish_reason":null}]}
data: {"id":"chatcmpl-abc","object":"chat.completion.chunk","created":1677858242,"model":"gpt-4o","choices":[{"index":0,"delta":{"content":"!"},"finish_reason":null}]}
data: {"id":"chatcmpl-abc","object":"chat.completion.chunk","created":1677858242,"model":"gpt-4o","choices":[{"index":0,"delta":{},"finish_reason":"stop"}]}
data: [DONE]
流式响应特点:
- 每个 chunk 的
object是chat.completion.chunk(而非chat.completion) - 内容在
delta字段中,而非message字段 - 第一个 chunk 通常只包含
role - 后续 chunk 包含
content片段 - 最后一个 chunk 的
finish_reason不为 null - 流结束时发送
data: [DONE]
注意事项:
- 流式响应不包含
usage字段(无法直接获取 token 统计) - 如需 token 统计,可设置
stream_options: {"include_usage": true} - 需要正确处理 SSE 格式,包括空行分隔和
data:前缀
Function Calling / Tools
Function Calling(函数调用)是 Chat Completions API 最强大的功能之一,它允许模型在对话中调用外部函数或 API,从而扩展模型的能力边界。
工作原理
sequenceDiagram
participant User as 用户
participant App as 应用
participant LLM as 模型
participant Tool as 外部工具
User->>App: 北京天气怎么样?
App->>LLM: 发送消息 + 工具定义
LLM->>App: 返回 tool_calls
App->>Tool: 调用天气 API
Tool->>App: 返回天气数据
App->>LLM: 发送工具结果
LLM->>App: 生成最终回复
App->>User: 北京今天晴,22°C模型本身不会执行函数,它只是决定应该调用哪个函数以及传递什么参数。实际的函数执行由你的应用程序完成。
定义工具
工具定义使用 JSON Schema 格式描述函数的名称、描述和参数:
{
"model": "gpt-4o",
"messages": [{"role": "user", "content": "What's the weather in Beijing?"}],
"tools": [
{
"type": "function",
"function": {
"name": "get_weather",
"description": "Get current weather for a location",
"parameters": {
"type": "object",
"properties": {
"location": {
"type": "string",
"description": "City name"
},
"unit": {
"type": "string",
"enum": ["celsius", "fahrenheit"]
}
},
"required": ["location"]
}
}
}
],
"tool_choice": "auto"
}
工具定义要点:
name:函数名称,应该简洁明了,使用 snake_casedescription:函数描述,这是模型决定是否调用的关键依据,要写清楚函数的用途parameters:使用 JSON Schema 定义参数,包括类型、描述、枚举值、必填项等strict:设为 true 可启用严格模式,保证参数完全符合 schema
tool_choice 选项:
| 值 | 说明 |
|---|---|
auto | 模型自动决定是否调用工具(默认) |
none | 禁止调用工具 |
required | 强制调用工具 |
{"type": "function", "function": {"name": "xxx"}} | 强制调用指定工具 |
工具调用响应
当模型决定调用工具时,响应中会包含 tool_calls 字段:
{
"choices": [
{
"message": {
"role": "assistant",
"content": null,
"tool_calls": [
{
"id": "call_abc123",
"type": "function",
"function": {
"name": "get_weather",
"arguments": "{\"location\": \"Beijing\", \"unit\": \"celsius\"}"
}
}
]
},
"finish_reason": "tool_calls"
}
]
}
注意事项:
content通常为 null(模型选择调用工具而非直接回复)arguments是 JSON 字符串,需要解析id是工具调用的唯一标识,返回结果时需要引用- 模型可能同时调用多个工具(并行调用)
返回工具结果
执行工具后,需要将结果以 tool 角色的消息返回给模型:
{
"messages": [
{"role": "user", "content": "What's the weather in Beijing?"},
{
"role": "assistant",
"content": null,
"tool_calls": [{"id": "call_abc123", "type": "function", "function": {"name": "get_weather", "arguments": "{\"location\": \"Beijing\"}"}}]
},
{
"role": "tool",
"tool_call_id": "call_abc123",
"content": "{\"temperature\": 22, \"condition\": \"sunny\"}"
}
]
}
关键点:
tool_call_id必须与之前的id匹配content是工具执行的结果,通常是 JSON 字符串- 如果有多个工具调用,需要为每个调用返回对应的结果
- 模型会根据工具结果生成最终的自然语言回复
JSON Mode
JSON Mode 强制模型输出有效的 JSON 格式,这在需要结构化数据的场景非常有用,如信息提取、数据转换、API 响应生成等。
为什么需要 JSON Mode?
默认情况下,模型可能输出:
- 带有 markdown 代码块的 JSON(
json ...) - 格式不完整的 JSON
- 混合文本和 JSON 的内容
JSON Mode 保证输出是纯净的、可直接解析的 JSON。
启用 JSON 输出
{
"model": "gpt-4o",
"messages": [
{"role": "system", "content": "Output valid JSON only."},
{"role": "user", "content": "List 3 colors"}
],
"response_format": {"type": "json_object"}
}
重要提示: 使用 JSON Mode 时,必须在 system 或 user 消息中明确提到 “JSON”,否则可能报错。
Structured Outputs(结构化输出)
Structured Outputs 是 JSON Mode 的增强版,不仅保证输出是 JSON,还保证输出符合指定的 JSON Schema。这是 2024 年 8 月引入的重要功能。
{
"model": "gpt-4o-2024-08-06",
"messages": [{"role": "user", "content": "List 3 colors with hex codes"}],
"response_format": {
"type": "json_schema",
"json_schema": {
"name": "colors",
"schema": {
"type": "object",
"properties": {
"colors": {
"type": "array",
"items": {
"type": "object",
"properties": {
"name": {"type": "string"},
"hex": {"type": "string"}
},
"required": ["name", "hex"]
}
}
},
"required": ["colors"]
}
}
}
}
Structured Outputs 的优势:
| 特性 | JSON Mode | Structured Outputs |
|---|---|---|
| 保证有效 JSON | ✅ | ✅ |
| 保证符合 Schema | ❌ | ✅ |
| 类型安全 | ❌ | ✅ |
| 必填字段保证 | ❌ | ✅ |
使用建议:
- 简单场景使用 JSON Mode 即可
- 需要严格数据结构时使用 Structured Outputs
- Structured Outputs 需要
gpt-4o-2024-08-06或更新的模型 - Schema 中的所有字段默认都是 required,需要显式设置
required数组
完整示例
cURL
curl https://api.openai.com/v1/chat/completions \
-H "Content-Type: application/json" \
-H "Authorization: Bearer $OPENAI_API_KEY" \
-d '{
"model": "gpt-4o",
"messages": [
{"role": "system", "content": "You are a helpful assistant."},
{"role": "user", "content": "Hello!"}
],
"temperature": 0.7,
"max_tokens": 1000
}'
Python
from openai import OpenAI
client = OpenAI()
response = client.chat.completions.create(
model="gpt-4o",
messages=[
{"role": "system", "content": "You are a helpful assistant."},
{"role": "user", "content": "Hello!"}
],
temperature=0.7,
max_tokens=1000
)
print(response.choices[0].message.content)
Python 流式
from openai import OpenAI
client = OpenAI()
stream = client.chat.completions.create(
model="gpt-4o",
messages=[{"role": "user", "content": "Write a haiku"}],
stream=True
)
for chunk in stream:
if chunk.choices[0].delta.content:
print(chunk.choices[0].delta.content, end="")
Node.js
import OpenAI from 'openai';
const openai = new OpenAI();
const response = await openai.chat.completions.create({
model: 'gpt-4o',
messages: [
{ role: 'system', content: 'You are a helpful assistant.' },
{ role: 'user', content: 'Hello!' }
],
temperature: 0.7,
max_tokens: 1000
});
console.log(response.choices[0].message.content);
错误处理
正确处理 API 错误是构建健壮应用的关键。OpenAI API 使用标准的 HTTP 状态码,并在响应体中提供详细的错误信息。
常见错误码
| 状态码 | 说明 |
|---|---|
| 400 | 请求格式错误 |
| 401 | API Key 无效 |
| 403 | 无权限访问 |
| 429 | 速率限制 |
| 500 | 服务器错误 |
| 503 | 服务过载 |
错误码详解:
400 Bad Request 请求格式有问题,常见原因:
- JSON 格式错误
- 缺少必需参数
- 参数类型错误
- 模型名称不存在
401 Unauthorized 认证失败,常见原因:
- API Key 错误或过期
- API Key 格式不正确
- 未设置 Authorization 头
403 Forbidden 权限不足,常见原因:
- 账户未开通某模型的访问权限
- 组织/项目权限限制
- 地区限制
429 Too Many Requests 触发速率限制,常见原因:
- 请求频率过高(RPM 限制)
- Token 使用量过大(TPM 限制)
- 并发请求过多
500/503 Server Error 服务端问题,通常是临时性的,建议重试。
错误响应格式
{
"error": {
"message": "Invalid API Key",
"type": "invalid_request_error",
"param": null,
"code": "invalid_api_key"
}
}
错误字段说明:
message:人类可读的错误描述type:错误类型分类param:导致错误的参数名(如果适用)code:机器可读的错误代码
错误处理最佳实践
from openai import OpenAI, APIError, RateLimitError, AuthenticationError
client = OpenAI()
try:
response = client.chat.completions.create(
model="gpt-4o",
messages=[{"role": "user", "content": "Hello"}]
)
except AuthenticationError:
print("API Key 无效,请检查配置")
except RateLimitError:
print("触发速率限制,请稍后重试")
except APIError as e:
print(f"API 错误: {e.message}")
模型列表
OpenAI 提供多种模型,各有特点和适用场景。选择合适的模型对于平衡性能和成本至关重要。
| 模型 | 上下文窗口 | 特点 | 适用场景 |
|---|---|---|---|
| gpt-4o | 128K | 最新旗舰,多模态 | 复杂任务、图像理解 |
| gpt-4o-mini | 128K | 快速经济 | 简单对话、高并发 |
| gpt-4-turbo | 128K | GPT-4 增强版 | 需要 GPT-4 能力但更快 |
| gpt-4 | 8K/32K | 原版 GPT-4 | 兼容旧代码 |
| gpt-3.5-turbo | 16K | 快速经济型 | 成本敏感场景 |
| o1 | 200K | 深度推理 | 数学、编程、复杂逻辑 |
| o1-mini | 128K | 轻量推理 | 需要推理但成本敏感 |
模型持续更新,请查阅 OpenAI Models 获取最新列表。
模型详解
GPT-4o(推荐)
GPT-4o 是 OpenAI 当前的旗舰模型,“o” 代表 “omni”(全能)。它原生支持多模态输入(文本、图像),响应速度比 GPT-4 Turbo 快 2 倍,价格更低。对于大多数应用场景,GPT-4o 是最佳选择。
GPT-4o-mini
GPT-4o 的轻量版本,在保持较高质量的同时大幅降低成本。适合简单对话、内容分类、数据提取等不需要最强能力的场景。性价比极高。
o1 系列(推理模型)
o1 是 OpenAI 的推理模型,专门针对需要深度思考的任务优化。它会在回答前进行”思考”,适合数学证明、代码调试、复杂逻辑推理等场景。但响应时间较长,成本较高。
GPT-3.5-turbo
老一代模型,速度快、成本低,但能力明显弱于 GPT-4 系列。仍然适合一些简单场景,但建议新项目直接使用 GPT-4o-mini。
模型选择建议
简单对话/高并发 → gpt-4o-mini
通用任务 → gpt-4o
复杂推理/数学 → o1 / o1-mini
图像理解 → gpt-4o
成本优先 → gpt-3.5-turbo
选择决策树:
flowchart TD
A[选择模型] --> B{需要图像理解?}
B -->|是| C[gpt-4o]
B -->|否| D{需要深度推理?}
D -->|是| E{预算充足?}
E -->|是| F[o1]
E -->|否| G[o1-mini]
D -->|否| H{任务复杂度?}
H -->|高| C
H -->|中| I[gpt-4o-mini]
H -->|低| J[gpt-3.5-turbo]最佳实践
1. 系统提示词设计
{
"role": "system",
"content": "你是一个专业的技术文档助手。回答要求:1. 简洁准确 2. 提供代码示例 3. 使用中文"
}
2. 控制输出长度
- 设置合理的
max_tokens避免浪费 - 在 system prompt 中明确要求”简洁回答”
3. 处理长对话
- 定期总结历史对话,压缩 context
- 只保留最近 N 轮对话
- 使用
tiktoken库计算 token 数量
4. 错误重试策略
import time
from openai import RateLimitError
def call_with_retry(func, max_retries=3):
for i in range(max_retries):
try:
return func()
except RateLimitError:
wait_time = 2 ** i # 指数退避
time.sleep(wait_time)
raise Exception("Max retries exceeded")
相关指南
官方文档
- API Reference: https://platform.openai.com/docs/api-reference/chat
- Text Generation Guide: https://platform.openai.com/docs/guides/text-generation
- Function Calling: https://platform.openai.com/docs/guides/function-calling
- Structured Outputs: https://platform.openai.com/docs/guides/structured-outputs