[{"data":1,"prerenderedAt":818},["ShallowReactive",2],{"article:llm-budget-token-accounting":3},{"meta":4,"raw":19,"references":20,"prev":50,"next":60,"body":61,"toc":806},{"slug":5,"title":6,"date":7,"updated":8,"tags":9,"summary":15,"draft":16,"lang":17,"minutes":18},"llm-budget-token-accounting","控制 LLM 预算：Token 计数、用量统计与没有官方数据时的做法","2025-09-16","2026-10-11",[10,11,12,13,14],"LLM","成本工程","Agent","Claude Code","Codex","分清请求前预估、响应 usage 和最终账单，避免缓存与推理 token 重复计费；用预算预占、逐次结算和任务成本指标管住长会话。",false,"zh-CN",6,"AI 功能上线后超预算，常见原因是少算了工具结果、重试和多轮历史。预算控制首先要分清三本账：**发送前的估算决定是否放行，响应里的 usage 用于逐次记账，供应商账单用于最终对账。** 三者相关，但不能互相替代。\n\n本文面向调用 API 或维护 Agent 网关的开发者。接口按 2026 年 10 月的官方文档核对；价格算例是教学假设，不代表现售模型报价。\n\n## Token 为什么不能按字数结账\n\nToken 是分词器处理的单元，可能是一段词、一个汉字，也可能是字符的一部分。不同模型不一定使用同一种分词方法；中文、代码、JSON、图片和音频的规则也不同。“一个汉字等于两个 token”只能粗估，不能作为跨模型计费公式。\n\n本地 tokenizer 能统计目标模型的文本，但完整请求还包括系统提示、消息包装、工具定义和多模态内容。只统计用户输入会漏掉上下文。JSON 也没有固定的“三倍膨胀率”：字段名、数组规模和输出任务共同决定体积，应在自己的样本上测量。\n\n最小校准集分别收集中文问答、代码、结构化抽取和长工具结果，保存完整请求的估算值与实际 usage。按模型、任务比较误差，模型升级后重新校准。\n\n## 官方用量：先分 API，再分字段\n\n![用量统计的四个环节：事前计数、事后 usage、缺失估算和账单核对](\u002Fdiagrams\u002Fusage-mindmap.svg)\n\n*图 1 · 计数帮助预估，usage 帮助记账，最终还要核对账单和工具费用。*\n\n### OpenAI：Chat Completions 与 Responses\n\nChat Completions 常见字段是 `prompt_tokens` \u002F `completion_tokens`；Responses 使用 `input_tokens` \u002F `output_tokens`。缓存和推理明细通常是总量的子集，**不要再次加到总数上**。支持缓存写入分类的模型还可能返回 `cache_write_tokens`，应按具体 API 和模型归一化。[OpenAI 缓存文档](https:\u002F\u002Fdevelopers.openai.com\u002Fapi\u002Fdocs\u002Fguides\u002Fprompt-caching)\n\n下面是 Chat Completions 风格的示意响应：\n\n```json\n{\n  \"prompt_tokens\": 8000,\n  \"completion_tokens\": 1500,\n  \"prompt_tokens_details\": { \"cached_tokens\": 6000 },\n  \"completion_tokens_details\": { \"reasoning_tokens\": 300 }\n}\n```\n\n300 个推理 token 已含在 1500 中。没有独立缓存写入收费项时，普通输入是 `8000 - 6000`；有写入明细时还要扣除写入部分，分别计价。\n\nChat Completions 流式可用 `stream_options.include_usage` 请求最终用量块；Responses 应处理携带最终响应的终止事件。连接提前断开，客户端可能拿不到最终 usage，此时标记“待核对”，不能写成零。请求前，OpenAI 现在提供 [Responses 输入 token 计数能力](https:\u002F\u002Fdevelopers.openai.com\u002Fapi\u002Fdocs\u002Fguides\u002Ftoken-counting)，本地 tokenizer 仍可用于支持范围内的预估。\n\n### Anthropic：输入分类口径不同\n\nClaude Messages 的 `input_tokens`、`cache_creation_input_tokens`、`cache_read_input_tokens` 分别描述普通输入、缓存写入、缓存读取。计算本次输入处理量时合计这三个分类；费用乘各自费率，不能照搬 OpenAI 的减法。[Claude 缓存文档](https:\u002F\u002Fplatform.claude.com\u002Fdocs\u002Fen\u002Fbuild-with-claude\u002Fprompt-caching)\n\n`messages.count_tokens` 可在发送前计数，但官方明确说明它是**估算**，实际 usage 可能有小幅差异；服务端工具等输入也有支持限制。它适合预检，不能承诺与账单精确一致。[Claude token counting](https:\u002F\u002Fplatform.claude.com\u002Fdocs\u002Fen\u002Fbuild-with-claude\u002Ftoken-counting)\n\n### 本地模型与网关\n\nOllama 的 `prompt_eval_count` \u002F `eval_count` 等计数描述工作量，自托管成本还包括 GPU 占用、空闲容量和运维。每百万 token 的摊销价随负载变化。\n\n网关适合统一字段、价格表与归因维度，不会让缺失用量自动变精确。保留原始 usage、归一化值、估算标记和价格版本，才能追溯差异。\n\n## 预算闸门：检查与预占必须原子化\n\n用户还剩 1 元，10 个请求同时查到“余额够”，事后扣费就可能超额。预算闸门需要**原子检查并预占**：\n\n```text\n创建 task_id\n估计输入 + 最大输出 + 允许的重试成本\n原子预占；不足则排队、缩小任务或拒绝\n每个 attempt 独立保存 request_id、usage、费用\n结算已知费用，释放未使用的预占\nusage 缺失进入待核对队列；恢复未结算任务\n```\n\n新增工具轮次或子任务要追加预占。仅限制输出 token，挡不住无限工具循环。还要限制任务轮数、并发和最长运行时间。\n\n![预算闭环：估计、预占、调用、结算，缺失数据进入待核对队列](\u002Fdiagrams\u002Festimate-loop.svg)\n\n*图 2 · 估算误差靠样本校准，并发超额靠原子预占，两者需要不同机制。*\n\n没有官方用量时，依次尝试目标模型 tokenizer、分任务经验估算、供应商聚合账单校准。安全余量取决于低估误差的分布，不能假定乘 1.2 一定安全。估算费用和确认费用应在报表上区分。\n\n## Agent 为什么越聊越贵\n\n设固定提示与工具定义为 `S` 个 token，每轮新增历史 `h` 个 token，每次发送全部历史。第 `i` 轮输入约为 `S + i·h`，共 `n` 轮：\n\n```text\n总输入 ≈ n·S + h·n·(n+1)\u002F2\n```\n\n**固定增量、重发全部历史、没有裁剪时，总输入量呈平方增长。** 这是输入量模型，不是所有 Agent 账单的复杂度定律。工具结果大小、缓存费率和压缩频率都会改变曲线。\n\n![长会话输入增长：完整历史、缓存计价和有上限的历史管理影响不同](\u002Fdiagrams\u002Fagent-cost-curve.svg)\n\n*图 3 · 缓存降低重复前缀成本，压缩与裁剪限制历史体积，不能画成同一种效果。*\n\n例如 `S=1000、h=500、n=10`，总输入是 37,500，而不是最后一轮的 6,000。一次 20,000 token 的工具结果还可能进入之后多轮历史；分页、按需读取常比精简一句提示更有收益。\n\nClaude Code 的 `\u002Fcost` 和监控指标、Codex 的会话状态与执行事件可辅助观察。**订阅额度、上下文余量和 API 美元账单是不同指标**；CLI 显示不能直接作为跨产品收费凭证。固定提示的体积随版本和配置改变，没有永远固定的“12K 底价”。\n\n## 一笔可复算的账\n\n假设普通输入 $2\u002FM、缓存读取 $0.20\u002FM、输出 $10\u002FM，本次普通输入 2,000、缓存读取 6,000、输出 1,500，没有缓存写入或其他工具费用：\n\n```text\n费用 = (2000×2 + 6000×0.20 + 1500×10) \u002F 1,000,000\n     = $0.0202\n```\n\n每天 30 万次、每月 30 天，则月费用 `$0.0202 × 9,000,000 = $181,800`。真实费率、缓存写入、工具费、失败重试与折扣必须逐项代入。\n\n业务上更有用的是 **每个成功任务的总成本**：把任务内所有调用、重试、检索和外部工具费用计入。便宜模型若增加轮次、降低成功率，单请求价格下降不一定降低任务成本。\n\n## 落地检查\n\n1. 按接口归一化，保留缓存分类和原始 usage；推理子集不重复累加。\n2. 每次尝试单独记账，流式中断进入待核对状态。\n3. 用户、项目与任务预算原子预占，循环和重试设上限。\n4. 价格表带生效时间、版本、单位和币种，定期与账单核对。\n5. 按中文、代码、多模态分别校准，升级模型后重测。\n6. 同看缓存命中、上下文长度、成功率与每成功任务成本。\n\n长输入也影响等待，下一篇拆解 [首 token 延迟](\u002Farticles\u002Fttft-first-token-latency)。\n\n## 参考资料\n\n- [OpenAI — Counting tokens](https:\u002F\u002Fdevelopers.openai.com\u002Fapi\u002Fdocs\u002Fguides\u002Ftoken-counting)\n- [OpenAI — Prompt caching](https:\u002F\u002Fdevelopers.openai.com\u002Fapi\u002Fdocs\u002Fguides\u002Fprompt-caching)\n- [OpenAI — Chat Completions API](https:\u002F\u002Fdevelopers.openai.com\u002Fapi\u002Freference\u002Fresources\u002Fchat\u002Fsubresources\u002Fcompletions\u002Fmethods\u002Fcreate)\n- [Claude — Token counting](https:\u002F\u002Fplatform.claude.com\u002Fdocs\u002Fen\u002Fbuild-with-claude\u002Ftoken-counting)\n- [Claude — Prompt caching](https:\u002F\u002Fplatform.claude.com\u002Fdocs\u002Fen\u002Fbuild-with-claude\u002Fprompt-caching)\n- [Claude Code — Monitoring usage](https:\u002F\u002Fcode.claude.com\u002Fdocs\u002Fen\u002Fmonitoring-usage)\n- [Claude Code — Manage costs](https:\u002F\u002Fcode.claude.com\u002Fdocs\u002Fen\u002Fcosts)",[21,26,30,34,38,42,46],{"title":22,"url":23,"type":24,"note":25,"checked":8},"OpenAI — Counting tokens","https:\u002F\u002Fdevelopers.openai.com\u002Fapi\u002Fdocs\u002Fguides\u002Ftoken-counting","官方文档","调用前输入计数的能力与口径；预估不是最终输出与费用账单。",{"title":27,"url":28,"type":24,"note":29,"checked":8},"OpenAI — Prompt caching","https:\u002F\u002Fdevelopers.openai.com\u002Fapi\u002Fdocs\u002Fguides\u002Fprompt-caching","OpenAI 提示缓存条件与 usage 语义；缓存不等于答案缓存或零费用。",{"title":31,"url":32,"type":24,"note":33,"checked":8},"OpenAI — Chat Completions API","https:\u002F\u002Fdevelopers.openai.com\u002Fapi\u002Freference\u002Fresources\u002Fchat\u002Fsubresources\u002Fcompletions\u002Fmethods\u002Fcreate","Chat Completions 的 usage 与推理明细等字段；避免把子项重复相加。",{"title":35,"url":36,"type":24,"note":37,"checked":8},"Claude — Token counting","https:\u002F\u002Fplatform.claude.com\u002Fdocs\u002Fen\u002Fbuild-with-claude\u002Ftoken-counting","Claude 输入计数能力及估计边界；实际用量以调用结果核算。",{"title":39,"url":40,"type":24,"note":41,"checked":8},"Claude — Prompt caching","https:\u002F\u002Fplatform.claude.com\u002Fdocs\u002Fen\u002Fbuild-with-claude\u002Fprompt-caching","Claude 缓存读取、写入与生命周期；计费字段不能与其他厂商直接互换。",{"title":43,"url":44,"type":24,"note":45,"checked":8},"Claude Code — Monitoring usage","https:\u002F\u002Fcode.claude.com\u002Fdocs\u002Fen\u002Fmonitoring-usage","Claude Code 用量监测与记录；聚合前确认会话和去重口径。",{"title":47,"url":48,"type":24,"note":49,"checked":8},"Claude Code — Manage costs","https:\u002F\u002Fcode.claude.com\u002Fdocs\u002Fen\u002Fcosts","上下文、模型选择与费用治理建议；定价和可用能力需另行核对。",{"slug":51,"title":52,"date":53,"updated":8,"tags":54,"summary":58,"draft":16,"lang":17,"minutes":59},"ttft-first-token-latency","首 token 为什么这么慢：TTFT 的构成与优化清单","2025-10-21",[10,55,56,57],"推理","延迟优化","流式","分清首事件、首 token 与首字上屏，拆解检索、排队、prefill 和渲染的延迟；用分阶段埋点、缓存对照与峰值压测找到真正瓶颈。",5,null,{"type":62,"children":63},"root",[64,80,85,92,97,102,107,113,122,131,138,198,203,404,417,438,444,477,501,506,526,531,537,549,559,564,572,580,585,591,636,645,655,663,671,684,704,709,714,723,736,748,753,788,801],{"type":65,"tag":66,"props":67,"children":68},"element","p",{},[69,72,78],{"type":70,"value":71},"text","AI 功能上线后超预算，常见原因是少算了工具结果、重试和多轮历史。预算控制首先要分清三本账：",{"type":65,"tag":73,"props":74,"children":75},"strong",{},[76],{"type":70,"value":77},"发送前的估算决定是否放行，响应里的 usage 用于逐次记账，供应商账单用于最终对账。",{"type":70,"value":79}," 三者相关，但不能互相替代。",{"type":65,"tag":66,"props":81,"children":82},{},[83],{"type":70,"value":84},"本文面向调用 API 或维护 Agent 网关的开发者。接口按 2026 年 10 月的官方文档核对；价格算例是教学假设，不代表现售模型报价。",{"type":65,"tag":86,"props":87,"children":89},"h2",{"id":88},"token-为什么不能按字数结账",[90],{"type":70,"value":91},"Token 为什么不能按字数结账",{"type":65,"tag":66,"props":93,"children":94},{},[95],{"type":70,"value":96},"Token 是分词器处理的单元，可能是一段词、一个汉字，也可能是字符的一部分。不同模型不一定使用同一种分词方法；中文、代码、JSON、图片和音频的规则也不同。“一个汉字等于两个 token”只能粗估，不能作为跨模型计费公式。",{"type":65,"tag":66,"props":98,"children":99},{},[100],{"type":70,"value":101},"本地 tokenizer 能统计目标模型的文本，但完整请求还包括系统提示、消息包装、工具定义和多模态内容。只统计用户输入会漏掉上下文。JSON 也没有固定的“三倍膨胀率”：字段名、数组规模和输出任务共同决定体积，应在自己的样本上测量。",{"type":65,"tag":66,"props":103,"children":104},{},[105],{"type":70,"value":106},"最小校准集分别收集中文问答、代码、结构化抽取和长工具结果，保存完整请求的估算值与实际 usage。按模型、任务比较误差，模型升级后重新校准。",{"type":65,"tag":86,"props":108,"children":110},{"id":109},"官方用量先分-api再分字段",[111],{"type":70,"value":112},"官方用量：先分 API，再分字段",{"type":65,"tag":66,"props":114,"children":115},{},[116],{"type":65,"tag":117,"props":118,"children":121},"img",{"alt":119,"src":120},"用量统计的四个环节：事前计数、事后 usage、缺失估算和账单核对","\u002Fdiagrams\u002Fusage-mindmap.svg",[],{"type":65,"tag":66,"props":123,"children":124},{},[125],{"type":65,"tag":126,"props":127,"children":128},"em",{},[129],{"type":70,"value":130},"图 1 · 计数帮助预估，usage 帮助记账，最终还要核对账单和工具费用。",{"type":65,"tag":132,"props":133,"children":135},"h3",{"id":134},"openaichat-completions-与-responses",[136],{"type":70,"value":137},"OpenAI：Chat Completions 与 Responses",{"type":65,"tag":66,"props":139,"children":140},{},[141,143,150,152,158,160,166,167,173,175,180,182,188,190],{"type":70,"value":142},"Chat Completions 常见字段是 ",{"type":65,"tag":144,"props":145,"children":147},"code",{"className":146},[],[148],{"type":70,"value":149},"prompt_tokens",{"type":70,"value":151}," \u002F ",{"type":65,"tag":144,"props":153,"children":155},{"className":154},[],[156],{"type":70,"value":157},"completion_tokens",{"type":70,"value":159},"；Responses 使用 ",{"type":65,"tag":144,"props":161,"children":163},{"className":162},[],[164],{"type":70,"value":165},"input_tokens",{"type":70,"value":151},{"type":65,"tag":144,"props":168,"children":170},{"className":169},[],[171],{"type":70,"value":172},"output_tokens",{"type":70,"value":174},"。缓存和推理明细通常是总量的子集，",{"type":65,"tag":73,"props":176,"children":177},{},[178],{"type":70,"value":179},"不要再次加到总数上",{"type":70,"value":181},"。支持缓存写入分类的模型还可能返回 ",{"type":65,"tag":144,"props":183,"children":185},{"className":184},[],[186],{"type":70,"value":187},"cache_write_tokens",{"type":70,"value":189},"，应按具体 API 和模型归一化。",{"type":65,"tag":191,"props":192,"children":195},"a",{"href":28,"rel":193},[194],"nofollow",[196],{"type":70,"value":197},"OpenAI 缓存文档",{"type":65,"tag":66,"props":199,"children":200},{},[201],{"type":70,"value":202},"下面是 Chat Completions 风格的示意响应：",{"type":65,"tag":204,"props":205,"children":210},"pre",{"className":206,"code":207,"language":208,"meta":209,"style":209},"language-json shiki shiki-themes vitesse-light vitesse-light","{\n  \"prompt_tokens\": 8000,\n  \"completion_tokens\": 1500,\n  \"prompt_tokens_details\": { \"cached_tokens\": 6000 },\n  \"completion_tokens_details\": { \"reasoning_tokens\": 300 }\n}\n","json","",[211],{"type":65,"tag":144,"props":212,"children":213},{"__ignoreMap":209},[214,226,262,291,345,396],{"type":65,"tag":215,"props":216,"children":219},"span",{"class":217,"line":218},"line",1,[220],{"type":65,"tag":215,"props":221,"children":223},{"style":222},"--shiki-default:#999999;--shiki-dark:#999999",[224],{"type":70,"value":225},"{\n",{"type":65,"tag":215,"props":227,"children":229},{"class":217,"line":228},2,[230,236,241,246,251,257],{"type":65,"tag":215,"props":231,"children":233},{"style":232},"--shiki-default:#99841877;--shiki-dark:#99841877",[234],{"type":70,"value":235},"  \"",{"type":65,"tag":215,"props":237,"children":239},{"style":238},"--shiki-default:#998418;--shiki-dark:#998418",[240],{"type":70,"value":149},{"type":65,"tag":215,"props":242,"children":243},{"style":232},[244],{"type":70,"value":245},"\"",{"type":65,"tag":215,"props":247,"children":248},{"style":222},[249],{"type":70,"value":250},":",{"type":65,"tag":215,"props":252,"children":254},{"style":253},"--shiki-default:#2F798A;--shiki-dark:#2F798A",[255],{"type":70,"value":256}," 8000",{"type":65,"tag":215,"props":258,"children":259},{"style":222},[260],{"type":70,"value":261},",\n",{"type":65,"tag":215,"props":263,"children":265},{"class":217,"line":264},3,[266,270,274,278,282,287],{"type":65,"tag":215,"props":267,"children":268},{"style":232},[269],{"type":70,"value":235},{"type":65,"tag":215,"props":271,"children":272},{"style":238},[273],{"type":70,"value":157},{"type":65,"tag":215,"props":275,"children":276},{"style":232},[277],{"type":70,"value":245},{"type":65,"tag":215,"props":279,"children":280},{"style":222},[281],{"type":70,"value":250},{"type":65,"tag":215,"props":283,"children":284},{"style":253},[285],{"type":70,"value":286}," 1500",{"type":65,"tag":215,"props":288,"children":289},{"style":222},[290],{"type":70,"value":261},{"type":65,"tag":215,"props":292,"children":294},{"class":217,"line":293},4,[295,299,304,308,312,317,322,327,331,335,340],{"type":65,"tag":215,"props":296,"children":297},{"style":232},[298],{"type":70,"value":235},{"type":65,"tag":215,"props":300,"children":301},{"style":238},[302],{"type":70,"value":303},"prompt_tokens_details",{"type":65,"tag":215,"props":305,"children":306},{"style":232},[307],{"type":70,"value":245},{"type":65,"tag":215,"props":309,"children":310},{"style":222},[311],{"type":70,"value":250},{"type":65,"tag":215,"props":313,"children":314},{"style":222},[315],{"type":70,"value":316}," {",{"type":65,"tag":215,"props":318,"children":319},{"style":232},[320],{"type":70,"value":321}," \"",{"type":65,"tag":215,"props":323,"children":324},{"style":238},[325],{"type":70,"value":326},"cached_tokens",{"type":65,"tag":215,"props":328,"children":329},{"style":232},[330],{"type":70,"value":245},{"type":65,"tag":215,"props":332,"children":333},{"style":222},[334],{"type":70,"value":250},{"type":65,"tag":215,"props":336,"children":337},{"style":253},[338],{"type":70,"value":339}," 6000",{"type":65,"tag":215,"props":341,"children":342},{"style":222},[343],{"type":70,"value":344}," },\n",{"type":65,"tag":215,"props":346,"children":347},{"class":217,"line":59},[348,352,357,361,365,369,373,378,382,386,391],{"type":65,"tag":215,"props":349,"children":350},{"style":232},[351],{"type":70,"value":235},{"type":65,"tag":215,"props":353,"children":354},{"style":238},[355],{"type":70,"value":356},"completion_tokens_details",{"type":65,"tag":215,"props":358,"children":359},{"style":232},[360],{"type":70,"value":245},{"type":65,"tag":215,"props":362,"children":363},{"style":222},[364],{"type":70,"value":250},{"type":65,"tag":215,"props":366,"children":367},{"style":222},[368],{"type":70,"value":316},{"type":65,"tag":215,"props":370,"children":371},{"style":232},[372],{"type":70,"value":321},{"type":65,"tag":215,"props":374,"children":375},{"style":238},[376],{"type":70,"value":377},"reasoning_tokens",{"type":65,"tag":215,"props":379,"children":380},{"style":232},[381],{"type":70,"value":245},{"type":65,"tag":215,"props":383,"children":384},{"style":222},[385],{"type":70,"value":250},{"type":65,"tag":215,"props":387,"children":388},{"style":253},[389],{"type":70,"value":390}," 300",{"type":65,"tag":215,"props":392,"children":393},{"style":222},[394],{"type":70,"value":395}," }\n",{"type":65,"tag":215,"props":397,"children":398},{"class":217,"line":18},[399],{"type":65,"tag":215,"props":400,"children":401},{"style":222},[402],{"type":70,"value":403},"}\n",{"type":65,"tag":66,"props":405,"children":406},{},[407,409,415],{"type":70,"value":408},"300 个推理 token 已含在 1500 中。没有独立缓存写入收费项时，普通输入是 ",{"type":65,"tag":144,"props":410,"children":412},{"className":411},[],[413],{"type":70,"value":414},"8000 - 6000",{"type":70,"value":416},"；有写入明细时还要扣除写入部分，分别计价。",{"type":65,"tag":66,"props":418,"children":419},{},[420,422,428,430,436],{"type":70,"value":421},"Chat Completions 流式可用 ",{"type":65,"tag":144,"props":423,"children":425},{"className":424},[],[426],{"type":70,"value":427},"stream_options.include_usage",{"type":70,"value":429}," 请求最终用量块；Responses 应处理携带最终响应的终止事件。连接提前断开，客户端可能拿不到最终 usage，此时标记“待核对”，不能写成零。请求前，OpenAI 现在提供 ",{"type":65,"tag":191,"props":431,"children":433},{"href":23,"rel":432},[194],[434],{"type":70,"value":435},"Responses 输入 token 计数能力",{"type":70,"value":437},"，本地 tokenizer 仍可用于支持范围内的预估。",{"type":65,"tag":132,"props":439,"children":441},{"id":440},"anthropic输入分类口径不同",[442],{"type":70,"value":443},"Anthropic：输入分类口径不同",{"type":65,"tag":66,"props":445,"children":446},{},[447,449,454,456,462,463,469,471],{"type":70,"value":448},"Claude Messages 的 ",{"type":65,"tag":144,"props":450,"children":452},{"className":451},[],[453],{"type":70,"value":165},{"type":70,"value":455},"、",{"type":65,"tag":144,"props":457,"children":459},{"className":458},[],[460],{"type":70,"value":461},"cache_creation_input_tokens",{"type":70,"value":455},{"type":65,"tag":144,"props":464,"children":466},{"className":465},[],[467],{"type":70,"value":468},"cache_read_input_tokens",{"type":70,"value":470}," 分别描述普通输入、缓存写入、缓存读取。计算本次输入处理量时合计这三个分类；费用乘各自费率，不能照搬 OpenAI 的减法。",{"type":65,"tag":191,"props":472,"children":474},{"href":40,"rel":473},[194],[475],{"type":70,"value":476},"Claude 缓存文档",{"type":65,"tag":66,"props":478,"children":479},{},[480,486,488,493,495],{"type":65,"tag":144,"props":481,"children":483},{"className":482},[],[484],{"type":70,"value":485},"messages.count_tokens",{"type":70,"value":487}," 可在发送前计数，但官方明确说明它是",{"type":65,"tag":73,"props":489,"children":490},{},[491],{"type":70,"value":492},"估算",{"type":70,"value":494},"，实际 usage 可能有小幅差异；服务端工具等输入也有支持限制。它适合预检，不能承诺与账单精确一致。",{"type":65,"tag":191,"props":496,"children":498},{"href":36,"rel":497},[194],[499],{"type":70,"value":500},"Claude token counting",{"type":65,"tag":132,"props":502,"children":504},{"id":503},"本地模型与网关",[505],{"type":70,"value":503},{"type":65,"tag":66,"props":507,"children":508},{},[509,511,517,518,524],{"type":70,"value":510},"Ollama 的 ",{"type":65,"tag":144,"props":512,"children":514},{"className":513},[],[515],{"type":70,"value":516},"prompt_eval_count",{"type":70,"value":151},{"type":65,"tag":144,"props":519,"children":521},{"className":520},[],[522],{"type":70,"value":523},"eval_count",{"type":70,"value":525}," 等计数描述工作量，自托管成本还包括 GPU 占用、空闲容量和运维。每百万 token 的摊销价随负载变化。",{"type":65,"tag":66,"props":527,"children":528},{},[529],{"type":70,"value":530},"网关适合统一字段、价格表与归因维度，不会让缺失用量自动变精确。保留原始 usage、归一化值、估算标记和价格版本，才能追溯差异。",{"type":65,"tag":86,"props":532,"children":534},{"id":533},"预算闸门检查与预占必须原子化",[535],{"type":70,"value":536},"预算闸门：检查与预占必须原子化",{"type":65,"tag":66,"props":538,"children":539},{},[540,542,547],{"type":70,"value":541},"用户还剩 1 元，10 个请求同时查到“余额够”，事后扣费就可能超额。预算闸门需要",{"type":65,"tag":73,"props":543,"children":544},{},[545],{"type":70,"value":546},"原子检查并预占",{"type":70,"value":548},"：",{"type":65,"tag":204,"props":550,"children":554},{"className":551,"code":553,"language":70,"meta":209},[552],"language-text","创建 task_id\n估计输入 + 最大输出 + 允许的重试成本\n原子预占；不足则排队、缩小任务或拒绝\n每个 attempt 独立保存 request_id、usage、费用\n结算已知费用，释放未使用的预占\nusage 缺失进入待核对队列；恢复未结算任务\n",[555],{"type":65,"tag":144,"props":556,"children":557},{"__ignoreMap":209},[558],{"type":70,"value":553},{"type":65,"tag":66,"props":560,"children":561},{},[562],{"type":70,"value":563},"新增工具轮次或子任务要追加预占。仅限制输出 token，挡不住无限工具循环。还要限制任务轮数、并发和最长运行时间。",{"type":65,"tag":66,"props":565,"children":566},{},[567],{"type":65,"tag":117,"props":568,"children":571},{"alt":569,"src":570},"预算闭环：估计、预占、调用、结算，缺失数据进入待核对队列","\u002Fdiagrams\u002Festimate-loop.svg",[],{"type":65,"tag":66,"props":573,"children":574},{},[575],{"type":65,"tag":126,"props":576,"children":577},{},[578],{"type":70,"value":579},"图 2 · 估算误差靠样本校准，并发超额靠原子预占，两者需要不同机制。",{"type":65,"tag":66,"props":581,"children":582},{},[583],{"type":70,"value":584},"没有官方用量时，依次尝试目标模型 tokenizer、分任务经验估算、供应商聚合账单校准。安全余量取决于低估误差的分布，不能假定乘 1.2 一定安全。估算费用和确认费用应在报表上区分。",{"type":65,"tag":86,"props":586,"children":588},{"id":587},"agent-为什么越聊越贵",[589],{"type":70,"value":590},"Agent 为什么越聊越贵",{"type":65,"tag":66,"props":592,"children":593},{},[594,596,602,604,610,612,618,620,626,628,634],{"type":70,"value":595},"设固定提示与工具定义为 ",{"type":65,"tag":144,"props":597,"children":599},{"className":598},[],[600],{"type":70,"value":601},"S",{"type":70,"value":603}," 个 token，每轮新增历史 ",{"type":65,"tag":144,"props":605,"children":607},{"className":606},[],[608],{"type":70,"value":609},"h",{"type":70,"value":611}," 个 token，每次发送全部历史。第 ",{"type":65,"tag":144,"props":613,"children":615},{"className":614},[],[616],{"type":70,"value":617},"i",{"type":70,"value":619}," 轮输入约为 ",{"type":65,"tag":144,"props":621,"children":623},{"className":622},[],[624],{"type":70,"value":625},"S + i·h",{"type":70,"value":627},"，共 ",{"type":65,"tag":144,"props":629,"children":631},{"className":630},[],[632],{"type":70,"value":633},"n",{"type":70,"value":635}," 轮：",{"type":65,"tag":204,"props":637,"children":640},{"className":638,"code":639,"language":70,"meta":209},[552],"总输入 ≈ n·S + h·n·(n+1)\u002F2\n",[641],{"type":65,"tag":144,"props":642,"children":643},{"__ignoreMap":209},[644],{"type":70,"value":639},{"type":65,"tag":66,"props":646,"children":647},{},[648,653],{"type":65,"tag":73,"props":649,"children":650},{},[651],{"type":70,"value":652},"固定增量、重发全部历史、没有裁剪时，总输入量呈平方增长。",{"type":70,"value":654}," 这是输入量模型，不是所有 Agent 账单的复杂度定律。工具结果大小、缓存费率和压缩频率都会改变曲线。",{"type":65,"tag":66,"props":656,"children":657},{},[658],{"type":65,"tag":117,"props":659,"children":662},{"alt":660,"src":661},"长会话输入增长：完整历史、缓存计价和有上限的历史管理影响不同","\u002Fdiagrams\u002Fagent-cost-curve.svg",[],{"type":65,"tag":66,"props":664,"children":665},{},[666],{"type":65,"tag":126,"props":667,"children":668},{},[669],{"type":70,"value":670},"图 3 · 缓存降低重复前缀成本，压缩与裁剪限制历史体积，不能画成同一种效果。",{"type":65,"tag":66,"props":672,"children":673},{},[674,676,682],{"type":70,"value":675},"例如 ",{"type":65,"tag":144,"props":677,"children":679},{"className":678},[],[680],{"type":70,"value":681},"S=1000、h=500、n=10",{"type":70,"value":683},"，总输入是 37,500，而不是最后一轮的 6,000。一次 20,000 token 的工具结果还可能进入之后多轮历史；分页、按需读取常比精简一句提示更有收益。",{"type":65,"tag":66,"props":685,"children":686},{},[687,689,695,697,702],{"type":70,"value":688},"Claude Code 的 ",{"type":65,"tag":144,"props":690,"children":692},{"className":691},[],[693],{"type":70,"value":694},"\u002Fcost",{"type":70,"value":696}," 和监控指标、Codex 的会话状态与执行事件可辅助观察。",{"type":65,"tag":73,"props":698,"children":699},{},[700],{"type":70,"value":701},"订阅额度、上下文余量和 API 美元账单是不同指标",{"type":70,"value":703},"；CLI 显示不能直接作为跨产品收费凭证。固定提示的体积随版本和配置改变，没有永远固定的“12K 底价”。",{"type":65,"tag":86,"props":705,"children":707},{"id":706},"一笔可复算的账",[708],{"type":70,"value":706},{"type":65,"tag":66,"props":710,"children":711},{},[712],{"type":70,"value":713},"假设普通输入 $2\u002FM、缓存读取 $0.20\u002FM、输出 $10\u002FM，本次普通输入 2,000、缓存读取 6,000、输出 1,500，没有缓存写入或其他工具费用：",{"type":65,"tag":204,"props":715,"children":718},{"className":716,"code":717,"language":70,"meta":209},[552],"费用 = (2000×2 + 6000×0.20 + 1500×10) \u002F 1,000,000\n     = $0.0202\n",[719],{"type":65,"tag":144,"props":720,"children":721},{"__ignoreMap":209},[722],{"type":70,"value":717},{"type":65,"tag":66,"props":724,"children":725},{},[726,728,734],{"type":70,"value":727},"每天 30 万次、每月 30 天，则月费用 ",{"type":65,"tag":144,"props":729,"children":731},{"className":730},[],[732],{"type":70,"value":733},"$0.0202 × 9,000,000 = $181,800",{"type":70,"value":735},"。真实费率、缓存写入、工具费、失败重试与折扣必须逐项代入。",{"type":65,"tag":66,"props":737,"children":738},{},[739,741,746],{"type":70,"value":740},"业务上更有用的是 ",{"type":65,"tag":73,"props":742,"children":743},{},[744],{"type":70,"value":745},"每个成功任务的总成本",{"type":70,"value":747},"：把任务内所有调用、重试、检索和外部工具费用计入。便宜模型若增加轮次、降低成功率，单请求价格下降不一定降低任务成本。",{"type":65,"tag":86,"props":749,"children":751},{"id":750},"落地检查",[752],{"type":70,"value":750},{"type":65,"tag":754,"props":755,"children":756},"ol",{},[757,763,768,773,778,783],{"type":65,"tag":758,"props":759,"children":760},"li",{},[761],{"type":70,"value":762},"按接口归一化，保留缓存分类和原始 usage；推理子集不重复累加。",{"type":65,"tag":758,"props":764,"children":765},{},[766],{"type":70,"value":767},"每次尝试单独记账，流式中断进入待核对状态。",{"type":65,"tag":758,"props":769,"children":770},{},[771],{"type":70,"value":772},"用户、项目与任务预算原子预占，循环和重试设上限。",{"type":65,"tag":758,"props":774,"children":775},{},[776],{"type":70,"value":777},"价格表带生效时间、版本、单位和币种，定期与账单核对。",{"type":65,"tag":758,"props":779,"children":780},{},[781],{"type":70,"value":782},"按中文、代码、多模态分别校准，升级模型后重测。",{"type":65,"tag":758,"props":784,"children":785},{},[786],{"type":70,"value":787},"同看缓存命中、上下文长度、成功率与每成功任务成本。",{"type":65,"tag":66,"props":789,"children":790},{},[791,793,799],{"type":70,"value":792},"长输入也影响等待，下一篇拆解 ",{"type":65,"tag":191,"props":794,"children":796},{"href":795},"\u002Farticles\u002Fttft-first-token-latency",[797],{"type":70,"value":798},"首 token 延迟",{"type":70,"value":800},"。",{"type":65,"tag":86,"props":802,"children":804},{"id":803},"参考资料",[805],{"type":70,"value":803},[807,808,813,814,815,816,817],{"id":88,"depth":228,"text":91},{"id":109,"depth":228,"text":112,"children":809},[810,811,812],{"id":134,"depth":264,"text":137},{"id":440,"depth":264,"text":443},{"id":503,"depth":264,"text":503},{"id":533,"depth":228,"text":536},{"id":587,"depth":228,"text":590},{"id":706,"depth":228,"text":706},{"id":750,"depth":228,"text":750},{"id":803,"depth":228,"text":803},1792400815607]