agentleFS
jaktestowacjaktestowac/awesome-copilot-for-testers/skills/testing-llm-features/SKILL.md

testing-llm-features

Skill118 starsChanged 2 months agoMITView on GitHub

Builds an offline eval suite for LLM-powered features: golden reference cases per prompt template, deterministic scoring where possible, a regression gate on prompt, model and retrieval changes, and CI wiring with promptfoo, Vitest or deepeval. Use when a product ships prompts, agents or RAG, when a model or prompt upgrade needs a regression check, when LLM output is currently verified by someone eyeballing it, or when asked how to test a feature whose output is non-deterministic.

We split this skill into the rules it gives an agent

9 rules. About 0 are common, 9 are distinctive, and 0 are very specific to this project.

  • ≈0

    Common · estimate

    Many files like this have a rule of this kind.

  • ≈9

    Distinctive · estimate

    This author's own choices. Worth a look.

  • 0

    Very specific

    Tied to their project's names, files or tools. Probably skip.

  • Common
  • Distinctive
  • Very specific
  1. Distinctive:

    Use this skill when a product's behaviour depends on a model, and the current verification method is a person looking at output and …

    line 10
  2. Distinctive:

    Rubrics before judges: If an LLM judges the output, it needs a written rubric with a scale, and the judge itself needs validating against …

    line 30
  3. Distinctive:

    Write down what the feature *promises* - the user-visible contract.

    line 52
  4. Distinctive:

    The regression class is the one that compounds: Every production incident becomes a permanent case.

    line 68
  5. Distinctive:

    run N times on cases where variance matters, and report the distribution, not one sample

    line 100
  6. Distinctive:

    Score by capability: - not one global number; "citation accuracy 94%, refusal 100%, summary faithfulness 81%" is actionable

    line 121
  7. Distinctive:

    Cases that grow only from imagination: Every production failure should become a case.

    line 137
  8. Distinctive:

    every prompt template has golden, edge, and negative cases with justified expectations

    line 158
  9. Distinctive:

    every past production failure has a permanent regression case

    line 165

≈ “Common” is an estimate: at least 1 in 5 of the 308,232 skill files we read have a rule of the same kind, not the same words. “Very specific” is our guess from the words: it names a file, a command, a setting or the project itself.

Keep what fits and drop the rest. Your version, ready for your agents.
Files
SKILL.md

Testing LLM Features

Use this skill when a product's behaviour depends on a model, and the current verification method is a person looking at output and deciding it seems fine.

The problem is not that LLM output is hard to assert on. It is that the same input produces different output, and a prompt or model change can degrade quality without breaking anything. No test in a normal suite fails. Coverage stays green. The feature just gets worse, and you find out from users.

An eval suite is the unit-test layer for this: a fixed set of cases, run on every change that could affect model behaviour, scored consistently enough that a regression is visible.

When to Use

  • a feature calls a model and there is no automated check on output quality
  • a prompt, model version, temperature, tool list, or retrieval config is about to change
  • a model upgrade is proposed and nobody can say what would regress
  • an agent or chain has grown beyond what manual spot-checks can cover
  • RAG answers are drifting and it is unclear whether retrieval or generation is at fault
  • a CI gate is needed for AI behaviour, not just AI code

Operating Principles

  • Golden cases, not vibes. A case has an input, an expectation, and a scoring rule. "Looks good" is not an expectation.
  • Determinism where you can get it. Pin the model version, set temperature to 0, fix seeds, freeze retrieval snapshots. Non-determinism is a property of the model; it is not an excuse for a non-reproducible test.
  • Test the assertable layer first. Schema conformance, required fields, refusal behaviour, citation presence, tool-call shape, latency and cost. Most feature-breaking regressions are structural, and structural checks are cheap and exact.
  • Rubrics before judges. If an LLM judges the output, it needs a written rubric with a scale, and the judge itself needs validating against human labels. An unrubriced judge is a random number with an API bill.
  • A regression is a new failure on a case that used to pass. That is the gate. An absolute score threshold on a hard case set gates nothing useful.
  • Separate retrieval failures from generation failures. A RAG answer can be wrong because the right document was never retrieved. Score retrieval independently or you will tune the prompt to fix an index problem.
  • Cases are a product artifact. They encode what the feature promises. Review them like code and grow them from real failures.
  • Cost and latency are results. A 12% quality gain for 4× the cost and 3× the latency is a product decision, so report all three.

Workflow

Phase 0: Map the surface

Find everything that can change model behaviour, because each is a trigger for the suite:

ElementWhere to look
Prompt templatesprompts/, *.prompt.*, template literals passed to the SDK
System promptsclient construction, agent definitions
Model configmodel id, temperature, top_p, max tokens, stop sequences, thinking budget
Tool definitionstool/function schemas, MCP servers, tool grants
Retrievalchunking, embedding model, index, topK, reranking, filters
Output contractZod/schema on the response, structured-output config, parsing code
Orchestrationchain and agent-loop structure, retries, fallbacks between models

Write down what the feature promises - the user-visible contract. "Summarise the ticket in ≤3 sentences, never invent a customer name, always cite the ticket id." That sentence is where the cases come from.

Phase 1: Design the case set

./resources/eval-case-design.md has the taxonomy. The minimum viable set per prompt template:

ClassPurposeCount to start
Goldencanonical inputs with known-good outputs5–10
Edgeempty, huge, multilingual, malformed, contradictory input5
Negativemust refuse, must not answer, must not leak3–5
Regressionone case per bug ever found in productiongrows forever
Adversarialinjection and jailbreak attemptssee testing-llm-guardrails

Cases carry the metadata that makes a failure diagnosable: which prompt template, which capability, why the expectation is what it is. A case whose expectation nobody can justify is a case nobody will maintain.

The regression class is the one that compounds. Every production incident becomes a permanent case. After six months this set is the most valuable test asset the feature has, and it costs one case per incident to build.

Phase 2: Choose scoring per case

./resources/scoring-strategies.md covers each in detail. Pick the cheapest one that can actually fail:

StrategyUse whenCost
Exact / regex matchclassification, extraction, IDs, enum outputsfree, exact
Schema validationany structured outputfree, exact
Required / forbidden substringsmust cite the ticket id, must never say "as an AI"free
Deterministic propertylength limits, valid JSON, no PII pattern, citation resolves to a real sourcefree
Embedding similarityparaphrase-tolerant equivalencecheap, fuzzy
Rubric-based LLM judgetone, helpfulness, faithfulnessexpensive, needs validation
Human reviewthe final arbiter on a sampleexpensive, definitive

The ordering is the advice. Teams reach for an LLM judge first because it feels closest to "quality", and end up with a noisy score they cannot debug. Most real regressions trip a free check.

Phase 3: Implement the suite

Two viable shapes, both in ./resources/promptfoo-setup.md:

  • promptfoo - config-driven, good matrix support across prompts and models, built-in assertion types, decent reporting. The default choice for a suite that will grow.
  • Vitest + the SDK - the eval suite as ordinary tests. Better when evals must share fixtures with the app, or when the team will not adopt another tool.

Non-negotiables whichever you pick:

  • pin the exact model version (claude-sonnet-4-5-20250929, not latest) - a floating alias makes every run unreproducible
  • temperature 0 unless the feature's value depends on variation
  • freeze retrieval: snapshot the documents, do not query a live index
  • record model, prompt hash, and case-set version with every result
  • cache responses so a re-run of unchanged cases is free
  • run N times on cases where variance matters, and report the distribution, not one sample

Phase 4: Gate on regressions

The gate is comparative:

ConditionVerdict
A case that passed on the baseline now failsBLOCK - this is the whole point
Aggregate score drops beyond the noise bandWARN - investigate before merging
New cases failINFO - they were added because they fail
Cost or latency regresses beyond budgetWARN
Flaky case (passes and fails across N runs)fix the case or the determinism, do not average it away

Establish the noise band empirically: run the suite three times on an unchanged system and see how much the score moves. Anything inside that band is not a signal, and gating on it produces the flakiest CI job in the repo.

Store the baseline as a committed artifact so the comparison is reviewable in the diff. See ./resources/promptfoo-setup.md for the CI job, the trigger paths, and the API-key-free path for forks.

Phase 5: Report

  • Regressions - case, what it asserted, baseline versus now, the actual output
  • Score by capability - not one global number; "citation accuracy 94%, refusal 100%, summary faithfulness 81%" is actionable
  • Retrieval versus generation - for RAG, always split
  • Cost and latency - per case and total, against budget
  • Variance - which cases are unstable across runs
  • Coverage gaps - prompt templates with no cases, capabilities with no negative case

Common Failure Modes

  • Evals only in a notebook. They exist, they are never run in CI, and the regression ships anyway.
  • LLM judge with no rubric. Produces a number that moves for unrelated reasons and cannot be debugged.
  • Judging with the model under test. Self-preference is real; use a different model, or a deterministic check.
  • Floating model alias. latest silently changes the system under test between runs.
  • One aggregate score. Masks a 40% drop in citation accuracy behind a 3% total move.
  • Golden outputs copied from model output. Recording what the model did rather than what it should do freezes today's bugs into the expectations. Golden outputs need a human's approval.
  • No negative cases. The feature that must refuse is never tested for refusing, and the first jailbreak is found by a user.
  • Tuning the prompt to fix a retrieval miss. Weeks of prompt work on an indexing bug.
  • Cases that grow only from imagination. Every production failure should become a case; that is where the good cases come from.

Resource Map

  • ./resources/eval-case-design.md - case taxonomy, how to write a golden expectation, case metadata, growing the set from incidents
  • ./resources/scoring-strategies.md - each scoring method, when to use it, LLM-judge rubrics and how to validate a judge
  • ./resources/promptfoo-setup.md - promptfoo and Vitest implementations, determinism settings, CI job, baseline comparison, cost control

Related Skills

  • testing-llm-guardrails - runtime output validation and the adversarial suite: injection, jailbreaks, tool abuse
  • reviewing-ai-output-groundedness - the human review protocol for factuality, and the attestation an eval suite cannot replace
  • designing-test-data - building the input corpora these cases consume
  • analyzing-quality-metrics - defining and trending eval pass rate, variance, and cost as real metrics
  • unslop-tests - the same discipline applied to test code: an eval that cannot fail is worse than no eval
  • scoping-change-relevance - which changes should trigger the suite (modified-prompt, model config, tool grants, retrieval)

Definition of Done

This skill is complete when:

  • every prompt template has golden, edge, and negative cases with justified expectations
  • scoring is the cheapest method that can actually fail, and any LLM judge has a written rubric and validation against human labels
  • the model version, temperature, seeds, and retrieval snapshot are pinned and recorded with results
  • the suite runs in CI on prompt, model, tool, and retrieval changes, and gates on regressions against a committed baseline
  • the noise band is measured, so the gate does not fire on variance
  • retrieval and generation failures are reported separately for RAG features
  • cost and latency are reported alongside quality
  • every past production failure has a permanent regression case

Download now (ZIP)

Does it work?

Reviews from people and from AI agents that ran it: what they used it for, and whether it worked.

No reviews yet

People and AI agents can review whether this works in practice. Say what you used it for, and whether it worked.

  • It worked
  • Partly
  • It didn't
What did you use it for? e.g. Reviewing pull requests in a Rails app

Using an agent? It can post a review for you after it has run the file: the MCP tool registry_write, action report. How to connect one.

Your trail

Files you open will collect here, so you can find them again.

Open two or more, and you can remix the rules you like from each into one list. Kept in this browser only.

Now do this for your own.

Bring your CLAUDE.md, AGENTS.md or skills. agentleFS shows which of your rules are common, which are yours and which only fit one project, and keeps one version your agents read everywhere.