跳转到内容
API 入口

Cookbook

OpenAI API 流式输出示例

OpenAI API 流式输出示例讲清 stream true、SSE、Responses、Chat Completions、Python、JavaScript、curl、前端展示和中断处理。

预计阅读
7 分钟
最近更新
2026/07/03
维护方式
人工编辑

流式输出适合聊天界面、长文生成、命令行工具和实时写作场景。它的价值不是让 模型“算得更快”,而是让用户更早看到文本片段,页面不必等完整响应返回后才开 始展示。

本文示例基于 OpenAI-compatible API 写法。使用 OfApp.cn 时,Base URL 可配置 为 https://api.ofapp.cn/v1,真实模型名、速率限制、流式事件支持和费用请以 OfApp.cn 控制台或官方文档为准。

项目 内容
阅读时间 约 7 分钟
更新时间 2026-07-03
适合场景 聊天界面、AI 写作、命令行助手、长文生成、实时摘要、代码助手和前端实时展示
核心问题 如何把 stream: true 从“能输出片段”做成可取消、可保存、可排错的产品体验
你会完成 curl 流式验证、JavaScript 与 Python 读取增量、Responses 事件处理、前端展示状态和中断处理清单
边界提醒 OfApp.cn 官方文档展示了 OpenAI 兼容端点和 stream 相关写法;具体模型、价格、额度、套餐、流式事件和速率限制请以 OfApp.cn 控制台或官方文档为准

普通请求会等模型生成完整结果后再返回。流式输出会把响应拆成多个事件或片段 逐步返回,应用可以边接收边展示。

对比项 非流式请求 流式请求
用户感受 等完整结果返回 更早看到首段内容
返回结构 一个完整 JSON 多个事件或 chunk
代码复杂度 需要处理空片段、结束事件和中断
适合场景 短答案、后台任务、批处理 聊天、长文、终端实时输出
保存方式 直接保存完整文本 展示片段,同时拼接完整 buffer

OpenAI 文档说明,Chat Completions 开启 stream: true 后会返回数据流事件; 流式 chunk 中读取的是 delta,不是非流式响应里的完整 message

非流式验证开启 stream读取事件更新界面保存 buffer处理中断Key URL Modelstream: trueSSE / chunk增量渲染完整文本重试与提示流式失败时先回到非流式请求,再查代理、超时和事件解析

OpenAI 迁移文档说明,Responses API 是新的接口形态,Chat Completions 仍被支 持。放到 OpenAI 兼容服务里,还要看服务商当前是否支持对应端点和流式事件。

场景 优先路径 原因
新项目、代理式流程 Responses API 输入、输出和事件结构更统一
旧项目、现有客户端 Chat Completions 兼容 messageschoices 结构
只想验证流式展示 服务商明确支持的端点 先让 UI 跑通,再评估迁移
客户端只支持 OpenAI Chat 格式 Chat Completions 工具协议比接口偏好更重要

建议调试顺序:非流式 Chat 或 Responses 成功后,再打开 stream: true。如果 非流式都失败,流式错误只会增加排查噪声。

不要因为界面看起来“实时”就默认所有任务都要流式。流式输出会提升等待体验,也会带来事件解析、中断恢复和前端状态管理成本。

任务 是否适合流式 先验证什么 主要风险
聊天界面 适合 非流式成功后,用 curl -N 验证增量返回 代理缓冲、空片段、用户取消
长文写作 适合 前端能边显示边拼接完整 fullText 只显示片段,没有保存最终文本
命令行助手 适合 终端能逐段打印,错误能落到 stderr 或日志 中断后不知道已生成内容是否完整
批处理任务 通常不优先 非流式结果稳定、错误可重试 片段过多,日志和重试复杂
数据分类 通常不优先 输出格式稳定,能整体验证 JSON 或标签 流式中途失败导致半个结构
前端演示原型 适合小范围验证 停止按钮、超时提示和回退非流式 把真实 Key 放进浏览器

如果任务目标是生成一个必须完整解析的结构化结果,非流式往往更容易验收。如果目标是改善用户等待体验,流式才值得单独设计。

Terminal window
export OPENAI_BASE_URL="https://api.ofapp.cn/v1"
export OPENAI_API_KEY="sk-xxxx"
export OPENAI_MODEL="以 OfApp.cn 控制台可用模型为准"

不要把真实 Key 写进前端代码、GitHub Actions 日志、README 截图或浏览器控制 台。前端页面应调用自己的服务端接口,由服务端再请求 OpenAI 兼容接口。

curl -N 可以关闭缓冲,更容易观察服务端是否逐块返回。调试时先跑非流式, 再把 stream 改成 true

Terminal window
curl -N "$OPENAI_BASE_URL/chat/completions" \
-H "Authorization: Bearer $OPENAI_API_KEY" \
-H "Content-Type: application/json" \
-d "{
\"model\": \"$OPENAI_MODEL\",
\"messages\": [
{\"role\":\"user\",\"content\":\"用三句话解释流式输出。\"}
],
\"stream\": true
}"

如果终端一次性吐出全部内容,可能是服务端不支持流式、代理发生缓冲、终端或 网络层没有按事件流展示。此时再看 SDK 代码意义不大,先排查请求链路。

这段适合 Node.js 服务端、CLI 工具和后端接口。它读取 choices[0].delta.content,并把每个片段写到终端。

import OpenAI from "openai";
const client = new OpenAI({
apiKey: process.env.OPENAI_API_KEY,
baseURL: process.env.OPENAI_BASE_URL,
});
const stream = await client.chat.completions.create({
model: process.env.OPENAI_MODEL,
messages: [
{ role: "user", content: "用三句话解释流式输出。" },
],
stream: true,
});
let fullText = "";
for await (const chunk of stream) {
const text = chunk.choices[0]?.delta?.content ?? "";
if (!text) continue;
fullText += text;
process.stdout.write(text);
}
console.log("\n\n完整文本:", fullText);

上线时不要只把片段写到屏幕。还要把完整文本拼成 fullText,用于保存、审计 和失败后的提示。

Python 适合脚本、后台任务、数据整理和命令行助手。

import os
from openai import OpenAI
client = OpenAI(
api_key=os.environ["OPENAI_API_KEY"],
base_url=os.environ["OPENAI_BASE_URL"],
)
stream = client.chat.completions.create(
model=os.environ["OPENAI_MODEL"],
messages=[
{"role": "user", "content": "用三句话解释流式输出。"},
],
stream=True,
)
full_text = ""
for chunk in stream:
text = chunk.choices[0].delta.content
if text is None:
continue
full_text += text
print(text, end="", flush=True)
print("\n\n完整文本:", full_text)

生产脚本还应加入超时、有限重试和日志脱敏。不要把完整用户材料、真实 Key 或 未脱敏响应写进日志。

Responses API 的流式返回是事件流。OpenAI 文档列出的常见文本事件包括 response.createdresponse.output_text.deltaresponse.completederror。兼容服务可能只实现其中一部分,接入前要用真实账号测试。

const stream = await client.responses.create({
model: process.env.OPENAI_MODEL,
input: "用三句话解释流式输出。",
stream: true,
});
let fullText = "";
for await (const event of stream) {
if (event.type === "response.output_text.delta") {
fullText += event.delta;
process.stdout.write(event.delta);
}
if (event.type === "error") {
throw new Error(event.message ?? "stream error");
}
}

如果 Responses 非流式可用,但流式事件缺失,可以先用 Chat Completions 流式 完成界面验证,再回到 Responses 做能力评估。

流式输出的核心不是只监听一个文本字段,而是把生命周期事件、空片段和错误都纳入状态机。

处理点 应用应该做什么 没处理时会怎样
开始事件 标记 isStreaming = true,禁用重复提交 用户连续点击导致重复请求
文本增量 把片段追加到可见文本和完整 buffer 页面能显示,但最终内容保存不完整
空片段 忽略或记录调试信息,不当作失败 错误提示乱跳,用户以为生成失败
完成事件 标记结束,保存完整文本,恢复输入框 loading 一直存在,用户不知道是否完成
错误事件 展示可理解提示,保存已接收内容 一次网络抖动就丢失全部草稿
用户取消 关闭连接,说明内容可能不完整 后端仍在生成,前端状态失真
超时 主动结束请求,允许用户重试或切换非流式 页面一直等待,体验像卡死

OpenAI 文档中 Responses 常见文本流事件包括 response.createdresponse.output_text.deltaresponse.completederror。Chat Completions 流式通常读取 choices[0].delta.content。放到兼容服务里,每个事件名和字段都要以服务商当前文档和真实账号测试为准。

前端不要直接请求 OpenAI 兼容接口。推荐结构是:

层级 职责 注意
浏览器 展示增量文本、取消请求、提示重试 不保存 API Key
服务端接口 持有 Key、转发流、记录脱敏日志 处理超时和取消
模型服务 返回 SSE 或 chunk 能力以当前文档和实测为准

前端状态建议分开维护:

状态 用途
visibleText 用户当前看到的增量内容
fullText 最终保存或复制的完整文本
isStreaming 控制 loading、停止按钮和输入框
streamError 展示中断、超时或解析失败

不要在每个字符到来时都做重排很重的操作。可以按句子、段落或小批量刷新,避 免长文输出时页面卡顿。

流式请求比非流式更容易暴露网络、代理和前端解析问题。上线前至少处理这些情 况:

现象 可能原因 处理方式
非流式成功,流式失败 代理缓冲、SSE 不通、端点不支持 curl -N 验证,检查网关设置
输出一半停止 超时、用户取消、网络中断 保存已接收文本,提示重新生成或继续补写
内容重复 自动重试了不可幂等请求 重试前让用户确认,或使用任务状态去重
页面乱码 把字节流当普通字符串拼接 使用正确的事件流解析和 UTF-8 处理
最终内容丢失 只更新 UI,没有保存 buffer 展示和保存分开维护
线上失败,本地正常 CDN、Serverless、反向代理差异 检查超时、缓冲和响应头

更多中断排查可以看 streaming interrupted

检查项 通过标准
非流式最小请求 同一 Key、Base URL、模型名能稳定返回
curl -N 终端能逐块看到事件或 chunk
SDK 读取 JavaScript 或 Python 能读取增量文本
前端代理 API Key 只在服务端,不进入浏览器
状态管理 UI 展示和完整保存各自有状态
取消操作 用户关闭页面或点击停止时能正确结束请求
中断提示 告知已生成内容是否完整,提供重试入口
日志脱敏 记录状态码、耗时、错误摘要,不记录完整 Key
回退方案 流式失败时可切回非流式或提示稍后重试

流式输出会减少总生成时间吗?

Section titled “流式输出会减少总生成时间吗?”

不一定。它主要减少首字等待时间,让用户更早看到部分输出。总耗时仍取决于模 型、输入长度、网络和服务状态。

Chat Completions 流式和 Responses 流式有什么区别?

Section titled “Chat Completions 流式和 Responses 流式有什么区别?”

Chat Completions 通常读取 choices[0].delta.content。Responses 流式更像事 件流,需要按 event.type 处理,例如文本增量、完成事件和错误事件。

OfApp.cn 一定支持所有流式事件吗?

Section titled “OfApp.cn 一定支持所有流式事件吗?”

本文不承诺具体事件覆盖。OfApp.cn 官方文档展示了多个 OpenAI 兼容端点;模型 能力、流式事件、速率限制和价格请以 OfApp.cn 控制台或官方文档为准。

可以做有限重试,但不要无脑重提不可幂等任务。聊天生成可以让用户选择重新生 成;涉及写入、付款、发送消息或外部动作的任务必须先确认状态。

浏览器可以直接连 OpenAI 兼容接口吗?

Section titled “浏览器可以直接连 OpenAI 兼容接口吗?”

不建议。浏览器会暴露 API Key。正确做法是浏览器连接你自己的服务端接口,由 服务端持有 Key 并转发流式响应。

流式 chunk 可能只携带 role、结束标记或其他元数据。读取时要允许空片段,不 要把空片段当成错误。

把 OpenAI API 流式输出做稳定,关键不只是加上 stream: true。更可靠的接入 路径是:用非流式请求确认 Key、Base URL 和模型可用;再用 curl -N 验证真实 事件流;接着在 SDK 里拼接完整文本;上线前补齐取消、超时、错误提示和日志脱 敏。

如果希望用 OpenAI 兼容方式快速验证本文流程,可以参考 OfApp.cn API 直转文 档。真实模型、价格、额度、套餐和流式事件请以 OfApp.cn 控制台或官方文档为 准。