上下文压缩
ADK 代理运行时,会不断累积上下文——用户消息、工具响应和生成的内容。随着上下文增长,LLM 处理时间会增加,因为每次请求都会发送更多数据。上下文压缩通过使用滑动窗口方法总结较早的事件来解决这一问题。
工作原理
上下文压缩使用滑动窗口,定期总结会话中的较早对话事件。当已完成调用的数量达到配置的间隔时,摘要器会将较早的事件压缩为一个摘要事件。
Invocations 1-3: [event1, event2, event3] → Summarized into "Summary A"
Invocations 4-6: [Summary A, event3, event4, event5, event6] → Summarized into "Summary B"
overlap_size 参数控制从上一个窗口延续到下一个摘要中的事件数量,从而保持连续性。
配置
将压缩功能添加到运行器配置中:
use adk_agent::LlmEventSummarizer;
use adk_runner::{Runner, RunnerConfig, EventsCompactionConfig};
use std::sync::Arc;
// Use any LLM for summarization (a fast, cheap model works well)
let summarizer_llm = Arc::new(my_model);
let summarizer = Arc::new(LlmEventSummarizer::new(summarizer_llm));
let runner = Runner::new(RunnerConfig {
app_name: "my_app".to_string(),
agent: root_agent,
session_service: sessions,
artifact_service: None,
memory_service: None,
plugin_manager: None,
run_config: None,
compaction_config: Some(EventsCompactionConfig {
compaction_interval: 3, // Compact every 3 invocations
overlap_size: 1, // Keep 1 prior invocation for context
summarizer,
}),
})?;
配置参数
| 参数 | 类型 | 描述 |
|---|---|---|
compaction_interval | u32 | 触发压缩的已完成调用次数 |
overlap_size | u32 | 上一个窗口中的事件,包含在下一个摘要中 |
summarizer | Arc<dyn BaseEventsSummarizer> | 摘要策略 |
自定义摘要器
您可以自定义摘要提示词:
let summarizer = LlmEventSummarizer::new(llm)
.with_prompt_template(
"Summarize this conversation focusing on action items \
and decisions:\n\n{conversation_history}"
);
或者实现 BaseEventsSummarizer 以获得完全控制:
use adk_core::{BaseEventsSummarizer, Event, Result};
use async_trait::async_trait;
struct MySummarizer;
#[async_trait]
impl BaseEventsSummarizer for MySummarizer {
async fn summarize_events(&self, events: &[Event]) -> Result<Option<Event>> {
// Custom summarization logic
// Return None to skip compaction for this window
todo!()
}
}
压缩如何影响历史记录
当在包含压缩事件的会话上调用 conversation_history() 时:
- 找到最近的压缩事件
- 使用其摘要替换截至压缩边界之前的所有事件
- 仅单独包含边界之后的事件
这对 agent 是透明的——它们会收到连贯的对话历史,其中包含摘要以及后续的最近事件。
示例时间线
使用 compaction_interval: 3 和 overlap_size: 1:
| 调用 | 事件 | 操作 |
|---|---|---|
| 1 | 用户→代理 | — |
| 2 | 用户→代理 | — |
| 3 | 用户→代理 | 将事件 1-3 压缩为摘要 A |
| 4 | 用户→代理 | — |
| 5 | 用户→代理 | — |
| 6 | 用户→代理 | 将事件 3-6(重叠=1)压缩为摘要 B |
调用 6 次后,代理看到:[Summary B, event 6 overlap events, event 7+]
注意事项
- 压缩失败不会导致致命错误——运行器会记录警告并继续运行
- 压缩会在调用流完成后运行,而不是在调用期间运行
- 压缩事件会持久化到会话服务中,以确保数据持久性
- 使用快速且成本低廉的模型进行摘要(例如
gemini-3.5-flash-lite)