告别海外账号与网络限制稳定直连全球优质大模型限时半价接入中。 点击领取海量免费额度1. 先明确目标20 行 Python 脚本流式打印内容与 usage如果你正在用openai-python写对话类应用大概率会遇到两个需求一是希望模型边生成边返回前端能像打字机一样逐字显示二是希望拿到这次请求的 token 消耗方便做成本核算或额度控制。这两件事在openai-python里都能做但流式场景下usage的返回方式和非流式不一样很多人第一次写会踩坑。这篇内容面向已经会一点 Python、想快速跑通流式 Chat Completions 的读者。目标很具体写一个 20 行左右的脚本从环境变量读取 API Key把base_url指向 TaoToken 的 API 地址发起一次流式请求逐段打印模型输出并在最后打印每段返回的usage字段。TaoToken 在这里作为默认供应商接入你只需要在官网拿到 Key填好地址就能跑。需要提前说明的是流式模式下usage并不是每一段 chunk 都带通常只在最后一个 chunk 出现而且需要显式开启stream_options{include_usage: True}。这一点是本文的核心操作点下面会结合代码讲清楚。2. 环境准备与依赖安装先确认 Python 版本。openai-python1.x 版本要求 Python 3.7 以上建议直接用 3.9 或更高。我试过在 3.8 和 3.11 上跑行为一致。安装依赖只有一条命令pip install --upgrade openai装完后可以用下面这条命令确认版本1.0.0 以上才支持本文的stream_options写法python -c import openai; print(openai.__version__)如果输出是1.x.x就可以继续。如果还是0.x说明环境里装的是旧版需要先卸载再装pip uninstall openai -y pip install --upgrade openai接下来设置环境变量。不要把 Key 写死在脚本里这是基本习惯。Linux 或 macOS 下export TAOTOKEN_API_KEY你的KeyWindows PowerShell$env:TAOTOKEN_API_KEY你的Key变量名用TAOTOKEN_API_KEY还是OPENAI_API_KEY都行关键是脚本里读的名字要一致。下面脚本统一用TAOTOKEN_API_KEY避免和本机已有的 OpenAI 配置混淆。3. 20 行脚本流式请求与 usage 打印先给完整代码再逐段解释。文件保存为stream_demo.pyimport os from openai import OpenAI client OpenAI( api_keyos.environ[TAOTOKEN_API_KEY], base_urlhttps://taotoken.net/api, ) stream client.chat.completions.create( modelgpt-4o-mini, messages[{role: user, content: 用三句话介绍流式输出的好处}], streamTrue, stream_options{include_usage: True}, ) for chunk in stream: if chunk.choices and chunk.choices[0].delta.content: print(chunk.choices[0].delta.content, end, flushTrue) if chunk.usage: print(\n--- usage ---) print(chunk.usage)这段代码正好 20 行左右核心逻辑分三块。第一块是客户端初始化。base_url填https://taotoken.net/api这是 TaoToken 的 API 入口。注意这里不要带末尾斜杠也不要写成/v1openai-python会自动拼接路径。Key 从环境变量读脚本里不出现明文。第二块是请求参数。streamTrue开启流式stream_options{include_usage: True}是关键不加这个参数最后一个 chunk 里不会有usage。model先填gpt-4o-mini具体可用模型以官网为准后面会讲怎么选。第三块是遍历。chunk.choices在最后一个 usage chunk 里可能是空列表所以要先判断chunk.choices再取delta.content。chunk.usage只在最后一个 chunk 有值用if chunk.usage判断即可。flushTrue保证内容实时输出不然可能被缓冲。运行python stream_demo.py正常输出类似流式输出可以让用户更早看到结果提升交互体验。 它还能降低首字延迟适合对话类应用。 同时便于前端逐段渲染减少等待焦虑。 --- usage --- CompletionUsage(completion_tokens48, prompt_tokens18, total_tokens66)usage对象里三个字段prompt_tokens是输入消耗completion_tokens是输出消耗total_tokens是合计。做成本统计时通常按输入和输出分别计价所以这两个字段都要留。4. TaoToken 接入与配置要点接入 TaoToken 只需要改两个地方api_key和base_url。Key 在官网获取地址是 https://taotoken.net/api-keys 登录后在控制台创建即可。创建时建议给 Key 起个名字比如stream-demo方便后续区分用途。base_url固定填https://taotoken.net/api。如果你用的是其他语言的 SDK路径拼接规则可能不同但 Python 这边按上面写就行。想确认当前账号可用的模型列表可以看接入文档 https://taotoken.net/doc 里面会列出模型名和对应的调用方式。有几个配置细节容易出错单独说一下。一是base_url不要重复加/v1。openai-python内部会拼/chat/completions如果你写成https://taotoken.net/api/v1最终路径会变成/api/v1/chat/completions可能返回 404。正确写法就是https://taotoken.net/api。二是环境变量读取失败会直接抛KeyError。如果报这个错先确认当前终端里echo $TAOTOKEN_API_KEY有输出。用 IDE 运行的话注意 IDE 可能没继承你 shell 里的环境变量需要在运行配置里单独设置。三是stream_options参数在部分旧模型上可能不支持。如果请求报参数错误先换gpt-4o-mini或文档里标注支持流式 usage 的模型。模型选择以官网为准不同模型对stream_options的支持情况可能不同。如果你打算长期在项目里用建议把客户端初始化封装成一个函数Key 和base_url都从配置读取。这样切换供应商时只改一处。需要管理多个 Key 或查看额度可以在控制台操作 https://taotoken.net/console 。5. 可验证结果与失败分支跑通后你可以用几个方式验证结果是否符合预期。第一看输出是否逐段出现。如果所有内容一次性打印出来说明stream没生效检查streamTrue是否写对。第二看最后是否有usage块。如果没有九成是漏了stream_options{include_usage: True}。第三看total_tokens是否等于prompt_tokens completion_tokens正常情况应该相等。下面列几个常见失败分支和处理方式。现象可能原因处理401 UnauthorizedKey 错误或未设置检查环境变量重新在官网创建 Key404 Not Foundbase_url多写了/v1改为https://taotoken.net/api最后一个 chunk 无 usage未开启include_usage加上stream_options参数报参数不支持模型不支持流式 usage换文档中标注支持的模型输出被缓冲未加flushTrueprint 时加flushTrue还有一个容易忽略的点chunk.choices在 usage chunk 里是空列表如果你直接写chunk.choices[0]会报IndexError。所以遍历时先判断chunk.choices是否非空再取内容。这个判断在本文脚本里已经加上。如果你想进一步验证可以把每次请求的usage累加到一个变量里跑多轮后对比控制台的用量统计。这样能确认本地统计和平台记录是否一致。6. 限制、成本与模型选择流式 usage 有一个天然限制它只在请求完全结束后才返回。也就是说你无法在生成过程中实时知道已经消耗了多少 token。如果需要中途控制成本只能在应用层按字符数或轮次做粗略估算精确值仍以最后一个 chunk 为准。成本方面不同模型的输入和输出单价不同具体价格以官网为准。做预算时把prompt_tokens和completion_tokens分开乘单价再相加。如果应用里系统提示词很长输入成本会明显上升可以考虑精简提示词或做缓存。模型选择上gpt-4o-mini适合大多数对话和轻量任务速度快、成本低。需要更强推理能力时再换更大的模型。具体哪些模型可用、是否支持stream_options以官网文档为准不要凭记忆写死模型名。最后给一个实用技巧把usage打印改成写入日志文件长期跑下来能看出哪些请求消耗高。比如import logging logging.basicConfig(filenameusage.log, levellogging.INFO) if chunk.usage: logging.info(prompt%s completion%s total%s, chunk.usage.prompt_tokens, chunk.usage.completion_tokens, chunk.usage.total_tokens)这样每次请求的消耗都有记录排查异常用量时比翻控制台方便。脚本本身不用改太多加几行日志就能长期用。 告别海外账号与网络限制稳定直连全球优质大模型限时半价接入中。 点击领取海量免费额度