Codex 用得越久,越要学会省 Token
原创 · 约 44 分钟阅读 · 阅读 --
Last updated on

Codex 用得越久,越要学会省 Token

作者: Alex Xiang


古董级程序员,大厂出来后一直在创业公司,现在还在一线写 AI 相关的后端。更完整的技术记录写在微信公众号「字与码」:踩过的坑、换技术栈时的权衡、和这些年绕过的弯路,会不定期发在那里。若这篇对你有用,欢迎顺手关注。

我最近把一条很长的 Codex 会话完整算了一遍账。结果有点出乎意料:真正贵的不是最后那几段回答,而是为了完成任务,模型在每一次循环里反复带上的上下文。

那条会话持续了一整天,做了很多典型的工程工作:读文档、查日志、改代码、解冲突、提 PR、上线、排查 CI。最后统计下来,主会话一共消耗了 119,743,174 tokens,大约相当于我当时 Codex 周用量的 15%。按 GPT-5.5 的标准 API 价格估算,原始成本约 79.28 美元。其中输出只有 219,381 tokens,不到总量的 0.2%。大头是输入,尤其是长会话里不断复用的缓存输入。

需要先强调一点:文里的美元价格只是拿公开 API 单价做的「原始成本估算」,不是我实际付给 Codex 的边际成本。订阅套餐、限额、缓存、服务侧调度和平台定价是另一套账,实际摊到个人使用上的成本通常远低于这个数字。这篇文章不是想制造「Codex 很贵」的焦虑,而是想把长会话里的 token 流向看清楚。看清楚以后,才能知道哪些优化有意义,哪些优化只是自我折腾。

这就是 Codex 这类 coding agent 的成本特点:它不像普通聊天那样「问一句,答一段」。它会读文件、跑命令、看日志、修改代码、再验证;每一步都要带着任务上下文继续推理。上下文越长,循环越多,token 就越容易悄悄涨上去。

Codex token optimization hero

先说结论

如果只记四件事,我会这样记:

第一,长会话不是免费记忆。哪怕 prompt caching 命中率很高,缓存输入仍然会计价,只是单价更低。

第二,最贵的对话往往不是文字最多的对话,而是跨仓库、跨系统、需要多轮工具调用的对话。比如排查线上问题、处理 PR 冲突、迁移部署配置、批量扫描 issue。

第三,省 token 的关键不是让回答变短,而是让任务边界变清楚:该拆会话就拆,会话之间用交接摘要;大段日志放文件里,让模型按需读;稳定规则沉淀到 AGENTS.md、skills 或本地配置里,不要每次都重新粘一遍。

第四,不要为了省 token 把工作流搞得很别扭。Codex 本身是够用的,真正值得优化的是那些明显浪费的输入:整段日志、无关历史、反复粘贴的固定规则、一次塞太多互不相关的任务。为了少花一点 token 而频繁打断工作状态,通常得不偿失。

这次统计怎么算

这次统计来自本地 Codex session log 里的 token_count 记录。计价口径使用 GPT-5.5 的公开 API 价格:

类型单价
非缓存输入$5.00 / 1M tokens
缓存输入$0.50 / 1M tokens
输出$30.00 / 1M tokens

计算公式很简单:

uncached_input = input_tokens - cached_input_tokens

cost =
  uncached_input / 1,000,000 * 5.00
  + cached_input / 1,000,000 * 0.50
  + output_tokens / 1,000,000 * 30.00

这里有两个容易算错的点。第一,reasoning_output_tokens 已经包含在 output_tokens 里,不能再单独加一次。第二,这只是 API 侧的原始价格估算,不等同于订阅制产品的真实边际成本。对个人用户来说,更有参考价值的反而是「它占了多少周用量」:这条一整天的长会话约占 15% 周用量;生成这篇文章本身约占 1% 周用量。

OpenAI 的模型文档显示,GPT-5.5 的文本 token 价格是 input $5.00、cached input $0.50、output $30.00;它还有 1,050,000 的上下文窗口和 128,000 的最大输出 tokens。文档也提醒,GPT-5.5 如果单次输入超过 272K tokens,会进入长上下文加价区间。本文统计的那条会话里,单次最大输入约 238,871 tokens,没有触发这条加价规则。

Prompt caching 这部分也值得单独说一下。OpenAI 的 prompt caching 文档写得很清楚:缓存命中依赖「完全匹配的前缀」,稳定的系统提示、工具定义、历史上下文更容易复用;静态内容应该放在 prompt 前面,动态内容放后面。缓存能显著降低延迟和输入成本,但它不是免费额度。

一次长 Codex 会话的成本结构

从这张图看,缓存输入的 token 数最多,费用也最多。它的单价只有非缓存输入的十分之一,但体量太大,最后仍然占了主要成本。

为什么一个短问题也可能很贵

很多人第一次看 agent 的 token 账单,会有一个误解:我明明只问了一句,为什么这轮消耗这么多?

原因是「这一句」并不是孤立发给模型的。对 Codex 来说,本轮请求通常会带上:

  • 系统和开发者规则;
  • 当前仓库的上下文摘要;
  • 会话历史;
  • 最近工具调用结果;
  • 可用工具定义;
  • 用户刚刚发的任务;
  • 可能还有打开过的文件片段、错误日志、测试输出。

所以,一个看上去只有十几个字的问题,实际输入可能是几十万 tokens。更关键的是,agent 任务往往不是一次模型调用,而是一串调用:先分析、再读文件、再改代码、再跑测试、再处理失败、再总结。每一次循环都会重新消耗一部分上下文。

Token 在 agent 对话里的流动方式

这也是为什么「让最终回答短一点」只能省一点输出成本,不能从根上解决问题。真正要省的是反复带进去的上下文,以及没有必要展开给模型看的材料。

哪些对话最耗 token

我把那条主会话里最贵的 10 个交互挑出来,结果很符合日常直觉:越是跨系统、跨仓库、需要不断验证的任务,越贵。

最贵的 10 类对话

这 10 个交互具体做了什么,也很有代表性。

排名估算成本这轮大概在做什么为什么贵
1$7.71迁移一套后台服务的 Kubernetes 部署方式,同时处理镜像仓库凭证、集群配置、密钥管理和部署验证。同时牵涉代码仓库、配置仓库、线上机器、K8s 资源、CI workflow;每一步都要确认不会影响既有服务。
2$7.01提交后台服务 PR、跟进上线、验证新镜像和新工作流是否生效。既要整理本地改动,又要查 PR 状态、构建日志、部署结果,属于高频工具调用任务。
3$5.61扫描一批指派给我的 issue,判断是否仍存在,能修就修,已修就 comment 并关闭。issue 数量多,每个 issue 都要看上下文、代码、历史 PR,有些还要实际验证。
4$4.62跟进配置仓库 PR 通过后的后续动作,确认配置能否进入部署链路。这类任务表面只是「PR 通过了」,实际要回到部署设计里确认下一步怎么触发。
5$3.80为 CLI 引入基于 MkDocs 的文档系统,梳理命令文档和线上文档结构。文档任务会读大量现有命令、配置和站点结构,输入材料多。
6$3.68调试本地 Job Platform 页面,增加开关、联动 run 列表、检查后台逻辑。前后端一起改,且需要反复看日志、看页面状态、看服务行为。
7$3.57处理已有 PR 的冲突,判断 PR 内容是否已合入测试分支,再修复冲突。冲突处理通常需要看两边历史、当前分支状态和目标分支内容。
8$2.91调试本地服务管理面板,排查为什么某个服务状态、日志或启动方式不对。本地进程、端口、日志、配置文件都要看,循环验证较多。
9$2.82合并当前改动到已有 PR,解决冲突并准备 release。PR 与 release 混在一起时,需要同时保留变更说明、测试结果和分支关系。
10$2.77把镜像仓库拉取凭证纳入配置管理,改成可复用的加密 Secret。涉及安全边界、命名、加密方式、部署兼容性,不能只改一行配置。

这些交互大致可以归为五类。

第一类是部署和配置迁移。 这种任务通常要读 README、看 Kubernetes 或 CI 配置、查线上环境、改 workflow、再验证部署结果。它贵的地方不在某一个回答,而在「查清楚」和「确认没影响别的服务」。

第二类是批量 issue 排查。 用户一次给十几个 issue,让 Codex 判断是否存在、能不能修、修了要不要关闭。每个 issue 都需要看上下文、看代码、看 PR、甚至跑测试。单个 issue 可能不贵,批量做就会叠起来。

第三类是多仓库 PR 和 release。 一个仓库改代码,另一个仓库更新依赖,第三个仓库改部署配置;中间还要解决冲突、更新 PR 说明、重新跑 CI。每跨一个仓库,上下文和工具循环都会变长。

第四类是长日志排查。 用户把几百行甚至几千行日志贴进来,模型确实能读,但也会完整计入输入。日志里真正有用的可能只有 20 行。

第五类是文档生成。 读飞书文档、结合代码、再生成长文档,看上去是「写作任务」,实际上包含读取、归纳、重写、排版和多次校正。

另一条同一天的长会话也印证了这个结论。按任务类型粗分,代码/PR/发布和问答/调试占了绝大多数成本,普通数据统计反而很少。

任务类型成本分布

任务类型估算成本占比
代码 / PR / 发布$29.3950.9%
问答 / 调试$25.0843.4%
文档 / 内容$2.093.6%
测试$1.101.9%
数据统计$0.100.2%

这个比例也和一篇关于 agentic coding token 消耗的研究结论一致:agentic coding task 的成本往往由输入 tokens 驱动,而不是输出 tokens;同一个任务的 token 消耗还可能有很大波动。换句话说,agent 的成本不是只由「任务看起来难不难」决定,更多取决于它为了完成任务走了多少步、读了多少材料、试错了多少次。

Prompt caching 能帮忙,但别把它当免费午餐

Prompt caching 是长会话能跑起来的重要原因。没有缓存,每一次都完整处理几十万 tokens,成本和延迟都会更难接受。

但 caching 的作用更像是「给重复前缀打折」,不是「把上下文变成免费」。所以它有几个工程上的启发:

做法影响
稳定规则放前面更容易命中前缀缓存
易变输入放后面避免破坏前缀
不要频繁改系统级规则减少缓存失效
大段日志不要直接贴降低非缓存输入
长任务拆成多个会话减少每轮携带的历史

这点在 Codex 里尤其明显。比如 AGENTS.md、skills、工具说明、固定工作流,这些内容适合成为稳定前缀;而某次报错日志、某个 PR 的 diff、某段临时 SQL,就应该靠文件和命令按需读取。

我的省 token 工作法

下面这些做法不是理论上的 prompt engineering,而是长时间用 Codex 做工程任务后留下来的习惯。

1. 一个会话最好只做一个主题

最容易失控的场景,是在同一个会话里连续做十几件互不相关的事:上午修 CI,下午查数据库,晚上写博客,中间还穿插几个 PR review。这样会话上下文越来越厚,后面的每一句都在为前面的历史付费。

更好的方式是按交付物拆:

  • 一个 PR 一个会话;
  • 一个线上事故一个会话;
  • 一篇文档一个会话;
  • 一次数据分析一个会话。

如果任务需要延续,就让 Codex 生成一段交接摘要,复制到新会话开头。摘要通常几百到一两千 tokens,远比带着几十万 tokens 的历史继续跑便宜。

这并不等于每个小问题都要新开窗口。我的经验是:只要任务还在同一个交付物里,比如同一个 PR、同一个线上问题、同一篇文档,就可以继续用同一个会话。Codex 自动 compact 以后,长会话仍然能工作,只是它会把历史压缩成摘要。这个能力很实用,不需要过度规避。

真正应该新开的,是「主题切换」:刚才在修后台部署,突然要写博客;刚才在查数据库,突然要 review 前端 PR;刚才在做线上问题,突然要研究一个完全不相关的新技术。这种切换不仅会增加 token,也会污染模型对当前任务优先级的判断。

2. 不一定每个仓库一个会话,但每个交付物最好一个会话

「每个仓库一个会话」听起来很清楚,但现实里很多任务天然跨仓库。比如一个功能可能要同时改后端、前端和部署配置;一个发布问题可能要看业务仓库、CLI 仓库和配置仓库。硬拆成三个会话,反而会丢失上下文。

我更推荐按交付物,而不是按仓库:

场景建议
单仓库小改动一个会话做完
一个 PR 牵涉多个仓库一个会话统筹,但每个仓库分阶段处理
多个互不相关 PR分多个会话
一个线上事故跨多个服务一个会话保留事故上下文
同一天连续处理很多 issue先建一个分诊会话,再把复杂 issue 单独拆出去

多仓库会话的关键是让 Codex 清楚当前阶段:现在只看哪个仓库、只改哪类文件、下一步验证什么。否则模型容易在多个目录之间来回跳,token 和时间一起涨。

3. 冷门任务尽量新开会话

有些任务很「冷门」:临时研究一个陌生库、查一个很少用的云服务、写一篇完全不同主题的文章、分析一份和当前项目无关的资料。这类任务如果塞进长期工程会话里,会带来两个问题。

第一,它会污染当前会话的语义背景。后面继续做原来的工程任务时,模型可能还会把刚才那堆陌生材料带在历史里。

第二,它不利于缓存。Prompt caching 依赖稳定前缀;长期工程会话里前缀相对稳定,突然插入大量异质材料,虽然不一定完全破坏缓存,但会让后续上下文变得更重。

所以我的做法是:冷门任务、一次性调研、和当前项目无关的写作,单独开会话。做完后只把结论摘要带回来,不把整个过程带回来。

4. 更好利用缓存:稳定内容早放,临时内容晚放

Prompt caching 对 agent 很重要,但它不是用户能手动「开关」的功能。我们能做的是提高它命中稳定前缀的概率。

几个简单原则:

  • 稳定规则放在 AGENTS.md、skills、README、本地配置里,不要每次临时粘贴;
  • 同一个会话里,不要反复改系统级要求和工作方式;
  • 临时日志、diff、SQL、CSV 放文件里,让 Codex 按需读取;
  • 长 prompt 里,稳定背景放前面,易变输入放后面;
  • 如果一段材料只对一次任务有用,不要把它带进长期会话。

这也是为什么我不喜欢在每次请求里重复贴一大段「你要如何工作」。稳定规则应该沉淀,临时材料应该隔离。

5. 日志只给关键段,全文放文件

不要把完整日志直接贴进聊天窗口。更好的写法是:

日志在 /tmp/deploy.log。
请先用 rg 查找 ERROR、Traceback、exit code、failed,再只读取相关上下文。
不要把整份日志输出给我。

这样模型会用工具定位,而不是把整份日志吞进去。对几千行 CI log 或服务日志来说,这个差异非常大。

还有一个实用做法:如果已经知道错误大概在哪里,只贴前后 30 到 80 行就够了。比如 CI 失败,通常只需要失败 job 的最后一段、报错栈、触发命令和环境变量摘要。完整日志可以放路径,留给 Codex 需要时再读。

6. 数据分析先确定口径,再跑全量

统计类任务容易反复返工。比如「统计最近 7 天某 provider 的调用量」看似简单,但数据源可能有 MongoDB、Postgres、历史表、账单表,口径可能是 raw call、billable result、成功调用、搜索曝光。

我现在会先问:

先不要全量跑。请先说明你准备用哪些表、哪些字段、什么时间窗口、如何判断成功和计费。

口径确认后再执行,能少很多无效查询和无效上下文。

如果数据量很大,尽量让 Codex 先产出 SQL 或脚本,再把结果落到临时文件。聊天里只展示 top N、异常样本和结论。完整结果留在 CSV、JSON 或 Markdown 文件里。

7. 让 Codex 用文件,不要用聊天框搬运文件

大段配置、SQL、JSON、CSV,都更适合放到文件里。用户只需要告诉 Codex 路径和目标。

数据在 /tmp/provider_stats.csv。
请读取并生成 top 20 的对比表,不要输出原始 CSV。

这样有两个好处:第一,聊天历史不被大文件污染;第二,Codex 可以用脚本处理,模型只读汇总结果。

8. 稳定偏好沉淀到规则里

有些信息每次都说,既浪费 token,也容易漏:

  • PR 标题必须中文;
  • 某个仓库的 release 分支规则;
  • 本地服务怎么启动;
  • 哪些群 ID 是固定的;
  • 某类测试怎么跑;
  • 某个产品怎么发版。

这类内容应该放进 AGENTS.md、skills、项目 README 或本地配置。这样模型能按需读取,也更容易保持一致。

9. 明确输出上限

很多时候,真正需要的是结论,不是完整过程。

原始说法更省 token 的说法
看一下这个 run 为什么失败只提取失败 job、关键错误、最可能原因和修复建议
分析这些 issue每个 issue 最多 5 行:是否存在、证据、建议动作
总结这个 PR只列行为变化、风险、测试,不要复述所有 diff
生成报表只列 top 20,完整结果写入文件
看日志rg 关键字,再读命中上下文

输出短一点当然能省输出 token,但更重要的是它会让模型少走弯路。

10. 不要把 compact 当成失败

Codex 自己做 compact,说明上下文接近窗口上限,需要把历史压缩成摘要。它不是坏事。对长任务来说,compact 能让会话继续进行,也能保留大体脉络。

但 compact 也不是万能的。它会丢掉一些细节,尤其是很早之前的边缘约束、某个文件的具体改动、某次命令输出里的小线索。所以长任务 compact 后,我通常会做两件事:

  • 让 Codex 先复述当前目标、已完成事项、未完成事项;
  • 如果某个关键细节很重要,把它写进文件、issue、PR 描述或交接摘要里。

不要指望会话历史永远完美保存。真正重要的东西应该落到可查的地方。

11. 多开窗口是可以的,但要有边界

多开几个 Codex 会话窗口是正常的。我一般会这样分:

  • 主线窗口:当前最重要的 PR、发布或事故;
  • 调研窗口:临时查资料、比较方案;
  • 文档窗口:写文章、整理飞书文档、生成报告;
  • 验证窗口:跑测试、查日志、做一次性数据分析。

多窗口的风险是结论分散。解决办法是每个窗口结束时生成一段交接摘要,明确「可以带回主线的结论」。不要把多个窗口的完整历史互相搬运,那只是把省下来的 token 又花回去。

12. 先让 Codex 计划,再让它执行

对复杂任务,直接说「帮我修好」当然可以,但容易让模型一上来就读很多文件、跑很多命令。更省也更稳的方式是:

先不要改代码。请先说明你会检查哪些文件、可能的原因、验证方式。

计划阶段通常不贵,但能避免后面走错方向。确认方向后再让它执行,整体反而更省。

一张实用检查表

高成本信号更好的做法
一个会话已经跨了多个主题生成交接摘要,开新会话
用户消息里贴了长日志改成给文件路径,让 Codex 搜关键行
一次要求处理很多 issue / PR分批处理,或先做优先级列表
需要读很多文档指定章节或目标问题,不要泛读全文
需要跑数据库统计先确认口径,再执行查询
反复强调固定规则写进 AGENTS.md 或 skill
输出经常很长明确 top N、只要差异、不要贴全文
任务需要长时间验证拆成「实现」「验证」「发布」多个会话

别把 token 优化变成新的负担

写到这里,很容易让人产生一种错觉:用 Codex 必须小心翼翼,时时刻刻算 token。我的实际感受正好相反。

Codex 的额度在日常工程使用里是够用的。真正需要关心的不是「每句话省一点」,而是避免明显浪费:把整份日志粘进来、一个会话混十几个主题、重复贴固定规则、让模型在错误方向上跑很久。这些优化本身也会改善工作质量,不只是省 token。

如果为了省 token,把本来顺畅的工作拆得七零八落,频繁开新窗口、复制摘要、重新解释背景,那就过头了。工程效率永远是第一位的。我的判断标准很简单:

情况是否值得优化
正在处理一个连续任务,会话上下文还能帮上忙不急着拆
会话已经混入多个不相关主题值得拆
只是怕 compact没必要
大段日志、CSV、JSON 正准备贴进聊天框值得改成文件路径
一次性冷门调研值得新开会话
固定规则每次都重复说值得沉淀到规则或 skill

所以更准确的说法不是「省 token」,而是「减少无效上下文」。有效上下文应该保留,无效上下文才应该删掉。

对团队来说,token 优化其实是流程优化

如果只是个人偶尔用 Codex,token 成本可能没那么显眼。但当团队开始把 Codex 用在 PR review、CI 排查、发版、数据分析、文档生成这些日常工作上,token 就会变成一种工程预算。

这个预算不应该靠「少用」来控制。真正有效的是把流程设计好:

  • 规则稳定、可复用;
  • 数据通过文件和脚本流动;
  • 对话按任务边界拆分;
  • 长日志和大文档不直接塞进聊天;
  • 每次让模型先说口径,再大规模执行;
  • 重要任务结束后生成交接摘要。

这样做不是为了抠几毛钱,而是为了让 Codex 的工作方式更可靠。长上下文很强,但它不是无限免费的白板。真正好用的 agent 工作流,应该让模型把精力花在判断和决策上,而不是反复读同一堆历史材料。

参考资料

附:写这篇文章时又花了多少 token

这部分统计会在文章生成完成前写入,因此不会包含最后一次构建校验之后的最终回复。这样处理是为了避免「为了统计统计本身又产生新的统计」。

截至写入本文前,本轮写作相关模型请求共 26 次(另有 1 条上下文压缩记录未计入接口成本),合计 3,517,666 tokens,约占当时 Codex 周用量的 1%。按 GPT-5.5 标准 API 价格估算,原始成本约 $4.1587。同样要注意,这只是 API 单价口径下的原始估算,不等同于订阅套餐里的真实摊销成本。

指标数值
输入 tokens3,501,200
缓存输入 tokens3,075,840
非缓存输入 tokens425,360
输出 tokens16,466
reasoning 输出 tokens1,683
缓存命中占输入比例87.9%
估算成本(API 原始价格口径)$4.1587

逐次模型请求明细如下。说明列是根据本轮操作顺序做的阶段标注,价格仍按上面的 GPT-5.5 标准 API 公式估算。

#本次调用说明输入缓存输入输出推理输出估算成本
1读取任务与写作规则,确认博客仓库结构203,0424,480478170$1.0094
2检索 OpenAI prompt caching、GPT-5.5 与 agent token 资料215,467202,62425897$0.1733
3读取飞书源文档和站点文章风格样例215,525208,768370$0.1393
4整理源文档中的主会话统计口径219,938215,42444287$0.1435
5确认图表方案与文章结构223,147219,5202848$0.1364
6生成/整理封面图与图表数据233,349223,10439347$0.1746
7起草文章主体前的结构化推理232,197208,7682,072225$0.2837
8上下文压缩记录;非一次实际模型接口成本0000-
9恢复压缩后的上下文并确认任务状态68,15153,63229550$0.1083
10检查博客仓库、frontmatter 和图片目录76,40167,968471101$0.0903
11生成 PNG 图表并处理中文字体问题77,67170,0169721$0.0762
12补充官方资料引用与外部研究引用77,84577,18435523$0.0525
13写入文章初稿与图片引用85,01277,696958$0.0783
14检查 session log 位置和 token 统计方法85,15484,8642,3209$0.1135
15解析 token_count 事件结构93,96084,8648019$0.0903
16定位当前用户消息所在窗口94,31193,5681,96912$0.1096
17聚合本轮 token 明细112,14394,0804,552369$0.2739
18检查图表实际显示效果114,94996,12826338$0.1501
19运行 Astro 构建校验115,259114,560936$0.0636
20等待构建完成并读取结果115,457115,07220217$0.0655
21准备写入本轮 token 统计说明115,848115,0722099$0.0677
22生成最终 token 明细表116,837115,58428117$0.0725
23构建后复核文章与图片资源119,278116,60854458$0.0880
24汇总最新统计口径120,697119,16817653$0.0725
25生成写入正文前的统计摘要121,498120,192335224$0.0767
26读取构建输出并准备最终补丁123,95553,632928$0.3812
27输出明细表供写入文章124,109123,264737$0.0680

这张表比总成本更有用,因为它能反推下一次怎么优化。

最明显的是第 1 次调用:输入 203,042 tokens,缓存输入只有 4,480 tokens,缓存命中率约 2.2%,单次成本就到了 $1.0094。原因并不复杂:这轮写博客是在一个长期工程会话里临时切出来的,模型要重新吸收写作任务、站点结构、工作区规则、飞书文档处理方式、图片要求等一整套背景。对一个不常发生的写作任务来说,这很正常;但如果以后经常写博客、同步公众号,就值得单独开一个「博客写作与发布」会话。

这个专用会话可以长期保留以下稳定上下文:

  • 博客仓库位置、文章目录、图片目录、frontmatter 规则;
  • 封面图和插图的尺寸、风格、不能用 SVG 的约束;
  • 常用构建命令和发布/同步公众号流程;
  • 文章风格偏好:少 AI 味、不要内部链接、保留个人技术复盘口吻;
  • 常用参考资料处理方式:飞书文档只当素材,不直接照搬。

如果这个任务不是天天做,也不需要一直开着窗口。更好的方式是保留这条专用会话,需要写博客时用 resume 拉起来。这样既能保留稳定前缀和缓存,又不会把博客写作材料混进主工程会话里。

第 2 到第 7 次调用的缓存命中已经明显改善,大多在 89% 到 98% 之间。说明一旦写作上下文稳定下来,继续查资料、读源文档、整理结构、生成图表,缓存就能发挥作用。这里的优化重点不是拆会话,而是避免在中途频繁改变写作规则。比如不要一会儿要求公众号风格、一会儿要求论文风格、一会儿又要求产品公告风格;风格稳定,前缀也更稳定。

第 11 次「生成 PNG 图表并处理中文字体问题」成本不高,但暴露出另一个可优化点:图表生成脚本可以沉淀成站点工具。现在每次都让 Codex 临时写 matplotlib 脚本、处理字体、检查 PNG,如果以后经常写带图表的文章,可以在博客仓库里放一个 scripts/render_blog_charts.py 模板,或者在 skill 里记录中文字体、尺寸、配色、输出路径。这样模型只需要填数据,不需要每次重新推导图表工程细节。

第 14 到第 17 次是在解析当前 session log,计算这篇文章自身消耗的 token。这里的输出和推理都明显变多,尤其第 17 次输出 4,552 tokens。它本身有价值,但不应该每篇文章都重新发明一次。更好的做法是把「解析 Codex session token 用量」做成固定脚本:输入 user message 片段或 turn id,输出 Markdown 表格和成本估算。这样以后写类似文章,只需要运行脚本,不需要让模型在聊天里反复解释和手工汇总。

第 19 到第 25 次大多是构建、复核、准备写入统计,缓存命中很好,成本都不高。这说明验证步骤不必为了省 token 而省掉。构建一次能发现 frontmatter、图片路径、Markdown 表格这类问题,收益远大于这点 token。

第 26 次调用比较特殊:输入 123,955 tokens,缓存输入只有 53,632 tokens,缓存命中率约 43.3%,成本突然升到 $0.3812。它发生在读取构建输出并准备最终补丁时。这里的优化不是不跑构建,而是控制构建输出进入上下文的方式:只保留是否成功、失败摘要和相关错误;对于成功构建,不需要把几百行 route 生成日志完整带进下一轮。可以让命令输出限制得更短,或者只 grep 新文章路径和最终 Complete

所以,单看这篇文章的写作过程,最具体的优化建议是:

观察下次怎么做
第 1 次调用缓存命中极低,说明写作背景是冷启动建一个「博客写作/公众号发布」专用会话,按需 resume
写作风格、目录、图片规则每次都要重新确认把这些规则沉淀到博客 skill 或仓库说明
图表脚本每次临时生成准备固定 PNG 图表模板,模型只填数据
token 统计逻辑靠临时脚本和聊天推理做成固定统计脚本,输出 Markdown 片段
成功构建日志很长构建输出只保留结果摘要和新页面路径
文档源和文章仓库是两个领域写作会话与主工程会话分开,避免污染主线缓存

换句话说,优化不是把写作拆得更碎,而是把可复用的写作环境固定下来。下一次再写同类文章,最理想的流程应该是:resume 博客会话,给出飞书文档或素材路径,直接生成文章、图表、构建校验和公众号同步草稿。这样既能减少冷启动成本,也能减少主工程会话被写作上下文污染。