OpenAI API 接口对接完全教程 / 03 - Chat Completions API
第 03 章 · Chat Completions API
Chat Completions 是 OpenAI 最核心的 API。本章详解消息格式、系统提示词、参数调优和多轮对话实现。
3.1 API 端点与基本调用
POST https://api.openai.com/v1/chat/completions
最简请求
from openai import OpenAI
client = OpenAI()
response = client.chat.completions.create(
model="gpt-4o-mini",
messages=[
{"role": "user", "content": "用一句话解释量子计算"}
]
)
print(response.choices[0].message.content)
3.2 消息格式详解
角色 (Role) 类型
| 角色 | 作用 | 必须性 |
|---|---|---|
system | 设定 AI 行为、性格、规则 | 可选但强烈推荐 |
user | 用户输入 | 必须 |
assistant | AI 的历史回复 | 用于多轮对话 |
tool | 工具调用的返回结果 | Function Calling 时使用 |
developer | 开发者指令(新格式) | 替代 system,优先级更高 |
System Prompt 设计
response = client.chat.completions.create(
model="gpt-4o",
messages=[
{
"role": "system",
"content": """你是一个专业的技术文档翻译助手。
规则:
1. 将用户提供的英文技术文档翻译为中文
2. 保留所有代码块、变量名、函数名不翻译
3. 技术术语首次出现时标注英文原文,如:向量嵌入(Embedding)
4. 使用 Markdown 格式输出
5. 如果原文有歧义,在括号中注明可能的含义"""
},
{
"role": "user",
"content": "Translate: An embedding is a vector representation of data."
}
]
)
多轮对话消息结构
messages = [
{"role": "system", "content": "你是一个友好的旅行顾问。"},
{"role": "user", "content": "我想去日本旅游,有什么建议?"},
{"role": "assistant", "content": "日本是个很棒的选择!请问您计划什么时间去?"},
{"role": "user", "content": "明年春天,大概3月底。"},
{"role": "assistant", "content": "3月底正是赏樱的好时节!推荐东京、京都..."},
{"role": "user", "content": "预算大概多少合适?"},
]
3.3 核心参数详解
完整参数列表
response = client.chat.completions.create(
model="gpt-4o", # 模型名称
messages=messages, # 消息列表
max_tokens=1000, # 最大输出 token 数
temperature=0.7, # 随机性 (0-2)
top_p=0.9, # 核采样 (0-1)
n=1, # 生成几个候选回复
stop=["\n\n", "END"], # 停止词
presence_penalty=0.0, # 主题新颖度 (-2 to 2)
frequency_penalty=0.0, # 重复惩罚 (-2 to 2)
logit_bias={}, # token 偏置
user="user-123", # 用户标识(用于追踪)
seed=42, # 随机种子(可复现结果)
response_format={"type": "json_object"}, # 输出格式
)
参数调优指南
temperature vs top_p
| 参数 | 低值效果 | 高值效果 | 适用场景 |
|---|---|---|---|
temperature | 0 → 确定性输出 | 2 → 高随机性 | 创意写作用 0.7-1.0,代码/数据用 0-0.3 |
top_p | 0.1 → 只考虑高概率词 | 1.0 → 考虑所有词 | 通常保持 1.0,只调 temperature |
建议:一般只调整其中一个,不要同时调两个。
调参实战对比
import json
# 事实性任务:低 temperature
factual = client.chat.completions.create(
model="gpt-4o-mini",
messages=[{"role": "user", "content": "水的化学式是什么?"}],
temperature=0.0, # 最确定性的回答
)
# 创意任务:高 temperature
creative = client.chat.completions.create(
model="gpt-4o-mini",
messages=[{"role": "user", "content": "写一个关于机器人的创意故事开头"}],
temperature=1.2, # 更有创意和随机性
)
presence_penalty vs frequency_penalty
# 场景:生成多样性内容(如头脑风暴)
brainstorm = client.chat.completions.create(
model="gpt-4o",
messages=[{"role": "user", "content": "列出10个创业点子"}],
presence_penalty=1.5, # 鼓励新话题
frequency_penalty=0.5, # 减少重复用词
)
# 场景:技术文档(需要精确一致的术语)
docs = client.chat.completions.create(
model="gpt-4o",
messages=[{"role": "user", "content": "解释RESTful API设计原则"}],
presence_penalty=0.0,
frequency_penalty=0.0, # 允许术语一致
)
3.4 响应对象结构
# 完整的响应对象结构
response = client.chat.completions.create(...)
# 顶层字段
print(response.id) # "chatcmpl-abc123"
print(response.object) # "chat.completion"
print(response.created) # 1717000000 (Unix 时间戳)
print(response.model) # "gpt-4o-2024-08-06"
# Choices 列表
for choice in response.choices:
print(choice.index) # 0
print(choice.message.role) # "assistant"
print(choice.message.content) # 回复文本
print(choice.finish_reason) # "stop" | "length" | "tool_calls"
# Token 用量
usage = response.usage
print(usage.prompt_tokens) # 输入 token 数
print(usage.completion_tokens) # 输出 token 数
print(usage.total_tokens) # 总 token 数
finish_reason 含义
| 值 | 含义 | 处理方式 |
|---|---|---|
stop | 正常结束 | 直接使用结果 |
length | 达到 max_tokens 截断 | 考虑增大 max_tokens 或分段 |
tool_calls | 需要调用工具 | 执行工具调用后继续 |
content_filter | 内容被过滤 | 检查输入内容 |
3.5 多轮对话管理
完整对话类
from openai import OpenAI
class ChatSession:
"""多轮对话会话管理"""
def __init__(self, model: str = "gpt-4o-mini", system_prompt: str = ""):
self.client = OpenAI()
self.model = model
self.messages: list[dict] = []
if system_prompt:
self.messages.append({"role": "system", "content": system_prompt})
self.history_limit = 20 # 保留最近 N 轮
def chat(self, user_input: str) -> str:
"""发送消息并获取回复"""
self.messages.append({"role": "user", "content": user_input})
# 裁剪历史,避免超出上下文窗口
trimmed = self._trim_messages()
response = self.client.chat.completions.create(
model=self.model,
messages=trimmed,
max_tokens=1000,
temperature=0.7,
)
reply = response.choices[0].message.content
self.messages.append({"role": "assistant", "content": reply})
return reply
def _trim_messages(self) -> list[dict]:
"""裁剪消息历史,保留 system + 最近 N 轮"""
if len(self.messages) <= self.history_limit:
return self.messages
# 保留 system prompt(如果有)
system_msgs = [m for m in self.messages if m["role"] == "system"]
other_msgs = [m for m in self.messages if m["role"] != "system"]
# 保留最近的消息
recent = other_msgs[-(self.history_limit - len(system_msgs)):]
return system_msgs + recent
def reset(self):
"""重置对话(保留 system prompt)"""
system_msgs = [m for m in self.messages if m["role"] == "system"]
self.messages = system_msgs
# 使用示例
session = ChatSession(
model="gpt-4o-mini",
system_prompt="你是一个Python编程导师,用简洁的方式教学。"
)
while True:
user_input = input("你: ")
if user_input.lower() in ["exit", "quit", "退出"]:
break
reply = session.chat(user_input)
print(f"AI: {reply}\n")
3.6 JSON 模式输出
强制 JSON 输出
response = client.chat.completions.create(
model="gpt-4o-mini",
messages=[
{"role": "system", "content": "你是一个数据提取助手,以JSON格式输出。"},
{"role": "user", "content": "从这段文字中提取人名和年龄:小明今年25岁,他的朋友小红23岁。"}
],
response_format={"type": "json_object"},
temperature=0.0,
)
import json
data = json.loads(response.choices[0].message.content)
print(json.dumps(data, ensure_ascii=False, indent=2))
输出示例:
{
"people": [
{"name": "小明", "age": 25},
{"name": "小红", "age": 23}
]
}
结构化输出 (Structured Outputs)
from pydantic import BaseModel
class PersonInfo(BaseModel):
name: str
age: int
occupation: str
class ExtractionResult(BaseModel):
people: list[PersonInfo]
response = client.beta.chat.completions.parse(
model="gpt-4o-mini",
messages=[
{"role": "user", "content": "小明是25岁的程序员,小红是23岁的设计师。"}
],
response_format=ExtractionResult,
)
result = response.choices[0].message.parsed
print(result.people[0].name) # 小明
print(result.people[0].age) # 25
3.7 业务场景
场景一:智能客服
customer_service_prompt = """你是XX公司的客服助手。
规则:
1. 语气友好、专业
2. 只回答与公司产品相关的问题
3. 如果不确定,告知用户将转接人工客服
4. 不要编造不存在的产品信息
5. 每次回复不超过100字
公司产品:
- 云服务器 ECS:弹性计算服务
- 对象存储 OSS:海量数据存储
- CDN:内容分发网络"""
session = ChatSession(system_prompt=customer_service_prompt)
reply = session.chat("你们的云服务器最低配置多少钱?")
场景二:代码审查助手
code_review_prompt = """你是一个资深代码审查专家。
对用户提交的代码进行审查,关注:
1. 潜在的 Bug 和安全漏洞
2. 性能问题
3. 代码规范和可读性
4. 建议改进方案
输出格式:先指出问题,再给出修改建议和示例代码。"""
3.8 注意事项
- 上下文窗口:输入 + 输出总 token 不能超过模型限制
- system prompt 位置:建议放在消息列表最前面
- temperature 设置:生产环境建议 0-0.3,保证稳定性
- max_tokens:务必设置,防止意外的长回复产生高额费用
- 并发安全:同一会话的多轮对话需要保证消息顺序
- 中文 token 效率:中文约 1-2 字/token,英文约 4 字符/token
3.9 扩展阅读
下一章:04 - 流式响应处理 — 实现打字机效果的流式输出。