Skip to content

Commit 693e249

Browse files
committed
docs(relay): clarify routing cost accounting
Signed-off-by: Alex Fournier <afournier@nvidia.com>
1 parent 4ee66fd commit 693e249

1 file changed

Lines changed: 58 additions & 24 deletions

File tree

docs/integrations/nemo_relay.md

Lines changed: 58 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -8,37 +8,71 @@ deployment through Relay's
88

99
## Why Use Switchyard with NeMo Relay?
1010

11-
Relay receives your agent's model request. Switchyard picks and calls the model.
12-
Relay continues to track the rest of the agent run and can export the routing
13-
details from Switchyard. Because the plugin runs inside Relay, you do not need
14-
to change the agent or run a separate Switchyard service.
11+
Using the strongest model for every request is simple, but routine work may not
12+
need it. Switchyard can send simpler requests to a lower-cost model and reserve
13+
a stronger model for harder work.
1514

16-
Together, they let you:
15+
Relay keeps the model choice, fallback, latency, and token use alongside the
16+
rest of the agent run. This lets teams answer practical questions:
1717

18-
- send simpler work to a less expensive model and keep a stronger model for
19-
harder work;
20-
- see which model was chosen and, when available, which model answered after a
21-
fallback;
22-
- track routing time, failures, and token use alongside the rest of the agent
23-
run; and
24-
- compare routing with using one model for every request.
18+
- How often did the lower-cost model handle the work?
19+
- How often did Switchyard fall back to another model?
20+
- How much time and token use did routing add?
21+
- Did the routed workload cost less than using one model for every request?
22+
23+
The plugin runs inside Relay, so the agent does not need to change and
24+
Switchyard does not need to run as a separate service.
2525

2626
Requests for models that Switchyard does not manage continue through Relay as
2727
usual.
2828

29-
### Check Whether Routing Saves Money
29+
### Measure the Cost of Routing
30+
31+
A routed request can spend tokens in two places. Some routes call a judge or
32+
classifier to choose a model. The selected model, or a fallback, then produces
33+
the answer. Relay and Switchyard record these parts separately.
34+
35+
Relay records the caller-facing request and response. In OpenInference traces,
36+
answer tokens appear as `llm.token_count.prompt`, `llm.token_count.completion`,
37+
and `llm.token_count.total`. When available, cache use appears as
38+
`llm.token_count.prompt_details.cache_read` and
39+
`llm.token_count.prompt_details.cache_write`. Relay also records
40+
`llm.cost.total` in USD when the provider reports a cost, or when the response
41+
contains enough model and usage data and a configured Relay pricing catalog
42+
has all required rates.
43+
44+
Switchyard records token use for its model calls in the
45+
`switchyard.routing.llm_tokens` metric when the provider reports usage. Each
46+
measurement identifies:
47+
48+
- `call_role`: `routing` or `answer`
49+
- `target_model`: the upstream model ID
50+
- `token_type`: `input`, `cached_input`, `cache_creation_input`, `output`,
51+
`reasoning`, or `total`
52+
53+
Switchyard also records the selected and served models, fallback use,
54+
routing-call latency, routing overhead, and failures.
55+
56+
No single total-cost or savings metric is emitted today. Relay prices the
57+
caller-facing answer, but it does not automatically price Switchyard's internal
58+
routing calls. For the common case, calculate the observed routed cost as:
59+
60+
```text
61+
Relay answer cost + cost of Switchyard tokens where call_role = "routing"
62+
```
3063

31-
Routing is not free. Some routes call another model to help choose the model
32-
that will answer. The plugin records the tokens used to make that choice
33-
separately from the tokens used for the answer. It also records the routing
34-
time, model choice, fallback, and failures.
64+
Apply the price of each `target_model` to those routing tokens. Do not add
65+
`call_role = "answer"` again because it describes the same successful answer
66+
that Relay recorded. Do not sum every `token_type`; `total` is a rollup, and
67+
cache or reasoning values may be a more detailed view of another count.
3568

36-
Relay can [estimate the cost of the response returned to the agent](https://docs.nvidia.com/nemo/relay/v0.8.3/nemo-relay-cli/basic-usage#add-model-pricing-for-cost-estimates)
37-
when model pricing is configured. It does not automatically price Switchyard's
38-
internal routing calls, so include the token counts from those calls when
39-
calculating the total. Run the same work once with a fixed model and once with
40-
routing to see whether routing actually saved money. If a provider does not
41-
report usage, the cost is unknown rather than zero.
69+
Relay does not ship a canonical price catalog. Follow its
70+
[model-pricing guide](https://docs.nvidia.com/nemo/relay/v0.8.3/nemo-relay-cli/basic-usage#add-model-pricing-for-cost-estimates)
71+
to supply and validate model rates. Run the same representative workload once
72+
with a fixed model and once with routing, then compare observed cost, latency,
73+
fallbacks, and your task-success measure. Missing usage, failed attempts,
74+
internal HTTP retries, and incomplete streams can leave some cost unknown. An
75+
absent value means unknown, not zero.
4276

4377
If Relay is not part of the application, run the [standalone server](../getting_started.md#server-path)
4478
or embed [`switchyard-libsy`](../../crates/libsy/README.md) directly.
@@ -302,7 +336,7 @@ response is available, the error mark describes the terminal failure instead.
302336
| `switchyard.routing.llm_calls` | Counter, events | Routing-model calls, labeled by `outcome`. |
303337
| `switchyard.routing.llm_call.duration` | Histogram, milliseconds | Routing-model call duration, labeled by `outcome`. |
304338
| `switchyard.routing.overhead` | Histogram, milliseconds | Time spent producing the routing outcome. |
305-
| `switchyard.routing.llm_tokens` | Counter, tokens | Provider-reported token values, labeled by `call_role`, `target_model`, and `token_type`. |
339+
| `switchyard.routing.llm_tokens` | Counter, tokens | Normalized token values derived from provider usage, labeled by `call_role`, `target_model`, and `token_type`. |
306340
| `switchyard.routing.failures` | Counter, events | Terminal failures, labeled by safe failure kind and available classification fields. |
307341

308342
`switchyard.routing.llm_calls` and `switchyard.routing.llm_call.duration` cover

0 commit comments

Comments
 (0)