概述
在前面的章节中,我们讨论了如何通过摘要压缩来管理上下文长度。除了对对话历史进行摘要外,我们还可以直接清理不再需要的工具输出,这也是一种有效的上下文管理方式。
在AI智能体执行复杂任务时,往往会调用多个工具,每个工具的执行结果都会添加到上下文中。这些工具输出可能会占用大量token,特别是当工具返回大量数据时。如果这些数据已经不再需要(比如已经处理过了),继续保留在上下文中就只是浪费token。
Context editing中间件就是为了解决这个问题而设计的。它可以在达到token限制时,自动清理较旧的工具调用输出,保留最近的关键工具结果,确保长对话和多工具调用场景下上下文窗口可控,同时降低token消耗。
使用场景
长对话场景
包含大量工具调用的长对话,工具输出会占用大量token。通过清理旧输出,可以控制上下文长度,确保对话能够继续。
降低token成本
清理不再相关的旧工具输出,减少发送给模型的token数量,降低API调用成本。特别是在工具返回大量数据的场景下,效果更明显。
保持上下文聚焦
只保留最近的N个工具结果,确保模型关注最新信息,提升决策准确性。旧的信息可能已经不再相关,清理掉反而更好。
核心功能需求
Token监控与触发
系统需要持续监控对话中的token数量,当达到预设阈值时,触发清理操作。
触发阈值设置
- trigger参数:设置触发清理的token数量阈值
- 建议值:根据模型上下文窗口设置,建议设为窗口的70%-80%,留出安全余量
- 动态调整:可以根据对话复杂度动态调整
Token计数方法
- 近似计数(approximate):快速但不够精确,适用于大多数场景
- 模型计数(model):精确但较慢,适用于对精度要求高的场景
- 性能权衡:需要在精度和性能之间权衡
清理策略
清理不是全部删除,而是要有选择地清理,保留关键信息。
保留最近N个工具结果
- keep参数:设置必须保留的最近工具结果数量
- 建议值:建议保留3-5个最近工具结果,确保模型有足够上下文
- 永远保留:这些工具结果永远不会被清理
排除特定工具
- exclude_tools参数:设置排除清理的工具名称列表
- 关键工具:关键工具(如数据库查询、支付工具)的输出应加入排除列表
- 永远保留:这些工具的输出永远不会被清理
清理粒度控制
- clear_at_least参数:设置编辑运行时至少回收的token数量
- 作用:确保每次清理有效果,避免频繁触发但回收不足
- 建议值:根据实际场景设置,比如每次至少回收500-1000 tokens
工具输入清理
- clear_tool_inputs参数:是否清理AI消息中的原始工具调用参数
- 建议:建议设置为False,保留工具调用参数,便于模型理解上下文
- 权衡:如果设置为True,可以节省更多token,但可能影响模型理解
占位符替换
被清理的工具输出不会直接删除,而是用占位符替换,保持消息结构完整。
占位符设计
- placeholder参数:设置占位符文本,如<code>[cleared]</code>或<code>[工具输出已清理]</code>
- 明确标识:占位符应明确标识为"已清理",避免模型误解
- 可配置:允许自定义占位符文本
产品建议:占位符应该清晰明了,让模型知道这里曾经有内容但被清理了。
PRD需求描述
功能需求
FR-1: Token监控与触发
- 描述:持续监控对话中的token数量,达到阈值时触发清理
- 触发阈值:支持配置触发清理的token数量阈值
- Token计数:支持近似计数和模型计数两种方法
- 优先级:P0(核心功能)
FR-2: 工具输出清理
- 描述:清理较旧的工具调用输出,保留最近的关键工具结果
- 保留策略:支持保留最近N个工具结果,排除特定工具
- 清理粒度:支持设置至少回收的token数量
- 优先级:P0(核心功能)
FR-3: 占位符替换
- 描述:用占位符替换被清理的工具输出,保持消息结构完整
- 占位符文本:支持自定义占位符文本
- 优先级:P0(核心功能)
FR-4: 工具输入清理(可选)
- 描述:可选是否清理AI消息中的原始工具调用参数
- 配置方式:通过clear_tool_inputs参数控制
- 优先级:P1
非功能需求
NFR-1: 性能要求
- 清理开销:清理操作本身有开销,需要在PRD中明确是否可接受
- Token节省:评估清理后节省的token数量,确保成本降低
- 延迟影响:清理操作会增加延迟,需要在PRD中明确延迟容忍度
NFR-2: 清理准确性
- 保留验证:确保清理后保留了正确的工具结果
- 排除验证:确保排除列表中的工具输出没有被清理
- 边界处理:处理工具数量少于keep值时的边界情况
NFR-3: 监控与日志
- 清理日志:记录每次清理操作的详细信息(清理的工具数量、回收的token数量等)
- 清理频率:监控清理触发频率,如果过于频繁,可能需要调整阈值
产品设计要点
触发阈值设置
根据模型窗口设置:
- 如果模型窗口是128K,trigger建议设置为100K,留出安全余量
- 如果模型窗口是8K,trigger建议设置为6K-7K
动态调整:
- 可以根据对话复杂度动态调整trigger
- 简单对话可以设置较高(如50K),复杂对话可以设置较低(如100K)
触发频率控制:
- 如果触发过于频繁,可能影响用户体验
- 需要在PRD中明确触发频率阈值
产品建议:建议在PRD中明确触发阈值设置原则,并根据实际效果调整。
保留策略设计
keep数量设置:
- 建议保留3-5个最近工具结果
- 确保模型有足够上下文理解当前状态
exclude_tools列表:
- 关键工具(如数据库查询、支付工具)的输出应加入排除列表
- 避免清理导致关键信息丢失
保留逻辑:
- 需要在PRD中明确哪些工具必须保留,哪些可以清理
- 根据业务场景制定保留策略
产品建议:建议在PRD中明确保留策略,确保关键信息不会被清理。
清理粒度控制
clear_at_least设置:
- 设置最小回收token数量,确保每次清理有效果
- 避免频繁触发但回收不足
clear_tool_inputs权衡:
- 建议设置为False,保留工具调用参数
- 如果token压力很大,可以设置为True,但需要评估对模型理解的影响
占位符设计:
- 占位符应明确标识为"已清理"
- 避免模型误解
产品建议:建议在PRD中明确清理粒度控制策略,平衡token节省和信息保留。
使用建议
什么时候应该使用
- 长对话场景:包含大量工具调用的长对话,工具输出占用大量token
- 成本敏感场景:需要降低token消耗,控制成本
- 需要保持上下文聚焦的场景:只需要最近的关键信息,旧信息不再相关
配置建议
- 触发阈值:根据模型窗口设置,建议为窗口的70%-80%
- 保留策略:保留最近3-5个工具结果,排除关键工具
- 清理粒度:设置合理的clear_at_least值,确保每次清理有效果
注意事项
- 关键信息保护:确保关键工具的输出不会被清理,避免信息丢失
- 清理频率:如果触发过于频繁,可能需要调整阈值
- 与摘要配合:可以与SummarizationMiddleware配合,双重压缩上下文
与其他中间件的配合
上下文清理可以与其他中间件配合使用:
- 与SummarizationMiddleware配合:清理工具输出 + 摘要历史消息,双重压缩上下文
- 与ToolCallLimitMiddleware配合:清理不影响工具调用限制,限制仍按实际调用次数计算
- 执行顺序:上下文清理应在模型调用前执行,确保模型看到的是清理后的上下文
后续优化方向
- 智能清理:根据工具结果的重要性,智能决定哪些清理,哪些保留
- 多策略组合:支持在不同token阈值下应用不同的清理策略
- 清理效果评估:评估清理对模型理解的影响,优化清理策略
- 用户反馈:根据用户反馈优化清理策略,提升用户体验