llm-evaluation
Skill17 starsChanged 4 months agoMITView on GitHub
Implement comprehensive evaluation strategies for LLM applications using automated metrics, LLM-as-judge, human feedback, and benchmarking. Use when testing LLM performance, measuring AI application quality, comparing prompts/models, or establishing evaluation frameworks. Covers RAGAS for RAG pipelines, evals-as-code CI/CD integration, and modern 2025/2026 practices including structured output evaluation and agentic task success measurement.
- Reads credentials
- Installs packages
19 other projects use a version of this, 8 of them edited.
Adopted by
Most recently taken up by
- ControllableModel/SWE-Skills-Benchedited, first seen Nov 8, 2026
- nicholas-greenwood/agentic-engineering-skillstheir own version, first seen Nov 1, 2026
- KMaruthi2002/universal-llm-skillstheir own version, first seen Oct 25, 2026
- KumailQazi/krmaazha-binance-mcpedited, first seen Oct 17, 2026
- asmamest/Nexus-Skillstheir own version, first seen Oct 15, 2026
- paulopestanajunior/agents-configtheir own version, first seen Oct 15, 2026
Used with
Projects with it also use code-review.
Other files people use alongside this one.
Files found in the same public projects as a version of this one, more often than they turn up anywhere else. Each project counts once, large collections count for less, and this file's own repository is left out.
GoogleSkillcode-review
Adversarial systems, concurrency, memory-model, and architecture code review protocol. Use this skill whenever asked to review code, PRs, diffs, or branches in Filament.
Also in 3 projects that use this
Other versions19 projects use a version of this.
Word for word · 0
None found.
Edited · 8
- xfstudio/skills★ 976% same
- ControllableModel/SWE-Skills-Bench★ 840% same
- KumailQazi/krmaazha-binance-mcp★ 453% same
- ai4brands-design/claude-skills★ 276% same
- CodeWithBehnam/cc-docs★ 243% same
- Ghosteken/agent-harness★ 274% same
- roshankodi/agent-skills★ 253% same
- Samueladewole/claude-skills★ 040% same
Wrote their own version · 11
- kumaran-is/claude-code-onboarding★ 35same name
- nimadorostkar/Claude-Skills-collection★ 33same name
- nicholas-greenwood/agentic-engineering-skills★ 3same name
- asmamest/Nexus-Skills★ 1same name
- KMaruthi2002/universal-llm-skills★ 1same name
- mehulpratapsing/ai-engineer-skill-stack★ 1same name
- paulopestanajunior/agents-config★ 1same name
- yiweiwan/skills★ 1same name
- kiko197/ai-agent-skills★ 0same name
- Red-empty-potato/ai-agent-skills★ 0same name
1 more not listed
How matches are found. Word for word: the exact same text. Edited: shares passages with this file (“99% same” means 99% of its five-word phrases also appear here; 10% or more counts). Their own version: similar meaning, or, weakest, the same name. We can’t tell which project had it first. Projects are counted among the 200 most-starred candidates, and mentions are links to the repository we found, up to 50 per site, so both counts are a floor.
In this repository60 other files it gives its agents.
- AGENTS.mdAGENTS.md
- CLAUDE.mdCLAUDE.md
- agent-browserSkill
- agent-engineeringSkill
- app-marketing-copySkill
- ascii-pixel-artSkill
- autopredictSkill
- autoresearchSkill
- babysit-prSkill
- bird-fastSkill
- blockchain-auditorSkill
- brainstormingSkill
- ceo-reviewSkill
- ck-reviewSkill
- cloudflare-managerSkill
- codex-advisorSkill
- content-trend-researcherSkill
- continuous-learningSkill
- coreml-optimizerSkill
- cto-reviewSkill
- direct-mail-strategistSkill
- evangelion-designSkill
- executing-plansSkill
- freshdesk-apiSkill
- gemini-image-generatorSkill
- gemini-visualSkill
- github-actions-templatesSkill
- googleSkill
- gsplat-optimizerSkill
- hyperagentSkill
- idea-mdSkill
- imagegenSkill
- ios-app-testerSkill
- llm-advisorSkill
- macos-appsSkill
- markdown-fetchSkill
- mcp-builderSkill
- mcp-testerSkill
- nano-bananaSkill
- opensea-apiSkill
- paperclipSkill
- playdate-devSkill
- poke-assistantSkill
- poplar-direct-mailSkill
- practical-typographySkill
- prompt-factorySkill
- qmdSkill
- scientific-critical-thinkingSkill
- security-best-practicesSkill
- security-threat-modelSkill
- seo-optimizerSkill
- shadertoySkill
- skill-finderSkill
- skimmableSkill
- subway-infoSkill
- systematic-debuggingSkill
- tui-designerSkill
- ui-designSkill
- video-editorSkill
- writing-plansSkill
The file
We split this skill into the rules it gives an agent
3 rules. 0 are common, 3 are distinctive, and 0 are very specific to this project.
0
Common
Most of the 17 edited versions we read keep these.
3
Distinctive
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
- Distinctive: line 55
Safety: No harmful content
- Distinctive: line 59
Use stronger LLMs to evaluate weaker model outputs.
- Distinctive: line 67
Constitutional: Check against a set of principles or rules
“Common” is measured: kept by at least 6 in 10 of the 17 edited versions of this file we could read. “Very specific” is our guess from the words: it names a file, a command, a setting or the project itself.
Files
LLM Evaluation
Master comprehensive evaluation strategies for LLM applications, from automated metrics to human evaluation and A/B testing.
When to Use This Skill
- Measuring LLM application performance systematically
- Comparing different models or prompts
- Detecting performance regressions before deployment
- Validating improvements from prompt changes
- Building confidence in production systems
- Establishing baselines and tracking progress over time
- Debugging unexpected model behavior
- Evaluating RAG pipeline quality (retrieval + generation)
- Measuring agentic task success rates
- Testing structured output schema compliance
Core Evaluation Types
1. Automated Metrics
Fast, repeatable, scalable evaluation using computed scores.
Text Generation:
- BLEU: N-gram overlap (translation)
- ROUGE: Recall-oriented (summarization)
- METEOR: Semantic similarity
- BERTScore: Embedding-based similarity
- Perplexity: Language model confidence
Classification:
- Accuracy: Percentage correct
- Precision/Recall/F1: Class-specific performance
- Confusion Matrix: Error patterns
- AUC-ROC: Ranking quality
Retrieval (RAG):
- MRR: Mean Reciprocal Rank
- NDCG: Normalized Discounted Cumulative Gain
- Precision@K: Relevant in top K
- Recall@K: Coverage in top K
2. Human Evaluation
Manual assessment for quality aspects difficult to automate.
Dimensions:
- Accuracy: Factual correctness
- Coherence: Logical flow
- Relevance: Answers the question
- Fluency: Natural language quality
- Safety: No harmful content
- Helpfulness: Useful to the user
3. LLM-as-Judge
Use stronger LLMs to evaluate weaker model outputs. This is the dominant approach in 2025/2026 for open-ended tasks.
Approaches:
- Pointwise: Score individual responses (0-10 Likert scales)
- Pairwise: Compare two responses (preferred by MT-Bench, Chatbot Arena)
- Reference-based: Compare to gold standard answer
- Reference-free: Judge without ground truth (good for creative/open-ended tasks)
- Rubric-based: Judge against explicit criteria (best for consistency)
- Constitutional: Check against a set of principles or rules
Key challenges:
- Position bias: judge models prefer whichever response appears first
- Verbosity bias: longer responses often rated higher regardless of quality
- Self-preference bias: a model may favor its own outputs
- Mitigation: swap order and average; use structured rubrics; use 3rd-party judges
4. RAG-Specific Evaluation (RAGAS)
For Retrieval-Augmented Generation pipelines, use RAGAS metrics:
from ragas import evaluate
from ragas.metrics import (
faithfulness, # Is answer grounded in retrieved context?
answer_relevancy, # Does answer address the question?
context_precision, # Is retrieved context relevant?
context_recall, # Is all necessary info retrieved?
)
from datasets import Dataset
# Prepare evaluation dataset
data = {
"question": ["What is the capital of France?"],
"answer": ["Paris is the capital of France."],
"contexts": [["Paris is a city in France. It is the capital."]],
"ground_truth": ["Paris"]
}
dataset = Dataset.from_dict(data)
result = evaluate(dataset, metrics=[faithfulness, answer_relevancy, context_precision, context_recall])
print(result)RAGAS metric interpretation:
- Faithfulness (0-1): Low score = hallucination. Critical for factual applications.
- Answer Relevancy (0-1): Low = answer is off-topic or evasive.
- Context Precision (0-1): Low = retrieval fetching irrelevant chunks.
- Context Recall (0-1): Low = missing relevant documents in retrieval.
5. Agentic Task Evaluation
For agents that execute multi-step tasks:
class AgentTaskEvaluator:
"""Evaluate agentic task completion."""
def evaluate_task(self, task, agent_trajectory, expected_result):
return {
"task_success": self._check_task_success(agent_trajectory, expected_result),
"tool_use_accuracy": self._check_tool_selection(agent_trajectory),
"step_efficiency": self._measure_step_efficiency(agent_trajectory),
"hallucination_rate": self._check_for_hallucinations(agent_trajectory),
}
def _check_task_success(self, trajectory, expected):
# Did agent achieve the goal? (binary or partial credit)
final_state = trajectory[-1]["state"]
return compare_states(final_state, expected)
def _measure_step_efficiency(self, trajectory):
# How many extra steps did agent take? (vs. optimal path)
actual_steps = len(trajectory)
optimal_steps = self.get_optimal_path_length(trajectory[0]["task"])
return optimal_steps / actual_steps # 1.0 = optimal
def _check_tool_selection(self, trajectory):
# Did agent use correct tools in correct order?
correct_tools = sum(1 for step in trajectory if step["tool_correct"])
return correct_tools / len(trajectory)Key agentic metrics:
- Task completion rate: % of tasks fully completed
- Step efficiency: optimal steps / actual steps taken
- Tool selection accuracy: correct tool chosen / total tool calls
- Error recovery: did agent recover from mistakes?
- Hallucinated tool calls: tools called with made-up parameters
Quick Start
from llm_eval import EvaluationSuite, Metric
# Define evaluation suite
suite = EvaluationSuite([
Metric.accuracy(),
Metric.bleu(),
Metric.bertscore(),
Metric.custom(name="groundedness", fn=check_groundedness)
])
# Prepare test cases
test_cases = [
{
"input": "What is the capital of France?",
"expected": "Paris",
"context": "France is a country in Europe. Paris is its capital."
},
# ... more test cases
]
# Run evaluation
results = suite.evaluate(
model=your_model,
test_cases=test_cases
)
print(f"Overall Accuracy: {results.metrics['accuracy']}")
print(f"BLEU Score: {results.metrics['bleu']}")Automated Metrics Implementation
BLEU Score
from nltk.translate.bleu_score import sentence_bleu, SmoothingFunction
def calculate_bleu(reference, hypothesis):
"""Calculate BLEU score between reference and hypothesis."""
smoothie = SmoothingFunction().method4
return sentence_bleu(
[reference.split()],
hypothesis.split(),
smoothing_function=smoothie
)
# Usage
bleu = calculate_bleu(
reference="The cat sat on the mat",
hypothesis="A cat is sitting on the mat"
)ROUGE Score
from rouge_score import rouge_scorer
def calculate_rouge(reference, hypothesis):
"""Calculate ROUGE scores."""
scorer = rouge_scorer.RougeScorer(['rouge1', 'rouge2', 'rougeL'], use_stemmer=True)
scores = scorer.score(reference, hypothesis)
return {
'rouge1': scores['rouge1'].fmeasure,
'rouge2': scores['rouge2'].fmeasure,
'rougeL': scores['rougeL'].fmeasure
}BERTScore
from bert_score import score
def calculate_bertscore(references, hypotheses):
"""Calculate BERTScore using pre-trained BERT."""
P, R, F1 = score(
hypotheses,
references,
lang='en',
model_type='microsoft/deberta-xlarge-mnli'
)
return {
'precision': P.mean().item(),
'recall': R.mean().item(),
'f1': F1.mean().item()
}Custom Metrics
def calculate_groundedness(response, context):
"""Check if response is grounded in provided context."""
# Use NLI model to check entailment
from transformers import pipeline
nli = pipeline("text-classification", model="microsoft/deberta-large-mnli")
result = nli(f"{context} [SEP] {response}")[0]
# Return confidence that response is entailed by context
return result['score'] if result['label'] == 'ENTAILMENT' else 0.0
def calculate_toxicity(text):
"""Measure toxicity in generated text."""
from detoxify import Detoxify
results = Detoxify('original').predict(text)
return max(results.values()) # Return highest toxicity score
def calculate_factuality(claim, knowledge_base):
"""Verify factual claims against knowledge base."""
# Implementation depends on your knowledge base
# Could use retrieval + NLI, or fact-checking API
passLLM-as-Judge Patterns
Single Output Evaluation (Rubric-Based)
from openai import OpenAI
import json
client = OpenAI()
def llm_judge_quality(response, question):
"""Use GPT-4.1 to judge response quality with structured output."""
prompt = f"""You are an impartial evaluator. Rate the following response on a scale of 1-10 for each criterion.
**Criteria:**
1. Accuracy (1=many factual errors, 10=completely correct)
2. Helpfulness (1=doesn't address question, 10=fully resolves question)
3. Clarity (1=confusing/unclear, 10=perfectly clear and well-structured)
**Question:** {question}
**Response:** {response}
Evaluate objectively. Provide ratings in JSON format:
{{
"accuracy": <1-10>,
"helpfulness": <1-10>,
"clarity": <1-10>,
"reasoning": "<2-3 sentence justification>",
"overall": <1-10>
}}
"""
result = client.chat.completions.create(
model="gpt-4.1",
messages=[{"role": "user", "content": prompt}],
temperature=0,
response_format={"type": "json_object"} # Structured output
)
return json.loads(result.choices[0].message.content)
### Pairwise Comparison (with position bias mitigation)
```python
def compare_responses(question, response_a, response_b):
"""Compare two responses using LLM judge with position bias mitigation."""
def _judge(q, r1, r2, label1, label2):
prompt = f"""Compare these two responses to the question. Which is better?
Question: {q}
Response {label1}: {r1}
Response {label2}: {r2}
Which response is better and why? Consider accuracy, helpfulness, and clarity.
Answer with JSON:
{{
"winner": "{label1}" or "{label2}" or "tie",
"reasoning": "<explanation>",
"confidence": <1-10>
}}
"""
result = client.chat.completions.create(
model="gpt-4.1",
messages=[{"role": "user", "content": prompt}],
temperature=0,
response_format={"type": "json_object"}
)
return json.loads(result.choices[0].message.content)
# Run twice with swapped order to detect position bias
result_ab = _judge(question, response_a, response_b, "A", "B")
result_ba = _judge(question, response_b, response_a, "B", "A") # swapped
# Normalize result_ba back to A/B labels
winner_ba_normalized = "A" if result_ba["winner"] == "B" else ("B" if result_ba["winner"] == "A" else "tie")
# Check for consistency
consistent = result_ab["winner"] == winner_ba_normalized
if not consistent:
final_winner = "tie" # Disagree = call it a tie
else:
final_winner = result_ab["winner"]
return {
"winner": final_winner,
"consistent": consistent,
"reasoning_ab": result_ab["reasoning"],
"reasoning_ba": result_ba["reasoning"],
}Human Evaluation Frameworks
Annotation Guidelines
class AnnotationTask:
"""Structure for human annotation task."""
def __init__(self, response, question, context=None):
self.response = response
self.question = question
self.context = context
def get_annotation_form(self):
return {
"question": self.question,
"context": self.context,
"response": self.response,
"ratings": {
"accuracy": {
"scale": "1-5",
"description": "Is the response factually correct?"
},
"relevance": {
"scale": "1-5",
"description": "Does it answer the question?"
},
"coherence": {
"scale": "1-5",
"description": "Is it logically consistent?"
}
},
"issues": {
"factual_error": False,
"hallucination": False,
"off_topic": False,
"unsafe_content": False
},
"feedback": ""
}Inter-Rater Agreement
from sklearn.metrics import cohen_kappa_score
def calculate_agreement(rater1_scores, rater2_scores):
"""Calculate inter-rater agreement."""
kappa = cohen_kappa_score(rater1_scores, rater2_scores)
interpretation = {
kappa < 0: "Poor",
kappa < 0.2: "Slight",
kappa < 0.4: "Fair",
kappa < 0.6: "Moderate",
kappa < 0.8: "Substantial",
kappa <= 1.0: "Almost Perfect"
}
return {
"kappa": kappa,
"interpretation": interpretation[True]
}A/B Testing
Statistical Testing Framework
from scipy import stats
import numpy as np
class ABTest:
def __init__(self, variant_a_name="A", variant_b_name="B"):
self.variant_a = {"name": variant_a_name, "scores": []}
self.variant_b = {"name": variant_b_name, "scores": []}
def add_result(self, variant, score):
"""Add evaluation result for a variant."""
if variant == "A":
self.variant_a["scores"].append(score)
else:
self.variant_b["scores"].append(score)
def analyze(self, alpha=0.05):
"""Perform statistical analysis."""
a_scores = self.variant_a["scores"]
b_scores = self.variant_b["scores"]
# T-test
t_stat, p_value = stats.ttest_ind(a_scores, b_scores)
# Effect size (Cohen's d)
pooled_std = np.sqrt((np.std(a_scores)**2 + np.std(b_scores)**2) / 2)
cohens_d = (np.mean(b_scores) - np.mean(a_scores)) / pooled_std
return {
"variant_a_mean": np.mean(a_scores),
"variant_b_mean": np.mean(b_scores),
"difference": np.mean(b_scores) - np.mean(a_scores),
"relative_improvement": (np.mean(b_scores) - np.mean(a_scores)) / np.mean(a_scores),
"p_value": p_value,
"statistically_significant": p_value < alpha,
"cohens_d": cohens_d,
"effect_size": self.interpret_cohens_d(cohens_d),
"winner": "B" if np.mean(b_scores) > np.mean(a_scores) else "A"
}
@staticmethod
def interpret_cohens_d(d):
"""Interpret Cohen's d effect size."""
abs_d = abs(d)
if abs_d < 0.2:
return "negligible"
elif abs_d < 0.5:
return "small"
elif abs_d < 0.8:
return "medium"
else:
return "large"Regression Testing
Regression Detection
class RegressionDetector:
def __init__(self, baseline_results, threshold=0.05):
self.baseline = baseline_results
self.threshold = threshold
def check_for_regression(self, new_results):
"""Detect if new results show regression."""
regressions = []
for metric in self.baseline.keys():
baseline_score = self.baseline[metric]
new_score = new_results.get(metric)
if new_score is None:
continue
# Calculate relative change
relative_change = (new_score - baseline_score) / baseline_score
# Flag if significant decrease
if relative_change < -self.threshold:
regressions.append({
"metric": metric,
"baseline": baseline_score,
"current": new_score,
"change": relative_change
})
return {
"has_regression": len(regressions) > 0,
"regressions": regressions
}Benchmarking
Running Benchmarks
class BenchmarkRunner:
def __init__(self, benchmark_dataset):
self.dataset = benchmark_dataset
def run_benchmark(self, model, metrics):
"""Run model on benchmark and calculate metrics."""
results = {metric.name: [] for metric in metrics}
for example in self.dataset:
# Generate prediction
prediction = model.predict(example["input"])
# Calculate each metric
for metric in metrics:
score = metric.calculate(
prediction=prediction,
reference=example["reference"],
context=example.get("context")
)
results[metric.name].append(score)
# Aggregate results
return {
metric: {
"mean": np.mean(scores),
"std": np.std(scores),
"min": min(scores),
"max": max(scores)
}
for metric, scores in results.items()
}CI/CD Integration: Evals as Code
Run evaluations automatically in your CI/CD pipeline:
# .github/workflows/eval.yml
name: LLM Evaluation
on:
pull_request:
paths: ['prompts/**', 'src/llm/**']
jobs:
evaluate:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Run evaluation suite
env:
OPENAI_API_KEY: ${{ secrets.OPENAI_API_KEY }}
run: |
pip install -r requirements-eval.txt
python scripts/run_evaluations.py --baseline main --compare HEAD
- name: Check for regression
run: |
python scripts/check_regression.py \
--threshold 0.05 \
--fail-on-regression# scripts/run_evaluations.py
import argparse
import json
from pathlib import Path
def run_eval_suite(model_fn, test_cases, metrics):
"""Run complete evaluation suite and return results."""
results = []
for case in test_cases:
prediction = model_fn(case["input"])
scores = {m.name: m.calculate(prediction, case["reference"]) for m in metrics}
results.append({"case": case["id"], "scores": scores})
aggregated = {
metric: sum(r["scores"][metric] for r in results) / len(results)
for metric in results[0]["scores"]
}
return aggregated
def main():
# Load test cases
test_cases = json.loads(Path("evals/test_cases.json").read_text())
# Run evaluation
results = run_eval_suite(your_model, test_cases, your_metrics)
# Save results with git commit hash
import subprocess
commit = subprocess.check_output(["git", "rev-parse", "HEAD"]).decode().strip()
output = {"commit": commit, "metrics": results}
Path(f"eval_results/{commit[:8]}.json").write_text(json.dumps(output, indent=2))
print(json.dumps(results, indent=2))
if __name__ == "__main__":
main()Structured Output Evaluation
For applications that require structured outputs (JSON schemas, function calls):
from pydantic import BaseModel, ValidationError
class ExpectedOutput(BaseModel):
name: str
age: int
email: str
def evaluate_structured_output(model_response: str, expected: dict) -> dict:
"""Evaluate whether model output conforms to schema and matches expected values."""
# 1. Schema compliance
try:
parsed = ExpectedOutput.model_validate_json(model_response)
schema_valid = True
except ValidationError as e:
return {"schema_valid": False, "error": str(e), "field_accuracy": 0}
# 2. Field accuracy
expected_obj = ExpectedOutput(**expected)
fields = ExpectedOutput.model_fields.keys()
correct = sum(1 for f in fields if getattr(parsed, f) == getattr(expected_obj, f))
return {
"schema_valid": True,
"field_accuracy": correct / len(fields),
"fields_correct": correct,
"fields_total": len(fields),
}Best Practices
- Multiple Metrics: Use diverse metrics for comprehensive view; no single metric tells the whole story
- Representative Data: Test on real-world, diverse examples; adversarial examples too
- Baselines: Always compare against baseline performance (previous prompt version, weaker model)
- Statistical Rigor: Use proper statistical tests; bootstrap confidence intervals when n < 100
- Continuous Evaluation: Integrate into CI/CD pipeline; eval on every prompt change
- Human Validation: Periodically validate LLM-as-judge outputs against human raters
- Error Analysis: Cluster failures to find systematic weaknesses, not just count them
- Version Control: Track evaluation datasets and results in git; treat evals as code
- Position Bias Mitigation: Swap A/B order in pairwise comparisons; average results
- Separate Dev/Test Sets: Don't tune prompts on your test set; maintain held-out data
Common Pitfalls
- Single Metric Obsession: Optimizing for one metric at the expense of others
- Small Sample Size: Drawing conclusions from too few examples (need 50+ for statistical power)
- Data Contamination: Testing on training data or data that was used to tune the prompt
- Ignoring Variance: Not accounting for statistical uncertainty; report confidence intervals
- Metric Mismatch: Using BLEU/ROUGE for open-ended tasks (they're correlation-poor for modern LLMs)
- Judge Model Bias: Not checking if your LLM judge has systematic biases
- Benchmark Leakage: Popular benchmarks may be in training data; prefer private evals
- Ignoring Latency/Cost: A metric improvement that triples cost may not be worth it
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
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.

