Skip to main content

Set up your agent

There are two ways to run LLM evaluations:

Calibrate agent

Define your agent completely within Calibrate

Agent connection

Connect your existing text or voice agent

Test cases

An array of test cases to evaluate your agent on. Each test case has:

Tool call test

Verifies the agent calls the correct tools with the expected arguments:
Passing "arguments": null will make the agent simply check if the tool is called without checking the arguments.

Judging an argument against a criteria

If exact matching is too strict, you can also pass a criteria that an LLM judge uses to evaluate if the argument is correct. Each argument is matched independently, letting you mix exact matches and criteria-based evaluations in the same tool call:
A plain literal value (e.g. "555-123-4567") is matched exactly, as usual. To opt an argument out of exact matching, give it a spec with one of these match_type values: To leave an argument completely unconstrained, give it an "any" spec. This is a wildcard: the parameter is ignored entirely — it need not appear in the produced tool call, and whatever value it has is accepted. Use it to pin down only the arguments that matter and leave free-form or non-deterministic ones unchecked.
Works for nested arguments as well where each sub-parameter is graded independently:
For agent connection, your agent owns its tools internally — there is no need to define them in the config. The history and evaluation keys work identically for both setup options.

Response test

Given a conversation history, this test verifies that the agent’s response meets the evaluation criteria defined by you (evaluated by an LLM judge):

Conversation test

Like a response test, the agent is run on the history to produce its next reply — but instead of grading only that reply, the entire resulting conversation (history + the new reply) is graded by the simulation judge. Use this when correctness depends on the whole exchange, not just the latest turn. As with response tests, history ends at the user’s turn that the agent should answer.
See examples/llm/config-conversation.json for a full template.

Evaluators

Response test cases can be evaluated by one or more text LLM judges (routed through OpenRouter, set OPENROUTER_API_KEY in your environment). Each evaluator’s system_prompt is sent to its own dedicated LLM judge call (one call per evaluator, run in parallel) with the conversation history and the agent’s last response as the inputs.

Defining custom evaluators

Define one or more evaluators at the top level and reference them by name from each test case. Each evaluator is an independent LLM call and produces its own column in the leaderboard:

Using the default evaluator

The simplest setup needs no top-level evaluators. Pass criteria as a string and the implicit correctness evaluator runs. The string is substituted into the default evaluator’s system prompt as the {{criteria}} variable:
When you omit top-level evaluators and pass a string criteria, this is the implicit evaluator from DEFAULT_LLM_TEST_EVALUATOR that is used by default. Your criteria string is substituted for {{criteria}}.

Variable substitution

A test case can pass arguments to an evaluator. Each {{variable}} placeholder in the evaluator’s system_prompt is replaced with the matching value before the judge call:
The string-form criteria (shown in the quickstart above) is just a shortcut for the implicit correctness evaluator with { "arguments": { "criteria": "<your string>" } }.

Binary vs rating

Binary evaluators produce per-row pass/fail and a mean pass-rate in aggregates. Rating evaluators report mean/min/max scores per model on the leaderboard. At test-case pass/fail time, every referenced evaluator must pass: binary evaluators require match: true, and rating evaluators require the numeric score to equal scale_max (anything lower fails that evaluator). So on a 1–5 scale (scale_min 1, scale_max 5), only a judge score of 5 counts as pass — intermediate scores fail unless they hit the top of your declared scale. If you want thresholds different from “top-of-scale” (for example “tone at least 4”), encode that as a binary evaluator whose system_prompt asks the judge explicitly (for example: “Mark True if and only if tone is at least 4 on a 1–5 scale”).

Full examples

Same structure as examples/llm/config-internal-agent.json, with documentation-only // comments before each test case (jsonc — strip comments if you paste into a strict JSON parser).
Same structure as examples/llm/config-external-agent.json, with documentation-only // comments before each test case (jsonc — strip comments if you paste into a strict JSON parser).

Get started

Interactive mode

Run calibrate-agent llm with no arguments to launch the interactive UI:
Calibrate agent — the UI detects that your config defines a system prompt and tools and guides you through:
  1. Config file — path to your config file
  2. Provider — OpenRouter or OpenAI
  3. Model entry — enter model names one at a time (single or multiple)
  4. Confirm models — review the list and add more or proceed
  5. Output directory — where results will be saved (defaults to ./out)
  6. API keys — enter the API keys for the selected provider
The evaluation runs the selected models in parallel (max 2 at a time), showing results for each test as they complete. Agent connection — the UI detects agent_url in your config and switches to agent mode: Single test:
  1. Config file — path to your config file (with agent_url and optionally agent_headers)
  2. Mode — select “Single test”
  3. Verify — calibrate verifies the connection; shows success or failure with the option to go back
  4. Output directory — where results will be saved (defaults to ./out)
  5. API keys — only OPENAI_API_KEY is required (used by the LLM judge)
Benchmark across models:
  1. Config file — path to your config file (with agent_url and optionally agent_headers)
  2. Mode — select “Benchmark across models”
  3. Model entry — enter a model name; calibrate verifies the connection with that model before asking if you want to add another
  4. Confirm models — review the list and add more or proceed
  5. Output directory — where results will be saved (defaults to ./out)
  6. API keys — only OPENAI_API_KEY is required (used by the LLM judge)

Non-interactive mode

Calibrate agent: Single model:
Multiple models (benchmark — runs in parallel, generates a leaderboard):
Agent connection: Your config must include agent_url and optionally agent_headers:
Single run (use the default model of the agent):
Calibrate verifies the connection before running. Results are saved directly to the output directory. Benchmark across models — calibrate verifies the connection for each model, then runs the test suite once per model. The model name is included in each request so your agent can route to the right model:
Each model gets its own results folder, and a summary with pass rates for all models is printed at the end. Skip verification: Pass --skip-verify to skip the agent connection verification step. This is useful in CI/automation pipelines where you’ve already confirmed the agent is reachable:

Output

Once all the models have completed, it displays a leaderboard with pass rates (% of tests passed) and bar charts for visualization.
LLM leaderboard
You can drill into each model to view the results for each test with the reasoning behind the pass/fail status.
LLM model outputs (pass)

Resources

Integrations

See the full list of supported providers and their configuration options