上下文压缩管理器
压缩管理器
相关源文件
本章引用的主要源码文件:
crates/jcode-compaction-core/Cargo.tomlcrates/jcode-compaction-core/src/lib.rscrates/jcode-tui-mermaid/src/mermaid_tests/part_01.rscrates/jcode-tui-mermaid/src/mermaid_viewport.rsdocs/SECURITY_DEPENDENCIES.mdscripts/security_preflight.shsrc/agent/compaction.rssrc/agent_tests.rssrc/compaction.rssrc/compaction_tests.rssrc/import_tests.rssrc/lib.rssrc/memory.rssrc/memory_agent.rssrc/memory_tests.rssrc/sidecar.rssrc/tool/memory.rssrc/tool/webfetch.rssrc/tool/websearch.rssrc/tui/app/conversation_state.rssrc/tui/info_widget_memory_render.rssrc/tui/ui_tests/diagrams/part_01.rssrc/tui/ui_tests/diagrams/part_02.rs
CompactionManager(压缩管理器)负责管理对话上下文窗口,确保大语言模型(LLM)代理能在其 Token 限制内持续运行。它实现了一种后台摘要策略,将对话历史压缩为简洁的摘要,使代理能够"遗忘"原始消息历史,同时保留必要的上下文、操作和用户偏好 src/compaction.rs:1-16。
核心机制与阈值
管理器会跟踪 Token 使用量是否超出预算(默认 200,000 Token)src/compaction.rs:99-100。它使用核心 crate 中定义的几个阈值来决定何时以及如何缩减上下文:
| 阈值 | 值 | 操作 |
|---|---|---|
COMPACTION_THRESHOLD | 80% | 触发后台摘要 crates/jcode-compaction-core/src/lib.rs:9。 |
CRITICAL_THRESHOLD | 95% | 触发同步的 hard_compact_with 紧急回退 crates/jcode-compaction-core/src/lib.rs:13。 |
MANUAL_COMPACT_MIN | 10% | 手动触发压缩所需的最低级别 crates/jcode-compaction-core/src/lib.rs:16。 |
管理器维护一个 compacted_count(已压缩计数),表示会话历史中已被成功摘要的前导消息数量,在构建下一个 API 载荷时应跳过这些消息 src/compaction.rs:68-68。
上下文流图
此图展示了在代理运行时循环中,CompactionManager 如何与消息历史及大语言模型(LLM)提供者交互。
来源: src/compaction.rs:65-138,crates/jcode-compaction-core/src/lib.rs:5-16,src/compaction.rs:41-47。
压缩模式
系统支持三种不同的操作模式,这些模式决定了摘要的触发逻辑 src/compaction.rs:11-17。
1. 反应模式(默认)
最简单的模式,当 observed_input_tokens(观察到的输入 Token)或估计的字符数超过 80% 阈值时严格触发压缩 src/compaction.rs:13。
2. 主动模式
使用指数加权移动平均(EWMA)预测未来的 Token 增长 src/compaction.rs:14。
- 预测: 它跟踪一个滚动窗口的 Token 历史(
TOKEN_HISTORY_WINDOW = 20)来估计增长率src/compaction.rs:119。 - 逻辑: 如果未来几轮对话的预测上下文使用量超过阈值,它会提前开始摘要,确保在达到限制之前摘要已准备就绪。
3. 语义模式
使用嵌入向量检测主题切换 src/compaction.rs:15-16。
- 主题切换: 它维护一个每轮对话嵌入向量的滚动窗口(
EMBEDDING_HISTORY_WINDOW = 10)src/compaction.rs:129。 - 逻辑: 基于嵌入向量检测到的主题切换和相关性评分触发压缩。
- 缓存: 使用每个管理器的缓存(
SEMANTIC_EMBED_CACHE_CAPACITY = 256)避免对消息文本进行重复的嵌入向量查找src/compaction.rs:132-135。 - 回退: 如果嵌入向量不可用,则回退到主动模式
src/compaction.rs:16-17。
来源: src/compaction.rs:11-17,src/compaction.rs:116-138,crates/jcode-compaction-core/src/lib.rs:35-45。
紧急操作
当上下文窗口几乎耗尽(>= 95%)时,管理器会执行紧急程序以防止 API 失败。
hard_compact_with
一个同步回退方法,立即从历史记录的前端丢弃消息 crates/jcode-compaction-core/src/lib.rs:88。它确保至少保留 MIN_TURNS_TO_KEEP(2 轮)以提供一定的连续性,即使信息丢失 crates/jcode-compaction-core/src/lib.rs:22。
emergency_truncate_with
一种细粒度的清理方法,针对近期历史中的特定大内容块:
- 工具结果截断: 大的工具输出会被截断为
EMERGENCY_TOOL_RESULT_MAX_CHARS(4000 字符)crates/jcode-compaction-core/src/lib.rs:25。 - 估算: 使用保守的
CHARS_PER_TOKEN(4)比率来估算截断的影响,当实际 Token 计数不可用时crates/jcode-compaction-core/src/lib.rs:28。
来源: crates/jcode-compaction-core/src/lib.rs:21-34,crates/jcode-compaction-core/src/lib.rs:87-89。
原生压缩(OpenAI)
对于 OpenAI 提供者,管理器支持一个涉及 encrypted_content(加密内容)的原生功能。这允许将摘要以提供者特定的格式存储在 Summary 结构体中 crates/jcode-compaction-core/src/lib.rs:61。
当调用 messages_for_api_with 时,如果存在 openai_encrypted_content,它会被作为 OpenAICompaction 块注入到消息流中 crates/jcode-compaction-core/src/lib.rs:160-162。这允许提供者从其内部检查点恢复,而不仅仅是文本摘要。
来源: src/compaction.rs:41-47,crates/jcode-compaction-core/src/lib.rs:59-64,crates/jcode-compaction-core/src/lib.rs:160-162。
实现细节
数据结构
CompactionManager 跟踪以下状态:
active_summary:最新的Summary结构体,包含摘要文本及其覆盖的轮次索引src/compaction.rs:71。active_message_chars:未压缩后缀中字符的滚动估计值,避免每轮重新扫描历史src/compaction.rs:77。pending_task:异步摘要任务的JoinHandlesrc/compaction.rs:84。observed_input_tokens:提供者报告的实际使用量,优先于启发式方法src/compaction.rs:102-104。
摘要提示
系统使用结构化的提示(SUMMARY_PROMPT)来生成摘要,要求包含上下文、我们做了什么、当前状态和用户偏好等部分 crates/jcode-compaction-core/src/lib.rs:47-55。
Token 开销
管理器会考虑 SYSTEM_OVERHEAD_TOKENS(18,000),这保守地估计了系统提示和注册表中 50 多个工具定义的开销 crates/jcode-compaction-core/src/lib.rs:30-33。
来源: src/compaction.rs:65-138,crates/jcode-compaction-core/src/lib.rs:30-33,crates/jcode-compaction-core/src/lib.rs:47-55。
代码实体映射
此图将高级压缩概念映射到代码库中的具体结构体和函数。
来源: src/compaction.rs:41-47,src/compaction.rs:65-138,crates/jcode-compaction-core/src/lib.rs:59-64,crates/jcode-compaction-core/src/lib.rs:81-89。