Some checks are pending
Documentation Lint & Validation / Markdown Linting (push) Waiting to run
Documentation Lint & Validation / Validate mdBook Configuration (push) Waiting to run
Documentation Lint & Validation / Content & Structure Validation (push) Waiting to run
Documentation Lint & Validation / Lint & Validation Summary (push) Blocked by required conditions
mdBook Build & Deploy / Build mdBook (push) Waiting to run
mdBook Build & Deploy / Documentation Quality Check (push) Blocked by required conditions
mdBook Build & Deploy / Deploy to GitHub Pages (push) Blocked by required conditions
mdBook Build & Deploy / Notification (push) Blocked by required conditions
Rust CI / Security Audit (push) Waiting to run
Rust CI / Check + Test + Lint (nightly) (push) Waiting to run
Rust CI / Check + Test + Lint (stable) (push) Waiting to run
141 lines
4.8 KiB
Rust
141 lines
4.8 KiB
Rust
//! # 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)
|
||
.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");
|
||
}
|
||
}
|