LLM-Eval-Guard
A CI/CD quality gate for LLM and RAG applications — scores outputs against quality, schema, and security metrics, and fails a pull request when thresholds aren't met.
Status: feature-complete for v0.1.0 (pre-release). Charter: VISION.md · roadmap:
plan.md.
Why
A bad prompt edit, a broken retrieval step or a regressed output schema merges silently, because
nothing fails CI. LLM-Eval-Guard is that missing gate: pytest --cov discipline for model outputs.
It's a gating and reporting layer on top of DeepEval, not a replacement. What it adds:
- One
Metricinterface over engine scores —metrics/ - $0 local judge by default (Ollama); OpenAI/Anthropic only as bring-your-own-key
- Judge calibration against human labels — docs/judge-calibration.md
- Schema/contract testing, strict or lenient —
schema/ - Prompt-drift snapshots for Jinja2 templates —
prompts/ - Red-team suite: prompt injection, jailbreak, PII, toxicity —
security/ - CI gating + reporting:
leg runexit code, job-summary report —ci.yml - Test strategy: risk → check, and what's left out on purpose — docs/test-strategy.md
Quickstart
pip install "llm-eval-guard[deepeval]"
ollama pull qwen2.5:7b # local, $0-cost calibrated judge
leg init # scaffolds leg.config.yaml + a sample dataset + example test
leg run # full suite, scored by the local Ollama judge
leg run --fast # schema/prompt-drift/rule checks only, no network call
From Python, or inside a pytest test via the judge_llm fixture:
from llm_eval_guard.core import EvalCase
from llm_eval_guard.metrics.deepeval_adapter import faithfulness_metric
case = EvalCase(
input="What's the storage limit on the Free plan?",
actual_output="The Free plan includes 5GB of storage.",
retrieval_context=["Free plan limits: 5GB total storage, 2GB max file size per upload."],
)
result = faithfulness_metric(threshold=0.8).evaluate(case) # pass model=judge_llm in pytest
print(result.score, result.passed, result.reason)
Full pytest pattern: tests/integration/test_faithfulness.py. A paid judge is opt-in: pass any
DeepEval model, e.g. model=OpenAIModel(model="gpt-4o-mini").
Configuration
leg.config.yaml at the project root drives every leg run:
suites:
quality:
dataset: datasets/golden/sample_rag_qa.jsonl
metrics:
- name: faithfulness
threshold: 0.6 # calibrated judge cutoff
judge:
model: qwen2.5:7b # calibrated judge
judge_profiles:
ci:
model: qwen2.5:0.5b # fast, uncalibrated: `leg run --judge ci`
- Every key: docs/architecture.md
- Why these thresholds: docs/thresholds.md
- Custom metric, schema or prompt source: docs/architecture.md
- New red-team entry:
datasets/redteam/README.md
What a CI run looks like
leg run --report-dir reports/ writes report.md into the GitHub Actions job summary:
# LLM-Eval-Guard Report
**✅ PASS** — 12/12 cases passed (100%)
## Per-metric summary
- **quality / faithfulness** — 6/6 passed (100%), avg score 0.95
- **security / compliance** — 6/6 passed (100%), avg score 1.00
Security failures get their own section, sorted by severity — see docs/security.md.
A caught regression
The gate also runs against a real (tiny) RAG app, examples/demo_rag.
PR #2 changes TOP_K = 3 → 1 ("one chunk
is enough") and CI goes red (run).
- CI gate (
context_recall): 12/12 → 8/12, exit 1 — every multi-hop question loses a fact. Deterministic, so no judge noise. - Calibrated judge: 20/24 → 19/24. "The context doesn't say" is faithful, so judge metrics barely move — why the gate checks retrieval directly.
- PR #2 stays open, never merged, as evidence. Red-team results for the same app: docs/security.md.
Development
make install && poetry run pre-commit install && make test
- Prerequisites and workflow: CONTRIBUTING.md
- Judge trust: the default judge agrees with human labels 82% (relevancy) and 71% (faithfulness) held-out — read docs/judge-calibration.md before trusting scores
Docs
- architecture — data flow, config keys, extension points
- thresholds — every cutoff and why
- datasets — golden dataset schema and labeling rules
- prompt-testing — prompt contracts and drift snapshots
- security — red-team metrics and findings
- ci-setup — CI jobs, branch protection, release
- judge-calibration — how far to trust the judge
- test-strategy — risks, checks, and gaps
Metadata
Release files for llm-eval-guard 0.1.0
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | Provenance | |
|---|---|---|---|---|
| llm_eval_guard-0.1.0.tar.gz | 37.7 kB | With provenance | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| llm_eval_guard-0.1.0-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 86.1 kB
Release files / llm_eval_guard-0.1.0.tar.gz
| Download URL | llm_eval_guard-0.1.0.tar.gz |
|---|---|
| Size | 37.7 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
3b38347507d06ad9aefacbcd596bdf6e0ff8426e57cb6c2eed75bc8d632f7880
|
|
BLAKE2b-256 checksum How to use checksums |
193382e2a458d1de00570f276eff9fd410f4b8f005aaf355c89730ebece22cc0
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/7.0.0 CPython/3.13.16
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Oct 22, 2026.
Transparency logRelease files / llm_eval_guard-0.1.0-py3-none-any.whl
| Download URL | llm_eval_guard-0.1.0-py3-none-any.whl |
|---|---|
| Size | 48.4 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
5e6410071bafefa97298c3fce684c84df441094f22987b6c90e692fce3c53c9e
|
|
BLAKE2b-256 checksum How to use checksums |
87cf81e780d334b845fdca13af1dbf6436ed33437effc99a8b47746c2d2c3cd8
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/7.0.0 CPython/3.13.16
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Oct 22, 2026.
Transparency logSecurity for llm-eval-guard 0.1.0
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
Full provenance
All 2 files in this release have been uploaded with provenance metadata.
Attestation for llm_eval_guard-0.1.0.tar.gz
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Oct 22, 2026.
Transparency logA note on package security
PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.