Skip to content

上下文压缩系统 ​

本文引用的源码文件

本文引用的文件

更新摘要 ​

变更内容

  • 新增详细的错误处理机制,区分超时错误、空摘要、HTTP失败和解析异常
  • 实现 compactErrorDetail 函数提供可操作的反馈信息
  • 增强 toast 通知系统,显示具体错误原因而非通用提示
  • 改进 SSE 流式处理的空闲超时检测
  • 完善单元测试覆盖各种错误场景

目录 ​

  1. 引言
  2. 项目结构
  3. 核心组件
  4. 架构总览
  5. 详细组件分析
  6. 依赖关系分析
  7. 性能与优化
  8. 质量评估与调优
  9. 故障排查指南
  10. 结论

引言 ​

本文件面向"上下文压缩系统"的完整技术文档,覆盖自动触发条件、压缩策略算法、质量评估、用户控制、压缩后重建、性能优化与效果调优。该系统在扩展端(Manifest V3)与本地 Agent 端之间协作:扩展端负责 UI 交互、阈值决策、素材组装与注入;Agent 端提供长期记忆存储等能力。

更新 新增了详细的错误处理机制,能够区分不同类型的压缩失败并提供具体的用户反馈。

项目结构 ​

上下文压缩相关代码分布在以下模块:

  • 侧边栏交互与自动触发:src/side_panel/context-indicator.js、src/side_panel/auto-compaction.js
  • 背景进程摘要生成与沉淀:src/background/context-compactor.js、src/background/compaction-memory.js
  • 共享提示词与上下文预算:src/shared/compaction-prompt.js、src/shared/context-usage.js、src/shared/token-counter.js
  • ReAct 循环中的增量批量压缩:src/background/context-summarizer.js
  • 配置与默认值:src/background/constants.js、src/background/config.js
graph TB
subgraph "侧边栏"
CI["context-indicator.js<br/>手动压缩/撤销/预览"]
AC["auto-compaction.js<br/>半自动触发决策"]
end
subgraph "背景进程"
CC["context-compactor.js<br/>结构化摘要生成"]
CM["compaction-memory.js<br/>摘要沉淀到长期记忆"]
CS["context-summarizer.js<br/>增量批量压缩"]
end
subgraph "共享层"
CP["compaction-prompt.js<br/>提示词模板与限量"]
CU["context-usage.js<br/>发送历史选择/注入"]
TC["token-counter.js<br/>Token估算/窗口/预算"]
end
subgraph "配置"
Cst["constants.js<br/>默认对话配置"]
Cfg["config.js<br/>读取 chatConfig"]
end
CI --> AC
CI --> CC
CC --> CM
CS --> CC
CI --> CU
AC --> CU
CU --> TC
CC --> CP
CM --> Cfg
Cst --> Cfg

图表来源

章节来源

核心组件 ​

  • 手动压缩入口与状态管理:context-indicator.js
  • 半自动触发策略:auto-compaction.js
  • 结构化摘要生成:context-compactor.js
  • 摘要沉淀为长期记忆:compaction-memory.js
  • 增量批量压缩(ReAct 超阈值):context-summarizer.js
  • 提示词模板与素材限量:compaction-prompt.js
  • 发送历史选择与摘要注入:context-usage.js
  • Token 估算、上下文窗口与预算:token-counter.js
  • 默认对话配置与读取:constants.js、config.js

章节来源

架构总览 ​

上下文压缩系统由三层组成:

  • 触发层:基于 Token 阈值检测、上下文窗口限制和性能监控指标决定是否压缩。
  • 处理层:执行摘要生成、历史消息合并、工具调用精简和无关内容过滤。
  • 重建层:将压缩结果注入 system prompt,并保证消息重组、工具链恢复与状态一致性。
sequenceDiagram
participant UI as "侧边栏界面"
participant Auto as "自动压缩决策"
participant Indicator as "手动压缩内核"
participant BG as "背景摘要生成"
participant Memory as "长期记忆沉淀"
participant Usage as "发送历史选择/注入"
participant Model as "模型 API"
UI->>Auto : 发送前检查是否自动压缩
Auto->>Indicator : silent=true 触发压缩
Indicator->>BG : 提交素材(material, model, sessionId)
BG->>Model : 请求结构化摘要
Model-->>BG : 返回摘要文本或错误
BG->>Memory : 可选沉淀摘要(带 memoryId 去重)
Memory-->>BG : 返回 memoryId
BG-->>Indicator : 返回 summary + memoryId 或错误详情
Indicator->>Usage : 更新 activeCompaction
Usage-->>UI : 注入 system prompt 并显示分隔条

图表来源

详细组件分析 ​

自动触发条件 ​

  • Token 阈值检测:通过 computeContextUsage 计算当前占用比 ratio,并与 autoCompactionThreshold 比较。
  • 上下文窗口限制:使用 getContextWindow 获取模型上下文窗口,结合 system、工具定义、输出预留和安全余量计算 historyBudget。
  • 性能监控指标:连续失败退避计数、生成中保护、记忆开关保护。
flowchart TD
Start(["进入发送前置"]) --> CheckEnabled{"自动压缩已启用?"}
CheckEnabled --> |否| Skip["跳过自动压缩"]
CheckEnabled --> |是| GetRatio["计算 ratio"]
GetRatio --> RatioOK{"ratio >= 阈值?"}
RatioOK --> |否| Skip
RatioOK --> |是| PendingCheck{"压缩点后新消息数 >= minPending?"}
PendingCheck --> |否| Skip
PendingCheck --> |是| Compact["silent=true 触发压缩"]
Compact --> Result{"压缩成功?"}
Result --> |是| ResetBackoff["重置连续失败计数"]
Result --> |否| IncFail["连续失败+1"]
ResetBackoff --> End(["继续发送"])
IncFail --> End
Skip --> End

图表来源

章节来源

压缩策略算法 ​

  • 摘要生成:buildCompactionPrompt 构建结构化四小节提示词,按语言选择指令块,并对素材进行单条与总量截断。
  • 历史消息合并:assembleCompactionMaterial 将已有摘要与窗口内消息合并为素材,避免被裁剪头部永久丢失。
  • 工具调用精简:context-summarizer.js 提取 tool_calls 的关键参数与结果片段,构造紧凑 transcript。
  • 无关内容过滤:sanitizeMaterialContent 清洗非字符串内容,去除图片数据,保留关键标识符。
classDiagram
class CompactionPrompt {
+buildCompactionPrompt(material, lang) string
+sanitizeMaterialContent(content) string
+COMPACTION_SECTION_HEADINGS
}
class ContextUsage {
+selectHistoryForSend(history, options) object
+assembleCompactionMaterial(history, options) object
+appendCompactionToSystemPrompt(systemContent, compaction) string
+applyCompactionInjection(messages, selection, compaction, logger) Array
+computeContextUsage(params) object
}
class TokenCounter {
+estimateTokens(text) number
+estimateMessagesTokens(messages) number
+truncateByTokens(content, maxTokens) string
+getContextWindow(modelName, userConfiguredWindow, customModelMap) number
+assessContextPressure(usedTokens, budget) object
}
CompactionPrompt <.. ContextUsage : "用于构建提示词"
TokenCounter <.. ContextUsage : "用于预算与窗口"

图表来源

章节来源

压缩质量评估 ​

  • 语义保留度:结构化四小节模板强调任务目标、已完成事项、关键标识符与未决问题,避免丢弃既有摘要有效信息。
  • 关键信息提取:工具调用关键参数与结果片段保留,路径、符号、URL 等标识符原样保留。
  • 用户反馈机制:手动确认框、进行中模态、完成 toast、撤销与再次压缩按钮,以及详情弹窗预览/源码双模式。

章节来源

用户控制 ​

  • 手动触发:triggerCompaction 弹出确认框与进行中模态,成功后显示节约 tokens 提示。
  • 压缩级别选择:通过 chatConfig.autoCompactionThreshold 调整触发阈值;maxMemoryMessages 控制携带历史范围。
  • 预览确认:详情弹窗支持查看摘要全文(Markdown 预览或源码),并可撤销压缩。

章节来源

压缩后的上下文重建 ​

  • 消息重组:selectHistoryForSend 根据压缩点过滤历史,仅保留压缩点之后的消息参与发送。
  • 工具链恢复:filterApiMessages 修复 assistant(tool_calls) 与 tool 配对,确保工具调用完整性。
  • 状态一致性:activeCompaction 包含 upToMessageId、compressedCount、summaryTokens、memoryId 等字段,保证跨会话一致性与去重。
sequenceDiagram
participant Usage as "context-usage.js"
participant TC as "token-counter.js"
participant UI as "context-indicator.js"
UI->>Usage : assembleCompactionMaterial(history, options)
Usage->>TC : estimateMessagesTokens(material)
TC-->>Usage : materialTokens
Usage-->>UI : material + includedCount
UI->>Usage : selectHistoryForSend(history, options)
Usage->>TC : estimateMessagesTokens(keptHistory)
TC-->>Usage : historyTokens
Usage-->>UI : messages + compactionApplied

图表来源

章节来源

错误处理与用户反馈 ​

新增 系统现在提供详细的错误处理机制,能够区分不同类型的压缩失败并通过 toast 通知向用户提供具体反馈。

错误类型分类 ​

  • 超时错误:SSE 流空闲超时(headers 后卡流),显示"请求超时"
  • 空摘要错误:模型返回空摘要,显示"模型未返回摘要"
  • HTTP 失败:API 错误状态码及详细信息,显示"API 错误 HTTP {status}"
  • 解析异常:JSON 解析失败或其他异常情况

错误详情映射机制 ​

compactErrorDetail 函数将后端返回的错误码转换为可读的用户反馈:

flowchart TD
Error["后端错误"] --> TypeCheck{"错误类型判断"}
TypeCheck --> |empty_summary| Empty["空摘要错误"]
TypeCheck --> |CHAT_STREAM_IDLE_TIMEOUT| Timeout["超时错误"]
TypeCheck --> |http_*| Http["HTTP 错误"]
TypeCheck --> |其他| Generic["通用错误"]
Http --> ParseBody["解析响应正文"]
ParseBody --> ExtractMsg["提取 error.message"]
ExtractMsg --> Display["显示详细错误信息"]
Empty --> ShowEmpty["显示'模型未返回摘要'"]
Timeout --> ShowTimeout["显示'请求超时'"]
Generic --> ShowGeneric["显示原始错误信息"]

图表来源

用户反馈流程 ​

  1. 配置缺失:直接显示"无法压缩:缺少 API 配置"
  2. 网络错误:显示 HTTP 状态码和具体错误原因
  3. 流式超时:显示"请求超时"而非原始错误码
  4. 空摘要:显示"模型未返回摘要"
  5. 其他异常:显示原始错误信息

章节来源

依赖关系分析 ​

  • 侧边栏依赖共享层进行上下文计算与注入。
  • 背景进程依赖共享层构建提示词与记录 token 使用。
  • 配置层提供默认值与读取逻辑,影响自动压缩行为。
graph LR
AC["auto-compaction.js"] --> CU["context-usage.js"]
CI["context-indicator.js"] --> CU
CC["context-compactor.js"] --> CP["compaction-prompt.js"]
CC --> TC["token-counter.js"]
CM["compaction-memory.js"] --> Cfg["config.js"]
Cst["constants.js"] --> Cfg

图表来源

章节来源

性能与优化 ​

  • 异步处理:所有 LLM 调用均使用异步接口,失败不阻塞主流程。
  • 增量压缩:context-summarizer.js 支持批量压缩多轮旧对话,减少重复调用。
  • 缓存策略:system prompt 与 MCP 工具数缓存,避免高频重算。
  • Token 校准:EWMA 校准因子平滑估算偏差,提升预算准确性。

章节来源

质量评估与调优 ​

  • 准确率测试:通过单元测试验证提示词构建、注入逻辑与自动触发决策。
  • 用户满意度调查:观察 toast 提示、撤销成功率与详情弹窗使用情况。
  • 参数优化:调整 autoCompactionThreshold、minPending、maxMemoryMessages 以平衡压缩频率与效果。

章节来源

故障排查指南 ​

  • 配置缺失:若 API 配置缺失,压缩将返回错误码 config_missing。
  • 生成中保护:正在生成回复时禁止压缩,避免打断用户。
  • 记忆关闭:记忆功能关闭时无可压缩内容,直接返回 memory_off。
  • 连续失败退避:自动压缩连续失败达到上限后进入退避,不再尝试。
  • 新增 错误类型识别:系统现在能够区分超时、空摘要、HTTP 错误和解析异常,并提供具体的用户反馈。

章节来源

结论 ​

上下文压缩系统通过结构化摘要、阈值驱动触发与多阶段重建,实现了高效且可控的上下文管理。系统在用户体验、性能与稳定性之间取得平衡,并提供丰富的用户控制选项与故障恢复机制。

更新 最新的错误处理改进显著提升了系统的可诊断性和用户体验,通过详细的错误分类和具体的用户反馈,帮助用户更好地理解压缩失败的原因并采取相应措施。未来可进一步优化摘要质量评估与自动化调参策略。