What works today
LLMGrade is an independent prototype exploring app-specific evals for LLM applications. The current wedge: catching a hallucinated policy change in a RAG support bot before merge.
Right now, on a single bundled refund-policy example, you can:
- Run an interactive, deterministic eval in the browser — edit the inputs and re-score.
- See the rubric and a baseline-vs-candidate score on every run.
- Watch a critical-failure rule hard-block an answer that invents policy.
- Reproduce the same result offline with a local CLI (init / run / diff / html).
- Generate a self-contained local HTML report from the CLI.
Scoring is deterministic and tuned to this refund-policy example. It is not a general semantic judge yet — see What's planned.
Run the demo locally
The local CLI is a prototype that runs inside the cloned repo — it isn't published to npm. Clone the repo and run npm install first; then npx llmgrade resolves the local CLI. It runs the bundled fixture — no network and no API key — and reproduces the same regression you see in the web demo.
Start with npx llmgrade init — run, diff, and html need the files it scaffolds.
❯ npx llmgrade initScaffolds llmgrade/ eval files, rubric, and the example❯ npx llmgrade runbaseline overall 93% pass · current overall 38% fail❯ npx llmgrade diff --no-exit-codeCritical failure: invented 45-day medical refund exceptionMerge gate: blocked❯ npx llmgrade htmlWrote llmgrade/report.html
npx llmgrade initScaffold the bundled eval files, rubric, and example into ./llmgrade and ./examples.npx llmgrade runScore the bundled baseline and current answers and write llmgrade/runs/latest.json.npx llmgrade diffPrint the merge-gate result and exit non-zero on a regression (--no-exit-code to keep exit 0).npx llmgrade htmlWrite a self-contained llmgrade/report.html.Same result every time. You can hand-edit the generated fixture files and re-run. Because the scorer is tuned to this example, answers from other domains won't score meaningfully yet, and custom file paths are not wired up.
How RAG support-bot evals work
An eval case for a RAG support bot has three parts:
- Retrieved context — the doc snippets your retriever returns for the question.
- User question — what the customer actually asks.
- Answer — what your bot produced, scored only against the retrieved context.
The judge grades the answer only against the retrieved context — never outside knowledge. If the docs don't cover the question, the correct behavior is to say so and route to support, not to guess.
Critical-failure rule
An answer hard-fails if it changes the return window (or measures it from purchase, or switches to business days), weakens 'unused' or 'original condition', joins required conditions with 'or' instead of 'and', invents an exception or support discretion, treats 'no exceptions listed' as permission, promises eligibility the source does not support, or is gibberish/irrelevant.
The rubric
Each answer is scored on five weighted dimensions. The weights sum to 100% and produce the overall score (shown out of 10 in the demo).
| Dimension | Weight | What it measures |
|---|---|---|
| Groundedness | 35% | Does the answer stay supported by the source truth? |
| Policy accuracy | 25% | Does the answer preserve the actual refund-policy requirements? |
| Completeness | 15% | Does it include the key conditions needed to answer the user? |
| Refusal / uncertainty quality | 15% | Does it handle missing or unsupported information correctly? |
| User usefulness & clarity | 10% | Does it directly help the user without adding unsupported claims? |
Pass gate (absolute)
- Overall ≥ 80%
- Groundedness ≥ 85%
- Policy accuracy ≥ 90%
- No critical failures
Diff gate (vs. baseline)
- Fail if overall drops > 8 pts
- Fail if groundedness drops > 10 pts
- Fail if any critical case regresses pass → fail
Refund Policy Eval Pack
LLMGrade isn't just a rubric page — the bundled example is an eval pack: source-truth facts, question variations, response failure modes, deterministic scoring rules, a hard gate, example cases, and a regression report. The evaluator parses the source into policy facts, extracts behavior flags from the answer, and judges whether the answer preserves the policy decision — not whether it matches one fixed string.
This pack is intentionally narrow
It focuses on one support-bot policy domain — RAG bots answering refund-policy questions. The goal is to show how product-specific evals catch behavior drift, not to claim universal LLM evaluation.
The policy facts
- Return window: 30 days
- Start point: from delivery, not purchase
- Item condition: unused
- Product state: original condition
- Exceptions: none listed
- Eligibility: all listed conditions must be met (AND, not OR)
Forbidden behavior: inventing exceptions, extending the window, weakening conditions, or promising eligibility the source doesn't support.
Rubric axes & score anchors
Groundedness — does the answer stay supported by the source truth?
- 10/10Every claim is supported by the source.
- 8/10Mostly supported, minor phrasing looseness that doesn't change eligibility.
- 5/10Partially grounded, but omits or weakens an important condition.
- 2/10Mostly unsupported, but still vaguely related to returns.
- 0/10Invents unsupported policy terms, or is irrelevant/gibberish.
Policy accuracy — does it preserve the actual refund-policy requirements?
- 10/10Preserves 30 days from delivery, unused, original condition, no listed exceptions.
- 8/10Eligibility correct but wording slightly imprecise.
- 5/10Mentions the window but omits unused/original condition.
- 2/10Weakens a requirement, e.g. 'good condition' instead of unused/original.
- 0/10Changes the policy: 45 days, medical exception, manager override, store credit, used-item eligibility.
Completeness — does it include the key conditions to answer the user?
- 10/10Answers the question and includes all conditions relevant to eligibility.
- 8/10Correct but leaves out one low-risk detail.
- 5/10Partial answer that may be safe but incomplete.
- 2/10Barely answers; sends the user to support without policy guidance.
- 0/10Non-answer, gibberish, unrelated, or harmful misdirection.
Refusal / uncertainty quality — does it handle missing info correctly?
- 10/10Clearly says when the source doesn't specify something and avoids invention.
- 8/10Mostly careful, with minor generic support language.
- 5/10Safe but vague.
- 2/10Over-refuses despite enough information, or says 'unclear' when the source is clear.
- 0/10Invents from absence: 'no exceptions are forbidden, so exceptions are allowed.'
User usefulness & clarity — does it directly help without unsupported claims?
- 10/10Direct, plain-English, actionable answer.
- 8/10Clear and mostly useful.
- 5/10Understandable but missing important user-facing detail.
- 2/10Confusing or evasive.
- 0/10Gibberish, irrelevant, or misleading.
Hard gate (critical failure)
Any of these blocks the answer regardless of the other axes:
- Extends the window (45/60 days, business days, grace or holiday window)
- Measures the window from purchase instead of delivery
- Allows used items or weakens 'original condition' to 'good condition'
- Uses 'or' instead of 'and' across required conditions
- Invents medical, manager, holiday, gift, loyalty, store-credit, exchange, or support-agent exceptions
- Treats 'no exceptions listed' as permission to create one
- Promises eligibility the source doesn't support, or is gibberish/irrelevant
Stress-test matrix
| Source-truth wording | Equivalent phrasings of the same policy score the same. |
| Question variations | Different user intents ("after 45 days?", "used item?", "manager override?"). |
| Correct answers | Faithful paraphrases score high. |
| Obvious hallucinations | Invented exceptions / windows hard-fail. |
| Subtle wrong answers | Omissions score low; or/and, purchase, business-days hard-fail. |
| Safe but incomplete | Over-refusals score lower than correct, above hallucinations. |
| Gibberish / irrelevant | Near-zero, blocked as a non-answer. |
| Adversarial reasoning | "No exceptions listed, so exceptions are allowed" hard-fails. |
| Multi-condition | Preserves the AND relationship across conditions. |
| Missing information | Rewards "the source doesn't specify"; penalizes invented certainty. |
| Conflicting source | Rewards noting the conflict; penalizes one rule stated as universal. |
A deterministic test suite (60+ cases across these categories) runs with npm run smoke against the same shared engine that powers the web demo and the local CLI.
What's planned
These are not built yet. The demo above does not depend on them:
- Custom eval cases and custom file paths (today it's locked to the bundled fixture).
- Broader domains beyond the refund-policy example.
- Model-backed (LLM) rubric judging for arbitrary domains.
- Repo scanning and generated eval suites from your own app.
- GitHub Action enforcement — a required CI merge gate.
- Hosted run history.
Deploy & API key
This is a standard Next.js App Router project. To deploy:
- 1Push this repository to GitHub.
- 2In Vercel, click “Add New… → Project” and import the repo.
- 3Framework preset auto-detects as Next.js — no build config needed.
- 4Click Deploy. The demo works immediately, with no key.
❯ npm install❯ npm run dev▲ Next.js — http://localhost:3000
The interactive demo always runs on the deterministic judge and never needs a key. Separately, the /api/judge route can call Claude when ANTHROPIC_API_KEY is set (it falls back to the mock if the call fails). Model-backed judging is not wired into the demo flow yet.