The comfort of deterministic testingβwhere 2 + 2 always equals 4 and the test goes green or redβis dead for Large Language Models. When you ask an LLM-powered assistant the same question twice, you often get two different answers, both potentially correct, or one confidently wrong. The standard assertion assert response == expected is useless in this context. To evaluate chat assistants, RAG search, and document understanding, developers must shift their mindset from binary pass/fail outcomes to continuous quality scoring.
From Binary Checks to Scored Qualities
Effective LLM evaluation requires measuring specific qualities on a scale, typically 0 to 1, against predefined thresholds. Key metrics include Accuracy (is the answer factually right?), Groundedness (is it supported by provided context?), and Relevance (does it answer the prompt?). Crucially, developers must test Refusal Behavior in both directions: ensuring the bot declines inappropriate queries while answering valid ones. A bot that refuses everything is safe but useless, while one that answers everything is helpful but risky.
Building a Golden Dataset and Automated Evals
The foundation of robust testing is a "golden dataset," a curated set of inputs with known-good expectations versioned in Git like code. This dataset must include hard cases such as ambiguous questions, typos, and multi-language inputs. Frameworks like DeepEval, Ragas, promptfoo, and LangSmith automate this process. For example, DeepEval allows writing tests that look like standard pytest functions, using metrics like FaithfulnessMetric and AnswerRelevancyMetric with specific thresholds. However, since these often rely on LLM-as-a-judge, teams must pin the judge model version to prevent score drift and manually spot-check verdicts to catch bias.
Testing Beyond Single Prompts and Integrating CI/CD
Real-world usage involves multi-turn conversations, tool calling, and failure recovery. While text generation is non-deterministic, tool calls can often be asserted deterministically; for instance, verifying that an agent called get_order_status with the correct order_id. Safety testing must also be rigorous, covering prompt injection, jailbreaks, and PII leakage. These adversarial tests should be treated like a security suite and run on every release. To protect production, evaluation suites must be integrated into CI/CD pipelines. Running a fast subset on every pull request and a full suite nightly ensures that metrics like hallucination rates do not regress below baseline thresholds.
Key Takeaways
- Replace
assert ==with scored metrics for Accuracy, Groundedness, Relevance, and Refusal Behavior. - Version golden datasets in Git and track hallucination rates over time.
- Use frameworks like DeepEval or Ragas but pin judge models to avoid drift.
- Integrate evaluations into CI/CD to fail builds when quality metrics drop.
- Convert every production failure into a new regression test case.
The Bottom Line
Testing AI isn't about proving it is always right; it is about knowing how often it is wrong and whether that error rate is trending down. If your QA process doesn't measure and track, you are flying blind.