跳到主要内容
ChatGPT API
文档

文档

如何使用 ChatGPT API

最后更新:

发出第一个请求很简单,难的是之后:如何让模型记住上下文、遇到 429 怎么办、哪些参数会推高账单。本文汇总了第一个请求跑通之后你需要知道的一切。

一个请求由什么组成

请求是一个消息数组。每条消息都有角色,模型按顺序读取。角色决定了模型把什么当作指令,把什么当作对话。

system
约束整段对话的指令:语气、输出格式、限制条件。放在最前面,且在各轮之间保持不变。
user
用户的消息,也就是模型当前要回答的内容。
assistant
模型此前的回复。正是它们让模型记得自己说过什么。
请求结构
curl https://api.llm-gate.tech/v1/chat/completions \
  -H "Authorization: Bearer $CHATGPT_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "model": "gpt-6.1-sol",
    "messages": [
      { "role": "system", "content": "Отвечай кратко, по-русски." },
      { "role": "user", "content": "Что такое токен?" }
    ]
  }'

如何进行多轮对话

API 不保存状态。模型不会记得上一次调用的任何内容,因此每次都要重新发送整段对话:系统指令、此前所有轮次,以及新的问题。模型的回复需要你自己追加到数组中,否则下一步它就看不到。

两轮对话
messages = [
    {"role": "system", "content": "Отвечай кратко, по-русски."},
    {"role": "user", "content": "Что такое токен?"},
    # ответ модели возвращаем обратно в массив
    {"role": "assistant", "content": "Токен это кусок текста примерно в 4 символа."},
    {"role": "user", "content": "А сколько их в слове «программирование»?"},
]

response = client.chat.completions.create(
    model="gpt-6.1-sol",
    messages=messages,
    max_completion_tokens=300,
)

历史越长,账单越高:每次请求都要为全部输入 token 付费。对话很长时,请裁剪旧轮次或将其压缩为简短摘要。

流式输出:边生成边返回

默认情况下,模型说完后答案才整体返回。对于长回答,这看起来就像卡住几十秒。开启流式后,文本会立刻分块到达,就像 ChatGPT 网页版那样。

开启流式输出
stream = client.chat.completions.create(
    model="gpt-6.1-sol",
    messages=messages,
    stream=True,
)

for chunk in stream:
    delta = chunk.choices[0].delta.content
    if delta:
        print(delta, end="", flush=True)
  • 有人盯着屏幕等待的聊天界面
  • 长输出:文章、代码、详细分析
  • 后台任务不需要:分类、字段抽取、定时作业

真正重要的参数

参数不止这些,但实际会动的就这四个。其余只在少数场景下才有意义。

参数作用何时调整
model选择模型成本与质量的主要杠杆。先用便宜的,不够再往上
max_completion_tokens限制回答长度务必设置:避免意外的超长高价回复
temperature措辞的随机程度事实和代码调低,文案和创意调高
stream分块返回答案只要有人在等待就开启

错误及其含义

状态码能说明问题出在谁那里,以及重试是否有用。这些错误一半能靠重试解决,一半永远不行。

状态码原因与处理
401密钥错误或缺失。检查 Authorization 头和密钥本身。重试无用
404找不到模型。对照我们的模型列表核对拼写。重试无用
429触发速率限制。暂停后重试,并逐次延长等待时间
5xx服务端故障。暂停后重试,通常会恢复
超时未在规定时间内返回。调高客户端超时:带推理的长回答耗时更久

带退避的重试

立刻重试没有意义:遇到速率限制只会拿到同样的错误并消耗配额。每次重试都延长等待时间,并限制重试次数。官方 SDK 自带这一机制;若直接调用 API,可参考下面的写法。

带退避的重试
import time

for attempt in range(5):
    try:
        response = client.chat.completions.create(
            model="gpt-6.1-sol",
            messages=messages,
            max_completion_tokens=300,
        )
        break
    except Exception:
        if attempt == 4:
            raise
        time.sleep(2 ** attempt)  # 1, 2, 4, 8 секунд

如何控制账单

账单取决于 token 数量,而不是请求次数。以下四点带来主要的节省。

限制回答长度

不设 max_completion_tokens,模型可能一路写到长度上限,而这笔钱由你买单。一个参数就能消除最糟的情况。

不要重发多余的历史

每次请求都要为整个消息数组付费。对话很长时,裁剪旧轮次或用摘要替代。

把提示词中稳定的部分放在前面

重复的前缀会进入缓存,价格只有普通输入的一小部分。把变化的数据放在最后。

按任务选模型

分类和字段抽取没必要跑在旗舰上:同样的结果,价格差距可达一百倍。

常见问题

模型为什么不记得之前的消息?+

因为 API 不保存状态。每个请求都从零处理,模型对这段对话的全部认知都来自你传入的 messages 数组。请把它此前的回答以 assistant 角色追加进去。

遇到 429 怎么办?+

这是速率限制。暂停后重试,并逐次延长等待:一秒、两秒、四秒。如果 429 持续出现,请降低请求频率或把负载分散到更长时间内。

使用你们的 API 需要改写代码吗?+

不需要。请求和响应格式与 OpenAI 一致,官方 SDK 只需替换 base URL 和密钥即可。本文所有示例对官方 API 和我们的 API 同样适用。

如何查看一次请求用了多少 token?+

响应中包含 usage 字段,列出输入和输出的 token 数。请把它记入日志:这是在账单到来之前了解钱花在哪里的唯一方式。

流式输出会更贵吗?+

不会,每 token 的价格完全相同。改变的只是传输方式:边生成边分块返回,而不是最后一次性返回。

下一步