mirror of
https://github.com/katanemo/plano.git
synced 2026-07-23 16:51:04 +02:00
feat(routing): decouple budget pricing from prompt_caching (#996)
* feat(routing): budget prices cache-aware regardless of prompt_caching flag * docs: prompt_caching is optional for the routing budget
This commit is contained in:
parent
66547bcef3
commit
ad92f7fbe7
8 changed files with 69 additions and 124 deletions
|
|
@ -9,8 +9,9 @@ There are two independent behaviors to observe:
|
|||
2. **Routing budget** — the router still runs every turn, but when it proposes a
|
||||
*different* model while the session's cache is plausibly warm, Plano only switches
|
||||
while the session's cumulative switch spend stays within `max_overhead_pct`% of what
|
||||
staying put would have cost. This is a routing concern and works whether or not
|
||||
prompt caching is on.
|
||||
staying put would have cost. This is a routing concern and is self-sufficient:
|
||||
it needs no `prompt_caching` config (it derives sessions and prices warm
|
||||
anchors at cached rates on its own).
|
||||
|
||||
---
|
||||
|
||||
|
|
@ -48,8 +49,10 @@ model_metrics_sources:
|
|||
openai-gpt-4o: openai/gpt-4o
|
||||
anthropic-claude-4.6-sonnet: anthropic/claude-sonnet-4-6
|
||||
|
||||
prompt_caching:
|
||||
enabled: true # automatic caching + session affinity (separate concern)
|
||||
# OPTIONAL for the routing budget — see below. Needed for §4 (real caching on
|
||||
# marker-based models when Plano proxies the request).
|
||||
# prompt_caching:
|
||||
# enabled: true
|
||||
|
||||
routing:
|
||||
routing_budget: # no default — presence turns it on
|
||||
|
|
@ -63,8 +66,12 @@ no aliases needed — its keys already match `provider/model` routing names). Th
|
|||
demo models are priced identically on both feeds, so every number in this guide
|
||||
holds either way.
|
||||
|
||||
The routing budget lives under `routing` and is independent of prompt caching — it
|
||||
applies whether or not `prompt_caching.enabled` is set.
|
||||
The routing budget is fully self-sufficient: configuring it turns on implicit
|
||||
session derivation and prices warm anchors at cached rates on its own —
|
||||
`prompt_caching` is **not** required. Enable `prompt_caching` for what it adds:
|
||||
injecting provider cache-control markers when Plano proxies the request (without
|
||||
markers, marker-based models like `anthropic/*` never actually cache — see §4)
|
||||
and session affinity when no budget is configured.
|
||||
|
||||
|
||||
|
||||
|
|
@ -121,9 +128,12 @@ The model listener comes up on **:12000** (per `config.yaml`).
|
|||
|
||||
## 4. See caching in action (single model)
|
||||
|
||||
Send the same large system prompt across several turns. With caching enabled,
|
||||
Plano derives an implicit session from the stable prefix and pins the model, so
|
||||
turns 2+ read the prefix from the provider cache.
|
||||
This section needs `prompt_caching: { enabled: true }` (uncomment it in
|
||||
`config.yaml`): the model here is Anthropic-family, which only caches when the
|
||||
request carries cache-control markers, and it's Plano proxying the request —
|
||||
so Plano must inject them. Send the same large system prompt across several
|
||||
turns. Plano derives an implicit session from the stable prefix and pins the
|
||||
model, so turns 2+ read the prefix from the provider cache.
|
||||
|
||||
```bash
|
||||
curl -s localhost:12000/v1/chat/completions \
|
||||
|
|
@ -353,8 +363,9 @@ the caching-ON/OFF comparison:
|
|||
|
||||
- **Baseline (no caching):** send requests with header `X-Plano-Cache: off`
|
||||
(disables implicit pinning + marker injection per request), or run with
|
||||
`prompt_caching.enabled: false`.
|
||||
- **Treatment (caching on):** default config in this folder.
|
||||
`prompt_caching` absent/disabled.
|
||||
- **Treatment (caching on):** the config in this folder with the
|
||||
`prompt_caching` block uncommented.
|
||||
|
||||
Compare, over an identical multi-turn eval set:
|
||||
|
||||
|
|
@ -400,6 +411,7 @@ curl -s localhost:12000/v1/chat/completions \
|
|||
|
||||
- Caching **never** changes which model routing selects — the router still makes
|
||||
the quality call; the overhead cap only vetoes a switch that the session can't afford.
|
||||
- The routing budget is independent of prompt caching (it lives under `routing`) and
|
||||
is fully opt-in with **no baked-in cap**: configuring it without a `max_overhead_pct`
|
||||
(or without a cost source) fails startup with a clear message.
|
||||
- The routing budget is independent of prompt caching (it lives under `routing`,
|
||||
needs no `prompt_caching` config, and always prices warm anchors at cached rates)
|
||||
and is fully opt-in with **no baked-in cap**: configuring it without a
|
||||
`max_overhead_pct` (or without a cost source) fails startup with a clear message.
|
||||
|
|
|
|||
|
|
@ -46,12 +46,13 @@ model_metrics_sources:
|
|||
# provider: models.dev
|
||||
# refresh_interval: 86400
|
||||
|
||||
# Automatic prompt caching (opt-in). Keeps a conversation pinned to the same
|
||||
# model so the upstream provider's prompt cache stays warm across turns, and
|
||||
# auto-injects cache-control markers where the provider needs them. This is a
|
||||
# separate concern from the routing budget below.
|
||||
prompt_caching:
|
||||
enabled: true
|
||||
# Automatic prompt caching (opt-in). OPTIONAL for the routing budget: the budget
|
||||
# derives sessions and prices warm anchors at cached rates on its own. Enable this
|
||||
# only for what it adds — injecting cache-control markers on the full-proxy path
|
||||
# (required for the provider cache to be real on marker-based models like
|
||||
# anthropic/*; see GUIDE.md §4) and session affinity without a budget.
|
||||
# prompt_caching:
|
||||
# enabled: true
|
||||
|
||||
routing:
|
||||
# Per-session cost gate on model switching. Independent of prompt caching: it
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue