跳转到内容

优化上下文窗口

当你需要控制运行时如何管理会话历史,以避免超过模型上下文上限时,使用本页。

  • 已添加 awaken
  • 已有一个 AgentSpec

每个 agent 都可以配置 ContextWindowPolicy

use awaken::ContextWindowPolicy;
let policy = ContextWindowPolicy {
max_context_tokens: 200_000,
max_output_tokens: 16_384,
min_recent_messages: 10,
enable_prompt_cache: true,
autocompact_threshold: Some(100_000),
compaction_mode: ContextCompactionMode::KeepRecentRawSuffix,
compaction_raw_suffix_messages: 2,
};
字段类型默认值说明
max_context_tokensusize200_000模型上下文总窗口(token 数)
max_output_tokensusize16_384为模型输出预留的 token
min_recent_messagesusize10始终保留的最近消息数,即使超出预算
enable_prompt_cachebooltrue是否启用 prompt cache
autocompact_thresholdOption<usize>None达到该 token 数时触发自动压缩,None 表示禁用
compaction_modeContextCompactionModeKeepRecentRawSuffix自动压缩策略
compaction_raw_suffix_messagesusize2后缀压缩模式下保留的原始消息数

当消息总量超过预算时,运行时会自动丢弃最旧消息。预算大致为:

available = max_context_tokens - max_output_tokens - tool_schema_tokens
  • 所有 system messages
  • 至少 min_recent_messages 条最近消息
  • 成对的 tool call / tool result
  • 不会留下悬挂的 tool calls

在真正截断前,过大的 tool result 会先被压缩成 preview,以减少 token 占用。system / user / assistant 普通消息不会做这种压缩。

压缩不会简单丢消息,而是把更早的历史总结成一条摘要消息。

let policy = ContextWindowPolicy {
autocompact_threshold: Some(100_000),
compaction_mode: ContextCompactionMode::KeepRecentRawSuffix,
compaction_raw_suffix_messages: 4,
..Default::default()
};
  • KeepRecentRawSuffix:保留最近 N 条原始消息,其余压缩
  • CompactToSafeFrontier:压缩到安全边界为止

安全边界的含义是:不会把某条 tool call 和它对应的结果拆开。

压缩子系统通过 CompactionConfig 配置:

use awaken::CompactionConfig;
let config = CompactionConfig {
execution_mode: CompactionExecutionMode::Background,
summarizer_system_prompt: "You are a conversation summarizer. \
Preserve all key facts, decisions, tool results, and action items. \
Be concise but complete.".into(),
summarizer_user_prompt: "Update the cumulative conversation summary.\n\n\
<existing-summary>\n{previous_summary}\n</existing-summary>\n\n\
<new-conversation>\n{messages}\n</new-conversation>".into(),
summary_max_tokens: Some(1024),
summary_model: Some("claude-3-haiku".into()),
min_savings_ratio: 0.3,
raw_retention: CompactionRawRetention::PreserveDurable,
};
字段类型默认值说明
modeCompactionExecutionModebackgroundbackground 异步执行摘要;off 即使设置阈值也不自动压缩
summarizer_system_promptString内置摘要 prompt摘要 LLM 的 system prompt
summarizer_user_promptString累积摘要 prompt摘要用户 prompt 模板;{messages} 会被替换为对话记录,{previous_summary} 会在已有摘要时替换为上一次累积摘要
summary_max_tokensOption<u32>None摘要响应的最大 token 数
summary_modelOption<String>None同一已解析 provider/executor 上的上游模型覆盖。若该值匹配 registry model id,则必须与 agent 模型属于同一 provider,并会在解析时规范化为该模型的 upstream name
min_savings_ratiof640.3接受一次压缩所需的最低 token 节省比例(0.0-1.0)
raw_retentionCompactionRawRetentionpreserve_durable压缩只改写运行时 prompt 窗口,原始用户消息仍保留在线程/运行历史中

内置 DefaultSummarizer 会读取 CompactionConfig,并支持“在已有摘要上继续增量总结”。初次压缩和增量压缩都会使用同一个 summarizer_user_prompt 模板;如果希望 prompt 带上已有累积摘要,请在模板中包含 {previous_summary}

压缩不会阻塞推理 phase。条件满足时,maybe_spawn_compaction 会先确定边 界、把 CompactionInFlight 标记写进 CompactionStateKey,再通过 agent 的 BackgroundTaskManager 把摘要 LLM 调用 spawn 到后台。完成事件经由 owner inbox 返回,由 try_consume_compaction_event 消费;如果边界依然存在, apply_summary 会把摘要 swap 到消息日志里。

实践上需要知道两件事:

  • 同一 agent 上的压缩是单飞(single-flight)的。CompactionState::is_compacting 为真时,下一轮推理不会再规划新的压缩,直接以未压缩的历史继续;swap 完成后 下一轮才会基于新的摘要前缀继续。
  • config-driven 本地运行在设置了 autocompact_thresholdmodebackground 时,会自动挂接内置 summarizer 和每次运行的 BackgroundTaskManager。直接构造 ResolvedAgent 的自定义 runtime 需要自行提供 两者;缺少任意一个,maybe_spawn_compaction 会 no-op,runtime 退回到 truncation。
  • 最新用户消息始终以原文保留在 prompt 窗口。更早的用户消息可以进入摘要,但 durable thread/run history 会保留原文。
  • KeepRecentRawSuffix 保留尾部 compaction_raw_suffix_messages 条原始消息。 CompactToSafeFrontier 会滚动到最新安全边界,并遵守 min_recent_messages。 两种模式都不会切断 tool call/result 对。

压缩结果会被保存成带 <conversation-summary> 标签的内部 system message。重新加载时,历史中较早的已摘要部分不会再被重新放回上下文窗口。

如果 LLM 因 MaxTokens 截断,而且已经产生部分文本或生成到一半的 tool call 参数不完整,运行时可以自动注入 continuation prompt 并重试,直到达到最大重试次数。

  • crates/awaken-runtime-contract/src/contract/inference.rs
  • crates/awaken-runtime/src/context/transform/mod.rs
  • crates/awaken-runtime/src/context/transform/compaction.rs
  • crates/awaken-runtime/src/context/compaction.rs
  • crates/awaken-runtime/src/context/summarizer.rs
  • crates/awaken-runtime/src/context/plugin.rs
  • crates/awaken-runtime/src/context/truncation.rs