141 lines
4.8 KiB
Rust
Raw Normal View History

2026-01-12 03:34:01 +00:00
//! # Learning Curves Example
//!
//! Demonstrates how agent learning curves are computed and displayed.
//!
//! ## What This Example Shows
//! - Recording execution data over time
//! - Computing learning curves from historical data
//! - Understanding performance trends
//! - Visualizing improvement over time
//!
//! ## Run
//! ```bash
//! cargo run --example 02-learning-curves -p vapora-knowledge-graph
//! ```
use chrono::{Duration, Utc};
fn main() {
println!("=== Learning Curves Example ===\n");
// Step 1: Simulate 30 days of execution history
let now = Utc::now();
#[derive(Clone)]
struct DailyStats {
date: String,
executions: u32,
successful: u32,
avg_duration_ms: u32,
}
let mut daily_data = vec![];
for day in 0..30 {
let date_obj = now - Duration::days(day);
let date_str = date_obj.format("%Y-%m-%d").to_string();
// Simulate improvement: success rate increases over time
let base_success_rate = 0.70 + (day as f64 / 30.0) * 0.22; // From 70% to 92%
let executions = 10;
let successful = (executions as f64 * base_success_rate) as u32;
let avg_duration = 300 - (day as u32 * 3); // Tasks get faster
daily_data.push(DailyStats {
date: date_str,
executions,
successful,
avg_duration_ms: avg_duration,
});
}
// Reverse to show chronologically
daily_data.reverse();
// Step 2: Display learning curve data
println!("=== Agent: developer-bob (30-day history) ===\n");
println!("Date | Success Rate | Duration | Trend");
println!("-----------|------|");
let mut prev_success = 0.0;
for data in &daily_data {
let success_rate = (data.successful as f64 / data.executions as f64) * 100.0;
let trend = if success_rate > prev_success {
""
} else if success_rate < prev_success {
""
} else {
""
};
let bar_length = (success_rate / 5.0) as usize;
let bar = "".repeat(bar_length) + &"".repeat(20 - bar_length);
println!(
"{} | {} | {:.0}% | {}ms | {}",
data.date, bar, success_rate, data.avg_duration_ms, trend
);
prev_success = success_rate;
}
// Step 3: Compute overall learning curve
println!("\n=== Learning Curve Analysis ===\n");
let total_executions: u32 = daily_data.iter().map(|d| d.executions).sum();
let total_successful: u32 = daily_data.iter().map(|d| d.successful).sum();
let overall_success = (total_successful as f64 / total_executions as f64) * 100.0;
println!("Total executions: {}", total_executions);
println!("Total successful: {}", total_successful);
println!("Overall success rate: {:.1}%\n", overall_success);
// Compute 7-day and 14-day windows
let recent_7 = &daily_data[daily_data.len() - 7..];
let recent_14 = &daily_data[daily_data.len() - 14..];
let recent_7_success: f64 = recent_7.iter().map(|d| d.successful as f64).sum::<f64>()
/ recent_7.iter().map(|d| d.executions as f64).sum::<f64>();
let recent_14_success: f64 = recent_14.iter().map(|d| d.successful as f64).sum::<f64>()
/ recent_14.iter().map(|d| d.executions as f64).sum::<f64>();
println!("Last 7 days success rate: {:.1}%", recent_7_success * 100.0);
println!(
"Last 14 days success rate: {:.1}%",
recent_14_success * 100.0
);
// Step 4: Demonstrate recency bias
println!("\n=== Recency Bias ===");
println!("Recent days weighted 3× higher than older days");
println!("Last 7 days: 3.0x weight");
println!("Days 8-30: 1.0x weight\n");
let weighted_recent = recent_7_success * 3.0;
let weighted_older: f64 = daily_data[0..23]
.iter()
.map(|d| d.successful as f64 / d.executions as f64)
2026-01-12 03:34:01 +00:00
.sum::<f64>()
/ 23.0;
let weighted_older = weighted_older * 1.0;
let final_score = (weighted_recent + weighted_older) / (3.0 + 1.0);
println!("Weighted score: {:.1}%", final_score * 100.0);
// Step 5: Recommendations
println!("\n=== Agent Performance Trend ===");
let improvement =
recent_7_success - (daily_data[0].successful as f64 / daily_data[0].executions as f64);
if improvement > 0.0 {
println!("✓ IMPROVING (+{:.1}%)", improvement * 100.0);
println!(" → Agent is learning from experience");
println!(" → Ready for more complex tasks");
} else if improvement < 0.0 {
println!("✗ DECLINING ({:.1}%)", improvement * 100.0);
println!(" → Check for blocking issues");
println!(" → Consider additional training");
} else {
println!("→ STABLE");
println!(" → Consistent performance");
}
}