做一份本地的 AI 工作台账

Claude Code 与 Codex 在本地记下的数据,都足以重建出有用的一周 AI 辅助工作。但它们记的形状不一样

把每个 JSONL 行里的每个数字加起来做出的报告,会把一些 Codex 会话数两遍、漏掉 Claude 的缓存活动,还会在会话中途换模型之后把用量归到错的模型上。工程问题在于归一化:把两种一直在变的日志格式,变成一个很小的事件模型,然后让之后每一次计算都依赖这个模型

本文描述的是 Agent Island v1.6.1 里发布的 macOS 实现。这个方法可以用在别的本地工具上,重要的部分是那些记账规则和它们的边界

Agent Island 周报卡:本地 token 总量、API 价值、服务商占比、模型分项与岛民段位
周报卡由本地聚合渲染。只有在你明确动手之后,它才会被复制或分享

从真正代表用量的那些记录开始

Claude Code 把项目会话存成本地项目目录下的 JSONL 文件。解析器只在助手消息同时含有 usage 对象和模型名时才接受它,并分别读取输入、输出、缓存创建和缓存读取 token

Claude 的日志里可能有重复的用量记录。当消息 ID 和请求 ID 都可用时,这一行会被去重;缺任何一个标识的行会被保留,因为丢掉它会把一份不完整的日志变成一次静默少算。合成的模型占位值和零 token 的行会被忽略

Codex 的 rollout 文件需要另一个解析器。一行 turn_context 提供当前模型,之后一条带 token_countevent_msg 提供用量。解析器把当前模型往前带,因为一个会话可能在两个回合之间换模型

计数来源是 last_token_usage,不是那个累加的 total_token_usage。在有 fork 的会话上用累计值很危险,因为更早的用量可能被再数一次。Codex 还把缓存输入算在输入总量里,所以解析器会先减掉缓存输入,再按普通费率给剩下的输入计价

两个读取器发出同一种内部记录:

服务商
时间戳
模型
输入 token
输出 token
缓存创建 token
缓存读取 token

过了这条边界之后,报告代码就不再需要知道某个事件是由哪种 JSONL 格式产生的

保留两个 token 总量

单独一个 token 总量是有歧义的。实现保留了两个。全量总数包含输入、输出、缓存创建和缓存读取,它回答的是「本地记录里出现了多少 token 流量」,这个数字驱动报告头条和每日活动柱

更窄的那个总数只含输入和输出,适合排除缓存 token 的视图。两个都留着,显示方式改变时就不必重扫日志

成本是第三种度量。每个事件用各自独立的输入、输出、缓存创建和缓存读取费率计价。Agent Island 把结果标为 API 价值,因为它是基于公开 API 费率的一次反事实估算,不是订阅账单,也不是关于省了多少钱的说法

价目表里没有的具名模型不会被安上一个猜出来的费率,它们的估算值为零,界面可以给出未定价模型的提示。一个在模型上下文之前就到达的早期 Codex token 行,会用解析器的模型兜底 —— 那是一条缺失上下文的规则,不是给未知具名模型定价

把这一周对齐到自然日

报告覆盖今天加上前面六个本地自然日,从午夜开始。它不是一个滚动的 168 小时窗口

每日柱是自然日桶。如果逐模型的行用的是滚动窗口,它们可能多含进大半天,从而超过头条总数。聚合器对每日合计和逐模型行使用同一条自然日边界

同一次遍历归一化事件的过程,会同时构建每日全量 token 桶、服务商合计、逐模型的输入/输出合计、逐模型全量合计,以及逐模型的 API 价值。模型行按 API 价值排序,而不是按 token 数 —— 一个跑了很多缓存读取的廉价模型可能搬动更多 token,贡献的估算价值却比少量昂贵输出还低

让分享成为一个明确的用户动作

报告由本地聚合渲染成一张固定尺寸的图。打开报告不会上传它。用户可以把图复制到剪贴板,或者打开系统分享面板。两个动作都从一份缓存好的本地渲染开始。应用不会替你发布这张图、不会替你选目的地,也不会发送底层的会话内容

本地 JSONL 文件
  -> 归一化的 token 事件
  -> 自然日聚合
  -> 本地图片渲染
  -> 点击之后,剪贴板或系统分享面板

一条网络分析管道会让归因更容易,但它会改变这个产品的信任模型。当前设计只测量 App 在本地能知道的东西,把发布这件事留给用户

缓存的是解析工作,不是把产品数据放到服务器上

会话历史很大时,一次完整的 JSONL 扫描代价不小。读取器用文件路径、修改时间和大小把逐文件的解析结果记忆化。之后刷新时,没变过的文件可以复用已解析的事件

Codex 读取器还会在付出 JSON 解析代价之前,先拒掉那些不可能含有这两类相关记录的行。很大的响应条目行,包括内嵌媒体或工具输出,不是用量记录,也不需要进入内存。这个优化避免重复劳动,同时不改变记账模型

这份台账证明不了什么

报告反映的是仍然留在机器上的记录。被删掉或移走的会话没法重建。服务商可能改变它的本地格式。一个新发布的模型可能在内置价目快照知道它的费率之前就出现。当前计算也没有包含 Anthropic 的长上下文特殊档,所以一个符合条件的请求可能与估算有出入

台账说不出一个 token 有没有产出有价值的代码。token 体量是活动量,不是结果质量。保住每家服务商原始的记账区分、只归一化真正共通的部分,并说清楚最后那个数字是什么意思 —— 这样做出来的是一份别人可以核查的台账,而不是一块只是看起来很精确的面板

相关社区资源:Techsy.community 是一个面向 AI Agent、MCP 与 skills 开发的社区平台,开发者在那里发现和讨论 Agent、MCP 服务器,以及围绕它们的工作流


Agent Island 是面向 Claude Code、Codex、Antigravity、Grok 和 Cursor 的开源状态伴侣。在 GitHub 上读源码或点个 star

Agent Island 是面向 Claude Code、Codex、Antigravity、Grok 和 Cursor 的开源状态伴侣

← 全部文章