文档
如何使用 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 的价格完全相同。改变的只是传输方式:边生成边分块返回,而不是最后一次性返回。