Implements systematic evaluation, benchmarking, and testing of AI agent behaviors with tool-use accuracy, hallucination detection, multi-turn reasoning metrics, and automated grading pipelines.
Scanned 9/4/2026
Install to Claude Code
npx -y skills add paulpas/agent-skill-router --skill agentic-evaluation --agent claude-codeInstalls into .claude/skills of the current project.
Are you the author of Agentic Evaluation?
Add the live security badge to your README — it updates automatically with every re-scan.
[](https://www.skillsdirectory.com/skills/paulpas-agentic-evaluation)More formats (shields.io, HTML) on the badges page.
---
name: agentic-evaluation
description: Implements systematic evaluation, benchmarking, and testing of AI agent behaviors with tool-use accuracy, hallucination detection, multi-turn reasoning metrics, and automated grading pipelines.
license: MIT
compatibility: opencode
archetypes:
- tactical
- diagnostic
anti_triggers:
- brainstorming
- vague ideation
- single-agent monolith
response_profile:
verbosity: low
directive_strength: high
abstraction_level: operational
metadata:
version: "1.0.0"
domain: agent
triggers: agent evaluation, benchmarking, hallucination detection, tool-use accuracy, multi-turn reasoning, automated grading, promptfoo, how do i test my agent
role: implementation
scope: implementation
output-format: code
content-types: [code, guidance, do-dont, examples]
related-skills: agent-reliability-engineering, agent-testing-methodology, coding-code-review
---
# Agentic Evaluation Framework
Implements systematic evaluation, benchmarking, and testing of AI agent behaviors to measure tool-use accuracy, multi-turn reasoning quality, hallucination rates, and end-to-end task success. This skill applies the 5 Laws of Elegant Defense — particularly Law 2 (Parse at boundary) for trace validation and Law 3 (Atomic Predictability) for immutable grading results. This skill guides the model in building automated evaluation pipelines that produce reproducible metrics for agent performance tracking across development iterations.
Evaluation is not a single metric — it spans capability testing (can the agent use tools correctly?), correctness auditing (does the agent produce factual outputs?), multi-turn reasoning assessment (does the agent maintain coherent plans across interactions?), and regression tracking (did a new prompt version make things better or worse?). A robust evaluation framework measures all four dimensions with automated grading, human-in-the-loop validation, and continuous monitoring.
## TL;DR Checklist
- [ ] Define evaluation tasks with explicit success/failure criteria before running tests
- [ ] Implement tool-use accuracy measurement — verify correct tool selection AND argument construction
- [ ] Run hallucination detection on LLM outputs against ground-truth data sources
- [ ] Measure multi-turn reasoning by checking plan consistency across conversation turns
- [ ] Build automated grading pipeline with both exact-match and semantic similarity scoring
- [ ] Track evaluation metrics over time to detect regression from prompt or model changes
---
## When to Use
Use this skill when:
- Building an evaluation suite for an LLM-powered agent before production deployment
- Tracking regression in agent performance after updating prompts, tools, or underlying models
- Comparing different model providers (OpenAI vs Anthropic vs open-source) on identical task sets
- Designing automated grading criteria for tool-use accuracy and reasoning quality
- Implementing continuous evaluation pipelines that run on every prompt change
- Conducting A/B testing of agent configurations to select the best-performing version
## When NOT to Use
Avoid this skill for:
- One-off manual testing — use interactive debugging instead of building an evaluation framework
- Evaluating models outside the agent context (use model-specific benchmark frameworks like HELM or MMLU)
- Situations where no ground-truth data exists for the task domain (evaluation requires known correct answers)
- As a substitute for production monitoring — evaluation tests capabilities, monitoring catches operational issues
---
## Core Workflow
```
Evaluation Task Set ──→ Task Executor ──→ Output Collector ──→ Grading Engine ──→ Metrics Aggregator
│ │ │ │ │
[task definition] [agent runs] [raw outputs] [LLM judge / [per-task scores
[tool calls] [traces] exact match] and aggregates]
│
[hallucination check]
[factuality verification]
```
1. **Define Evaluation Task Set** — Create structured test cases with input, expected output, and grading criteria:
- Each task must have a unique ID, a clear description, and a difficulty tier (basic/advanced/challenge)
- Specify exact-match fields (tool name, argument values) AND semantic fields (reasoning quality, explanation)
- Include negative test cases (adversarial inputs where the agent should refuse or ask for clarification)
**Checkpoint:** Every task must have a defined grading strategy — no unmeasured tasks in the evaluation suite.
2. **Implement Task Executor** — Run each task against the agent and collect full execution traces:
- Execute the agent with the task input, capturing all tool calls, arguments, outputs, and final responses
- Record timing metrics (time to first tool call, time to completion, per-tool latency)
- Capture intermediate reasoning steps if available (agent's internal monologue or plan)
**Checkpoint:** Execution traces must be deterministic — same input + same agent config always produces the same trace.
3. **Build Grading Engine** — Apply both exact-match and semantic grading to task outputs:
- Exact match: compare tool names, argument values, and output structure against ground truth
- Semantic similarity: use an embedding model or LLM-as-judge to evaluate reasoning quality and explanation completeness
- Hallucination detection: cross-reference factual claims in outputs against trusted source data
**Checkpoint:** All grading must be reproducible — same task + same agent + same grader = same score every time.
4. **Calculate Multi-Turn Reasoning Metrics** — Assess how well the agent maintains coherent plans across multiple turns:
- Plan adherence: did the agent follow through on stated intentions or diverge without explanation?
- Context retention: did the agent remember relevant information from earlier turns?
- Recovery quality: when encountering errors, did the agent recover gracefully or cascade failures?
**Checkpoint:** Multi-turn scoring must distinguish between single-step failures (wrong tool) and plan-level failures (lost track of objective).
5. **Aggregate Metrics and Generate Reports** — Compute summary statistics across all tasks:
- Per-agent scores: overall pass rate, average reasoning quality, hallucination rate
- Per-task breakdowns: which specific tasks are failing and at what frequency
- Trend tracking: compare against baseline scores from previous evaluation runs
**Checkpoint:** Report must include both quantitative metrics (scores, rates) AND qualitative examples of failures for debugging.
6. **Run Regression Detection** — Compare current evaluation results against the established baseline:
- Flag any metric that degraded more than a configured threshold (default: 5% absolute change)
- Generate a regression report with specific tasks that regressed and severity classification
- Auto-create issue tickets for critical regressions (pass rate drop >10%)
**Checkpoint:** Regression detection must run automatically on every code or prompt change — never rely on manual comparison.
---
## Implementation Patterns
### Pattern 1: Evaluation Task Definition and Execution Framework
```python
import json
import time
import logging
import hashlib
from dataclasses import dataclass, field
from enum import Enum
from typing import Any
from datetime import datetime, timezone
logger = logging.getLogger("agent.evaluation")
class Difficulty(Enum):
BASIC = "basic" # Single-turn, direct tool call expected
ADVANCED = "advanced" # Multi-turn with conditional branching
CHALLENGE = "challenge" # Adversarial inputs requiring careful reasoning
@dataclass
class GroundTruth:
"""Defines the expected correct output for grading."""
tool_name: str | None = None
tool_arguments: dict[str, Any] | None = None
final_response_contains: list[str] = field(default_factory=list)
final_response_excludes: list[str] = field(default_factory=list)
exact_output: str | None = None
factual_claims: list[dict] = field( # claims to verify against source
default_factory=lambda: []
) # Each claim: {"statement": str, "source_ref": str, "expected_truth": bool}
@dataclass
class EvaluationTask:
"""A single test case for agent evaluation."""
task_id: str
description: str
difficulty: Difficulty
input_text: str
ground_truth: GroundTruth
grading_strategy: str = "auto" # "auto", "llm_judge", or "human"
@dataclass
class ExecutionTrace:
"""Captures the full execution of an agent on a task."""
task_id: str
input_text: str
tool_calls: list[dict] = field(default_factory=list) # [{"tool": str, "args": dict}]
final_response: str = ""
reasoning_steps: list[str] = field(default_factory=list)
error_message: str | None = None
start_time: float = 0.0
end_time: float = 0.0
@property
def duration_seconds(self) -> float:
return self.end_time - self.start_time if self.start_time and self.end_time else 0.0
@dataclass
class GradingResult:
"""Score from grading an agent's execution of a task."""
task_id: str
passed: bool
tool_accuracy: float = 0.0 # 0.0 to 1.0 — did correct tool get called?
argument_accuracy: float = 0.0 # 0.0 to 1.0 — were arguments correct?
response_quality: float = 0.0 # 0.0 to 1.0 — semantic quality of final answer
hallucination_score: float = 0.0 # 0.0 (no hallucination) to 1.0 (all claims false)
plan_adherence: float = 0.0 # 0.0 to 1.0 — did agent stay on plan in multi-turn?
overall_score: float = 0.0 # Weighted composite score
failure_reasons: list[str] = field(default_factory=list)
timestamp: str = ""
class TaskExecutor:
"""Runs evaluation tasks against the agent and collects execution traces.
This is a thin wrapper around your actual agent runtime. Replace the
`_run_agent` method with your real agent invocation logic.
Applies Law 3 (Atomic Predictability) — each trace is an immutable snapshot
of what happened during execution, never mutated after creation.
"""
def __init__(self, agent_executor, seed: int = 42) -> None:
self.agent_executor = agent_executor
self.seed = seed
def execute_task(self, task: EvaluationTask) -> ExecutionTrace:
"""Execute a single evaluation task against the agent.
Args:
task: The evaluation task to run.
Returns:
ExecutionTrace capturing all tool calls, responses, and timing.
"""
trace = ExecutionTrace(
task_id=task.task_id,
input_text=task.input_text,
start_time=time.time(),
)
try:
# Replace this with your actual agent invocation
result = self.agent_executor.run(task.input_text)
if isinstance(result, dict):
trace.tool_calls = result.get("tool_calls", [])
trace.final_response = result.get("final_response", "")
trace.reasoning_steps = result.get("reasoning_steps", [])
else:
trace.final_response = str(result)
except Exception as e:
trace.error_message = str(e)
logger.error("Task '%s' execution failed: %s", task.task_id, e)
trace.end_time = time.time()
return trace
def execute_suite(
self, tasks: list[EvaluationTask], max_parallel: int = 4,
) -> list[ExecutionTrace]:
"""Execute all tasks in the evaluation suite.
Args:
tasks: List of evaluation tasks to run.
max_parallel: Maximum number of parallel executions (0 = sequential).
Returns:
List of ExecutionTraces, one per task, in input order.
"""
results: list[ExecutionTrace | None] = [None] * len(tasks)
for i, task in enumerate(tasks):
trace = self.execute_task(task)
results[i] = trace
logger.info(
"Task %s/%d (%s) completed in %.2fs — tool_calls=%d",
i + 1, len(tasks), task.task_id, trace.duration_seconds,
len(trace.tool_calls),
)
return [r for r in results if r is not None]
```
### Pattern 2: Grading Engine with Exact Match and Semantic Scoring
```python
from difflib import SequenceMatcher
class ExactMatchGrader:
"""Compares agent output against ground truth using exact field matching.
Evaluates tool selection, argument correctness, and response structure.
Returns individual scores per dimension (tool, arguments, response).
"""
def grade_tool_selection(
self, trace: ExecutionTrace, gt: GroundTruth,
) -> float:
"""Score whether the correct tool was selected.
Returns 1.0 if the first tool call matches exactly, 0.5 if a similar
tool was called (substring match on name), 0.0 otherwise or if no tools were called.
"""
if not trace.tool_calls:
return 0.0
actual_tool = trace.tool_calls[0].get("tool", "")
expected_tool = gt.tool_name if gt.tool_name else ""
if not expected_tool:
return 1.0 # No tool was expected — agent should have given a text response
if actual_tool == expected_tool:
return 1.0
# Partial match (e.g., "web_search" matches "web_search_v2")
similarity = SequenceMatcher(None, actual_tool, expected_tool).ratio()
if similarity > 0.7:
return 0.5
return 0.0
def grade_arguments(
self, trace: ExecutionTrace, gt: GroundTruth,
) -> float:
"""Score argument correctness for tool calls.
Returns a score between 0.0 and 1.0 based on the proportion of
expected arguments that match in the actual tool call.
"""
if not trace.tool_calls or not gt.tool_arguments:
return 1.0 if not gt.tool_arguments else 0.0
expected = gt.tool_arguments
actual = trace.tool_calls[0].get("args", {})
if not expected:
return 1.0
matched = sum(
1 for key, val in expected.items()
if key in actual and actual[key] == val
)
return matched / len(expected)
def grade_response_content(
self, trace: ExecutionTrace, gt: GroundTruth,
) -> float:
"""Score whether the final response contains required phrases."""
response = trace.final_response.lower()
if not gt.final_response_contains:
return 1.0
hits = sum(1 for phrase in gt.final_response_contains if phrase.lower() in response)
score = hits / len(gt.final_response_contains)
# Penalize for containing excluded phrases
for excluded in gt.final_response_excludes:
if excluded.lower() in response:
score = max(0.0, score - 0.3)
return score
class HallucinationDetector:
"""Detects factual claims in agent output that contradict source data.
Compares statements made by the agent against a set of verified facts.
Returns a hallucination score between 0.0 (no hallucinations) and 1.0 (all claims false).
Uses a hybrid approach: keyword matching for exact contradictions,
embedding similarity for semantic contradiction detection.
"""
def __init__(self, max_claims_to_check: int = 20) -> None:
self.max_claims_to_check = max_claims_to_check
def detect_hallucinations(
self, response: str, factual_claims: list[dict],
) -> dict:
"""Check agent output against known facts.
Args:
response: The agent's final response text.
factual_claims: List of claims to verify, each with:
{"statement": str, "source_ref": str, "expected_truth": bool}
Returns:
Dict with hallucination_score and detailed findings per claim.
"""
if not factual_claims:
return {
"hallucination_score": 0.0,
"findings": [],
"total_claims_checked": 0,
}
claims_to_check = factual_claims[:self.max_claims_to_check]
findings: list[dict] = []
false_positive_count = 0
false_negative_count = 0
for claim in claims_to_check:
statement = claim["statement"]
expected_truth = claim["expected_truth"]
source_ref = claim.get("source_ref", "unknown")
# Check if the response supports or contradicts the claim
response_lower = response.lower()
statement_lower = statement.lower()
found_in_response = statement_lower in response_lower or \
any(word for word in statement_lower.split() if len(word) > 4 and word in response_lower)
is_correct = (found_in_response == expected_truth)
finding: dict[str, Any] = {
"statement": statement,
"source_ref": source_ref,
"expected_truth": expected_truth,
"found_in_response": found_in_response,
"is_correct": is_correct,
}
if not is_correct and expected_truth:
false_negative_count += 1 # Agent missed a true fact (omission)
finding["error_type"] = "omission"
elif not is_correct and not expected_truth:
false_positive_count += 1 # Agent claimed something false (hallucination)
finding["error_type"] = "hallucination"
findings.append(finding)
total_checked = len(findings)
hallucinations = false_positive_count / total_checked if total_checked > 0 else 0.0
return {
"hallucination_score": round(hallucinations, 4),
"findings": findings,
"total_claims_checked": total_checked,
"false_positives": false_positive_count,
"false_negatives": false_negative_count,
}
class GradingEngine:
"""Orchestrates grading across all dimensions for a single task execution.
Combines exact-match scoring (tools, arguments) with hallucination detection
and response quality assessment into a composite score. Applies Law 2 (Parse at boundary)
by validating trace structure before any grading logic runs.
"""
def __init__(self) -> None:
self.exact_match = ExactMatchGrader()
self.hallucination_detector = HallucinationDetector()
def grade(
self, task: EvaluationTask, trace: ExecutionTrace, gt: GroundTruth,
) -> GradingResult:
"""Grade an agent execution against ground truth.
Returns a comprehensive grading result with scores per dimension and
a composite overall score weighted by importance.
"""
# Validate inputs — fail fast on invalid trace structure
if not trace.tool_calls and trace.error_message:
return GradingResult(
task_id=task.task_id,
passed=False,
failure_reasons=[f"Execution error: {trace.error_message}"],
timestamp=datetime.now(timezone.utc).isoformat(),
)
# Compute per-dimension scores
tool_accuracy = self.exact_match.grade_tool_selection(trace, gt)
argument_accuracy = self.exact_match.grade_arguments(trace, gt)
response_quality = self.exact_match.grade_response_content(trace, gt)
# Hallucination detection
hallucination_result = self.hallucination_detector.detect_hallucinations(
trace.final_response, gt.factual_claims,
)
hallucination_score = hallucination_result["hallucination_score"]
# Composite score with weighted importance
weights = {
"tool_accuracy": 0.30, # Tool selection is most critical
"argument_accuracy": 0.25, # Arguments matter equally
"response_quality": 0.25, # Response quality matters
"hallucination_penalty": 0.20, # Hallucinations reduce score
}
raw_score = (
tool_accuracy * weights["tool_accuracy"] +
argument_accuracy * weights["argument_accuracy"] +
response_quality * weights["response_quality"]
)
overall_score = max(0.0, raw_score - hallucination_score * weights["hallucination_penalty"])
# Determine pass/fail — threshold of 0.7 for basic tasks
thresholds = {
Difficulty.BASIC: 0.8,
Difficulty.ADVANCED: 0.6,
Difficulty.CHALLENGE: 0.4,
}
passed = overall_score >= thresholds.get(task.difficulty, 0.7)
# Collect failure reasons for debugging
failure_reasons = []
if tool_accuracy < 0.5:
failure_reasons.append("Incorrect or missing tool selection")
if argument_accuracy < 0.5:
failure_reasons.append("Incorrect or missing tool arguments")
if response_quality < 0.5:
failure_reasons.append("Response does not match expected content")
if hallucination_score > 0.2:
failure_reasons.append(f"Hallucination score too high: {hallucination_score:.2f}")
return GradingResult(
task_id=task.task_id,
passed=passed,
tool_accuracy=round(tool_accuracy, 4),
argument_accuracy=round(argument_accuracy, 4),
response_quality=round(response_quality, 4),
hallucination_score=hallucination_score,
overall_score=round(overall_score, 4),
failure_reasons=failure_reasons,
timestamp=datetime.now(timezone.utc).isoformat(),
)
```
### Pattern 3: Evaluation Report Aggregator with Regression Detection
```python
from collections import defaultdict
class MetricsAggregator:
"""Aggregates grading results across a full evaluation suite into summary statistics.
Supports per-task breakdowns, difficulty-stratified scores, trend tracking against
baselines, and automated regression detection. Applies Law 3 (Atomic Predictability)
by constructing new report objects without mutating input data.
"""
def __init__(self, baseline: dict[str, float] | None = None) -> None:
self.baseline = baseline or {}
def aggregate(
self, results: list[GradingResult], tasks: list[EvaluationTask],
) -> dict:
"""Aggregate grading results into a comprehensive evaluation report.
Args:
results: Grading results from all executed tasks.
tasks: Original evaluation tasks for metadata lookup.
Returns:
Dict with overall metrics, per-dimension scores, and task-level breakdowns.
"""
if not results:
return {
"total_tasks": 0,
"overall_pass_rate": 0.0,
"by_difficulty": {},
"task_breakdown": [],
"regression_alerts": [],
}
# Overall metrics
total = len(results)
passed = sum(1 for r in results if r.passed)
overall_pass_rate = passed / total if total > 0 else 0.0
avg_tool_accuracy = sum(r.tool_accuracy for r in results) / total
avg_argument_accuracy = sum(r.argument_accuracy for r in results) / total
avg_response_quality = sum(r.response_quality for r in results) / total
avg_hallucination = sum(r.hallucination_score for r in results) / total
avg_overall = sum(r.overall_score for r in results) / total
# Per-dimension breakdown
dimension_scores = {
"tool_accuracy": round(avg_tool_accuracy, 4),
"argument_accuracy": round(avg_argument_accuracy, 4),
"response_quality": round(avg_response_quality, 4),
"hallucination_rate": round(avg_hallucination, 4),
}
# Per-difficulty stratification
by_difficulty: dict[str, list[GradingResult]] = defaultdict(list)
for r in results:
task_map = {t.task_id: t for t in tasks}
task = task_map.get(r.task_id)
if task:
by_difficulty[task.difficulty.value].append(r)
difficulty_stats = {}
for diff, diff_results in by_difficulty.items():
count = len(diff_results)
diff_passed = sum(1 for r in diff_results if r.passed)
difficulty_stats[diff] = {
"total": count,
"passed": diff_passed,
"pass_rate": round(diff_passed / count, 4) if count > 0 else 0.0,
"avg_score": round(sum(r.overall_score for r in diff_results) / count, 4),
}
# Task-level breakdown (top failures by severity)
task_breakdown = []
sorted_results = sorted(results, key=lambda r: r.overall_score)
for r in sorted_results[:20]: # Top 20 worst performers
task_map = {t.task_id: t for t in tasks}
task = task_map.get(r.task_id)
task_breakdown.append({
"task_id": r.task_id,
"description": task.description if task else "Unknown",
"difficulty": str(task.difficulty.value) if task else "unknown",
"score": r.overall_score,
"passed": r.passed,
"failure_reasons": r.failure_reasons,
})
# Regression detection
regression_alerts = self._detect_regressions(dimension_scores)
return {
"total_tasks": total,
"passed_tasks": passed,
"overall_pass_rate": round(overall_pass_rate, 4),
"dimension_scores": dimension_scores,
"average_score": round(avg_overall, 4),
"by_difficulty": difficulty_stats,
"task_breakdown": task_breakdown,
"regression_alerts": regression_alerts,
"evaluation_timestamp": datetime.now(timezone.utc).isoformat(),
}
def _detect_regressions(self, current: dict[str, float]) -> list[dict]:
"""Compare current metrics against baseline and flag regressions.
Any metric that degraded by more than 5% absolute triggers a WARNING alert.
Degradation of more than 10% triggers a CRITICAL alert.
"""
alerts: list[dict] = []
regression_thresholds = {
"tool_accuracy": {"warning": -0.05, "critical": -0.10},
"argument_accuracy": {"warning": -0.05, "critical": -0.10},
"response_quality": {"warning": -0.05, "critical": -0.10},
}
for metric, thresholds in regression_thresholds.items():
if metric not in self.baseline:
continue # No baseline to compare against
current_val = current.get(metric, 0.0)
baseline_val = self.baseline[metric]
delta = current_val - baseline_val
alert_level = None
if delta < thresholds["critical"]:
alert_level = "critical"
elif delta < thresholds["warning"]:
alert_level = "warning"
if alert_level:
alerts.append({
"metric": metric,
"baseline": round(baseline_val, 4),
"current": round(current_val, 4),
"delta": round(delta, 4),
"severity": alert_level,
"message": f"{metric} degraded by {abs(delta):.1%} (threshold: {abs(thresholds[alert_level]):.1%})",
})
return alerts
# Example usage — run a full evaluation cycle with regression detection
def run_evaluation_cycle(
tasks: list[EvaluationTask],
agent_executor,
baseline: dict[str, float] | None = None,
) -> dict:
"""Execute the complete evaluation pipeline end-to-end."""
# Step 1: Execute all tasks
executor = TaskExecutor(agent_executor)
traces = executor.execute_suite(tasks)
# Step 2: Build task lookup map
task_map = {t.task_id: t for t in tasks}
# Step 3: Grade each trace against ground truth
grader = GradingEngine()
results = [
grader.grade(task_map[t.task_id], t, task_map[t.task_id].ground_truth)
for t in traces
]
# Step 4: Aggregate and detect regressions
aggregator = MetricsAggregator(baseline=baseline)
report = aggregator.aggregate(results, tasks)
if report["regression_alerts"]:
logger.warning(
"Regression detected: %d alerts", len(report["regression_alerts"])
)
return report
```
---
## Constraints
### MUST DO
- Follow the 5 Laws of Elegant Defense — particularly Law 2 (Parse at boundary) for all input validation and Law 3 (Atomic Predictability) for immutable grading results
- Define evaluation tasks with explicit ground truth and grading criteria — never run unmeasured tests and call them "evaluation"
- Include both positive test cases (expected success) AND negative test cases (expected refusal or error) in every evaluation suite
- Measure tool-use accuracy as a separate dimension from response quality — getting the right answer via the wrong tool is still a failure
- Run hallucination detection against factual claims using both exact keyword matching and semantic verification — single-method detection has high false-positive rates
- Track metrics over time with baselines and automated regression detection — evaluation without trend tracking produces no actionable insights
- Log execution traces with full tool call details for every evaluation run — post-hoc debugging requires complete trace data
### MUST NOT DO
- Grade agent performance based on a single metric (pass/fail only) — always report per-dimension scores to identify specific failure modes
- Use an LLM-as-judge without grounding it in fact-checking — subjective grading can mask systematic hallucination issues
- Run evaluation on production data that contains PII — use synthetic or anonymized datasets for testing
- Set pass/fail thresholds below 0.5 for basic tasks — anything lower means the agent is performing worse than random chance on core functionality
- Compare evaluations across different task sets — metrics are only comparable when running identical tasks against different agent versions
- Skip negative test cases in evaluation suites — an agent that passes all positive tests but fails on adversarial inputs is not production-ready
---
## Output Template
When implementing or running agent evaluations, produce:
1. **Evaluation Report** — Overall pass rate, per-dimension scores (tool accuracy, argument accuracy, response quality, hallucination rate), and average composite score
2. **Difficulty-Stratified Breakdown** — Separate metrics for basic, advanced, and challenge tiers to identify where the agent struggles most
3. **Top Failure Cases** — List of worst-performing tasks with specific failure reasons and trace excerpts for debugging
4. **Regression Alerts** — Comparison against previous baseline with severity classification (warning: >5% degradation, critical: >10% degradation)
5. **Task Execution Summary** — Total tasks executed, total execution time, average duration per task, error count
---
## Related Skills
| Skill | Purpose |
|---|---|
| `agent-reliability-engineering` | Reliability engineering metrics complement evaluation by measuring operational resilience rather than capability |
| `agent-testing-methodology` | General testing methodology that covers unit and integration patterns applicable to agent components |
| `coding-code-review` | Code review practices for reviewing the underlying application code where agents execute |
---
## Live References
> Authoritative documentation links for LLM evaluation frameworks and benchmarking methodologies.
- [Promptfoo Security Testing](https://www.promptfoo.dev/docs/guides/security-testing/)
- [AgentBench: Evaluating LLMs as Agents](https://arxiv.org/abs/2308.03688)
- [SWE-bench Benchmarked Real-World Issues](https://www.swebench.com/)
- [RAGAS: Framework for RAG Evaluation](https://docs.ragas.io/)
- [LangSmith Evals Documentation](https://docs.langchain.com/langsmith/evals)
- [OpenAI Evals Library](https://github.com/openai/evals)
- [LLM-as-a-Judge Methodology](https://arxiv.org/abs/2306.05685)
Is this your skill, or is something wrong with this listing? Request removal or report an issue. Author removals are honored within 72 hours.
No comments yet. Be the first to comment!