Best Metrics for Evaluating AI Agent Performance: A Complete Technical Guide

The best metrics for evaluating AI agent performance combine task-level outcome verification, process-level compliance checking, and quality-level rubric scoring, as implemented in the bojieli/ai-agent-book repository.

Evaluating autonomous AI agents requires more than simple accuracy scores. The bojieli/ai-agent-book repository demonstrates a comprehensive framework that captures whether agents achieve goals, follow policies, and maintain high interaction quality. This guide examines the specific implementation details and source code patterns used to measure these critical performance dimensions.

The Three-Layer Evaluation Architecture

The repository structures evaluation into three complementary layers that together provide deterministic, reproducible assessment while allowing for LLM-based quality judgment.

Result verification checks environmental outcomes, process verification audits behavioral compliance, and quality judgment evaluates linguistic excellence. Each layer emits standardized DimensionResult objects defined in chapter3/user-memory-evaluation/models.py, enabling seamless aggregation across test suites.

Task-Level Outcome Metrics

The ResultVerifier class in chapter8/trajectory-verifier/verifier.py (lines 51-75) implements the most fundamental metric: did the agent reach the intended final state?

This verifier compares the recorded final_state against an expected_outcome and returns a DimensionResult containing a PASS/FAIL verdict. It focuses exclusively on environmental correctness regardless of the trajectory taken, making it ideal for goal-oriented tasks where only the destination matters.

from chapter8.trajectory_verifier.verifier import ResultVerifier

trajectory = {
    "expected_outcome": {"file_saved": True},
    "final_state": {"file_saved": True},
}

result = ResultVerifier().evaluate(trajectory)
print(f"Task outcome: {result.verdict}")

Process-Level Compliance Metrics

The ProcessVerifier class (lines 78-161 in chapter8/trajectory-verifier/verifier.py) inspects how the agent behaved through four specialized dimensions:

  • _policy: Verifies adherence to organizational rules and safety constraints
  • _privacy: Checks for proper handling of sensitive values like SSNs
  • _grounding: Validates factual claims against source citations
  • _promise_action: Ensures commitments made to users match subsequent tool executions

Each helper method inspects the trajectory's process_facts, claims, promises, and sensitive_values to emit independent DimensionResult objects. This granular approach identifies specific failure modes—such as privacy leaks or hallucinated facts—separate from task completion status.

from chapter8.trajectory_verifier.verifier import ProcessVerifier

trajectory = {
    "process_facts": {"policy_violations": [], "checked_rules": ["no-external-call"]},
    "claims": [{"text": "The sky is blue", "supported_by": ["Wikipedia"]}],
    "promises": [{"required_tool": "search", "text": "I will search", "turn": 3}],
    "sensitive_values": [{"label": "SSN", "value": "123-45-6789"}],
}

process_result = ProcessVerifier().evaluate(trajectory)

Quality-Level LLM-Rubric Metrics

Human-like interaction quality is measured through HeuristicQualityJudge (lines 163-200 in chapter8/trajectory-verifier/verifier.py), which serves as a deterministic stand-in for LLM-based evaluation.

This judge reads quality_facts containing expression issues and flexibility confidence scores, then returns PASS/FAIL verdicts for expression_quality and compliant_flexibility. While the current implementation uses heuristic rules, the interface supports swapping in actual LLM judges via the QualityJudge protocol without changing downstream reporting.

Recall-Based Information Retrieval Metrics

For knowledge-retrieval tasks, KeywordRecallEvaluator in chapter3/user-memory-evaluation/metrics.py (lines 66-124) measures information fidelity.

This offline metric loads gold facts from JSON files and checks for normalized substring matches within the agent's response and optional memory dump. It returns an EvaluationResult containing a continuous reward score between 0 and 1, with a PASS flag triggered at the 0.8 threshold.

from chapter3.user_memory_evaluation.metrics import KeywordRecallEvaluator, load_gold_facts
from chapter3.user_memory_evaluation.models import TestCase

gold = load_gold_facts("tests/gold_facts.json")
evaluator = KeywordRecallEvaluator(gold)

test_case = TestCase(
    test_id="TC001",
    category="layer2",
    title="Bank account retrieval",
    evaluation_criteria="Recall the 12-digit number.",
    # ... other fields

)

result = evaluator.evaluate(test_case, agent_response="Your account number is 1234-5678-9012.")
print(result.to_summary())  # Test TC001: PASSED (Reward: 1.00)

Reward-Based Reinforcement Learning Metrics

The repository also supports RL-style evaluation through agent-specific evaluate() methods. In chapter1/learning-from-experience/rl_agent.py (lines 236-250), the RLAgent.evaluate(num_episodes=200) function returns a dictionary containing:

  • average_reward: Numeric accumulation across episodes
  • success_rate: Binary success ratio
  • Per-episode logs: Optional detailed trajectory records

This approach suits agents learning from environmental interaction rather than static test cases.

from chapter1.learning_from_experience.rl_agent import RLAgent

agent = RLAgent(env=my_env, policy=my_policy)
metrics = agent.evaluate(num_episodes=200, verbose=True)

print(f"Average reward: {metrics['average_reward']}")
print(f"Success rate: {metrics['success_rate']}")

Aggregating Multi-Dimensional Results

All metrics share common Pydantic models defined in chapter3/user-memory-evaluation/models.py (lines 74-81). The DimensionResult and EvaluationResult classes standardize outputs across deterministic verifiers and stochastic judges, enabling weighted aggregation or learned model training.

To evaluate a complete trajectory:

  1. Run ResultVerifier for environmental correctness
  2. Run ProcessVerifier for policy compliance
  3. Run HeuristicQualityJudge for interaction quality
  4. Combine results using standard set operations on DimensionResult lists

Summary

  • Task completion is verified via ResultVerifier.evaluate() in chapter8/trajectory-verifier/verifier.py, comparing final states against expected outcomes.
  • Behavioral compliance is audited through ProcessVerifier, which checks policy adherence, privacy protection, factual grounding, and promise fulfillment.
  • Interaction quality is scored by HeuristicQualityJudge using rubric-based assessment of expression and flexibility.
  • Knowledge recall is measured by KeywordRecallEvaluator in chapter3/user-memory-evaluation/metrics.py using gold-standard fact matching.
  • RL performance is tracked through agent.evaluate() methods returning average rewards and success rates.
  • All metrics emit standardized DimensionResult or EvaluationResult objects for consistent reporting and aggregation.

Frequently Asked Questions

How do I choose between outcome-based and process-based metrics?

Use outcome-based metrics (ResultVerifier) when the goal state is clearly defined and the path is irrelevant. Use process-based metrics (ProcessVerifier) when safety, compliance, or user trust depends on how the agent behaves. Most production systems require both: outcome metrics verify business value, while process metrics prevent harmful side effects.

Can I replace the heuristic quality judge with an actual LLM?

Yes. The QualityJudge protocol in chapter8/trajectory-verifier/verifier.py abstracts the evaluation interface. You can implement a new class that calls GPT-4, Claude, or another judge while maintaining the same evaluate(trajectory) -> List[DimensionResult] signature. The demo file shows how to swap implementations without changing the aggregation logic.

What threshold should I use for the keyword recall metric?

The default threshold is 0.8 (80% of gold facts recalled), as implemented in KeywordRecallEvaluator. However, chapter3/user-memory-evaluation/main.py demonstrates batch evaluation across multiple test cases, allowing you to tune thresholds based on your specific domain's precision requirements. Lower thresholds suit fuzzy matching scenarios; higher thresholds suit strict compliance domains.

How do these metrics handle stochastic agent behavior?

The RL evaluation methods explicitly account for stochasticity by averaging across multiple episodes. The RLAgent.evaluate(num_episodes=200) method runs the agent repeatedly and reports both mean rewards and variance. For deterministic verifiers like ResultVerifier and ProcessVerifier, stochasticity is handled at the test harness level by running multiple trajectories and aggregating the resulting DimensionResult collections.

Have a question about this repo?

These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:

Share the following with your agent to get started:
curl -s "https://instagit.com/install.md"

Works with
Claude Codex Cursor VS Code OpenClaw Any MCP Client

Maintain an open-source project? Get it listed too →