尧图网络 高端网站定制 · 原创设计
免费咨询热线
400-888-6620
免费获取方案
OpenAI Agents SDK 工程笔记:Usage 用量统计、token 预算与成本闸门生产禁区
千笔-AIWritePaper · https://www.aiwritepaper.comAgent 能跑通不等于成本账能平。生产里最常见的五类事故是只抄最后一轮 token、流式还没消费完就入库、as_tool子 agent 用量漏计、用启发式估算代替账单、超预算后静默截断上下文还继续跑。它们都不会立刻抛异常却会在月末账单和上下文完整性上一起爆。本文在openai-agents 0.23.1下核对Usage/RunContextWrapper.usage字段与累计语义并用假模型固定用量做离线 smoke注入子 agent 漏计、流式中途记账、超预算仍继续三类故障各留日志与 CSV_w/usage-cost-smoke/。不打真实计费 API。图上排为每次 run 可读字段中排为累计路径与预算闸门底部为五条生产禁区。目标说明读完你应能独立完成五件事。从context.usage或等价的 run 上下文读出请求数、输入/输出/总 token以及缓存与推理细分。在多轮、handoff、as_tool子 agent 场景用Usage.add或共享同一 usage 对象做整次 run 累计。流式场景等到最后一块消费完再记账中途读数视为过时。实现按 run 的 token 预算闸门超限拒绝禁止静默截断后续跑。把五条失败样本写进禁区表与 CI。适用与边界适合已在 Agents SDK 里跑多 agent / 工具子 agent需要按次 run 做用量审计与成本上限。不讲tool 循环与超时、MCP、guardrails、lifecycle、ModelSettings、RunContext 业务字段、streaming 事件协议细节、handoffs 路由、tracing、ModelProvider、LocalShell、needs_approval、tool_use_behavior、SQLiteSession、AgentsException、托管 WebSearch/FileSearch见既有工程笔记。本篇专写用量统计与成本闸门。失败含义smoke 用固定Usage对象验证累计与闸门逻辑真实账单以平台结算为准。类名与字段来自本机openai-agents 0.23.1。机制从哪里读、怎样累计、何时完整字段含义工程注意requests对本轮 LLM API 的请求次数多轮会累加input_tokens/output_tokens/total_tokens跨请求合计账单主字段用累计值input_tokens_details.cached_tokens缓存命中输入 token可为 0勿当「免费」就忽略审计input_tokens_details.cache_write_tokens写入缓存的 token与 cached 分开记账output_tokens_details.reasoning_tokens推理类输出细分有的模型为 0request_usage_entries每次请求的拆条目add()会保留便于分请求成本读数入口RunContextWrapper.usage。文档写明流式响应在最后一块处理完之前usage 是过时的。因此「流式中途打印 token」不能当结账依据。累计同一 run 内多次模型调用应落到同一Usage上。Usage.add(other)会累加请求数与各类 token并合并request_usage_entries。as_tool子 agent 在 SDK 里通过 fork 共享父级 usage 引用你若在外层自己开子 Runner必须显式把子结果 usageadd回父级否则就是 F3。fromagents.usageimportUsage,InputTokensDetails,OutputTokensDetails run_usageUsage()run_usage.add(parent_turn_usage)run_usage.add(as_tool_child_usage)# 漏掉这一行 子 agent 漏计# 预算闸门用累计 total_tokens不用估算ifrun_usage.total_tokensMAX_TOKENS_PER_RUN:raiseRuntimeError(token budget exceeded)预算闸门建议钉在「整次 Runner.run / run_streamed 结束且流已耗尽」之后、对外交付之前。超限动作只能是拒绝或降级到人工不能静默截断历史消息继续自动跑。离线 smoke5 条通过 5 条失败P1 PASS 假模型固定 Usage请求数与 token/缓存/推理细分可读 - req2 in1200 out300 total1500 cached400 cache_write50 reasoning80 P2 PASS 多 agent/as_tool父子 Usage.add 累计且保留 request_usage_entries - req2 total880 entries2 cached40 P3 PASS 流式未消费完 usage 过时最后一块后才完整 - mid_total0 completeTrue final_total1020 P4 PASS 按 run 的 token 预算闸门未超限放行 - allowTrue billed1000 max2000 actioncontinue P5 PASS 账单以累计 Usage.total_tokens 为准估算不得替代 - estimated5000 billed_usage880 use_estimate_as_billFalse F1 FAIL 禁区只看最后一轮用量 - last_only670 true_total1120 undercount450 F2 FAIL 禁区流式未消费完就记账 - booked_early0 stream_completeFalse staleTrue F3 FAIL 禁区as_tool 子 agent 用量漏计 - parent_only_total600 child_missed280 true_should_be880 F4 FAIL 禁区把估算当账单 - estimate_as_bill5000 actual_usage1500 mismatchTrue F5 FAIL 禁区超预算后静默截断上下文仍继续 - overTrue allowTrue silent_truncateTrue billed3500 actioncontinue_truncated CSV rows: 10逐条读法。P1固定假用量可读出 requests、in/out/total、cached、cache_write、reasoning。P2父 600 子 280累计 total880entries2缓存细分一并相加。P3流式中途mid_total0过时消费完后final_total1020。P4预算 2000实际 1000放行。P5估算 5000 与真实累计 880 分离禁止用估算代替账单。F1只看最后一轮 670真实合计 1120少计 450。F2只消费 1/4 块就记账booked_early0且staleTrue。F3只计父 600子 280 漏计。F4把估算 5000 当账单与实际 Usage 1500 不一致。F5超预算 35002000 仍allowTrue且silent_truncateTrue。生产禁区表禁区失败含义正确动作只看最后一轮用量前面轮次成本消失读整次 run 的累计usage流式未消费完就记账入库数字过时或为 0等最后一块处理完as_tool子用量漏计子调用「免费」幻觉共享 usage 或显式add估算当账单财务与工程对数不上只认 Usage / 平台账单超预算静默截断续跑上下文残缺仍对外答闸门拒绝或转人工最小接入示例读数 闸门把闸门挂在 Runner 返回之后先取result.context_wrapper.usage字段名以你使用的结果对象为准再调用TokenBudgetGate.check。若你使用run_streamed必须先异步迭代至流结束再读 usage否则会落入 F2。对含as_tool的图在返回前断言usage.requests不少于「父模型调用次数 子模型调用次数」的下界作为漏计的廉价探针。本地联调可用假模型固定 Usage每次响应带上已知的 input/output跑完后检查累计是否等于各次之和并故意丢掉子段add让 F3 复现。通过后再接真实模型避免一上来就被缓存命中波动干扰断言。验收清单每次 run 结束后持久化requests/input/output/total与缓存、推理细分。多 agent / handoff /as_tool场景核对累计是否等于各段之和。流式路径在complete之前禁止写账单表。TokenBudgetGate超限返回 reject测试里断言不存在continue_truncated。CI 跑smoke.pyP1至P5 保持 PASSF1至F5 保持 FAIL。跑 smoke 前确认本机已安装openai-agents0.23.1脚本只依赖agents.usage的数据类不发起网络请求。把smoke_output.txt与 CSV 一并归档换小版本 SDK 时先看Usage字段是否仍含缓存与推理细分再决定是否更新断言。当天 30 分钟落地5 分钟在现有 Runner 回调里打印context.usage.total_tokens非流或流结束后。10 分钟给一次含as_tool的 run 做父/子分项与合计对照。10 分钟接入TokenBudgetGate用固定假用量打超限用例。5 分钟把 F1至F5 写进 oncall 手册。流式取消与中途快照用户或网关取消流式生成时已发出的 chunk 可能已经产生部分 output tokens但RunContextWrapper.usage在最后一块处理完之前仍可能过时。正确做法是取消路径也要走到「流关闭/耗尽」钩子再读取一次 usage 作为不完整 run的审计记录并打上cancelledTrue。错误做法是把取消前某次日志里的total_tokens0或中间值写成正式账单或因为取消就整行删除用量平台侧仍可能计费。F2 用「只消费 1/4 块就记账」模拟这一类事故booked_early0且stream_completeFalse。CI 里应断言账单写入函数的前置条件包含stream_complete或非流路径的run_done。缓存 token 要不要进预算cached_tokens与cache_write_tokens进入input_tokens_details不一定与「向用户报价」的口径相同但预算闸门默认应看total_tokens或平台定义的计费 token而不是只看非缓存输入。若产品政策允许缓存优惠应在闸门外单独配置「计费口径」并在 CSV 里同时留下 raw Usage 与计费口径两列避免事后无法对账。smoke 的 P1 要求缓存与推理字段可读不等于要求它们从预算中豁免。与 oncall 手册的衔接告警建议至少三条单 runtotal_tokens超预算、同日累计超日预算、as_tool调用次数与requests增量明显不匹配。前两条直接绑TokenBudgetGate第三条用 entries 条数或子调用计数做启发式命中后人工抽查是否漏add。手册里写清估算值只用于容量规划不用于客户账单与拒绝决策。踩坑用「大约几千 token」做额度申请月末才发现 Usage 合计翻倍。取消流式生成后仍把中途快照当最终用量。子 agent 单独 Runner 跑完不回写父 usage。超限时删掉最早的 tool 结果再重试还不记截断事件。只监控 output_tokens忽略巨大的 input 与缓存写入。假模型固定用量怎么对照账单字段对照时先固定金标准一次 run 结束后的Usage快照含requests、input_tokens、output_tokens、total_tokens以及cached_tokens、cache_write_tokens、reasoning_tokens。若启用了request_usage_entries还应能按请求拆开复核。假模型侧每次调用返回写死的 Usage便于断言加减真实平台延迟与缓存命中率会变但字段名与累计规则应保持一致。实践上建议把成本终裁拆成三道门。第一道流是否已耗尽或非流路径已返回。第二道父 run 与所有as_tool/handoff 子段是否都已add。第三道累计total_tokens是否小于本 run 预算。三道都过才允许写入账单表或触发下游计费事件。任何一道失败输出停在草稿区禁止用「大概没超」作结案理由。与「托管检索选型」「异常恢复」「会话持久化」分开记账本文只验收用量对象与预算闸门。检索是否抽检、异常是否可恢复各自用各自的 smoke避免一篇工程笔记塞满所有 SDK 主题。预算闸门伪代码与拒绝语义dataclassclassTokenBudgetGate:max_total_tokens:intdefcheck(self,usage:Usage)-str:ifusage.total_tokensself.max_total_tokens:returnreject# 禁止 continue_truncatedreturncontinue拒绝后的产品行为可以是返回明确错误码、降级到更小模型的新run新预算、新 usage、或转人工。不允许的行为是删掉上下文前缀使 total 表面下降却继续同一 run 编号对外回答。F5 专拦后一种「看起来还能跑」的静默截断。若业务必须做上下文压缩应开新 run旧 usage 冻结入库新 run 使用压缩后的输入并重新累计。这样财务与审计仍能把两次 run 分开看而不是在同一次自动循环里把截断藏掉。多 agent 累计的两种合法写法写法一SDK 默认的共享引用。as_toolfork 让子调用直接往父usage上累加父侧结束时读一次即可。写法二子 Runner 独立 usage结束后parent_usage.add(child_usage)。两种都可以不合法的是「子跑完只把文本结果拼回去usage 丢在子作用域」。handoff 换 agent 后同样要确认仍落在同一 run 上下文的 usage 上而不是每个 agent 各记一份末轮快照却从不汇总。排查漏计时用request_usage_entries的条数与requests对照若请求次数对得上但 total 偏小多半是某次add被跳过若 entries 偏少说明有请求从未进入累计对象。为何不能只监控 output不少团队面板只画 output_tokens因为「生成字数」好懂。实际成本与上下文风险往往由 input 主导工具结果回灌、历史消息、缓存写入都会推高input_tokens。预算闸门与告警应以total_tokens或平台计费口径为主output 仅作辅助序列。P1 把 in/out/total 与缓存、推理一并打印就是为了避免单一指标盲区。总结用量统计的入口是每次 run 上下文上的Usage请求数、输入/输出/总 token以及缓存与推理细分add与共享引用负责多 agent/as_tool累计流式必须消费到最后一块才完整。成本闸门按累计total_tokens做硬拒绝。五条禁区只看末轮、中途记账、子用量漏计、估算当账单、超预算静默截断在离线 smoke 中全部 FAIL。把同一脚本挂进 CI换模型时复跑而不是凭感觉调额度。用量与预算闸门日志可用千笔-AIWritePaper 整理归档骨架与脚本不依赖产品名。
RELATED

相关推荐

AI驱动测试用例生成:从需求描述到可执行自动化脚本的完整实践指南

AI驱动测试用例生成:从需求描述到可执行自动化脚本的完整实践指南

1. 为什么需要AI驱动用例生成:从两条完全不同的语言体系说起我见过的绝大多数测试团队,都卡在同一个地方:需求文档写了一大堆,测试用例却少得可怜。产品经理交付的需求描述,是人话,带上下文、带业务背景、带…

📅 2026/10/14 2:44:59
三阶RC低通滤波器定点化与移位优化:无FPU MCU的高效实现

三阶RC低通滤波器定点化与移位优化:无FPU MCU的高效实现

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

📅 2026/10/14 2:44:59
为什么两台电脑直连都无法通信

为什么两台电脑直连都无法通信

网线类型:现代网卡大多支持 Auto-MDI/MDIX,普通直通线也能直连。但如果是老设备,直连需要 交叉线(一头 568A、一头 568B)。最稳妥:换一根确认好的网线试试。我怀疑是网线类型的原因:直连到底要不…

📅 2026/10/14 2:44:59
MORE NEWS

更多资讯

📰

Codex CLI配置指南:从环境变量到代理网络的完整实战方案

简介:面向国内开发者的 OpenAI Codex 配置指南项目源码包,解决三大操作系统下访问与安装 Codex 的痛点,帮助个人开发者和团队将 AI 编程助手接入日常开发流程。包内共 3 个文件,压缩后仅 8KB:html 指南页面承载完整配置…

📰

KVM虚拟化深度实践:从内核原理解析到命令行实战

虚拟化这块儿,很多朋友一开始接触的是桌面级方案,比如在个人电脑上装个带图形界面的虚拟机软件,体验一下Linux或者跑个隔离环境。但真正到了生产环境、到了机房,你发现那套思路根本不够用。我这些年折腾下来最大的感受就是&#x…

📰

变电站设备缺陷检测:8307张VOC+YOLO双格式标注数据集实战

简介:面向电力系统智能巡检场景的变电站缺陷图像数据集,含8307张现场拍摄的高清jpg图像,提供Pascal VOC xml与YOLO txt双格式标注,覆盖避雷器破损、变压器渗油、开关柜异物、隔离开关锈蚀、绝缘子污闪、小动物入侵等17类运维高频典…

📰

给LEGO挖掘机换一套光,居然要靠一个视频生成模型来完成

你有没有想过,同一辆玩具车,放在正午的沙漠里拍和放在夜晚的酒吧霓虹灯下拍,看起来会像是两个完全不同的物体?材质没变,形状没变,变的只是光。这背后藏着计算机图形学里一个折磨了研究者几十年的老问题:重新打光。**问题到底难在哪**传统的做法是走"逆向渲染"这条路…

📰

Qt+MSVC工具链配置实战:让AI生成代码在Windows下直接跑通

简介:面向从 QtCreator 转向 Trae 的 Qt 开发者,这份可运行源码包聚焦 Trae Qt MSVC 环境搭建难题,解决了插件安装、环境变量配置、编译任务定义等关键环节。包体非常精简,共 3 个文件,含 .inscode 工程入口、HTML 说…

📰

【单片机毕设案例分享】基于STM32的洗衣机洗涤甩干控制与状态显示系统设计 基于单片机的智能洗衣机洗衣程序与预约功能实现(032801)

博主介绍:✌️码农一枚 ,专注于大学生项目实战开发、讲解和毕业🚢文撰写修改等。全栈领域优质创作者,博客之星、掘金/华为云/阿里云/InfoQ等平台优质作者、专注于单片机,STM32单片机,51单片机,J…

TODAY

今日更新

THIS WEEK

本周精选

THIS MONTH

本月热门

读完文章,想聊聊您的网站?

告诉我们您的行业与需求,资深顾问一对一梳理方案与报价,全程免费。

📞 💬