流式输出
各协议的 server-sent events、流末尾的用量与费用、中途出错与取消请求。
每个对话模型都支持在全部四种协议上流式输出。在 Chat Completions、Responses 或 Messages 中设置 stream: true,在 Gemini 中调用 :streamGenerateContent。响应是一串 server-sent events,格式与你调用的协议一致。流以 token 用量结尾(Chat Completions 需要你主动要求);Chat Completions、Responses 和 Messages 的流还会带上本次请求的费用。
| 协议 | 事件 | 最后一个事件 |
|---|---|---|
| Chat Completions | data: {chat.completion.chunk} | data: [DONE] |
| Responses | response.created、response.output_text.delta…… | response.completed、response.incomplete 或 response.failed |
| Messages | message_start、content_block_delta、ping…… | message_stop |
| Gemini | data: {GenerateContentResponse} | 带有 usageMetadata 的那个数据块 |
通过 SDK 调用
import os
from openai import OpenAI
client = OpenAI(
base_url="https://api.ohmygpt.com/v1",
api_key=os.environ["OHMYGPT_API_KEY"],
)
stream = client.chat.completions.create(
model="ohmygpt/mock",
messages=[{"role": "user", "content": "ping"}],
stream=True,
)
for chunk in stream:
if chunk.choices and chunk.choices[0].delta.content:
print(chunk.choices[0].delta.content, end="", flush=True)与 OpenAI 一致,Chat Completions 的流只在设置了 "stream_options": {"include_usage": true} 时返回用量。用量放在最后一个数据块里,这个数据块的 choices 是空数组,所以取下标之前先检查 choices。
原始数据帧
设置了 stream_options.include_usage 时,Chat Completions 流的结尾:
data: {"id":"chatcmpl-ohmygpt-mock","object":"chat.completion.chunk","created":1793318400,"model":"mock","choices":[{"index":0,"delta":{},"finish_reason":"stop"}]}
data: {"id":"chatcmpl-ohmygpt-mock","object":"chat.completion.chunk","created":1793318400,"model":"mock","choices":[],"usage":{"prompt_tokens":29,"completion_tokens":17,"total_tokens":46}}
: x-cost-credits: 0
data: [DONE]Messages 流的结尾:
event: message_delta
data: {"delta":{"stop_reason":"end_turn","stop_sequence":null,"stop_details":null},"type":"message_delta","usage":{"input_tokens":33,"output_tokens":17}}
: x-cost-credits: 0
event: message_stop
data: {"type":"message_stop"}如果自己解析流,请逐行读取,跳过以 : 开头的行,解析 data: 之后的 JSON。在 Chat Completions 中,读到 data: [DONE] 即停止。
流式请求的费用
Chat Completions、Responses 和 Messages 的流会在最后一个事件之前,以一行 SSE 注释 : x-cost-credits: N 给出本次费用(单位为 Credits)。SDK 会跳过注释行,所以要拿到它,需要读取原始流。
对于任何请求,无论是否流式、使用哪种协议,都可以用响应头 X-Request-ID 查询费用:
curl https://api.ohmygpt.com/v1/generations/$REQUEST_ID \
-H "Authorization: Bearer $OHMYGPT_API_KEY"{
"object": "request_receipt",
"id": "01a19b55-f2f8-787b-941c-7e3e0bda2b0a",
"status": "succeeded",
"model": { "id": "google/gemini-3.1-flash-lite" },
"usage": { "input_tokens": 16, "output_tokens": 3, "reasoning_tokens": 118, "cache_read_tokens": 0, "cache_creation_tokens": 0 },
"cost": { "list_credits": 48, "credits": 43 }
}流式输出中途出错
第一个事件之前发生的错误,会以普通的 HTTP 错误返回。如果流已经以 200 开始、模型随后出错,流会以一个错误事件结束,格式与你调用的协议一致:
| 协议 | 最后一个事件 |
|---|---|
| Chat Completions | data: {"error": {...}} |
| Responses | event: response.failed,带有 response.error.code 和 response.error.message |
| Messages | event: error,内容为 {"type": "error", "error": {...}} |
| Gemini | data: {"error": {"code": ..., "status": ...}} |
出错之前收到的输出不完整,请重新发送请求。
取消请求
关闭连接即可停止流。生成随即停止,只按已经发给你的输出计费。