Vapora/crates/vapora-agents/examples/02-learning-profile.rs

114 lines
3.9 KiB
Rust
Raw Normal View History

2026-01-12 03:34:01 +00:00
//! # Learning Profile Example
//!
//! Demonstrates how to build and update learning profiles from execution
//! history.
//!
//! ## What This Example Shows
//! - Creating a `LearningProfile` for an agent
//! - Recording execution data with timestamps
//! - Computing task type expertise from historical data
//! - Understanding recency bias weighting
//! - Confidence scoring based on sample size
//!
//! ## Run
//! ```bash
//! cargo run --example 02-learning-profile -p vapora-agents
//! ```
use chrono::{Duration, Utc};
use vapora_agents::{ExecutionData, LearningProfile, TaskTypeExpertise};
fn main() {
println!("=== Learning Profile Example ===\n");
// Step 1: Create sample execution history
let agent_id = "developer-alice".to_string();
let now = Utc::now();
// Simulate 30 days of execution history
let executions: Vec<ExecutionData> = (0..30)
.map(|i| ExecutionData {
timestamp: now - Duration::days(i),
duration_ms: 200 + (i as u64 * 5),
success: i < 28, // 93% success rate (28/30 successes)
})
.collect();
println!("Agent: {}", agent_id);
println!("Historical executions: {} days", executions.len());
println!("Success rate: {:.1}%\n", (28.0 / 30.0) * 100.0);
// Step 2: Create learning profile
let mut profile = LearningProfile::new(agent_id);
println!("Created learning profile\n");
// Step 3: Compute task type expertise
let coding_expertise = TaskTypeExpertise::from_executions(executions.clone(), "coding");
println!("=== Task Type Expertise: Coding ===");
println!(
"Success rate: {:.2}%",
coding_expertise.success_rate * 100.0
);
println!("Average duration: {}ms", coding_expertise.avg_duration_ms);
println!("Total executions: {}", coding_expertise.total_executions);
println!("Confidence: {:.2}", coding_expertise.confidence);
println!(
"Recent success rate: {:.2}%",
coding_expertise.recent_success_rate * 100.0
);
// Step 4: Demonstrate recency bias
println!("\n=== Recency Bias Impact ===");
println!("Recent 7 days: weighted 3× higher");
println!("Days 8-30: weighted 1× normal");
let recent_success = (6.0 / 7.0) * 100.0; // Last 7 days all successful
let older_success = (22.0 / 23.0) * 100.0; // Days 8-30
println!("Recent success rate (7d): {:.1}%", recent_success);
println!("Older success rate (23d): {:.1}%", older_success);
println!(
"Weighted average: {:.1}%\n",
coding_expertise.success_rate * 100.0
);
// Step 5: Add expertise to profile
profile.set_task_type_expertise("coding".to_string(), coding_expertise.clone());
// Simulate another task type with lower expertise
let test_executions: Vec<ExecutionData> = (0..20)
.map(|i| ExecutionData {
timestamp: now - Duration::days(i),
duration_ms: 150 + (i as u64 * 3),
success: i < 16, // 80% success rate (16/20)
})
.collect();
let testing_expertise = TaskTypeExpertise::from_executions(test_executions, "testing");
profile.set_task_type_expertise("testing".to_string(), testing_expertise.clone());
println!("=== Overall Profile ===");
println!("Agent expertise levels:");
println!(
" coding: {:.1}% (high)",
coding_expertise.success_rate * 100.0
);
println!(
" testing: {:.1}% (medium)",
testing_expertise.success_rate * 100.0
);
// Step 6: Demonstrate confidence scaling
println!("\n=== Confidence Scaling ===");
println!("Confidence increases with sample size:");
let sample_sizes = vec![5, 10, 20, 50, 100];
for size in sample_sizes {
let confidence = ((size as f64 - 1.0) / (size as f64 + 9.0)).min(1.0);
println!(" {} samples → confidence: {:.2}", size, confidence);
}
println!("\n✓ Learning profile created and ready for task assignment");
}