强曰为道
与天地相似,故不违。知周乎万物,而道济天下,故不过。旁行而不流,乐天知命,故不忧.
文档目录

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 注意事项

  1. 上下文窗口:输入 + 输出总 token 不能超过模型限制
  2. system prompt 位置:建议放在消息列表最前面
  3. temperature 设置:生产环境建议 0-0.3,保证稳定性
  4. max_tokens:务必设置,防止意外的长回复产生高额费用
  5. 并发安全:同一会话的多轮对话需要保证消息顺序
  6. 中文 token 效率:中文约 1-2 字/token,英文约 4 字符/token

3.9 扩展阅读


下一章04 - 流式响应处理 — 实现打字机效果的流式输出。