Local BYOK LLM and RAG evaluation metrics (Qapitol Evals Kit)
Project description
qapitol-evals-kit
Local BYOK LLM and RAG evaluation metrics from Qapitol. Your data never leaves your machine — no Qapitol account, no trace upload.
Version 0.2.0 · Usage guide · JSONL & traces · CI gates
Who this is for
- ML / LLM engineers adding evals to notebooks, pipelines, or CI
- QA / eval leads who want coherence, relevance, RAG faithfulness, etc. without writing judges from scratch
- Teams with data-sovereignty rules (BYOK only; eval runs stay in your environment)
What you can do
| Capability | How |
|---|---|
| Score a single response | Python API or qapitol-evals run CLI |
| Score many rows in Python | evaluate_batch_sync |
| Load traces from JSONL | load_jsonl → run_metrics → write_results_jsonl |
| Multi-turn agent sessions | records_per_turn, record_final_turn, format_transcript |
| RAG grounding checks | Pass context + use Faithfulness / Answer Relevancy |
| CI threshold gates | Code metrics or MockCompletionClient — no API key required |
| Code metrics (no API key) | ExactMatchEvaluator, CustomAccuracyEvaluator |
| LLM-as-judge (OpenAI / Anthropic) | LLM(provider=...) + 7 judge metrics |
After
pip install, detailed docs live on GitHub (PyPI Documentation link). The wheel ships code + CLI only.
Install
PyPI:
pip install qapitol-evals-kit==0.2.0
pip install "qapitol-evals-kit[all]==0.2.0" # OpenAI + Anthropic client libraries
From source (development):
pip install -e ".[dev,all]"
From GitHub (fallback):
pip install "qapitol-evals-kit @ git+https://github.com/QapitolAI/qapitol-evals-kit@v0.2.0"
pip install "qapitol-evals-kit @ git+https://github.com/QapitolAI/qapitol-evals-kit.git@main"
Verify: qapitol-evals doctor
Repo: github.com/QapitolAI/qapitol-evals-kit · Releases: v0.2.0 · PyPI: qapitol-evals-kit
Quick starts
Code metric (no API key)
from qapitol.evals import ExactMatchEvaluator
score = ExactMatchEvaluator().evaluate({
"output": "Paris",
"expected": "Paris",
})
print(score.score, score.label) # 1.0 match
LLM judge (BYOK)
export OPENAI_API_KEY=sk-...
# or: export ANTHROPIC_API_KEY=...
from qapitol.evals import CoherenceEvaluator
from qapitol.evals.llm import LLM
llm = LLM(provider="openai", model="gpt-4o-mini")
score = CoherenceEvaluator(llm).evaluate({
"input": "What is RAG?",
"output": "RAG retrieves context then generates an answer.",
})
print(score.score, score.label, score.explanation)
RAG evaluation
from qapitol.evals import FaithfulnessEvaluator
from qapitol.evals.llm import LLM
score = FaithfulnessEvaluator(LLM()).evaluate({
"input": "Refund policy?",
"output": "Returns accepted within 30 days.",
"context": "Policy: 30-day return window for all items.",
})
JSONL batch (100+ traces)
from pathlib import Path
from qapitol.evals import CoherenceEvaluator, load_jsonl, run_metrics, summarize, write_results_jsonl
from qapitol.evals.llm import LLM
records = load_jsonl("traces.jsonl")
results = run_metrics(records, [CoherenceEvaluator(LLM())])
by_metric: dict[str, list] = {}
for row in results:
for s in row["scores"]:
by_metric.setdefault(s.name, []).append(s)
print(summarize(by_metric))
write_results_jsonl("results.jsonl", [(row, row["scores"]) for row in results])
Full schema and trace-mapping cookbook: docs/BATCH_AND_TRACES.md.
Multi-turn conversations
from qapitol.evals import records_per_turn, record_final_turn, format_transcript
session = {
"session_id": "s1",
"messages": [
{"role": "user", "content": "What is ML?"},
{"role": "assistant", "content": "Machine learning learns from data."},
{"role": "user", "content": "Give an example."},
{"role": "assistant", "content": "Email spam filters use ML."},
],
}
per_turn = records_per_turn(session) # Pattern A — judge each reply
final = record_final_turn(session) # Pattern B — last reply only
transcript_input = format_transcript(session["messages"][:-1]) # Pattern C
CI threshold gate (no API key)
from qapitol.evals import ExactMatchEvaluator, load_jsonl, run_metrics, summarize
THRESHOLD = 0.9
results = run_metrics(load_jsonl("golden.jsonl"), [ExactMatchEvaluator()])
by_metric: dict[str, list] = {}
for row in results:
for s in row["scores"]:
by_metric.setdefault(s.name, []).append(s)
if summarize(by_metric).get("exact_match", 0) < THRESHOLD:
raise SystemExit("FAIL: exact_match below threshold")
Mocked LLM judges for CI: docs/CI.md.
CLI
qapitol-evals doctor
qapitol-evals run --metric coherence --input "What is AI?" --output "AI is ..."
qapitol-evals run --metric faithfulness --output "30-day returns." --context "Policy: 30 days."
| Limit (v0.2) | Workaround |
|---|---|
One row per run command |
JSONL batch via Python (load_jsonl + run_metrics) |
| Code metrics not in CLI | Python API or examples/01_basic_code.py |
Metrics
| Type | Evaluators |
|---|---|
| Code | ExactMatchEvaluator, CustomAccuracyEvaluator |
| LLM | Coherence, Relevance, Correctness, Hallucination, Toxicity |
| RAG | Faithfulness, Answer Relevancy |
Public API (v0.2 highlights)
| Module | Functions |
|---|---|
| I/O | load_jsonl, write_jsonl, write_results_jsonl |
| Runner | run_metrics, summarize |
| Conversation | format_transcript, records_per_turn, record_final_turn |
| Batch | evaluate_batch, evaluate_batch_sync |
All evaluators and Score are exported from qapitol.evals. See docs/USAGE.md for the full reference.
Examples
Clone or browse examples/:
| File | What it shows |
|---|---|
01_basic_code.py |
Exact match & custom accuracy — no API key |
02_rag_mock.py |
Faithfulness with mocked judge |
03_agent_smoke.py |
Coherence + relevance on agent output |
04_batch_jsonl.py |
JSONL load → run_metrics → write results |
05_multiturn.py |
Multi-turn patterns A / B / C |
pip install -e ".[dev,all]"
python examples/01_basic_code.py
python examples/04_batch_jsonl.py
python examples/05_multiturn.py
Test
ruff check src tests
pytest tests/ -v
All default tests use mocks — no OPENAI_API_KEY required.
Documentation
| Doc | Contents |
|---|---|
| docs/USAGE.md | Install, evaluators, CLI, FAQ |
| docs/BATCH_AND_TRACES.md | JSONL schema, trace mapping, multi-turn |
| docs/CI.md | Pipeline gates, mocked vs live eval |
License
MIT
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file qapitol_evals_kit-0.2.0.tar.gz.
File metadata
- Download URL: qapitol_evals_kit-0.2.0.tar.gz
- Upload date:
- Size: 11.2 kB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
b02969d3b33998b6f0ae6f810975ed6f79c84853105780a080ab731bd6d334ce
|
|
| MD5 |
75e0f7ff3f8dedd15df0828a7275bf69
|
|
| BLAKE2b-256 |
91626c094fe94eaac38784e306a0abe9c8019216054eb6cafe6c985e0cca04aa
|
Provenance
The following attestation bundles were made for qapitol_evals_kit-0.2.0.tar.gz:
Publisher:
release.yml on QapitolAI/qapitol-evals-kit
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
qapitol_evals_kit-0.2.0.tar.gz -
Subject digest:
b02969d3b33998b6f0ae6f810975ed6f79c84853105780a080ab731bd6d334ce - Sigstore transparency entry: 1717244150
- Sigstore integration time:
-
Permalink:
QapitolAI/qapitol-evals-kit@5482c9b60c897a5f5527d8b3beefab41e7bde5de -
Branch / Tag:
refs/tags/v0.2.0 - Owner: https://github.com/QapitolAI
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
release.yml@5482c9b60c897a5f5527d8b3beefab41e7bde5de -
Trigger Event:
push
-
Statement type:
File details
Details for the file qapitol_evals_kit-0.2.0-py3-none-any.whl.
File metadata
- Download URL: qapitol_evals_kit-0.2.0-py3-none-any.whl
- Upload date:
- Size: 16.5 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
c0a53005d70867961d26f50c813d55e4ada58a65a459e24c8f00af304b158288
|
|
| MD5 |
5f31f55fd2e7928de0cad6923b17bc33
|
|
| BLAKE2b-256 |
56f77c4285957327d759389ed2bcaea50c0f983a899f7a636e5421ebe17b8b6c
|
Provenance
The following attestation bundles were made for qapitol_evals_kit-0.2.0-py3-none-any.whl:
Publisher:
release.yml on QapitolAI/qapitol-evals-kit
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
qapitol_evals_kit-0.2.0-py3-none-any.whl -
Subject digest:
c0a53005d70867961d26f50c813d55e4ada58a65a459e24c8f00af304b158288 - Sigstore transparency entry: 1717244252
- Sigstore integration time:
-
Permalink:
QapitolAI/qapitol-evals-kit@5482c9b60c897a5f5527d8b3beefab41e7bde5de -
Branch / Tag:
refs/tags/v0.2.0 - Owner: https://github.com/QapitolAI
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
release.yml@5482c9b60c897a5f5527d8b3beefab41e7bde5de -
Trigger Event:
push
-
Statement type: