What is a target
A target is one oftraces, threads or llm-spans. It sets what one judged row is and which text the judge reads for it. Pass it as --target on the CLI or target on the API; the default is traces.
A conversation is one row when its traces share a
gen_ai.conversation.id. A project that does not set one has no rows under threads, so ask for traces instead.
The time window
--last takes a number and a unit, 30m, 24h, 7d or 2w, and defaults to 7d. --start and --end take an ISO 8601 timestamp or epoch milliseconds. The window is written into the statement as two bound instants, start_at and end_at, so a run that pages through its rows several times reads one fixed selection.
Narrowing the rows with a trace filter
--filter takes the same syntax as the Trace Explorer’s search bar, with AND, OR, NOT, parentheses, * wildcards on model, and ranges such as cost:>0.01 and duration:[100 TO 500]. Under threads a conversation is judged when any of its traces matches; under llm-spans a call is judged when its trace matches.
Fields that read spans, evaluations, events, annotations or scenario runs are refused by name, with the list above in the refusal, because dropping the condition would charge you for rows you meant to leave out. Ask for those with a statement of your own instead.
The statement a target writes
Every run is one LangWatchQL statement. A target plus your questions expands into one, the run stores it, andrun prints it under Statement: with the two window values under Parameters:. Each question becomes one column, named after the question.
traces, with one yes or no question:
threads, one row per conversation, addressed by the conversation’s last trace:
llm-spans, one row per model call:
--filter on traces goes into that WHERE. On threads and llm-spans it goes into a subquery over analytics.traces with the same window, because the trace’s attributes are not columns of the conversation or span views.
What is the token budget per row
Undertraces the digest is cut to 8,000 tokens. Under threads the budget handed to llm_readable_thread is the judge’s whole text budget, about 31,000 judge tokens once your questions are counted in, so an ordinary conversation arrives whole. The number in the statement, 18729 for one short question, is that budget in the renderer’s own count of four bytes per token. Under llm-spans the text goes to the judge whole, up to the same ceiling.
A long conversation costs more than a short one, and the estimate measures your rows as they are.
When a conversation is over the budget, you still get a verdict: every turn is shortened before any is dropped, and when turns do have to go, the opening and closing turns stay and a marker in the middle names the turns left out. A question about how the conversation ended still reads the ending.
threads reads the agent’s work because a question about tools needs it and a question about the conversation scores within 2.5 points of the plain transcript. To judge only what was said, at fewer tokens, write the statement with conversation_bounded, which shows each turn’s messages and the names of the tools it used:
Writing your own statement
Take the statement a run printed, edit it, and send it back with--sql.
Run it before you judge it
Run the statement throughlangwatch query first to see the rows before you pay to judge them. It needs the two window values the run printed:
What a statement needs
A statement is a run when:- it projects
TraceIdand at least one eval function column - it projects
SpanIdtoo when it has one row per span, so you get one verdict per span - it has an
ORDER BYwhen you use aLIMIT, so every pass over the rows reads the same set
--sql or --target, not both. Use --param only with your own statement.
Text functions
The text to judge is one of these functions over the row’s key:Eval functions
The question is one of these functions over that text:
The same functions work in a plain
langwatch query, which judges the rows the query returns and charges for them the same way. A run is how you take one past the query’s page size, up to the row cap.