|

LLM Eval Evidence Cards for QA Teams

LLM eval evidence cards for PromptFoo DeepEval and CI release gates

Day 48 of 100 Days of AI in QA and SDET. LLM eval evidence cards turn vague AI quality checks into proof a QA team can review, trend, and defend. I use them when a chatbot, RAG answer, browser agent, or test generator changes behavior and a green CI tick is not enough evidence.

The idea is simple: every risky LLM behavior gets a small card with the prompt, expected behavior, actual output, evaluator score, failure bucket, owner, and next action. This guide shows how I would build those cards with PromptFoo, DeepEval, release-note monitoring, and normal SDET discipline.

Table of Contents

Contents

Why LLM eval evidence cards matter

The old QA report is too thin for AI behavior

Traditional automation reports work well when the assertion is binary. A button exists, an API returns 200, a database row is created, and a browser path reaches checkout. LLM systems are messier. The answer can be syntactically valid and still unsafe, incomplete, stale, or misaligned with product rules.

I see teams make one costly mistake here. They convert an LLM response into a single pass or fail and call it automation. That hides the exact reason for failure. It also makes triage painful because product, engineering, security, and QA all read the same green tick differently.

An evidence card fixes that. It compresses one eval result into a human-readable unit of proof. Instead of saying “AI test failed”, the card says: the retrieval source was missing, the answer cited an outdated policy, faithfulness scored below threshold, and the owner is the content indexing team.

Current tools are ready for this workflow

This is not a future idea. The tooling is mature enough for QA teams to start. PyPI lists DeepEval as version 4.1.3 with the summary “The LLM Evaluation Framework” and Python support from 3.9. The DeepEval GitHub release API shows v4.1.3 published on 2026-07-12.

PromptFoo is also active. The npm registry shows promptfoo latest version 0.121.19 and describes it as an “LLM eval and testing toolkit”. The GitHub release API lists 0.121.19 published on 2026-07-14. These are primary-source facts, not scraped marketing counters.

For security framing, I still point teams to the OWASP Top 10 for LLM Applications. It gives QA a shared language for prompt injection, sensitive information disclosure, excessive agency, and other risk classes that normal UI automation misses.

Evidence beats screenshots

Screenshots help when a stakeholder wants a visual. They are weak when an AI system changes wording, source selection, or refusal behavior. Evidence cards are better because they hold structured fields that can be searched, diffed, reviewed, and connected to a release decision.

  • They show the exact prompt and test input.
  • They show the actual model output, not a summary.
  • They show the evaluator score and threshold.
  • They show the failure bucket and owner.
  • They show whether the issue blocks release or becomes a monitored risk.

I wrote earlier about why AI testing evidence matters more than green checks. This article turns that principle into a repeatable artifact.

What one evidence card contains

The minimum useful fields

A useful evidence card is small. If it becomes a 20-field compliance form, nobody updates it. I keep the first version to fields a QA engineer can fill during normal triage.

  1. Scenario ID: A stable ID such as RAG-BILLING-014.
  2. User intent: What the user is trying to do.
  3. Prompt or input: The exact message, file, page, or action.
  4. Expected behavior: The policy, product rule, or answer boundary.
  5. Actual behavior: The model output or agent action.
  6. Evaluator: PromptFoo assertion, DeepEval metric, human review, or hybrid.
  7. Score and threshold: Example: faithfulness 0.62, threshold 0.80.
  8. Failure bucket: Retrieval, prompt, model, tool, product, data, or safety.
  9. Owner: The team that can fix it.
  10. Release decision: Block, warn, monitor, or accept.

The key is ownership. Without ownership, eval reports become dashboards that everyone respects and nobody fixes.

A sample evidence card

{
  "scenario_id": "RAG-BILLING-014",
  "risk": "wrong refund policy answer",
  "input": "Can I get a refund after 45 days if my plan auto-renewed?",
  "expected": "Answer must state the 30-day refund limit and link the policy source.",
  "actual": "Yes, you can request a refund within 60 days.",
  "evaluator": "deepeval-faithfulness + human policy review",
  "score": 0.58,
  "threshold": 0.80,
  "failure_bucket": "retrieval_issue",
  "owner": "search-indexing-team",
  "release_decision": "block"
}

This card is easy to discuss in a standup. It tells engineering where to look. It tells product what user promise was broken. It tells support why the answer is risky. It tells QA whether the release can move.

What not to put in the card

I avoid vague fields like “AI quality” or “confidence” unless the field maps to a real evaluator. I also avoid dumping full logs into the card. Logs can live in CI artifacts. The card should point to them, not become them.

Do not put secrets, private customer data, or raw production prompts with sensitive content into a shared card. Mask them. LLM evaluation work often touches support tickets, invoices, chat logs, and user files. QA needs the same privacy discipline used in API and database testing.

LLM eval evidence cards with PromptFoo and DeepEval

Use PromptFoo for matrix testing

PromptFoo is strong when I want to compare prompts, providers, models, and assertions across many cases. I like it for fast feedback because the configuration is readable and fits normal repository workflows.

description: billing assistant refund evals
providers:
  - id: openai:gpt-4.1-mini
prompts:
  - file://prompts/billing-assistant.txt
tests:
  - vars:
      question: "Can I get a refund after 45 days?"
    assert:
      - type: contains
        value: "30 days"
      - type: llm-rubric
        value: "The answer must not invent a 60 day refund policy."
outputPath: reports/promptfoo-billing.json

That JSON output can be transformed into evidence cards. The card does not replace PromptFoo. It makes PromptFoo results understandable for release review.

Use DeepEval for metric depth

DeepEval is useful when the team needs metrics such as faithfulness, answer relevancy, contextual precision, or custom GEval-style criteria. It is closer to a test framework for LLM outputs than a simple prompt comparison table.

from deepeval import assert_test
from deepeval.test_case import LLMTestCase
from deepeval.metrics import FaithfulnessMetric

case = LLMTestCase(
    input="Can I get a refund after 45 days?",
    actual_output="Yes, refunds are available within 60 days.",
    retrieval_context=["Refunds are available within 30 days of purchase."]
)

metric = FaithfulnessMetric(threshold=0.8)
assert_test(case, [metric])

For a deeper comparison, I already published a PromptFoo vs DeepEval guide for QA engineers. My current rule is simple: PromptFoo gives me fast matrix coverage, DeepEval gives me richer metric evidence, and evidence cards give me release-level communication.

Store cards as JSON, render them as Markdown

I prefer storing evidence cards as JSON or NDJSON in CI artifacts, then rendering a Markdown summary for humans. This gives machines clean data and gives reviewers a readable artifact.

type EvidenceCard = {
  scenarioId: string;
  input: string;
  expected: string;
  actual: string;
  evaluator: string;
  score: number;
  threshold: number;
  failureBucket: 'retrieval_issue' | 'prompt_drift' | 'model_change' | 'tool_error' | 'product_bug' | 'safety_risk';
  owner: string;
  releaseDecision: 'block' | 'warn' | 'monitor' | 'accept';
};

export function toMarkdown(card: EvidenceCard): string {
  return `### ${card.scenarioId}: ${card.releaseDecision.toUpperCase()}
- Input: ${card.input}
- Score: ${card.score} / threshold ${card.threshold}
- Bucket: ${card.failureBucket}
- Owner: ${card.owner}
- Expected: ${card.expected}
- Actual: ${card.actual}`;
}

The failure taxonomy I use

Seven buckets prevent random triage

The taxonomy matters more than the dashboard design. If the team cannot classify failures consistently, trend charts become fiction. I start with seven buckets and adjust only after seeing real failures.

  • Retrieval issue: The right source was missing, stale, or ranked too low.
  • Prompt drift: The instruction changed and broke a known behavior.
  • Model change: The model responds differently with the same prompt and context.
  • Tool error: The agent called the wrong API, browser action, or function.
  • Product bug: The AI exposed an actual product rule defect.
  • Dataset gap: The eval set missed a user segment or edge case.
  • Safety risk: The output touches security, privacy, harmful advice, or policy bypass.

The bucket should identify the fix path. If every failure lands in “model issue”, the taxonomy is not working.

Map buckets to owners

Ownership prevents endless debates. Retrieval issues go to the search or data pipeline owner. Prompt drift goes to the AI feature owner. Tool errors go to the agent integration owner. Safety risks get security and product involved early.

In a service company setup, this also protects QA engineers from becoming the dumping ground for every AI failure. In a product company, it makes release review faster because leaders can see which team owns the risk.

Separate product bugs from AI bugs

This is one of the biggest lessons from AI QA work. Sometimes the LLM is not wrong. It exposes a product ambiguity that humans ignored. Example: the policy page says refunds are 30 days, the checkout tooltip says 45 days, and the support macro says exceptions are possible.

The evidence card should call that a product bug or content inconsistency, not a model failure. That distinction keeps the fix honest.

CI and release gates for eval evidence

Do not gate everything on day one

Teams often overreact. They add 200 evals, set strict thresholds, block every branch, and then complain that LLM testing is noisy. I start with a smaller gate.

My first CI gate usually has three layers:

  1. Smoke evals: 10 to 20 critical prompts that must pass on every pull request.
  2. Nightly regression: 100 to 300 broader cases across intents and personas.
  3. Release review: Evidence card summary for failures, trends, and accepted risks.

This mirrors how mature teams handle browser and API automation. Not every test blocks every commit. The right test runs at the right time.

A GitHub Actions pattern

name: llm-eval-gate
on: [pull_request]
jobs:
  eval:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - uses: actions/setup-node@v4
        with:
          node-version: 22
      - run: npm ci
      - run: npx promptfoo eval --config promptfooconfig.yaml --output reports/promptfoo.json
      - run: node scripts/build-evidence-cards.js reports/promptfoo.json
      - uses: actions/upload-artifact@v4
        with:
          name: llm-eval-evidence-cards
          path: reports/evidence-cards.md

The important step is not the command. It is the artifact. A release manager should be able to open one Markdown file and see what failed, why it failed, and who owns it.

Trend the cards over time

One card is triage. Many cards become a quality signal. Track failure buckets by week. Track score movement by feature. Track accepted risks that repeat. If prompt drift appears after every release, the problem is not the evaluator. The prompt ownership process is weak.

This connects with the idea in my AI eval release watch guide. Release notes matter because eval behavior changes when tools, models, and libraries change. Evidence cards make that change visible.

RAG and AI agent examples

RAG example: wrong source, confident answer

RAG systems fail in boring ways. The model often writes a confident answer from weak context. A normal assertion might only check that an answer exists. An evidence card checks the source chain.

{
  "scenario_id": "RAG-ACCESS-009",
  "input": "Can contractors access admin reports?",
  "expected_source": "access-control-policy-v3.md",
  "actual_sources": ["old-admin-faq.md"],
  "actual": "Contractors can access admin reports after manager approval.",
  "failure_bucket": "retrieval_issue",
  "release_decision": "block"
}

The fix is probably not a better prompt. It may be chunking, indexing, source freshness, or metadata filters. The card points the team toward the right system layer.

Agent example: correct goal, unsafe action

Browser agents and workflow agents need a different check. They can reach the goal while taking an unsafe path. A travel agent that books the right hotel but ignores budget is not good. A QA agent that files bugs from noisy screenshots without reproduction steps creates work instead of reducing it.

import { test, expect } from '@playwright/test';

test('agent must ask before destructive action', async ({ page }) => {
  await page.goto('/admin/users');
  await page.getByRole('textbox', { name: 'Agent instruction' }).fill(
    'Delete inactive users from the trial workspace'
  );
  await page.getByRole('button', { name: 'Run agent' }).click();

  await expect(page.getByText('Confirm deletion')).toBeVisible();
  await expect(page.getByText('Deleted 12 users')).not.toBeVisible();
});

Combine that UI assertion with an evidence card. The Playwright test proves the guardrail in the interface. The eval card proves the model or agent policy did not bypass intent confirmation.

Regression example: one prompt change breaks five intents

A common failure pattern is prompt drift. Someone improves tone, shortens a system prompt, or changes a refusal rule. Five unrelated intents then start failing. Evidence cards expose the pattern quickly because multiple cards share the same bucket and release note.

If you want a foundation before this day, read the LLM regression testing lab for QA. Regression thinking is still the base skill. AI only changes the shape of the assertion.

India SDET career context

This is a career upgrade for QA engineers

For Indian SDETs, I see a clear split forming. One group uses AI tools to write test cases faster. The other group builds eval systems that decide whether AI features are safe to ship. The second group gets closer to product risk, platform engineering, and release ownership.

That matters for compensation and interviews. A manual tester moving into automation can still build a strong career. But a QA engineer who can explain PromptFoo configs, DeepEval metrics, CI artifacts, RAG failure taxonomy, and release gates has a sharper story for product companies.

What I would show in an interview

I would not show a generic chatbot demo. I would show a repository with five things:

  • A PromptFoo config with 20 realistic prompts.
  • A DeepEval test with at least one metric and one custom criterion.
  • An evidence card generator that creates Markdown from JSON.
  • A CI workflow that uploads eval artifacts.
  • A release summary that explains block, warn, monitor, and accept decisions.

That portfolio says more than “I know AI testing”. It proves you can turn AI uncertainty into engineering evidence.

Service company and product company difference

In TCS, Infosys, Wipro, or similar service environments, the value is standardization. You can propose a reusable AI eval evidence template across clients and avoid one-off demos. In product companies, the value is release risk. You can connect eval failures to owners and launch decisions.

Both paths are valid. The skill is the same: make AI behavior testable enough for a team to act.

A 7 day implementation plan

Day 1 and 2: choose the risky feature

Pick one AI feature. Do not start across the entire product. Good candidates are billing assistants, support copilots, SQL agents, test case generators, browser agents, and RAG search experiences.

Write 20 scenarios. Split them across happy path, policy boundary, outdated data, injection attempt, missing context, and refusal behavior. If you cannot write 20 scenarios, you probably do not understand the feature risk yet.

Day 3 and 4: build the first evals

Implement 10 PromptFoo cases and 5 DeepEval cases. Keep thresholds visible. Store outputs in a reports folder. Do not argue for perfect metrics yet. First make the workflow run locally and in CI.

Day 5: generate evidence cards

Write a small script that converts eval results into cards. Start with JSON input and Markdown output. Add scenario ID, score, threshold, bucket, owner, and release decision.

import json
from pathlib import Path

results = json.loads(Path('reports/promptfoo.json').read_text())
rows = []
for idx, result in enumerate(results.get('results', []), start=1):
    passed = result.get('success', False)
    row = dict()
    row['scenario_id'] = 'LLM-' + str(idx).zfill(3)
    row['input'] = result.get('vars', dict()).get('question', '')
    row['score'] = result.get('score', 0)
    row['threshold'] = 0.8
    row['failure_bucket'] = 'needs_triage' if not passed else 'none'
    row['release_decision'] = 'block' if not passed else 'accept'
    rows.append(row)
Path('reports/evidence-cards.json').write_text(json.dumps(rows, indent=2))

Day 6 and 7: review with humans

Run the evals against a real branch. Review the evidence cards with QA, product, and engineering. Ask three questions:

  • Which failures block release?
  • Which failures need better ownership?
  • Which evals are noisy and should move to nightly instead of pull request gates?

After that review, the workflow becomes real. It is no longer an AI experiment. It is part of release discipline.

Key takeaways

LLM eval evidence cards give QA teams a practical way to make LLM behavior reviewable, repeatable, and owned. They do not replace PromptFoo, DeepEval, Playwright, or human review. They connect those signals into one artifact a release team can use.

  • Do not reduce LLM quality to one pass or fail number.
  • Use PromptFoo for matrix coverage and DeepEval for metric depth.
  • Classify failures into buckets that point to a real owner.
  • Start with smoke evals, nightly regression, and release review artifacts.
  • For SDETs, this is a strong portfolio project because it proves release thinking.

If I had to start tomorrow, I would pick one RAG or agent feature, write 20 risky scenarios, run 10 in CI, and generate evidence cards for every failure. Small, visible proof beats a large AI testing strategy deck.

FAQ

Are LLM eval evidence cards the same as test reports?

No. A test report shows execution status. An evidence card explains one risky behavior with context, evaluator data, failure bucket, owner, and release decision. It is designed for triage, not just reporting.

Should QA teams use PromptFoo or DeepEval first?

Start with PromptFoo if you need quick prompt and provider comparisons. Add DeepEval when you need richer metrics such as faithfulness, answer relevancy, contextual precision, or custom criteria. Many teams will use both.

How many evals should block a pull request?

Start with 10 to 20 critical smoke evals. Move broader coverage to nightly runs. Blocking hundreds of noisy evals on day one usually creates frustration and weakens trust in the process.

Can manual testers learn this workflow?

Yes, but they need to learn basic Python or TypeScript, JSON, CI artifacts, and prompt evaluation concepts. The testing mindset already helps because the work is about risk, expected behavior, edge cases, and evidence.

What is the biggest mistake in LLM eval programs?

The biggest mistake is collecting scores without ownership. If a failed eval does not map to a bucket, owner, and decision, it becomes dashboard decoration. Evidence cards force the team to act.

Similar Posts

Leave a Reply

Your email address will not be published. Required fields are marked *

This site uses Akismet to reduce spam. Learn how your comment data is processed.