0 only if every assertion passes. It writes a JSON
report with per-turn metrics.
Evaluation runs against a real agent, over the same runtime path that a live
call uses. It uses the same speech-to-text, language, and speech providers
that your agent runs with. Thus a green run reflects real behavior, not a
mock.
Write a scenario
A scenario is JSON. It sets who the caller is, which agent to test, the scripted turns, and the assertions on each turn and on the call as a whole.agent_key to the agent you built in the console. Or set it to "" to
smoke-test the default speech-to-text → language → speech pipeline with no
agent configured. A turn is either scripted user text (spoken through the
TTS provider) or a wav fixture (PCM16, mono or stereo, any sample rate).
Use a wav fixture when you need a specific voice, accent, or noise profile.
Assertion types
Each turn carriesexpect assertions. The call carries call-level
expectations, which the judge grades against the whole transcript.
{ ms: number }
Latency gate: the gap from the caller’s last speech frame to the agent’s
first audio frame must be under
ms. It catches a slow agent before your
users do.{ pattern: string }
Case-insensitive regex over the agent’s transcript for that turn. It is
good for must-say phrases, disclosures, or IDs.
{ criterion: string }
LLM-as-judge: the configured judge model returns a strict
{ "pass": bool, "reason": string } verdict against your plain-English criterion. It
fails closed. A malformed or flaky judge reply counts as a fail. Thus a
bad judge can never silently green a run.{ name: string, args_contains?: object }
Assert that the agent called a
tool by the end of the turn. You
can also assert certain argument values.
Preview — pairs with the runtime’s tool-call surface.
Metrics in the report
Every run writes a JSON report with per-turn timings. All timings are measured client-side:
Pair these metrics with the live-call
latency breakdown and
MOS / jitter / loss to
compare test-bench numbers against production.
Run an evaluation
1
Point at an agent
Build and save the agent in the console, so its config is live. Note its
agent_key. To smoke-test with no agent, use agent_key: "". The default
pipeline then runs off your provider keys.2
Provide credentials
The simulated caller reuses the same provider clients that your agent
uses. Thus it needs keys for the TTS, ASR, and judge providers in your
scenario (e.g. Deepgram, ElevenLabs, OpenAI). Set the keys in the
environment.
3
Run the evaluator
Point the evaluator at your engine and scenario. Run it. The evaluator
connects, plays the scripted call, grades every assertion, and writes the
report.
Today the evaluator ships as a standalone binary. You run it against a
self-hosted or managed engine. The
clutchcall eval wrapper is
the convenience entry point. See
Self-Hosted deployment to run it
against your own engine.4
Read the result
The process exits
0 only if every assertion passed. The JSON report
lands in your output directory. The report holds the per-turn metrics
above and, for each failed assertion, the judge’s reason.Gate your CI on it
The run is a single command with a meaningful exit code. Thus you can drop it into CI to block a regression before it ships:Related
Turn Detection & Barge-in
Tune what your latency and barge-in assertions test.
Tool Calling
Learn the tools that
function_call assertions check for.Runtime Configuration
Learn the agent config that an evaluation runs against.
Latency Breakdown
Compare bench latency to production.

