上下文摘要与裁剪
上下文摘要与裁剪
学习目标
本章聚焦 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)三级回退:
- 无
reserveRatio→ 使用maxContextTokens - 有
reserveRatio→ 按比例计算,但不低于 1024 tokens - 有
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 同时支持两种模式:默认同端点(简单),用户可配置跨端点(灵活)。