New:Microsoft Teams Notifications Are Now Available in Socket.Learn more
Get Started

@trazum/cli

Package Overview
Dependencies
Maintainers
1
Versions
101
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

@trazum/cli

Trazum CLI: find where your LLM bill goes, price every finding per month, and enforce token budgets in CI.

latest
Source
npmnpm
Version
2.4.1
Version published
Weekly downloads
294
-38.36%
Maintainers
1
Weekly downloads
 
Created
Source

@trazum/cli

Optimise prompts, enforce token budgets in CI, and price the saving — from your terminal.

Zero runtime dependencies, asserted in CI. This tool reads your prompts; every dependency would be someone else's code reading them too.

Part of Trazum. For the library, see @trazum/core.

npm install -g @trazum/cli

Commands

trazum optimize <file>shorten it, and price what that is worth
trazum profile <logs> --by-sourcethe fleet: one summary per service, the rollup, per-service budgets
trazum check <file|dir>does it fit its budget, and has the repo drifted past its baseline — exits 1 when either fails
trazum baseline [dir]what the prompts cost now, recorded to a file you commit
trazum profile <log|dir>where the money actually went — reads a usage log (or a directory of rotated ones, .gz included), not a prompt. --against compares to the previous log; --what-if <model> prices these exact calls at another rate card; --label/--since/--until drill down; --max-usd/--max-day-usd/--max-growth-usd/--max-cache-loss-usd gate the spend; --json/--csv-out/--markdown-out for pipelines and CI
trazum route <log.jsonl>is the cheaper model good enough? — measured, and it asks before spending
trazum plan <log|dir>the findings as a ranked plan: what to do first, route+batch combined never summed, projections and money already spent totalled apart, every assumption named. -o saves it dated for a later verify; --min-usd names what it drops
trazum verify <plan.json> --against <log>did the plan's savings arrive? Three outcomes, never two — arrived, did not, cannot be told — with the world's movement named beside each verdict. --gate fails CI on broken promises
trazum history <dir>the long run: series from stored --json reports, the climbs and decays no pairwise comparison finds, and plans nobody is executing. Shapes named, nothing forecast
trazum connect <provider>your bill read from the provider's usage API — no export by hand. The credential is borrowed from the environment and never stored; a connected report is restricted on purpose and names the findings a sum cannot support
trazum storewhat the local store holds and what a prune would take. Re-pulls converge instead of doubling; records it cannot tell apart are kept as two and named; pruning refuses without a retention policy and says what went
trazum watchthe spend gates evaluated as the money moves, not three weeks later. Measured crossings only, a day half-measured is not-yet-judgeable rather than passed, a restart neither re-alerts nor calls a blown budget clean
trazum servea loopback endpoint answering what a call will cost and whether there is budget, in milliseconds. The measured half and the estimated half stay apart, and the verdict says which it rests on
trazum doctor [dir]the whole workspace: what nothing is watching, and what fixing would be worth
trazum rank <dir>of these forty prompts, which is worth an afternoon
trazum prune <file> --cases <file>which few-shot examples earn their tokens — measured, and it asks before spending
trazum diff <before> <after>somebody edited this; did it get worse?
trazum blame <file>who made this prompt expensive, and when
trazum eval <file> --cases <file>does the shorter prompt still work
trazum from-claude-code <dir>what my Claude Code sessions cost — reads the transcripts already on disk, the numbers only and never the words
trazum from-otel <file>what the LLM calls in my OpenTelemetry export cost — the GenAI spans any exporter already emits, counts only
trazum switch <log> --to <model>should we move this traffic, and when does moving pay — measured saving, declared migration cost, break-even as division on the past
trazum ownratewhat my self-hosted model costs per million tokens — your GPU rate over your measured throughput, derived rather than guessed
trazum where [file]which prompts hide in my source files, and which model they call
trazum models · trazum rulesprices; what each rule does

That table is a selection, not the whole set. trazum --help lists every command and documents every flag. Several have no row above — among them trazum gateway, the only thing here that can refuse a call before the money is spent; ask the tool how many rather than this page, which cannot stay right about it. A table that stops without saying it has stopped reads as the complete list, and this one is on the page most people meet first.

Reports are available in English and Spanish (--locale es); the locale changes the report, never the optimisation.

Optimise

trazum optimize prompt.txt --calls 50000 --diff

Or stop typing the figures and measure them — --from-log reads the call count, output size, cache share and model from a usage log, names which figures are measured, and refuses the typed flags beside it. --all-labels ranks every prompt in the config's labels map by what optimising it is worth on its own measured traffic:

trazum optimize prompt.txt --from-log usage.jsonl --label support
trazum optimize --all-labels --from-log usage.jsonl
Input tokens
  190 → 137   -27.9% (estimated, ±6%)

Cost with Claude Opus 5
  50,000 calls/month · 300 output tokens per call
  $422.50 → $409.25   saving $13.25/month (3.1%)

Beyond shortening the prompt
  → This task may not need Claude Opus 5 ~$327.40/month
  → If the work tolerates latency, use the Batch API ~$204.62/month

Read the last block first. Trimming is usually not where the money is.

Redirected output is only the optimised prompt, so it pipes cleanly:

cat prompt.md | trazum optimize - --level aggressive > prompt.optimised.md

Budgets in CI

trazum check prompts/system.txt --max-tokens 2000
# FAILED 2,481 tokens busts the budget of 2,000.
#   Optimised with "trazum optimize --level safe" it would land at ~1,913 tokens and fit.

Point it at a directory to govern a whole repository in one step, using the per-pattern budgets in trazum.config.json. A file no pattern covers is listed as unbudgeted rather than skipped quietly, and a run where nothing at all was budgeted is an error — "0 failures" from a check that measured nothing is the most misleading thing this tool could tell you.

--markdown-out <file> writes the report as GitHub-flavoured markdown, for a step summary or a pull request comment. There is also a packaged GitHub Action.

Where the money actually went

Every other command reads a prompt and reasons forward about what it would cost. This one reads what the provider charged and reasons backward, because the forward direction only sees the smallest line item — measured on an ordinary support prompt, the rules recover about 1% of the monthly figure while output alone was 87% of it.

trazum profile usage.jsonl

One JSON object per line, each with a model and the usage object the API returned. Recording it is three lines and no transformer:

appendFileSync('usage.jsonl', JSON.stringify({
  model: response.model,
  label: 'support-rag',       // which workload — without it every call looks alike
  session: conversationId,    // which conversation — grouped by, never printed
  ...response.usage,
}) + '\n');

OpenAI's shape works too, with the one real difference handled: it counts cached tokens inside prompt_tokens while Anthropic reports them beside input_tokens.

It reads a file, not your traffic. The record shape has no field for content, so a usage log handed to Trazum cannot contain a prompt even by accident. And it reports no saving — attributing "you could have saved X" to a call that already happened means guessing what the call should have been.

A model the pricing catalogue does not know is named and kept out of the totals, because a total that silently omits calls is wrong in the flattering direction.

What would actually move this bill

The rules recover about 1% — measured. Which model a call goes to moves 40% to 80%, and the Batch API moves 50% flat. profile prices those from your log:

  → support-rag on Claude Opus 5 — up to $16.80 of this bill (52.2%)
    400 calls, $21.00 spent
    · route it to Claude Sonnet 5, $12.60
    · send it through the Batch API, $10.50

  For comparison: shortening the prompt text can touch $18.00 at the very most.

The options are combined, never summed — batching a routed call discounts the cheaper model, so the pair is $16.80 and not $23.10 against $21.00 spent. A route prints the eval command rather than a recommendation: the arithmetic is exact and says nothing about quality. Nothing crosses a vendor, and no figure is ever "per month" — a log covers whatever period you recorded.

What re-sending the conversation costs

A chat or agent workload replays the whole conversation every turn, so the input grows with the turn count — routinely the largest line on an agent bill, and invisible to everything else here. Add session (or conversation_id) to the log and profile measures it:

  agent on Claude Opus 5: input ranges from 600 tokens on the smallest turn
  to 5,000 on the largest, over conversations of up to 12 turns.
  If every turn had been the size of its smallest one, that input would have
  cost $7.20 instead of $33.60 — so at most $26.40 of this bill is
  conversation growth (57.9%).

A ceiling, not a saving: some of that growth is the user's own new messages, and this reads counts rather than content. The session key is never printed — it groups calls and counts turns, every figure comes out per label, and a test asserts it appears nowhere in the report or in --json.

Why a failing cache fails

profile can say that caching loses money on a label — the log carries counts, not content. Map the label to its prompt file and it reads the file and says why:

{ "labels": { "support-rag": "prompts/support.txt" } }
  prompts/support.txt (as it is today — the log may predate it): the stable
    prefix is 13 tokens and Claude Opus 5 caches nothing under 512. Setting
    cache_control there does not error, it simply never caches.

Three diagnoses: a prefix under the model's minimum, stable tokens stranded behind the first placeholder (--reorder moves them), or a healthy file whose problem is byte-identity between calls. Every sentence says the file is today's — the log may predate it, and a fresh file presented as the history's explanation would be a figure attributed to something it does not describe.

Is the cheaper model good enough? — trazum route

The section above prices a route and can say nothing about whether it works. This runs the measurement:

trazum route usage.jsonl --prompt-file prompts/support.txt --cases cases.txt --yes
  support-rag on Claude Opus 5 → Claude Sonnet 5, worth $12.60 of this bill (60.0%).

  The cheaper model agrees with the original 94% of the time. The original
  agrees with itself 91% of the time — that is the yardstick, not 100%.

  ✓ HOLDS — the difference is inside the original model's own noise.

The yardstick is the expensive model's own variance, measured on the same cases in the same run, so the verdict is not a threshold somebody picked. Three provider calls per case — two on the original, one on the candidate — and it prints the count and stops unless you pass --yes.

It says agreement is not correctness on every verdict, including the good one. This measures whether the answers moved, not whether they were ever right.

Did the caching pay for itself?

The rest of Trazum tells you to cache. This is the one report that can say the advice was wrong here — and the cache hit rate will not.

A cache write costs 1.25x plain input on Anthropic and 2x at the one-hour TTL, so a prefix that changes faster than it is reused pays that premium for nothing:

  Cache hit rate 97.8% of billable input.
  Caching took $0.2675 off this bill, against the same tokens uncached.
  ! The total above hides a loss: caching costs $0.1250 across rag.

Computed per label as well as overall — ranked by what caching cost each one, not by the size of its bill, because the worst cache in an estate usually sits on a small workload. Each side is priced per model, so a provider whose writes cost the same as input is never accused of a loss it cannot have; a model added through a pricing overlay can declare its own multipliers for the same reason.

When the log cannot settle it, neither does the report. A cache write whose TTL was not recorded is priced at the cheaper of the two rates, and that moves the verdict rather than only the total — so instead of a figure you get both, and what to record to remove the doubt.

This is the only counterfactual here, and it is arithmetic rather than a guess: caching changes the multiplier on a token, never the token. --json carries it as cache and cacheByLabelpositive deltaUsd means worse.

The ceiling is not the problem

A budget says nothing while a prompt climbs from 800 tokens to 1,900 under a limit of 2,000, and that climb is what actually happens to a repository — nobody adds a thousand tokens in one commit. A baseline records where you are now:

trazum baseline prompts/          # writes trazum.baseline.json — commit it
{ "baseline": { "path": "trazum.baseline.json", "maxGrowthTokens": 500 } }

trazum check then gates on drift away from that record as well as on the ceiling, and exits 1 when either fails. One of maxGrowthTokens or maxGrowthPct is required, because a baseline with no threshold gates nothing. --no-baseline skips it for a run.

The gate is in tokens, not dollars. Prices move on somebody else's schedule and a price change is not a regression in your prompts. The file still records the money it was written under and the report compares it — but only while the scenario and the pricing date still match, and it says why not when they do not.

Added files count, or the gate would be defeated by adding a prompt rather than editing one. And re-recording is how you accept growth: it is a commit, in a diff, where a decision to spend five hundred more tokens belongs.

Did this edit make it worse?

trazum diff old.txt new.txt --calls 50000 --max-growth 10

Every figure is after - before, so positive means worse — the opposite of every other Trazum output. The gate is opt-in: growth alone exits 0, and --max-growth is what makes it exit 1. A tool that fails a build nobody armed gets removed from the pipeline rather than fixed.

Configuration

trazum.config.json, found by walking up from the working directory:

{
  "level": "safe",
  "usage": { "model": "claude-opus-5", "callsPerMonth": 50000 },
  "budgets": { "prompts/**": 2000, "prompts/system.txt": 4000 },
  "maxGrowth": 100,
  "baseline": { "path": "trazum.baseline.json", "maxGrowthTokens": 500 },
  "pricing": "./prices.json"
}

Flags beat the config; the config beats the defaults. A boolean the config switched on comes back off with --no-batch.

An invalid config is a hard error, including an unknown key. A lenient parser would restore defaults silently, and for a budget the default is no budget — a green build for a prompt nobody measured.

pricing points at a local price overlay, so correcting a published price does not require upgrading Trazum. Every report says when overlaid prices were used.

Does the shorter prompt still work?

trazum eval prompt.txt --cases cases.txt --level aggressive

Everything else Trazum reports is arithmetic; this is not. It runs the original twice per case to measure the model's own run-to-run variance, and judges the rewrite against that rather than against a determinism it never had. Costs three provider calls per case, prints the count before spending anything, and says inconclusive rather than inventing a verdict when the baseline is too noisy.

Needs TRAZUM_LLM_* configured. Exits 1 on diverges.

MIT.

Keywords

prompt

FAQs

Package last updated on 18 Sep 2026

Related posts