☰
TuriX长任务如何不失忆:recent、summary、snapshot三层记忆压缩与read_files召回机制源码解析
2026/9/30 15:44:45 网站建设 项目流程

TuriX长任务如何不失忆:recent、summary、snapshot三层记忆压缩与read_files召回机制源码解析

【免费下载链接】TuriX-CUAThis is the official website for TuriX Computer-use-Agent项目地址: https://gitcode.com/gh_mirrors/tu/TuriX-CUA

TuriX 是一款开源的桌面端 AI Agent(Computer-use Agent),它通过"Brain + Actor"双模型架构驱动 macOS 完成多步 GUI 操作。当任务步骤超过几十步时,上下文窗口很快就会被挤爆。TuriX 用recent(短期记忆)→ summary(压缩摘要)→ snapshot(原始快照)三层记忆压缩配合read_files 按需召回,让长任务始终"记得"关键信息而不撑爆 token。下面结合源码逐层拆解这套机制。

一、为什么长任务会"失忆"

TuriX 的 Brain 模型每一步都要接收:系统提示词 + 记忆摘要 + 两张截图 + UI 树状态。以 32000 token 的输入上限为例,十几步之后历史消息就会逼近天花板。

如果简单地把所有步骤塞进上下文,结果只有两种:

  • 直接报错(token 超限)
  • 强行截断(丢失早期步骤的关键信息,Agent 开始"失忆")

TuriX 的解法是:分级压缩 + 按需召回——热数据留在内存,冷数据压缩成摘要,原始数据落盘成快照,需要时再按文件名精确取回。

二、三层记忆架构总览

核心状态变量定义在 service.py:

层级变量内容预算
缓冲区pending_recent_memory当前步骤(尚未被评估)不计入预算,最多 20 行
短期记忆recent_memory已评估的最近步骤(Step N | Eval: success | Goal: …)memory_budget_tokens
长期摘要summary_memory多轮压缩后的高层摘要memory_budget_tokens × 4

预算比例在 service.py 中配置:memory_warn_ratio = 0.7(预警线)、memory_hard_ratio = 1.0(触发压缩线)。

三层数据最终拼接为 Brain 模型的输入,拼接逻辑见_refresh_brain_memory:

Summarized memory (compressed from earlier steps…) → Recent steps → Pending steps

三、第一层:pending 缓冲区与 recent 短期记忆

3.1 步骤如何进入 pending

Actor 执行完动作后,_update_memory会写入一行:

Step 5 | Eval: pending | Goal: 在 Safari 中搜索航班

这一行进入pending_recent_memory,此时不参与预算计算,避免刚执行完就被压缩掉。

3.2 pending → recent 的晋升

下一步 Brain 评估完前一步后(brain_step),会把Eval: pending替换为真实结果success/failed,并把该行从 pending 移入recent_memory。同时调用_save_step_record将该步骤的 eval + goal + analysis持久化到磁盘(文件名如step_5.txt),为后续召回留底。

3.3 预算检查与触发压缩

每次晋升后,brain_step检查recent_memory的 token 数:

  • 超过budget × 1.0(硬限制)→ 立即调用_summarise_recent_memory
  • 超过budget × 0.7(预警线)→ 仅打日志提醒

四、第二层:summary 压缩与 snapshot 快照

4.1 压缩前先拍快照

_summarise_recent_memory的核心流程:

  1. 调用memory_llm对recent_memory做摘要
  2. 无论成功还是失败,都先调用_save_memory_snapshot把原始文本落盘
  3. 摘要通过_is_summary_valid校验(必须 ≥10 token 且比原文短)
  4. 校验通过 →recent_memory清空,摘要追加到summary_memory

快照文件的描述固定为"Pre-summarization snapshot of recent memory at step N",record_type标记为snapshot,这样 Brain 在索引中能看到它和step/info记录的区别。

4.2 摘要的二次压缩

summary_memory也会增长。当它超过自己的预算(memory_budget × 4)时,_summarise_summary_memory会再做一轮更高层的压缩——相当于"摘要的摘要",始终保持总占用可控。

4.3 快照存储位置

所有快照通过 RecordStore 写入memory_snapshots/目录,每个文件带 YAML frontmatter(name、description、type、step_id、created_at),为 read_files 召回提供结构化元数据。

五、第三层:read_files 按需召回

5.1 记忆索引

每步 Brain 调用前,_format_memory_index会渲染一份索引(最多 50 条,最新在前):

- step_12 (step, step 12): Step 12 (Success): 点击"下一步"按钮 - user_profile (info, step 3): 用户偏好:靠窗座位 - memory_snapshot_recent_step_8 (snapshot, step 8): Pre-summarization snapshot of recent memory at step 8

这份索引随截图一起送入 Brain 模型。

5.2 Brain 发起召回

Brain 提示词 明确告诉模型:

当索引中某条记录的描述表明它包含你需要的细节时,输出{"read_files": {"files": ["step_5", "user_profile"]}}代替正常的 analysis/current_state。

5.3 召回执行流程

BrainSearchFlow 负责拦截与执行:

  1. parse_response解析 Brain 的 JSON 输出
  2. extract_read_files检测是否存在read_files字段
  3. maybe_reinvoke从 RecordStore 读取文件全文,拼入 state_content,重新调用 Brain
  4. Brain 拿到完整内容后输出正常的analysis+current_state

这意味着:被压缩掉的早期步骤,只要 Brain 判断需要,就能按文件名精确取回原始记录,而不必把所有历史都留在上下文里。

六、容错与断点恢复

  • 孤儿清理:_sweep_orphaned_pending会回收因 Brain 调用失败而滞留的 pending 行,将其标记为Eval: unknown并补写 step 记录
  • 断点恢复:load_memory从memory.jsonl恢复全部三层状态,兼容旧版本格式(如 pending 行混在 recent 里的情况会自动迁移)
  • Token 兜底:当消息窗口仍超限时,MessageManager.cut_messages 按"先删图片 → 再删最旧消息 → 最后截断尾部"三阶段降级

七、关键源码文件索引

文件职责
src/agent/service.py三层记忆状态管理、压缩调度、快照保存、断点恢复
src/agent/prompts.pyBrain 提示词中 read_files 召回协议
src/utils/record_store.py带 frontmatter 的文件级记录存储
src/utils/brain_search.pyread_files 检测与二次调用
src/agent/message_manager/service.pyToken 计数与消息裁剪

这套机制让 TuriX 在 OSWorld 基准上保持高成功率——记忆压缩保证上下文不溢出,read_files 召回保证关键信息可回溯,两者结合正是长任务"不失忆"的核心。

【免费下载链接】TuriX-CUAThis is the official website for TuriX Computer-use-Agent项目地址: https://gitcode.com/gh_mirrors/tu/TuriX-CUA

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

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询