Agentenbewertung
Das adk-eval-Crate bietet umfassende Tools zum Testen und Validieren des Agentenverhaltens. Im Gegensatz zu traditionellem Softwaretesting muss die Agentenbewertung die probabilistische Natur von LLMs berücksichtigen und dennoch aussagekräftige Qualitätssignale liefern.
Übersicht
Die Agentenbewertung in ADK-Rust unterstützt mehrere Bewertungsstrategien:
- Trajectory Evaluation: Validieren, dass Agenten erwartete Tools in der richtigen Reihenfolge aufrufen
- Response Similarity: Vergleichen von Agentenantworten unter Verwendung verschiedener Algorithmen (Jaccard, Levenshtein, ROUGE)
- LLM-Judged Evaluation: Verwenden eines anderen LLM zur Bewertung der semantischen Ähnlichkeit und Qualität
- Rubric-Based Scoring: Bewerten nach benutzerdefinierten Kriterien mit gewichteter Bewertung
Schnellstart
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(())
}
Testdateiformat
Testfälle werden in JSON-Dateien mit der Erweiterung .test.json definiert:
{
"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"}
}
]
}
}
]
}
]
}
Bewertungskriterien
Tool-Trajektorien-Matching
Überprüft, ob Agents die erwarteten Tools in der richtigen Reihenfolge aufrufen:
let criteria = EvaluationCriteria {
tool_trajectory_score: Some(1.0), // 100% Übereinstimmung erforderlich
tool_trajectory_config: Some(ToolTrajectoryConfig {
strict_order: true, // Tools müssen in exakter Reihenfolge aufgerufen werden
strict_args: false, // Zusätzliche Argumente in Tool-Aufrufen zulassen
}),
..Default::default()
};
Optionen:
strict_order: Erfordert exaktes Sequenz-Matchingstrict_args: Erfordert exaktes Argument-Matching (keine zusätzlichen Argumente erlaubt)- Partielles Matching mit konfigurierbaren Schwellenwerten
Antwort-Ähnlichkeit
Vergleicht den Antworttext mithilfe verschiedener Algorithmen:
let criteria = EvaluationCriteria {
response_similarity: Some(0.8), // 80% Ähnlichkeit erforderlich
response_match_config: Some(ResponseMatchConfig {
algorithm: SimilarityAlgorithm::Jaccard,
ignore_case: true,
normalize: true,
..Default::default()
}),
..Default::default()
};
Verfügbare Algorithmen:
| Algorithm | Beschreibung |
|---|---|
Exact | Exakte Zeichenkettenübereinstimmung |
Contains | Teilzeichenkettenprüfung |
Levenshtein | Editierdistanz |
Jaccard | Wortüberlappung (Standard) |
Rouge1 | Unigramm-Überlappung |
Rouge2 | Bigramm-Überlappung |
RougeL | Längste gemeinsame Teilsequenz |
LLM-bewertetes semantisches Matching
Verwendet ein LLM, um die semantische Äquivalenz zu bewerten:
use adk_eval::{Evaluator, EvaluationConfig, EvaluationCriteria, LlmJudge};
use adk_model::GeminiModel;
// Evaluator mit LLM-Richter erstellen
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);
Der LLM-Richter bewertet:
- Semantische Äquivalenz (gleiche Bedeutung, andere Worte)
- Faktenbasierte Genauigkeit
- Vollständigkeit der Antwort
Rubrik-basierte Bewertung
Bewertet anhand benutzerdefinierter Kriterien mit gewichteter Punktvergabe:
use adk_eval::{Rubric, EvaluationCriteria};
let criteria = EvaluationCriteria::default()
.with_rubrics(0.7, vec![
Rubric::new("Accuracy", "Antwort ist sachlich korrekt")
.with_weight(0.5),
Rubric::new("Helpfulness", "Antwort adressiert die Bedürfnisse des Benutzers")
.with_weight(0.3),
Rubric::new("Clarity", "Antwort ist klar und gut organisiert")
.with_weight(0.2),
]);
Jede Rubrik wird vom LLM-Richter mit 0-1 Punkten bewertet und dann unter Verwendung von Gewichtungen kombiniert.
Sicherheits- und Halluzinationserkennung
Überprüft Antworten auf Sicherheitsprobleme und Halluzinationen:
let criteria = EvaluationCriteria {
safety_score: Some(0.95), // Hohen Sicherheitswert erforderlich
hallucination_score: Some(0.9), // Niedrige Halluzinationsrate erforderlich
..Default::default()
};
Ergebnisberichterstattung
Der Bewertungsbericht liefert detaillierte Ergebnisse:
let report = evaluator.evaluate_file(agent, "tests/agent.test.json").await?;
// Zusammenfassende Statistiken
println!("Total: {}", report.summary.total);
println!("Passed: {}", report.summary.passed);
println!("Failed: {}", report.summary.failed);
println!("Pass Rate: {:.1}%", report.summary.pass_rate * 100.0);
// Detaillierte Fehler
for result in report.failures() {
println!("Failed: {}", result.eval_id);
for failure in &result.failures {
println!(" - {}: {} (expected: {}, actual: {})",
failure.criterion,
failure.message,
failure.expected,
failure.actual
);
}
}
// Export nach JSON für CI/CD
let json = report.to_json()?;
std::fs::write("eval_results.json", json)?;
Batch-Evaluierung
Parallele Evaluierung
Evaluieren Sie mehrere Testfälle gleichzeitig:
let results = evaluator
.evaluate_cases_parallel(agent, &cases, 4) // 4 concurrent evaluations
.await;
Verzeichnis-Evaluierung
Evaluieren Sie alle Testdateien in einem Verzeichnis:
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
);
}
Integration mit cargo test
Verwenden Sie die Evaluierung in Standard-Rust-Tests:
#[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());
}
Beispiele
# Basic evaluation
cargo run --example eval_basic
# Trajectory validation
cargo run --example eval_trajectory
# LLM-judged semantic matching
cargo run --example eval_semantic
# Rubric-based scoring
cargo run --example eval_rubric
# Response similarity algorithms
cargo run --example eval_similarity
# Report generation
cargo run --example eval_report
Best Practices
- Einfach beginnen: Beginnen Sie mit der Trajektorienvalidierung, bevor Sie semantische Prüfungen hinzufügen
- Repräsentative Fälle verwenden: Testdateien sollten Grenzfälle und gängige Szenarien abdecken
- Schwellenwerte kalibrieren: Beginnen Sie mit nachsichtigen Schwellenwerten und ziehen Sie diese an, wenn der Agent sich verbessert
- Kriterien kombinieren: Verwenden Sie mehrere Kriterien für eine umfassende Evaluierung
- Testdateien versionieren: Halten Sie Testdateien zusammen mit dem Agent-Code in der Versionskontrolle
- CI/CD-Integration: Führen Sie Evaluierungen in CI aus, um Regressionen abzufangen
Zurück: ← A2A Protocol | Weiter: Access Control →