Evaluación de Agentes

El crate adk-eval proporciona herramientas completas para probar y validar el comportamiento de los agentes. A diferencia de las pruebas de software tradicionales, la evaluación de agentes debe tener en cuenta la naturaleza probabilística de los LLMs, al mismo tiempo que proporciona señales de calidad significativas.

Resumen

La evaluación de agentes en adk-rust admite múltiples estrategias de evaluación:

  • Evaluación de Trayectoria: Valida que los agentes llamen a las herramientas esperadas en la secuencia correcta
  • Similitud de Respuesta: Compara las respuestas de los agentes utilizando varios algoritmos (Jaccard, Levenshtein, ROUGE)
  • Evaluación Juzgada por LLM: Utiliza otro LLM para evaluar la similitud semántica y la calidad
  • Puntuación Basada en Rúbricas: Evalúa según criterios personalizados con puntuación ponderada

Inicio Rápido

use adk_eval::{Evaluator, EvaluationConfig, EvaluationCriteria};
use std::sync::Arc;

#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
    // Create your agent
    let agent = create_my_agent()?;

    // Configure evaluator with criteria
    let config = EvaluationConfig::with_criteria(
        EvaluationCriteria::exact_tools()
            .with_response_similarity(0.8)
    );

    let evaluator = Evaluator::new(config);

    // Run evaluation against test file
    let report = evaluator
        .evaluate_file(agent, "tests/my_agent.test.json")
        .await?;

    // Check results
    if report.all_passed() {
        println!("All {} tests passed!", report.summary.total);
    } else {
        println!("{}", report.format_summary());
    }

    Ok(())
}

Formato de Archivo de Prueba

Los casos de prueba se definen en archivos JSON con la extensión .test.json:

{
  "eval_set_id": "weather_agent_tests",
  "name": "Weather Agent Tests",
  "description": "Test weather agent functionality",
  "eval_cases": [
    {
      "eval_id": "test_current_weather",
      "conversation": [
        {
          "invocation_id": "inv_001",
          "user_content": {
            "parts": [{"text": "What's the weather in NYC?"}],
            "role": "user"
          },
          "final_response": {
            "parts": [{"text": "The weather in NYC is 65°F and sunny."}],
            "role": "model"
          },
          "intermediate_data": {
            "tool_uses": [
              {
                "name": "get_weather",
                "args": {"location": "NYC"}
              }
            ]
          }
        }
      ]
    }
  ]
}

Criterios de Evaluación

Coincidencia de Trayectoria de Herramientas

Valida que los agents llamen a los Tool esperados en el orden correcto:

let criteria = EvaluationCriteria {
    tool_trajectory_score: Some(1.0),  // Requiere una coincidencia del 100%
    tool_trajectory_config: Some(ToolTrajectoryConfig {
        strict_order: true,   // Los Tools deben ser llamados en el orden exacto
        strict_args: false,   // Permite argumentos extra en las llamadas a Tool
    }),
    ..Default::default()
};

Opciones:

  • strict_order: Requiere coincidencia exacta de la secuencia
  • strict_args: Requiere coincidencia exacta de los argumentos (no se permiten argumentos extra)
  • Coincidencia parcial con umbrales configurables

Similitud de Respuesta

Compara el texto de respuesta usando varios algoritmos:

let criteria = EvaluationCriteria {
    response_similarity: Some(0.8),  // Se requiere un 80% de similitud
    response_match_config: Some(ResponseMatchConfig {
        algorithm: SimilarityAlgorithm::Jaccard,
        ignore_case: true,
        normalize: true,
        ..Default::default()
    }),
    ..Default::default()
};

Algoritmos disponibles:

AlgoritmoDescripción
ExactCoincidencia exacta de cadena
ContainsVerificación de subcadena
LevenshteinDistancia de edición
JaccardSuperposición de palabras (por defecto)
Rouge1Superposición de unigramas
Rouge2Superposición de bigramas
RougeLSubsecuencia común más larga

Coincidencia Semántica Evaluada por LLM

Usa un LLM para evaluar la equivalencia semántica:

use adk_eval::{Evaluator, EvaluationConfig, EvaluationCriteria, LlmJudge};
use adk_model::GeminiModel;

// Crea un Evaluator con el LLM judge
let judge_model = Arc::new(GeminiModel::new(&api_key, "gemini-2.0-flash")?);
let config = EvaluationConfig::with_criteria(
    EvaluationCriteria::semantic_match(0.85)
);
let evaluator = Evaluator::with_llm_judge(config, judge_model);

El LLM judge evalúa:

  • Equivalencia semántica (mismo significado, diferentes palabras)
  • Precisión fáctica
  • Exhaustividad de la respuesta

Evaluación Basada en Rúbricas

Evalúa contra criterios personalizados con puntuación ponderada:

use adk_eval::{Rubric, EvaluationCriteria};

let criteria = EvaluationCriteria::default()
    .with_rubrics(0.7, vec![
        Rubric::new("Precisión", "La respuesta es objetivamente correcta")
            .with_weight(0.5),
        Rubric::new("Utilidad", "La respuesta aborda las necesidades del usuario")
            .with_weight(0.3),
        Rubric::new("Claridad", "La respuesta es clara y bien organizada")
            .with_weight(0.2),
    ]);

Cada rúbrica es puntuado de 0 a 1 por el LLM judge, y luego se combinan usando pesos.

Detección de Seguridad y Alucinaciones

Verifica las respuestas en busca de problemas de seguridad y alucinaciones:

let criteria = EvaluationCriteria {
    safety_score: Some(0.95),        // Requiere una puntuación de seguridad alta
    hallucination_score: Some(0.9),  // Requiere una baja tasa de alucinación
    ..Default::default()
};

Reporte de Resultados

El reporte de evaluación proporciona resultados detallados:

let report = evaluator.evaluate_file(agent, "tests/agent.test.json").await?;

// Estadísticas de resumen
println!("Total: {}", report.summary.total);
println!("Aprobado: {}", report.summary.passed);
println!("Falló: {}", report.summary.failed);
println!("Tasa de Aprobación: {:.1}%", report.summary.pass_rate * 100.0);

// Fallos detallados
for result in report.failures() {
    println!("Falló: {}", result.eval_id);
    for failure in &result.failures {
        println!("  - {}: {} (esperado: {}, actual: {})",
            failure.criterion,
            failure.message,
            failure.expected,
            failure.actual
        );
    }
}

// Exportar a JSON para CI/CD
let json = report.to_json()?;
std::fs::write("eval_results.json", json)?;

Evaluación por lotes

Evaluación paralela

Evalúa múltiples casos de prueba concurrentemente:

let results = evaluator
    .evaluate_cases_parallel(agent, &cases, 4)  // 4 evaluaciones concurrentes
    .await;

Evaluación de directorio

Evalúa todos los archivos de prueba en un directorio:

let reports = evaluator
    .evaluate_directory(agent, "tests/eval_cases")
    .await?;

for (file, report) in reports {
    println!("{}: {} passed, {} failed",
        file,
        report.summary.passed,
        report.summary.failed
    );
}

Integración con cargo test

Usa la evaluación en pruebas estándar de Rust:

#[tokio::test]
async fn test_weather_agent() {
    let agent = create_weather_agent().unwrap();
    let evaluator = Evaluator::new(EvaluationConfig::with_criteria(
        EvaluationCriteria::exact_tools()
    ));

    let report = evaluator
        .evaluate_file(agent, "tests/weather_agent.test.json")
        .await
        .unwrap();

    assert!(report.all_passed(), "{}", report.format_summary());
}

Ejemplos

# Evaluación básica
cargo run --example eval_basic

# Validación de trayectoria
cargo run --example eval_trajectory

# Coincidencia semántica juzgada por LLM
cargo run --example eval_semantic

# Puntuación basada en rúbricas
cargo run --example eval_rubric

# Algoritmos de similitud de respuesta
cargo run --example eval_similarity

# Generación de informes
cargo run --example eval_report

Mejores prácticas

  1. Empieza simple: Comienza con la validación de trayectoria antes de añadir comprobaciones semánticas
  2. Usa casos representativos: Los archivos de prueba deben cubrir casos extremos y escenarios comunes
  3. Calibra los umbrales: Comienza con umbrales permisivos y ajústalos a medida que el Agent mejore
  4. Combina criterios: Usa múltiples criterios para una evaluación completa
  5. Versiona los archivos de prueba: Mantén los archivos de prueba en control de versiones junto con el código del Agent
  6. Integración CI/CD: Ejecuta evaluaciones en CI para detectar regresiones

Anterior: ← A2A Protocol | Siguiente: Access Control →