A unit test can assert that a function returns the right value for a given input, every time, deterministically. An LLM's response to the same prompt isn't guaranteed to be identical twice. Evaluating an agent needs a different kind of test.
3 min read
Unit tests remain genuinely essential for everything mechanical in an agent system — the tool registry, the confirm flow, the rate limiter, the persistence layer (a real system reports "100 tests pass" across exactly these modules) — because that code is deterministic. What unit tests can't meaningfully assert is "does the model produce a good, grounded answer to this kind of question," because the model's actual response is exactly the part that varies. A test suite covering everything except the model's actual behavior is covering the machine around the agent, not the agent itself.
fixtures.ts:
[
{ question: "What's the visitor parking policy?",
expectedSource: "visitor-parking-policy.md" },
{ question: "How do I reset my portal password?",
expectedSource: "password-reset-guide.md" },
{ question: "What's the capital of France?",
expectedFallback: true }, // should say "I don't know" / decline
... (dozens more)
]
run-eval.ts:
for each fixture:
hit the REAL, live agent endpoint (not a mock)
check: did the response cite the expected source?
OR, for out-of-scope questions: did it correctly decline
rather than confidently making something up?
record pass/fail
This is closer to an integration test suite than a unit test suite — it hits the actual live SSE endpoint with real questions, and asserts on the shape of correctness (grounded in the right source, or a correct refusal) rather than an exact string match, since exact output text is expected to vary between runs even for a good answer.
NO_INFO_FALLBACK - the agent correctly recognized it doesn't
have grounding for this and said so
NO_TOOLS_NO_CITATIONS - the agent answered confidently, but with
nothing backing the answer up — no tool
was called, no source was cited
The first is the correct behavior for an out-of-scope question — the system working as intended. The second is the dangerous one: a confident-sounding answer with nothing underneath it, which is much harder to notice than an outright error message, precisely because it doesn't look like a failure to a user reading it. A real system logs both patterns into a dedicated table for gap analysis — not because either single instance is necessarily wrong, but because a rising rate of NO_TOOLS_NO_CITATIONS responses over time is exactly the kind of drift that traditional tests, running once and passing, would never catch on their own.
A mocked LLM response can only test "does my code correctly handle a response shaped like X" — it says nothing about whether the actual model, given the actual system prompt and actual tool catalog, produces X (or something good) in the first place. An eval suite's entire value is testing the one part a unit test structurally can't: real model behavior, against real fixtures, hitting the real endpoint.
Both matter, for different reasons: unit tests catch a regression in the deterministic scaffolding around the model (a broken rate limiter, a confirm-step bug) fast and cheaply, on every commit. Evals catch a regression in the model-facing behavior itself (a prompt change that quietly makes the agent worse at knowing when to say "I don't know") — slower to run, more expensive, but checking something unit tests fundamentally cannot.
Check your understanding
A quick comprehension check — not tracked, not graded, just for you.
1. Why can't a standard unit test suite meaningfully assert "the agent gives a good, grounded answer to this question"?
2. An eval fixture asks an out-of-scope question (e.g. "What's the capital of France?") to a building-management assistant. What counts as a PASS for this fixture?
3. Why is a NO_TOOLS_NO_CITATIONS response — a confident answer with no tool call or citation backing it — considered a more dangerous pattern than a correct fallback response?
4. Do evals replace unit tests in an agent system, or serve a different purpose?
AI Agents & LLM Integration