跳转到内容

上下文摘要与裁剪

上下文摘要与裁剪

学习目标

本章聚焦 LibreChat 的上下文管理机制。你将了解:

  • 可配置的摘要触发条件与跨端点模型选择
  • 上下文裁剪的 EMA 校准机制
  • reserveRatio 的 per-agent 覆盖策略
  • 同端点优化的自摘要路径

前置知识

下文假设你已理解上述概念,直接聚焦 LibreChat 的具体实现。


项目实践

摘要配置形状

shapeSummarizationConfig 将用户的摘要配置转换为 SDK 期望的格式:

shapeSummarizationConfig(config, fallbackProvider, fallbackModel, appConfig, agentEndpoint)
→ {
enabled: boolean,
config: {
trigger: { type: 'tokens' | 'messages', value: number },
provider: string,
model: string,
parameters: Record<string, unknown>,
prompt: string | undefined,
updatePrompt: string | undefined,
reserveRatio: number | undefined,
maxSummaryTokens: number | undefined,
},
contextPruningConfig: ContextPruningConfig | undefined,
reserveRatio: number | undefined,
}

跨端点摘要模型选择

摘要可以使用不同于主 Agent 的模型。resolveSummarizationProvider 负责解析自定义端点名:

1. 从 appConfig 中查找自定义端点配置
2. 提取 API Key 和 baseURL(支持环境变量解析)
3. 通过 getOpenAIConfig 生成 LLM 配置(继承 headers、transforms 等)
4. 返回 provider + clientOverrides

同端点优化:当摘要使用的端点与主 Agent 相同时,跳过 clientOverrides,SDK 的自摘要路径会直接复用 agentContext.clientOptions

if normalizeEndpointName(rawProvider) == normalizeEndpointName(agentEndpoint):
return { provider: fallbackProvider, clientOverrides: undefined }

这保留了请求级动态解析的 headers、fetch 选项等状态,这些在 getOpenAIConfig 中无法完全重建。

上下文预算计算

computeEffectiveMaxContextTokens 根据储备比例计算实际可用的上下文预算:

computeEffectiveMaxContextTokens(reserveRatio, baseContextTokens, maxContextTokens):
if reserveRatio == null 或 <= 0 或 >= 1:
return maxContextTokens
ratioComputed = max(1024, round(baseContextTokens * (1 - reserveRatio)))
return min(maxContextTokens, ratioComputed)

三级回退

  1. reserveRatio → 使用 maxContextTokens
  2. reserveRatio → 按比例计算,但不低于 1024 tokens
  3. maxContextTokens → 取两者中的较小值

上下文裁剪的 EMA 校准

calibrationRatio 从上一次运行传递到下一次,种子化 pruner 的指数移动平均(EMA):

createRun({
calibrationRatio: previousRun.calibrationRatio, // 从上一次传递
...
})

这使得裁剪策略能够自适应对话的实际 Token 分布,而不是使用固定的启发式规则。


问题与规避

问题 1:摘要配置使用了无法解析的自定义端点

规避resolveSummarizationProvider 在构建前验证 API Key 和 baseURL 的可用性。如果环境变量未配置,回退到原始提供商,让 SDK 给出清晰的错误信息。

问题 2:摘要模型与主模型使用不同的 reasoning 字段

规避getReasoningKey 函数根据 provider 和 endpoint 选择正确的字段名(reasoning_content vs reasoning),此逻辑同时用于主 Agent 和摘要配置。

问题 3:储备比例设置不当导致上下文浪费

规避DEFAULT_RESERVE_RATIO = 0.05(5%)作为默认值。当引入 summarization 后,从 10% 降低到 5%,因为摘要主动管理溢出,不需要那么多预留空间。


设计取舍

跨端点摘要 vs 同端点自摘要

方案优势代价
跨端点摘要可以用更便宜的模型配置复杂,需要额外的端点解析
同端点复用现有连接和配置摘要成本与主对话相同

LibreChat 同时支持两种模式:默认同端点(简单),用户可配置跨端点(灵活)。


参考来源