LLM evaluation for AI agents: regression tests before deployment
An agent finishing without errors is not the same as an agent producing the intended result. London System Agent splits the two into separate layers, scores each with deterministic checks, and leaves a record of what justified a deployment.
Why two layers
Agent evaluation mixes two different questions: ① does the graph compile and run to a finite end (structure/execution), and ② is the result semantically correct (accuracy). Conflate them and you can't tell a “it ran but the answer is wrong” regression from a “the answer looks fine but the loop never terminates” risk.
London System Agent separates them into a top and bottom section of one screen — the Eval panel. Layer 1 checks structure/execution quickly; layer 2 runs the agent against the template's golden dataset and scores it. Below is the current beta Eval panel.
Layer 1 — structure and execution checks
The first layer is five deterministic checks: GraphIR compiled (node/edge counts), bounded execution (terminates as completed with no infinite loop), steps executed, no step errors, and budget respected (cumulative cost ≤ the cap). All are fast and deterministic, so they resolve immediately after compilation.
Below them, the ‘node execution’ list shows whether each node was ok (✓), errored (✗), or not run (·) on this run, alongside its type (TOOL_CALL, CONDITION, LOOP, LLM_CALL, END). The same status is overlaid on the canvas graph itself, so you can point at the exact node where cost accrued or execution stopped.

Layer 2 — golden-dataset evaluation
The second layer is semantic accuracy. Each template ships a versioned ‘golden dataset’ — a bundle of cases with defined expectations. The research template, for instance, bundles 8 query cases (research-v1). Evaluation feeds each case to the agent, actually runs it, and scores the output with a set of evaluators per case.
Template → (dataset, evaluator set) is wired through a versioned registry. Four templates — research, document, branch, simple — have datasets registered; freeform or unregistered templates have no golden baseline, so evaluation isn't offered (the panel says ‘no dataset’).
This layer catches regressions that are structurally fine but wrong in their answers — which layer 1 can never see.
What an evaluator looks at
There are two kinds. Deterministic evaluators score from the run's structured result with no LLM, so they return identical results even in Stub mode. The research set has five:
citation_presence — at least one citation when sources were gathered. source_coverage — distinct cited sources ≥ the case's min_sources. source_relevance — every cited id resolves to an actually-gathered source (no phantom citations). bounded_loop_termination — every routing node exited as ‘bounded_exit’ with visits ≤ its bound (a forced exit fails). cost_cap_adherence — cumulative cost ≤ the budget cap.
Judge evaluators use an LLM judge to score meaning 0–1 and run only in Real mode (skipped in Stub): groundedness — the summary's claims are supported by the cited source content; answer_relevance — the summary actually answers the question. Each must score ≥ 0.5 to pass. Non-research templates (document, branch, simple) gather no sources, so they use a generic set: output presence, bounded termination, cost-cap adherence, plus the universal answer_relevance judge.
How scores combine
A case passes only if every one of its evaluator scores passes (AND). The case score is the mean of its evaluator scores. The dataset pass_rate is ‘passed cases over cases evaluated,’ with the denominator explicitly the number of cases that finished evaluation.
Budget is tracked on separate exec and judge ledgers (the panel's ‘exec cost / judge cost’). If any case's run is not completed (budget exceeded, error, …), evaluation stops there and the report is marked status=incomplete. Incomplete runs are not scored, and the denominator (total_cases) stays the full dataset size — so you can't get a good score by only running part of it.
The per-evaluator aggregate reports each evaluator's pass rate, mean score, and sample count (n) separately, making it obvious which criterion failed.
Stub vs Real — the honesty guard
A Stub-mode report is labeled ‘contract regression.’ With no LLM calls, it deterministically regression-tests structure and contract — it does not claim empirical quality. Run the judge evaluators with BYOK keys in Real mode and it becomes ‘pre-deployment empirical evaluation.’
That mode label guards against confusing what the report proves with what it doesn't. The ‘100% pass’ in the screenshot is a contract-regression result over five deterministic criteria — not a guarantee about model answer quality.
Certification and reproducibility
A report becomes certified only when all four hold: status is complete, cases evaluated equals the full dataset, pass_rate meets the threshold (currently 0.8), and the dataset and evaluator-set versions are not placeholders (“v0”). That last condition enforces the principle that a certified artifact must be reproducible.
For reproducibility the report records the IR's canonical hash (ir_hash — sha256 of the sorted, compact JSON of the IR), the dataset version, the evaluator-set version, and (in Real mode) the judge model and judge-prompt version. Given the same IR, dataset, and evaluator versions, deterministic evaluation reproduces the same result.
The deploy decision
Evaluation and gate results create evidence for a deployment decision. The product currently supports API key issuance and /v1/runs execution for saved agents, and the Deploy panel visualizes gate failures as blocked. That banner is not hard enforcement yet, so beta users should review eval_id, run_id, ir_hash, and gate verdict before promoting a graph.
Your turn to build
Compile your first agent graph from a single sentence.