我正在构建 Tokamak,一个监控 Claude Max 配额的 macOS 菜单栏应用。几周前,Anthropic 在他们的服务条款中发布了这样的条文:
“您不得使用 OAuth 或类似的授权机制来允许第三方应用程序代表用户访问 Claude。”
而我,正在使用浏览器 cookies 调用一个未公开的端点来读取 Claude Max 配额,盯着屏幕想:“现在怎么办?”
今天的工作方式(有用的权宜之计)
Tokamak 需要知道你的配额百分比。就是当你在 claude.ai 上用了一段时间后看到的那个 42%。问题是Anthropic 没有公开的配额 API。没有一个带 API key 的文档化的 GET /api/quota。
但确实存在一个 claude.ai 网站自己使用的内部端点:
GET /api/organizations/{org_id}/usage
返回类似这样的内容:
| |
要调用这个端点,你需要已登录用户的会话 cookies。Tokamak 用一个隐藏的 WKWebView 解决这个问题:用户在应用内的 claude.ai 中登录,cookies 保留在 WebView 中,应用每 30 秒使用这些 cookies 进行轮询。
这样做有效。已经运行了好几个月。但这是一个优雅的权宜之计,而不是稳健的解决方案。我们在使用一个内部 API,Anthropic 可以随时更改、破坏或阻止它,而无需预先通知。
法律灰色地带
OAuth 的禁令是明确的。但这适用于 cookies 吗?技术上我们没有使用 OAuth 或"类似的授权机制"。用户直接在标准 WebView 中登录 claude.ai。就像在应用内打开 Safari。
但"类似授权机制"这个短语足够模糊,Anthropic 的律师可以随意解释。今天我们处于法律灰色地带:没有明确禁止,但也没有明确允许。
如果有一天 Anthropic 决定第三方 cookies 也不行,我们就失去了配额数据。就这样,一夜之间。
B 计划:无 API 估算
这里开始变得有趣。问题是:我们能仅使用本地数据估算你的配额百分比吗?
在回答之前,你需要了解 Claude Max 配额是如何工作的。这不是简单的令牌计数器。
配额是等效成本,不是令牌
Anthropic 不像数碗里的花生一样数令牌。它计算按 API 定价的等效成本。每个令牌根据其类型和模型有不同的"价格":
| 令牌类型 | 相对权重 |
|---|---|
| 输出(回复) | 比输入贵 5 倍 |
| 输入(你的消息) | 1x(基准) |
| 缓存读取 | 0.1x(几乎免费) |
| Opus | 比 Sonnet 贵 1.67 倍 |
简单来说:一条让 Claude 深度思考并写长回复的简短 Opus 消息比你发给 Haiku 的长消息加简短回复消耗更多配额。
就像电费账单。你不是按"插电小时数"付费。你按千瓦时付费,烤箱比卫生间灯泡耗电 10 倍。
5 小时窗口
配额不会无限累积。它像一个5 小时的滑动窗口。你发送的每个令牌在确切的 5 小时后"过期"。如果上午 10:00 你用高强度会话消耗了 30% 的配额,下午 15:00 那 30% 就会释放。
想象一个底部有洞的水桶。你倒入的水(你的消息)5 小时后从底部流出。水位就是你的使用率。
三个组件
好,我们知道配额是等效成本,在 5 小时窗口中移动。我们能在本地复制这个吗?
诚实的答案:不能达到手术级精度,但能达到实用精度。 我们不会准确命中 73%。但我们会知道你处于"橙色区域,小心"。结果表明这正是你需要的。
系统有三个部分,每个都有明确的角色:
1. 估算器(M1):会计
负责计算。读取 ~/.claude/ 的本地文件(包含你发送和接收的所有令牌,带时间戳和模型),计算过去 5 小时的等效成本,除以等级的"总预算"。
估算 = 5小时窗口成本 / 等级预算 * 100
就像记录这个月用了多少电:你知道烤箱、冰箱、电脑的千瓦时。相加,除以你的费率,就得到账单估算。
问题: 我们不知道确切的总预算。Anthropic 不公布。所以我们需要校准它。这就是第二个组件的作用。
2. 校准器(A3):观察学习者
这是最优雅的部分。称为衰减估算器,工作原理如下:
当你停止工作时(去吃饭、开会、睡觉),5 小时前发送的令牌开始过期。配额自动下降。由于我们确切知道发送了什么令牌以及何时发送(在本地 JSONL 中),我们可以观察当这些特定令牌过期时配额下降了多少。
就像前面的水桶例子:如果你倒入一升红水和一升蓝水,看到红水流出时水位下降 3 格,蓝水流出时下降 1 格,现在你知道红水比蓝水重 3 倍。没人告诉你。只是通过观察。
注意:这自然发生。不消耗配额。不需要实验。每次你起身喝咖啡,校准器都在学习每种令牌类型的真实权重。
3. 分类器(A5):将数字转化为决策
这里有个反直觉的洞察。第一反应是尝试估算精确百分比:“你在 73%"。但这在数学上很难精确做到。API 返回 0 到 100 的整数,有我们无法测量的隐藏因素,来自其他设备的活动(claude.ai 网页版、移动端)对我们是不可见的。
但你需要知道是 73% 还是 77% 吗?不需要。你需要知道在哪个区域:
| 区域 | 范围 | 含义 |
|---|---|---|
| 绿色 | 0-60% | 放心,大胆使用 |
| 黄色 | 60-80% | 适度使用,特别是 Opus |
| 橙色 | 80-95% | 小心,接近限制 |
| 红色 | 95-100% | 停止或切换到 Haiku |
分类为 4 个区域而不是回归 100 个值更容易也更有用。如果真实配额是 72%,分类器说"黄色”,就是对的。如果估算器说"72% +-20%",52-92% 的范围跨越三个区域,什么都说明不了。
这就像带两位小数的数字温度计和有三种颜色的水银温度计的区别:冷、温、发烧。对于决定是否吃布洛芬,三色的同样好用或更好用。
完整流程
graph TD
A["~/.claude/*.jsonl<br/>(本地令牌)"] --> B["估算器 M1<br/>(会计)"]
B --> |"5小时窗口内<br/>等效成本"| D["分类器 A5<br/>(红绿灯)"]
C["校准器 A3<br/>(观察衰减)"] --> |"每种令牌类型<br/>真实权重"| B
E["配额 API<br/>(运行时)"] --> |"基准事实<br/>用于校准"| F["QuotaCalibrationLog<br/>(配对数据)"]
F --> |"持续<br/>校准"| C
F --> |"等级<br/>预算"| B
D --> G["🟢 绿色"]
D --> H["🟡 黄色"]
D --> I["🟠 橙色"]
D --> J["🔴 红色"]
style E stroke-dasharray: 5 5
style F stroke-dasharray: 5 5
当 API 工作时,我们有真实数据,同时用配对数据训练估算器:“当你有这些本地令牌时,API 显示 42%"。我们积累数千个这样的配对。API 消失的那天,估算器已经知道每种令牌类型的"权重”,因为它通过观察学到了。
精度如何随时间提高
整个系统的窍门是 QuotaCalibrationLog:每 30 秒保存的记录,包含两项内容:
- API 说什么(真实数据,基准事实)。
- 我们本地计算什么(窗口中的令牌、等效成本、使用的模型)。
每条记录都是一个校准点。每天 2,880 个点(使用时间内每 30 秒一个),两周内我们有足够数据用于:
- 校准等级预算:我们知道当本地成本达到 $X 时,API 显示 100%。现在我们知道了 $X。
- 验证权重:如果我们的比率(输出 5x 输入,Opus 1.67x Sonnet)有误,配对数据会揭示。
- 检测 Anthropic 的变化:如果某天估算器的残差激增,我们知道公式变了。自动重新校准。
第一天,估算器使用公开 API 价格作为近似。一周后,已有经验权重。一个月后,有了真实行为的相当精确模型。
诚实的限制
把这个当作银弹来卖是不诚实的。有些东西我们永远无法捕获:
- 其他设备的活动。 如果你在手机上使用 claude.ai,这些令牌消耗配额但对 Tokamak 不可见。估算器会低估。
- 隐藏因素。 如果 Anthropic 根据时间、服务器负载或任务复杂性应用惩罚,我们无法测量。
- 点精度。 估算器误差约 +-15-25%。对于精确百分比,这不够。对于知道是绿色、黄色、橙色还是红色区域,这够了。
这就是为什么分类器是用户看到的组件,而不是直接的估算器。我们不说"你在 73%"。我们说"你在黄色区域"。这个我们 85-90% 的时间都能说对。
“为什么不用机器学习模型?”
如果你读到这里,可能在想:“兄弟,为什么不用校准数据训练一个 CoreML 模型就完事了?“这是个显而易见的问题。答案是这就像用大炮打蚊子,而且蚊子还在防弹玻璃后面。
问题在玻璃,不在大炮
想象酒吧里的糖果罐。你知道有软糖、甘草和口香糖,每种都有不同的"价格”。你想知道已经吃了罐子的百分之几。但你只能从外面看罐子,玻璃有扭曲:只能区分"满的”、“半满”、“快空"或"空”。看不到单个糖果。
无论你戴 1 万元的眼镜还是用电子显微镜都没关系。玻璃仍然扭曲。 如果接收到的信号本质上是模糊的,更强的光学功率不会给你更多信息。
这正是这里发生的情况:
- 单一观测值:API 返回 0 到 100 之间的整数。一个数字。这就是我们从真实系统接收的全部信息。
- 残酷的量化:大多数连续观测(每 30 秒)的增量 = 0。有变化时,是 1% 或更多。没有精细信息。
- 6+ 个未知数:每个模型的输出、输入、缓存读取、缓存写入权重,加上总预算,加上可能的隐藏因素(GPU 时间、服务器负载)。
一个有 6 个未知数和 1 个方程的系统。无论你用线性回归、梯度提升、神经网络还是 transformer 都没关系。这是一个欠定问题。信号中没有足够信息解决所有未知数,即使有十亿个参数也不行。
机器学习得到什么 vs. 失去什么
| 线性回归(M1) | CoreML / 神经网络 | |
|---|---|---|
| 精度 | +-15-25% | +-15-25%(同样上限) |
| 可解释性 | 完全(看到每个权重) | 黑盒 |
| 调试 | “output_opus 权重错了” | “准确率下降了” |
| 打包大小 | 0 KB | 2-5 MB 框架 |
| 重新校准 | 改一个 JSON | 重新训练 + 转换 .mlmodel |
| 漂移检测 | 比较残差 | 比较…什么? |
如果 Anthropic 明天改变配额公式,用线性估算器你能确切看到哪个残差激增,哪个权重需要调整。用机器学习模型你看到指标下降,必须用新数据盲目重新训练,希望它收敛。
温度计的类比
如果你的水银温度计分辨率是 1°C,买一个 0.001°C 的数字温度计不会改善测量,如果你通过同样的厚玻璃墙测量烤箱温度。瓶颈是墙,不是仪器。
这里的"墙"是整数量化 + 隐藏因素 + 其他设备的不可见活动。无论多复杂的模型都无法看穿它。
相位检测器(红绿灯)正是因为接受了这个限制而工作:不尝试猜测"73.2%",而是分类为 4 个区域。这在可用信息范围内是稳健的。
我们现在正在做什么
最紧急的是开始记录数据。每一天没有记录就是失去的校准天数。所以优先级是:
- 现在:实现 QuotaCalibrationLog。UI 无变化。只是静默积累配对数据。
- 2-4 周内:有了累积数据,当 API 失败时激活估算器作为后备。
- 4+ 周内:激活被动校准器(衰减估算器)来学习经验权重。
如果明天 Anthropic 关闭供应,估算器已经校准好了,用户会看到红绿灯而不是百分比。不完美。但有用。而且对其限制是诚实的,这已经比大多数仪表板强了。
有时最好的 B 计划是在需要之前就开始构建的计划。