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

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用户输入必须
assistantAI 的历史回复用于多轮对话
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

参数低值效果高值效果适用场景
temperature0 → 确定性输出2 → 高随机性创意写作用 0.7-1.0,代码/数据用 0-0.3
top_p0.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 - 流式响应处理 — 实现打字机效果的流式输出。