Judge a Conversation
asz judge measures one collected conversation: the targets the person set, whether each was
achieved, what each cost in tokens, money and time, and how much went to avoidable work. The
Conversation Judge page explains what it answers.
What an evaluator reads goes to the model behind it.
Run it
The conversation must be collected and parsed, as asz collect or asz server does.
asz judge 0438c73b-2367-4ed5-9de3-13ef9a17ed01
It runs judge.plan and prints each target’s outcome and cost when the run closes. -round N judges
the conversation as it was at round N of its chain. To give every stage to one evaluator, or each stage
to its own:
asz judge -evaluator codex 0438c73b-2367-4ed5-9de3-13ef9a17ed01
asz judge -plan targets=claude,achievement=codex,subtasks=codex,efficiency=claude 0438c73b-2367-4ed5-9de3-13ef9a17ed01
To judge part of a long conversation, give a window. A window takes whole main talks, each with every sub-task it started: by the time they start, or by their ids.
asz judge -from 2026-10-19 -to 2026-10-20 0438c73b-2367-4ed5-9de3-13ef9a17ed01
asz judge -from 2026-10-19T14:00 0438c73b-2367-4ed5-9de3-13ef9a17ed01
asz judge -from-id talk/main/3f1c… -to-id talk/main/9a07… 0438c73b-2367-4ed5-9de3-13ef9a17ed01
-from takes the talks that start at that time or later, and -to those that start before it. A time
is RFC 3339, or a date with or without a time of day, in the local time zone. -from-id and -to-id
name the first and the last talk, both included, as asz judge -show and the page name them.
-mode single gives each stage to one call, and -mode stream cuts each into calls; the default,
judge.mode, is auto.
Run it again whenever you want another judgment: later, as the conversation grows, or now, with another evaluator. Each run is kept.
Read the results
asz judge -list 0438c73b-2367-4ed5-9de3-13ef9a17ed01 # every run
asz judge -show 2 0438c73b-2367-4ed5-9de3-13ef9a17ed01 # one run
asz judge -show 2 -json 0438c73b-2367-4ed5-9de3-13ef9a17ed01 # its stage files
To compare the run with what a person concluded, such as a ticket or an incident report, give each
source with -reference: a file, an http or https URL, or a source a configured command fetches. The
run then finds the conclusions each source holds, and compares the conversation with each.
asz judge -reference OPS-4412.md -reference https://example.com/postmortem 0438c73b-2367-4ed5-9de3-13ef9a17ed01
A source that needs a login goes through a command you configure, given the source as its last argument; it writes the content on its standard output and never sees the conversation:
judge:
references:
fetch:
- prefix: https://example.atlassian.net/browse/
command: [jira-export, --markdown]
content_type: text/markdown
To compare the judge’s grouping with your own, list your goals for the conversation in your own words:
goals:
- Finish the post-vote steps of the 0.4.0 release
- Remove the website pull request step from the post-vote script
asz judge -labels goals.yaml 0438c73b-2367-4ed5-9de3-13ef9a17ed01 # a new run, regrouped
asz judge -regroup 2 -labels goals.yaml 0438c73b-2367-4ed5-9de3-13ef9a17ed01 # a closed run
One call of an evaluator places each target of the run in the goal it serves: the one -evaluator
names, or the plan’s targets stage’s.
-show then follows your goals and says where the judge’s grouping differed.
-show prints a run goal by goal, the most severe outcome first. Each target has its final score out
of 100, with the record’s score beside it when they differ. Then come why it holds, what was done for
it, the person’s corrections, its rework, what it still misses, and what it cost. A text the evaluator
wrote is marked read:, apart from what asz checked.
A run is kept in the session’s directory, under judgments/. Its work/ directory holds what each
evaluator was given, every navigation call it made, and what it answered. For an agent CLI it also
holds the CLI’s output. For an API evaluator it holds what the model said on each turn, up to 2,000
bytes, and what it called. What a tool answered is not kept: the run is pinned to its head, so the
same call answers the same again. work/sources/ holds each source as asz saved it: R1.json, its
manifest, R1.fetched, the bytes fetched, and R1.txt, the text the evaluators read.
When export.otlp.endpoint is set, asz collect, asz server and asz push send each run once it has
closed. See Export over OpenTelemetry.
Evaluators
judge.evaluators names the evaluators a stage can be given to. The defaults are the three agent
CLIs:
judge:
evaluators:
claude:
kind: cli
program: claude
args: []
max_turns: 60
codex:
kind: cli
program: codex
args: []
kiro:
kind: cli
program: kiro-cli
args: []
An agent CLI must be installed and logged in. asz gives it the conversation through asz judge mcp as
its only tools. claude runs with its built-in tools, other MCP servers, and user and project settings
switched off, so their hooks and plugins do not run; settings an organization enforces still apply.
codex runs without the user’s configuration, its shell, image and browser tools off. model picks
the CLI’s model; empty leaves its default. command is its path when it is not on PATH.
kiro-cli keeps every session it runs in Kiro’s history, by directory, so a kiro-cli stage leaves its
session there. kiro-local collects the sessions of Kiro’s V3 engine. When kiro-cli runs that engine,
exclude the storage root, where a stage runs, so asz does not collect its own judge sessions. A file that
lists adapters replaces the whole default list, so keep the others you use:
adapters:
- name: kiro-local
enabled: true
exclude:
- /private/tmp/**
- /absolute/path/to/the/storage/root/**
An API evaluator is called by asz itself:
judge:
evaluators:
haiku:
kind: api
program: anthropic
endpoint: https://api.anthropic.com
model: claude-haiku-4-5
api_key_env: ANTHROPIC_API_KEY
gpt:
kind: api
program: openai
endpoint: https://api.openai.com/v1
model: gpt-5
api_key_env: OPENAI_API_KEY
deepseek:
kind: api
program: bedrock
model: us.deepseek.r1-v1:0
region: us-east-1
profile: default
deepseek-key:
kind: api
program: bedrock
model: deepseek.v3.2
region: us-west-2
api_key_env: AWS_BEARER_TOKEN_BEDROCK
anthropicis the Messages API.openaiis any endpoint that speaks the OpenAI chat completions API, such as a gateway or a local model server. Itsendpointends before/chat/completions.bedrockis Amazon Bedrock’s Converse API. Withapi_key_env, that variable holds a Bedrock API key, sent as a bearer token. Without it, requests are signed with the credentials inAWS_ACCESS_KEY_ID,AWS_SECRET_ACCESS_KEYandAWS_SESSION_TOKEN, or else with those the AWS CLI gives forprofile. Runaws loginfirst when the profile uses a login.
max_turns bounds the model calls an API evaluator makes in one evaluator call, 40 when unset, and
max_tokens what one model call may answer: 8000 when unset for anthropic and bedrock, and the
server’s own limit when unset for openai, since OpenAI’s reasoning models refuse the field.
judge.timeout bounds one evaluator call of any evaluator. A stage cut into calls runs several, and a
call that fails, a timeout included, is tried once more. When the timeout passes, the CLI is stopped,
with everything it started on Linux and macOS. On Windows a program the CLI started can outlive it.
Prices
Money needs a price file. Name it in judge.pricing, or pass -pricing to asz measure:
currency: USD
models:
- model: claude-opus-5
per_million: {in: 5, out: 25, cache_read: 0.5, cache_write: 6.25}
- model: claude-opus-5
from: 2026-11-01T00:00:00Z
per_million: {in: 4, out: 20, cache_read: 0.4, cache_write: 5}
- model: deepseek.v3.2
aliases: [us.deepseek.v3.2]
per_million: {in: 0.62, out: 1.85, cache_read: 0.062, cache_write: 0}
model is the name exactly as the runtime recorded it, and aliases are other recorded names for the
same price. An entry with from applies to calls recorded at or after that time. An entry without it
applies when no dated entry does. A call whose model has no entry is left unpriced, and its tokens
still count.
asz measure prints what a conversation’s calls consumed, per talk, with no model and no run:
asz measure -pricing pricing.yaml 0438c73b-2367-4ed5-9de3-13ef9a17ed01
Keep things from the evaluators
judge.hide lists the flags whose records the evaluators are never shown, as view.hide does for the
page: system_prompt, tool_schemas.