Repository navigation
pricing: bill cache hits at the model's own fraction on Opus 5.5, Sonnet 5.5, Fable, Mythos - #201
Open
Vishal Kannankara (kvishalv) wants to merge 2 commits into
Open
Vishal Kannankara (kvishalv) wants to merge 2 commits into
Vishal Kannankara (kvishalv) wants to merge 2 commits into
Conversation
…net 5.5, Fable, Mythos weights_for gave every claude-* id outside MODEL_WEIGHTS one curve with cache_read=0.10 and called the ratios uniform. Anthropic's price list bills a cache hit at 0.05x input on Opus 5.5 and Sonnet 5.5 and at 0.025x on Fable and Mythos 5.1 and 5.2; every other ratio is the same on all models. Cache hits are most of a session's tokens, so a Claude Code session on one of these models was priced well above its bill. Pick the ratio by model in _claude_weights, on the id with dots as dashes, so a router's spelling and a dated snapshot match too. The live ledger test prices Opus 5.5 at 435 per request, not 485, and an "id outside the table" test uses Opus 4.5.
Muhammad Abdullah Butt (1AbdullahButt)
left a comment
Contributor
There was a problem hiding this comment.
Looks correct. Here's what I checked.
- The prices. I read Anthropic's pricing page today. Cache hits are 0.05x input on Opus 5.5 ($0.20 against $4) and Sonnet 5.5 ($0.10 against $2), and 0.025x on Fable 5.1/5.2 and Mythos 5.1/5.2 (the page's footnote 1). Every other model is at 0.1x, including Opus 5 ($0.50/$5), Sonnet 5 ($0.20/$2), Fable 5 and Mythos 5 ($1/$10), and Haiku 5.5 in both tiers. The other ratios match the curve on those models (5m write 1.25x, 1h write 2x, output 5x), so changing only
cache_readis right. - The patterns. I copied
_CLAUDE_CACHE_READand the dot-to-dash step of_claude_weightsinto a standalone snippet and ran ids through it. These get the new ratio:claude-opus-5-5,claude-opus-5-5-20261101,claude-sonnet-5.5,us.anthropic.claude-opus-5-5-v1:0,claude-opus-5-5[1m],claude-fable-5-1andclaude-mythos-5.2. These stay at 0.1:claude-opus-5, a datedclaude-opus-5-20260601,claude-fable-5,claude-fable-5-20260801,claude-haiku-5-5andclaude-opus-5-50. The\bis what keeps a dated Fable 5 id (5-2026...) out of the5-[12]pattern. - Lookup order.
claude-opus-5andclaude-sonnet-5are still exactMODEL_WEIGHTSentries at 0.10, which is correct for them. No 5.5, 5.1 or 5.2 id is in the table, so none of them skips the new path.
I didn't run the test suite.
Optional: the comment above WEIGHTS_CLAUDE (pricing.py:118) still says Opus/Sonnet/Haiku share the ratios. It could point to _CLAUDE_CACHE_READ, as the module docstring now does.
Reviewed with help from Claude Code.
…odel Two comments in pricing.py still called the Claude ratios the same on every model: the one above WEIGHTS_CLAUDE and the one above AGENT_DEFAULT_MODEL. Point both to _CLAUDE_CACHE_READ. No code changes.
Contributor
Author
|
Muhammad Abdullah Butt (@1AbdullahButt) thanks for checking the prices and the id patterns yourself, and for the list of ids you ran. You are right about the comment: it still called the ratios shared. I changed it in ee5340f, and also the comment above |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
pricing.weights_forreturns one curve for everyclaude-*id that is not inMODEL_WEIGHTS, withcache_read=0.10, and its docstring calls the Claude ratios uniform. Anthropic's price list (pricing, read on 2026-11-10) shows that every ratio is the same on all Claude models except the cache hit. A cache hit costs 0.05x the input price on Opus 5.5 and Sonnet 5.5, and 0.025x on Fable and Mythos 5.1 and 5.2. It costs 0.1x on the other models. Cache hits are 90% or more of an agent session's tokens, so the wrong ratio moves the whole figure. TheMODEL_WEIGHTSsnapshot is from 2026-07-27, before these models, so they all fall to the generic curve.I measured it on my own Claude Code logs, counts only. In the 150 most recent session files (14,178 unique assistant messages, with the 1-hour split from #192), 90% of the messages are on
claude-opus-5-5,claude-sonnet-5-5orclaude-fable-5-1, and cache hits are 95% to 98% of their tokens. Priced asmaindoes it, effective tokens are 52% above the documented price on Opus 5.5, 31% above on Sonnet 5.5, and 48% above on Fable 5.1. Over all models in the logs, they are 41% above.te statusand the ledger overstate these sessions by that much._CLAUDE_CACHE_READlists the 2 exceptions as patterns on the id with dots as dashes:claude-(opus|sonnet)-5-5andclaude-(fable|mythos)-5-[12]._claude_weightsreturns the Claude curve with thatcache_read, andweights_foruses it for any otherclaude-*id. A router's spelling (claude-sonnet-5.5), a provider prefix and a dated snapshot match too. Mythos has no id in the models overview (limited availability), so a pattern covers it and I did not guess an id.The tests are in the existing
tests/test_cache_write_1h.py. They check the 6 ids and 3 spellings that get the model's own ratio and price, 9 other Claude ids that keep 0.1, and a live session on Opus 5.5 priced throughaccounting.effective. Two existing tests change. The test for "a Claude id outside the table" usedclaude-opus-5-5as its example, which no longer keeps 0.1, so it usesclaude-opus-4-5. The ledger test intests/test_live_hooks.pypriced a session of the helper's default model, Opus 5.5, at 485 per request. It is 435 with the 0.05 ratio, and the comment says why.How it was produced: Claude Code, an AI coding agent, found the mismatch while checking #191 and #192 against Anthropic's price list, measured it on my logs, and wrote the fix and the tests. I directed the work and ran the checks below.
What was verified, on macOS with Python 3.12.0, on
mainatfd6299a:python -m pytest tests/test_cache_write_1h.py tests/test_live_hooks.py -k "cache_hit or folded_once"reports 11 failed and 10 passed. The failures are the 9 ratio cases, the live-session test and the ledger test. The 9 control cases pass. The failing values are the ones the bug predicts, for exampleassert 0.1 == 0.05, and 1455 for the ledger test where 1305 is right.python -m pytest tests -rfEs --tb=linereports 901 passed, 16 skipped and 0 failed. Each skip needs a tool or a platform that the machine does not have, for example a real Codex, Hermes or opencode CLI.mainhas since moved to81e32e5. None of its 6 new commits touchespricing.pyor the accounting code, and the branch merges cleanly with it.Note for the experiments, as in #192: Claude rows priced after this change on these models are not directly comparable to rows priced before it. I did not run
experiments/tests.