Skip to content

Add routes

A route is the product surface a call belongs to, independent of which function made it. It is the unit cost is compared on and the unit a cheaper model is tested against, so a repository with no routes captures cost but cannot be optimized. This is the highest-value follow-up pass after instrumenting a repository.

Paste the block for your language into a coding agent, from inside the repository.

This Python repository already uses the Metergraph SDK. Add route names.
A route is the product surface a call belongs to, independent of which
function made it: "ticket-classifier", "invoice-summary", "search-rerank".
It is the unit cost is compared on and the unit cheaper models are tested
against, so a call with no route cannot be optimised.
with metergraph.route("ticket-classifier"):
client.chat.completions.create(...)
Read the code and group calls by what the user is getting, not by which
module they live in. Two functions serving the same surface share one
route. One function serving two surfaces needs two.
Use lowercase, hyphenated, stable names. Do not invent a route per
function. Do not put a version or a model name in a route name.
Where a workflow makes several model calls that belong together, wrap it
in metergraph.trace("name") as well, so they are grouped as one unit of
work.
Route, trace, function, session and tags are five different labels
answering five different questions. If you are unsure which one a piece
of information belongs on, read
https://www.metergraph.dev/docs/concepts/identity-model/
before choosing.
Change nothing else. Do not refactor, rename or reformat code you are
not routing, and do not add a dependency.
When done, list every route you introduced, which call sites it covers,
and any call you deliberately left unrouted with the reason.
This TypeScript repository already uses the Metergraph SDK. Add route
names.
A route is the product surface a call belongs to, independent of which
function made it: "ticket-classifier", "invoice-summary", "search-rerank".
It is the unit cost is compared on and the unit cheaper models are tested
against, so a call with no route cannot be optimised.
mg.route("ticket-classifier", () => client.chat.completions.create(...))
Read the code and group calls by what the user is getting, not by which
module they live in. Two functions serving the same surface share one
route. One function serving two surfaces needs two.
Use lowercase, hyphenated, stable names. Do not invent a route per
function. Do not put a version or a model name in a route name.
Where a workflow makes several model calls that belong together, wrap it
in mg.trace("name", fn) as well, so they are grouped as one unit of work.
Note that route() and track() are different things and you need both:
track() names the function, route() names the surface.
Route, trace, function, session and tags are five different labels
answering five different questions. If you are unsure which one a piece
of information belongs on, read
https://www.metergraph.dev/docs/concepts/identity-model/
before choosing.
Change nothing else. Do not refactor, rename or reformat code you are
not routing, and do not add a dependency.
When done, list every route you introduced, which call sites it covers,
and any call you deliberately left unrouted with the reason.

The naming rules in the prompt exist because a route name is a join key across time. Renaming one splits its history in two.

  • Lowercase and hyphenated, so it reads the same everywhere it appears.
  • Named after the surface, not the implementation. invoice-summary survives a rewrite. summarize_v2_handler does not.
  • No version and no model name. Swapping the model is the thing routes exist to measure, so a route named after a model cannot measure it.
  • Stable. Prefer an imperfect name you keep to a perfect one you change.

Name a route walks through the same decision by hand, and the dashboard reference shows where routes surface in the app.