use rucora::{CompressionConfig, LayeredCompressor};
use tracing::{Level, info};
use tracing_subscriber::FmtSubscriber;
#[tokio::main]
async fn main() -> anyhow::Result<()> {
dotenv::dotenv().ok();
let subscriber = FmtSubscriber::builder()
.with_max_level(Level::INFO)
.with_target(false)
.finish();
tracing::subscriber::set_global_default(subscriber)?;
info!("╔════════════════════════════════════════╗");
info!("║ rucora 分层上下文压缩引擎示例 ║");
info!("╚════════════════════════════════════════╝\n");
info!("═══════════════════════════════════════");
info!("示例 1: 压缩配置说明");
info!("═══════════════════════════════════════\n");
info!("CompressionConfig 配置项:\n");
info!(" strategy: 压缩策略");
info!(" - Aggressive: 激进压缩(适合长对话)");
info!(" - Balanced: 平衡压缩(默认)");
info!(" - Conservative: 保守压缩(适合短对话)\n");
info!(" protect_head_count: 保护头部消息数量");
info!(" - 这些消息永远不会被压缩\n");
info!(" protect_tail_tokens: 保护尾部消息 Token 数");
info!(" - 最近的消息保留这么多 token\n");
info!(" compression_threshold: 触发压缩的使用率阈值");
info!(" - 0.85 = 85% 时触发\n");
info!(" target_usage_ratio: 压缩后的目标使用率");
info!(" - 0.60 = 压缩到 60%\n");
info!(" max_iterations: 最大压缩迭代次数");
info!(" - 防止过度压缩\n");
info!(" summary_cooldown_seconds: 摘要失败冷却期");
info!(" - 防止频繁重试\n");
info!("═══════════════════════════════════════");
info!("示例 2: 使用不同的压缩策略");
info!("═══════════════════════════════════════\n");
let strategies = vec![
("Aggressive (激进)", CompressionConfig::aggressive()),
("Balanced (平衡)", CompressionConfig::default()),
("Conservative (保守)", CompressionConfig::conservative()),
];
for (name, config) in &strategies {
info!("策略: {}", name);
info!(" protect_head_count: {}", config.protect_head_count);
info!(" protect_tail_tokens: {}", config.protect_tail_tokens);
info!(
" compression_threshold: {:.0}%",
config.compression_threshold * 100.0
);
info!(
" target_usage_ratio: {:.0}%",
config.target_usage_ratio * 100.0
);
info!("");
}
info!("═══════════════════════════════════════");
info!("示例 3: 判断是否需要压缩");
info!("═══════════════════════════════════════\n");
let engine = LayeredCompressor::default_engine();
let test_cases = vec![
(10_000, 128_000, "10K/128K (7.8%)"),
(50_000, 128_000, "50K/128K (39.1%)"),
(100_000, 128_000, "100K/128K (78.1%)"),
(110_000, 128_000, "110K/128K (85.9%)"),
(120_000, 128_000, "120K/128K (93.8%)"),
(10_000, 8_192, "10K/8K (122.1%)"),
];
info!("GPT-4o 上下文窗口: 128K tokens");
info!("GPT-4 上下文窗口: 8K tokens\n");
for (tokens, window, desc) in &test_cases {
let should = engine.should_compress(*tokens, *window);
let usage = *tokens as f64 / *window as f64 * 100.0;
info!(" {}: {:.1}% -> 压缩: {}", desc, usage, should);
}
info!("");
info!("═══════════════════════════════════════");
info!("示例 4: 消息分层概念");
info!("═══════════════════════════════════════\n");
info!("压缩引擎会将消息分为三层:\n");
info!("1. 头部 (Head):");
info!(" - 包含系统提示词和首次交互");
info!(" - 默认保护前 3 条消息");
info!(" - 这些消息永远不会被压缩\n");
info!("2. 中间 (Middle):");
info!(" - 对话的中间部分");
info!(" - 这是会被压缩的部分");
info!(" - 使用结构化摘要替换\n");
info!("3. 尾部 (Tail):");
info!(" - 最近的对话内容");
info!(" - 默认保护最近 20K tokens");
info!(" - 保持对话的连续性\n");
info!("分层的好处:");
info!(" - 保护关键信息(系统提示、用户偏好)");
info!(" - 保留最近上下文(避免断裂)");
info!(" - 只压缩中间部分(最大化效率)\n");
info!("═══════════════════════════════════════");
info!("示例 5: 结构化摘要模板");
info!("═══════════════════════════════════════\n");
info!("压缩引擎使用以下结构化摘要模板:\n");
let template_sections = vec![
("Goal", "用户试图完成什么"),
("Constraints & Preferences", "用户偏好、编码风格"),
("Progress", "Done / In Progress / Blocked"),
("Key Decisions", "重要技术决策"),
("Resolved Questions", "已回答的问题"),
("Pending User Asks", "未回答的问题"),
("Relevant Files", "读取/修改/创建的文件"),
("Remaining Work", "剩余工作"),
("Critical Context", "不能丢失的具体值"),
("Tools & Patterns", "使用过的工具及有效用法"),
];
for (section, desc) in &template_sections {
info!(" ## {} - {}", section, desc);
}
info!("");
info!("结构化摘要的优势:");
info!(" 1. 信息密度高,保留关键内容");
info!(" 2. 结构一致,便于模型理解");
info!(" 3. 支持迭代更新,保持信息新鲜");
info!(" 4. 防止信息丢失,特别是决策和问题\n");
info!("═══════════════════════════════════════");
info!("示例 6: 迭代压缩机制");
info!("═══════════════════════════════════════\n");
info!("迭代压缩工作流程:\n");
info!("首次压缩:");
info!(" 1. 修剪旧工具结果");
info!(" 2. 分离头部/中间/尾部");
info!(" 3. 使用结构化模板生成摘要");
info!(" 4. 替换中间消息为摘要\n");
info!("后续压缩:");
info!(" 1. 保留先前摘要");
info!(" 2. 添加新的对话内容");
info!(" 3. 更新摘要以反映新进展");
info!(" 4. 避免信息丢失\n");
info!("冷却期机制:");
info!(" - 默认 600 秒 (10 分钟)");
info!(" - 防止频繁压缩导致信息不稳定");
info!(" - 可配置调整\n");
info!("═══════════════════════════════════════");
info!("示例 7: 工具结果修剪");
info!("═══════════════════════════════════════\n");
info!("不同策略保留的工具结果数量:\n");
let _aggressive_engine = LayeredCompressor::new(CompressionConfig::aggressive());
let _balanced_engine = LayeredCompressor::default_engine();
let _conservative_engine = LayeredCompressor::new(CompressionConfig::conservative());
info!(" Aggressive: 最多保留 2 个工具结果");
info!(" Balanced: 最多保留 4 个工具结果");
info!(" Conservative: 最多保留 6 个工具结果\n");
info!("工具结果修剪的优势:");
info!(" - 工具结果通常占用大量 token");
info!(" - 旧的工具结果对当前任务价值低");
info!(" - 保留最近的结果即可\n");
info!("═══════════════════════════════════════");
info!("示例 8: 实际应用建议");
info!("═══════════════════════════════════════\n");
info!("与 rucora 集成建议:\n");
info!("1. 在 Agent 运行循环中检查上下文:");
info!(" ```rust");
info!(" if compressor.should_compress(tokens, window) {{");
info!(" messages = compressor.compress(&provider, messages, window).await?;");
info!(" }}");
info!(" ```\n");
info!("2. 根据对话长度选择策略:");
info!(" - 短对话 (< 50 轮): Conservative");
info!(" - 中对话 (50-200 轮): Balanced");
info!(" - 长对话 (> 200 轮): Aggressive\n");
info!("3. 监控压缩效果:");
info!(" - 记录压缩前后的 token 数");
info!(" - 监控压缩率");
info!(" - 评估信息保留质量\n");
info!("4. 结合 Usage 追踪:");
info!(" - 使用 output.usage() 获取 token 统计");
info!(" - 根据实际使用量调整压缩阈值\n");
info!("═══════════════════════════════════════");
info!("示例完成!");
info!("═══════════════════════════════════════\n");
info!("📝 分层上下文压缩总结:\n");
info!("1. 核心优势:");
info!(" - 智能分层保护关键信息");
info!(" - 结构化摘要保持信息密度");
info!(" - 迭代更新避免信息丢失\n");
info!("2. 三种策略:");
info!(" - Aggressive: 最大压缩比,适合长对话");
info!(" - Balanced: 平衡压缩比和信息保留");
info!(" - Conservative: 最小压缩,保护更多信息\n");
info!("3. 关键参数:");
info!(" - protect_head_count: 保护头部消息");
info!(" - protect_tail_tokens: 保护尾部 token");
info!(" - compression_threshold: 触发阈值\n");
info!("4. 与 Hermes Agent 的对比:");
info!(" - 相同的分层保护思想");
info!(" - 相同的结构化摘要模板");
info!(" - Rust 实现带来类型安全和性能优势\n");
info!("5. 最佳实践:");
info!(" - 根据对话长度选择策略");
info!(" - 监控压缩效果");
info!(" - 结合 Usage 追踪调整参数");
info!(" - 定期评估信息保留质量\n");
Ok(())
}