Token Tracker - 从 Token 记账到个人 AI Gateway 本文由作者提供想法和校验,DeepSeek V4 Pro协助编写、整理和发布。
摘要
本文介绍作者开发的 Token Tracker:从插件上报演进为个人 AI Gateway,零插件透传自动记账,支持多协议、虚拟 key 与故障转移,记录 TTFT 并估算成本。作者发现平台间缓存命中率差异显著(80-90% vs 65%),采用 Docker + SQLite 部署。
最近几个月我先后用了好几个平台的 Coding Plan——GitHub Copilot、百炼、Kimi,还有公司提供的 API。用着用着,发现公司 API 的缓存命中率特别低。低到什么程度?我想知道具体数字,于是就 vibe coding 了一个 Token Tracker。
从插件到网关
第一版 Token Tracker 是 Server + 客户端插件 + Dashboard 的结构:我在 Opencode 里写了一个插件,每次对话结束后把 Token 使用详情上报给 Server 端。
用了一段时间,效果不太理想——每个客户端都要单独装插件,装不上或者插件挂了,数据就是空白。不同 agent 生态(Opencode、Claude Code、Codex)插件机制各不相同,维护成本也高。
后来我想通了:与其在客户端上挨个打补丁,不如把所有流量都收口到自己的网关里,在透传的时候自动记账。客户端零改造,只要把 base_url 和 key 指过来,流量自然经过网关,账就记下了——网关没经过的流量本来也就不在我要统计的范围内。
于是 Token Tracker 就从一个记账工具,长成了个人 AI Gateway。
架构
Token Tracker 现在是 Next.js 单进程,跑三个角色:
| |
几个关键设计:
- 零插件接入:OpenAI、Anthropic、Gemini 三种协议全部支持,客户端只换 base_url 和 key 就走通了
- 自动记账:从响应里解析 usage(输入 / 输出 / 缓存读 / 缓存写),流式和非流式都覆盖
- 虚拟 key:
vk-前缀随机生成,AES-256-GCM 加密落库,可以单独吊销。key 的名字就是统计维度——一个 agent 一把 key,谁的用量一目了然 - 多 key 故障转移:每个上游可以配多个 key,遇到 429 / 5xx / 超时自动切换下一个;流式一旦开始输出就不重试
- 模型路由:按请求里的 model 匹配上游,支持精确匹配和前缀通配
一个上游配多把 key 的好处,是用满各家平台的套餐额度;坏处是如果频繁切换 key,上游的 prompt cache 就废了。所以网关默认"粘住"顺序第一个可用的 key,尽量保住缓存命中率——这个后面还会提到。
缓存命中率
缓存命中率是我最关注的指标。通过这几天的记录,不同平台的缓存命中率差别非常明显。
大概说一下我观察到的数据:
| 平台 | 缓存命中率 |
|---|---|
| 其他平台(DeepSeek、Kimi等) | 约 80-90% |
| 公司 API | 约 65% |
公司 API 的命中率差了将近 20 个百分点,这是 API 层面直接带来的差异。当时我猜测是公司中转做了一些处理——比如对请求做了额外的包装、校验或者日志记录——导致缓存命中条件被破坏了,可能是供应商的问题。
如果这部分可以优化,应该能降低不少成本。毕竟缓存命中的成本一般是非命中的10%甚至更低。
这里没有 GitHub Copilot 的数据——因为我已经退订了。
缓存命中率这个指标为什么重要?它反映了你对 Coding Agent 的利用效率。命中率高,意味着你之前的上下文被有效复用了,Agent 不用重新处理同样的信息。命中率低,说明每次对话都像是"从头开始",浪费了大量 Token 去重复建立上下文。
网关模式下,这个指标还多了两个变数:
- 路由策略:如果上游 key 频繁切换,缓存就命中不了——所以网关默认粘住同一把 key
- 透传的纯度:网关纯透传不改 body,请求和直连上游一模一样,缓存命中率不会被网关自己损耗
当然,很大一部分优化是工具自己做的——比如 Opencode 的上下文管理策略。但我们自己的使用习惯也会影响命中率。比如:
- 规划做得清晰,一次对话专注于一个任务,上下文连贯性好,命中率就高
- 频繁切换话题或重置对话,命中率自然低
这个指标在未来一长段时间里应该都会比较重要。随着各家模型按 Token 计费的趋势,缓存做得好不好,直接影响到成本和效率。
Token 输入输出比
另一个有意思的发现是关于输入输出比。我的实际数据大约是 100:1——输入 Token 远多于输出 Token。
为什么会这样?因为在 Coding 的过程中,制定规划可能需要多轮对话。一次对话的上下文可能累积到几十 K 甚至上百 K。一段时间内累计的上下文达到一兆级别,但实际输出的代码并没有那么多。
举个例子,跟 Agent 讨论一个架构方案,来回确认需求、调整设计、澄清细节,这个过程的输入是大段的上下文 + 你的反馈,但 Agent 的输出只有几段文字。等到真正写代码了,Agent 输出的也只是一个文件或一个函数。
这个数据有什么实际意义?如果用的是 DeepSeek 这类按用量付费的 API,可以根据自己的使用习惯做一个大概的成本估算,不至于对输入成本完全没有概念。
TTFT 与成本
除了 token 本身,网关顺手还记了两个指标:TTFT 和成本。
TTFT(Time To First Token):流式响应的首 token 延迟——请求发出去到第一个字返回,中间隔了多久。这个指标直观反映上游 API 的响应速度:模型推理快不快、网关转发慢不慢,都体现在这里。非流式请求没有首 token 的概念,只记总耗时(Latency)。
成本:基于模型单价在查询时实时估算,单价(输入 / 输出 / 缓存读 / 缓存写,USD 每 1M tokens)自动从 models.dev 拉取填充,也可以手动改。改完单价历史用量会按新价整体重算——所以它不是账单,而是一个"官方价参考":知道这些 Token 按官方定价值多少钱,方便横向比较各家 API 的性价比。
基于这两组数据,Dashboard 上还能看到:
- 平均每次请求的成本、平均每 1M token 的成本(拆分输入 / 缓存读 / 输出单价)
- 每日成本堆叠图(按模型族),以及叠加在趋势图上的缓存命中率曲线
- 价格模拟器:输入一个假设的单价,重算历史成本,估算"如果换一个 API 会花多少钱"
顺便说一句,Token Tracker 本身是个轻量的个人 AI Gateway——核心就是"流量经过的地方自动记账",外加一个管理界面和 Dashboard,没有其他花活。也正是因为记账发生在透传链路上,TTFT、延迟这些数据才有机会被完整记下来。
部署方案
部署用的是 Docker + SQLite,跑在自己服务器上:
| |
首次启动后到 /admin 配好上游、创建虚拟 key,客户端改一下 base_url 就全线走通了。
之前用 Vercel + Neon 免费方案部署过一版,个人用倒是能跑,但 Neon 的数据库空间限制比较紧,数据量大起来要清理旧数据。换成 SQLite 单文件 + 服务器部署之后,不用再操心容量配额;而且网关要透传流量,跑在自己服务器上延迟和可靠性也更有保障。
GATEWAY_SECRET 是主密钥,用来加密落库的上游 key 和虚拟 key,建议用 openssl rand -hex 32 生成。
总结
Token Tracker 从最初的记账工具变成了个人 AI Gateway,中间最大的转折是想明白了一件事:记录流量,最好的方式不是旁路监听,而是让自己成为流量的必经之路。只要流量过网关,账就自动记上了,还顺带拿到了每个 agent 最真实的用量数据。
它反映了一个正在发生的趋势:AI Coding 工具越来越像一种"基础设施消费",我们需要开始关注它的效率指标,就像我们关注 CPU 利用率和内存占用一样。缓存命中率、输入输出比、TTFT 和成本,这些都是在为 Token 付费时需要关心的数字。
代码和部署记录都开源了: