In four passes. Normalize — OTel GenAI spans, Bedrock traces, plain JSONL all map into one canonical shape, or every check downstream has to know about every framework. Run deterministic checks first, because much of what matters is mechanical. Then a model, only for what genuinely needs language understanding, and only to extract findings with pointers into steps. Then score in ordinary code, so the same trace gives the same verdict tomorrow without a model in the loop.
Evaluation quality is capped by capture quality. Before anything else, check that the export actually carries:
Where a field is missing, the honest output is "unverifiable" — which doubles as a useful signal about the instrumentation, rather than a failure of the agent.
The ordering is a cost and reliability decision. A surprising share of what a reviewer cares about needs no model at all, and mechanical checks are free, instant, and identical on every run:
Only after those does a model earn its place, on questions like whether a claim is supported by a retrieved passage.
The naive approach stuffs the whole trace into one call, which silently truncates evidence the moment a run gets big — and agent runs get big. Raising the context limit postpones the problem rather than solving it.
The better shape is to give the model a closed set of read-only navigation tools over the trace and let it pull the slice each claim needs. Log every retrieval, and the investigation becomes replayable rather than an opinion — you can see exactly what the model looked at before it concluded anything.
The last pass matters more than it sounds. A finding backed by a retrieved source document and a finding backed by the agent's own account of a tool result are not equally strong, and collapsing them is how an evaluator starts making accusations it can't support.
Mark each one: independently observable ground truth, agent self-report, or nothing in the trace speaks to it. Let only the first fail a gate on its own. The rest still get recorded and shown.
The short answer above is ours, and we've written at length about how we got to it: