ARTICLE · INTELLIGENCE

战地情报 · 详情页

来自尧图项目组的一线实战观察与深度解析

thClaws如何压缩超长对话?Compaction上下文管理机制全解析

thClaws如何压缩超长对话?Compaction上下文管理机制全解析

【免费下载链接】thClaws

Open-source AI agent harness in native Rust — GUI, CLI, headless, and webapp from one binary. Multi-provider, MCP, skills, plugins, agent teams.

项目地址:https://gitcode.com/gh_mirrors/th/thClaws
点击查看免费下载

thClaws 是一款用 Rust 编写的开源 AI agent 框架,支持 GUI、CLI、headless 与 Webapp 多种运行形态。面对越来越长的对话,thClaws 内置的Compaction(上下文压缩)机制会在每一轮自动估算 token 占用、裁剪超预算的历史消息,甚至调用 LLM 生成摘要来"瘦身"对话,让超长会话永远不会撑爆模型上下文窗口。这篇文章带你完整看懂这套机制的 5 个入口、预算算法和持久化策略。

为什么 AI Agent 必须有上下文压缩?

大模型都有固定的上下文窗口(context window),比如 128K token。一次请求里要装下的不只是聊天记录,还包括系统提示词、工具定义、历史消息。当 agent 长时间运行——读文件、跑命令、调工具——历史消息会迅速膨胀,最终触发服务商的400 context length exceeded错误。

thClaws 的解法是:在每一轮(turn)发出请求之前,先做一次预算核算,超了就自动压缩。整个过程对用户完全透明,无需任何配置(见 ch07-sessions.md 的 "Compaction" 小节)。

每轮的预算是怎么算出来的?

在 agent.rs 的run_turn_multipart中,真正的消息预算是"扣扣扣"出来的:

消息预算 = 模型上下文窗口 − 系统提示词 token − 工具定义预留(1024 token)

  • 模型上下文窗口:来自项目/用户配置的modelOverrides,否则查模型目录,查不到则回退到 128K 的默认值。
  • 系统提示词扣除:CLAUDE.md/AGENTS.md 级联、记忆、技能清单都可能让系统提示词高达数万 token。早期版本没算这笔账,导致"消息看似装得下、整包请求却溢出"。
  • 1 KiB 工具定义预留:内置 30~40 个工具加 MCP 工具的 JSON Schema 也要占窗口,预留一块粗粒度余量最省事。

token 估算本身很轻量:tokens.rs 用"字符数 ÷ 2.8 向上取整"的启发式,不求精确、只求保守。

5 个压缩入口一览

压缩逻辑集中在 compaction.rs,官方技术手册的汇总见 thclaws-technical-manual/compaction.md。

入口触发时机策略
compact每轮自动执行(预算内则直接跳过)丢最旧消息,保住工具调用配对,必要时原地截断
compact_with_summary用户输入/compact调 LLM 把旧消息总结成一段摘要,最近 4 条原样保留
compact_for_step_boundaryPlan 模式跨步骤时(默认)结构性瘦身:普通工具结果换成占位符,计划工具结果保留
clear_for_step_boundaryPlan 模式planContextStrategy = "clear"除第一条用户消息外清空全部历史
truncate_oversized_messagecompact内部的兜底救援单条消息超预算时按字符边界原地截断并追加提示

自动压缩:drop-oldest 的两条铁律

每轮执行的compact()是同步、零 API 开销的"丢弃最旧"策略,但有两条不变式:

  1. 绝不拆散工具配对:ToolUse(工具调用)必须和它的ToolResult(工具结果)成对出现,所有服务商的线上格式都强制这一对。丢弃最旧消息时,如果会留下"孤儿结果",结果消息会被一并丢掉。

  2. 至少保留一条 + 截断救援:丢弃循环保证至少留最后一条消息。如果这一条本身就超出预算(比如粘贴了一个巨大文件),truncate_oversized_message会在 UTF-8 字符边界处原地截断每个 Text / ToolResult 块,并追加一行模型能读懂的提示:

    [...truncated by thClaws: original content exceeded the N token context budget]

    模型看到这个提示后,可以主动换一种更窄的读取策略。修复前,这种"单条超大消息"会原样发出去,换来一个 HTTP 400。

预算内时compact()是纯 no-op(不写任何东西),所以日常对话不会有任何额外成本。

手动压缩:/compact一键生成 LLM 摘要

自动压缩是"粗暴裁剪",而/compact是"智能压缩"。在 CLI 或 GUI 输入框中输入/compact,流程是(源码见 compaction.rs):

  1. 把历史在"倒数第 4 条"处切开——最近 4 条消息原样保留(最近一轮往往含有模型下一轮还要引用的工具调用 ID,总结会丢失结构化信息);
  2. 把更早的消息渲染成转录文本(工具调用渲染成[Called tool: …],工具结果只保留 500 字符预览);
  3. 用独立的摘要提示词调当前 provider:系统提示见 compaction_system.md,指令见 compaction.md——"简明总结,保留关键事实、决策和工具结果";
  4. 摘要被包成一条合成用户消息[Conversation summary — earlier messages were compacted]插到保留消息之前。

失败自动降级:摘要调用报错或返回空时,自动退回 drop-oldest 策略,并提示"compaction failed, dropped oldest instead"——压缩永远不会把会话搞坏。

Plan 模式:步骤边界处的"换血"

Plan 模式(Ralph 驱动)会把长任务切成多个步骤,跨步骤的瞬间就是天然的瘦身时机。此时只压缩"边界之前"的历史:

  • 默认策略"compact":保留计划工具(SubmitPlan/UpdatePlanStep等)的结果——它们是模型判断"哪些步骤已完成"的面包屑;其余普通工具结果(比如 50KB 的 Read 输出)替换为[ToolResult elided by step-boundary compaction]占位符。
  • 激进策略"clear":除了第一条用户消息,历史全部清空。适合 20+ 步、步骤彼此独立的超长计划,通过.thclaws/settings.json中planContextStrategy配置。

由于历史在每个步骤边界都会被压缩,Plan 模式还设计了显式的output字段,让步骤之间通过它传递路径、端口号等关键信息,而不是依赖聊天记录。详见 ch18-plan-mode.md 的 "Step-boundary compaction" 小节。

压缩结果如何持久化?

/compact和步骤边界压缩都会把压缩后的消息列表写成一条compaction检查点事件,追加到会话 JSONL 文件(session.rs 的append_compaction_to):

{"type":"compaction","messages":[...],"replaces_count":42,"timestamp":1777752000}

下次/load恢复会话时,load_from走到这条事件会清空并重置消息列表为压缩后的视图——你看到的是瘦身后的历史,而不是原始记录。而被替换掉的原始消息事件永远留在磁盘上(审计痕迹),需要时cat session.jsonl即可看到完整原貌。

每轮 no-op 的compact()不写检查点(太吵),只有真正发生裁剪的路径才落盘。

与 Prompt Cache 的联动:/compact 为什么"贵两次"

服务商的提示词缓存以"字节级前缀不变"为前提。compact_with_summary改写了消息列表,会打断缓存断点——/compact一次要付两笔钱:摘要调用本身 + 下一轮重新写缓存的溢价(详见 thclaws-technical-manual/prompt-cache.md 第 8 节)。

所以官方建议:有意识地用/compact,而不是反射性地用。而每轮自动compact()在预算内不动消息列表,完全不破坏缓存。

如何观察和控制压缩行为?

🔍Hooks 审计:当且仅当本轮真的发生裁剪时(pre_tokens > messages_budget),会触发pre_compact/post_compact两个钩子,环境变量THCLAWS_COMPACT_MESSAGES和THCLAWS_COMPACT_TOKENS分别提供压缩前后的消息数和 token 数,可写入审计日志。配置示例见 ch13-hooks.md。

🔔上下文警告横幅:当会话 JSONL 文件大到压缩已跟不上(如数十 MB)时,GUI 会在右上角弹出警告,推荐Fork with summary——用 LLM 摘要为新会话播种,开启一个"记得你在哪"的干净上下文。对应组件见 ContextWarningBanner.tsx。

总结:三句话看懂 thClaws Compaction

  1. 每轮自动:先扣系统提示词和工具定义再算预算,超了就丢最旧、保工具配对、兜底截断,全程零 API 开销;
  2. 按需智能:/compact用 LLM 把旧历史总结成一段摘要,最近 4 条原样保留,失败自动降级;
  3. 可追溯:压缩检查点写入会话 JSONL,恢复时看到瘦身视图,磁盘上始终留有完整审计痕迹。

理解了这套机制,你就不会再担心 thClaws 跑长任务时"突然失忆"或报错 400——它只是安静地把历史瘦身了一版。

【免费下载链接】thClaws

Open-source AI agent harness in native Rust — GUI, CLI, headless, and webapp from one binary. Multi-provider, MCP, skills, plugins, agent teams.

项目地址:https://gitcode.com/gh_mirrors/th/thClaws
点击查看免费下载

相关推荐

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

RELATED READING

延伸阅读

更多一线实战笔记与深度复盘,助您持续精进