Solon v3.9.3

react - 上下文摘要压缩(summarize)

</> markdown
2026年2月14日 下午11:54:42

在智能体(Agent)的长期运行中,上下文窗口(Context Window)的限制是开发者面临的最大挑战。随着对话轮次的增加,Token 消耗不仅会带来高昂的成本,更会导致模型因为信息过载而变得迟钝甚至失忆。

Solon AI 通过 SummarizationInterceptor 拦截器与多维摘要策略,为智能体提供了类似人类的“长短期记忆”管理机制。

1. 核心组件:SummarizationInterceptor

SummarizationInterceptor 负责监控智能体执行过程中的 Trace(轨迹)。当历史消息数量达到预设的阈值时,它会自动触发“裁减与压缩”动作。

工作原理

  • 监控阈值:设定一个 maxMessages(如 12 条)。
  • 触发裁减:当消息超过阈值时,取最老的一段消息(Expired Messages)。
  • 执行策略:调用配置的 SummarizationStrategy 对这段消息进行加工。
  • 注入摘要:将加工后的摘要消息重新注入上下文头部,并物理移除原始明细。

2. 内置摘要策略全家桶

Solon AI 提供了四种开箱即用的策略,满足从“简单压缩”到“无限续航”的不同业务场景。

A. 基础语义压缩 (LLMSummarizationStrategy)

  • 职能:调用轻量级模型对过期的对话段落进行一次性概括。
  • 场景:通用场景,对历史细节要求不高。
  • 特点:精简、准确,带有明显的视觉标记。

B. 关键信息看板 (KeyInfoExtractionStrategy)

  • 职能:作为“信息审计专家”,只提取事实、参数、结论和已验证的失败尝试。
  • 场景:垂直领域任务(如 SQL 生成、自动化运维),需要防止核心参数丢失。
  • 特点:过滤掉冗长的思考过程,只保留“硬干货”。

C. 层级滚动摘要 (HierarchicalSummarizationStrategy)

  • 职能:将“旧摘要”与“新消息”递归合并。(Summary_N-1 + History_New) -> Summary_N。
  • 场景:超长任务流。
  • 特点:支持无限续航。记忆链条永不断裂,历史背景通过摘要不断向后传递。

D. 冷记忆归档 (VectorStoreSummarizationStrategy)

  • 职能:将原始明细异步存入向量数据库,仅在上下文中留下一个“检索锚点”。
  • 场景:合规审计、需要回溯原始细节的复杂推理。
  • 特点:物理存盘。配合 RAG 工具使用,让 Agent 具备“翻阅档案”的能力。

3. 级联编排:CompositeSummarizationStrategy

在生产环境下,单一策略往往不够。你可以通过 CompositeSummarizationStrategy 将多个策略串联起来,构建多层级记忆体系。

最佳实践建议顺序:

  • 先通过 VectorStore 存盘(保证原始数据不丢)。
  • 再通过 KeyInfo 提纯(保证硬核数据在看板上)。
  • 最后通过 Hierarchical 压缩(保证全局进度不丢失)。

4. 快速上手

以下示例展示了如何为 ReAct 智能体配置一个“永不失忆”的记忆模型:

// 1. 选择并组合策略
SummarizationStrategy myStrategy = new CompositeSummarizationStrategy()
    .addStrategy(new VectorStoreSummarizationStrategy(vectorRepo)) // 冷归档
    .addStrategy(new KeyInfoExtractionStrategy(chatModel))        // 事实看板
    .addStrategy(new HierarchicalSummarizationStrategy(chatModel)); // 滚动摘要

// 2. 注入拦截器 (设置超过 15 条消息时触发)
SummarizationInterceptor memoryGuard = new SummarizationInterceptor(15, myStrategy);

// 3. 构建 Agent
Agent agent = ReActAgent.builder()
                .chatModel(chatModel)
                .interceptors(memoryGuard) // 挂载记忆守卫
                .build();