Skip to main content
每个 Mycel Agent 都内置了持久记忆。对话历史跨重启保留,长会话自动管理以保持上下文窗口可用,无需任何外部记忆服务。

记忆的工作原理

Mycel 的记忆分为两层:
  1. 持久化 — 对话历史使用 LangGraph AsyncSqliteSaver checkpointer 存储在 SQLite(~/.leon/leon.db)。每条消息、工具调用和结果都被记录。恢复 Thread 时,完整历史会被重放。
  2. 上下文管理 — 随着对话增长,MemoryMiddleware 会在每次模型调用前自动裁剪和压缩历史,确保上下文窗口始终可用。这一过程对用户完全透明。

裁剪(Pruning)

裁剪负责截断过长的工具结果,防止单个输出占用过多上下文。 工具结果超过软阈值时被截断,超过硬阈值时直接清除。最近的消息受到保护不被裁剪,确保 Agent 保有当前的工作上下文。 默认配置:
字段默认值说明
soft_trim_chars3,000超过此长度(字符数)的工具结果被截断
hard_clear_threshold10,000超过此长度的工具结果被直接清除
protect_recent3最近 N 条工具消息不被裁剪
trim_tool_resultstrue启用裁剪
runtime.json 中配置:
{
  "memory": {
    "pruning": {
      "soft_trim_chars": 5000,
      "hard_clear_threshold": 20000,
      "protect_recent": 5
    }
  }
}

压缩(Compaction)

压缩通过 LLM 对旧的对话历史进行摘要,在上下文窗口填满时自动触发。这让 Agent 在非常长的任务中也不会丢失有意义的上下文 — 旧消息被摘要后替换为紧凑的表示。 压缩触发条件(同时满足):
  • 对话消息数不少于 min_messages
  • 上下文窗口已使用超过 70%
触发时,压缩模型会对除最近 keep_recent_tokens token 之外的所有内容进行摘要,然后用摘要替换旧历史。 默认配置:
字段默认值说明
reserve_tokens16,384为新消息预留的 token 数
keep_recent_tokens20,000保留最近 N 个 token 的原文
min_messages20压缩可以触发的最少消息数
runtime.json 中配置:
{
  "memory": {
    "compaction": {
      "enabled": true,
      "reserve_tokens": 32768,
      "keep_recent_tokens": 40000,
      "min_messages": 30
    }
  }
}

溢出缓冲区(Spill buffer)

对于输出非常大的工具(例如在大型代码库上运行 Grep),溢出缓冲区会自动将输出写入临时文件,而不是内联到对话中。这保持了上下文的整洁,同时数据仍然可以访问。 按工具配置阈值:
{
  "tools": {
    "spill_buffer": {
      "default_threshold": 50000,
      "thresholds": {
        "Grep": 20000,
        "run_command": 100000
      }
    }
  }
}

持久化详情

存储位置内容
Thread 历史~/.leon/leon.db所有消息、工具调用、结果(LangGraph checkpoints)
沙箱状态~/.leon/sandbox.db会话租约、指标
聊天消息~/.leon/chat.dbEntity-Chat 社交层消息
Thread 历史是追加式的。回退 Thread 时移动的是活跃 checkpoint 指针,不会删除中间历史。

禁用压缩

如果你想自己管理上下文,或只运行短会话:
{
  "memory": {
    "compaction": {
      "enabled": false
    }
  }
}
裁剪可以独立禁用:
{
  "memory": {
    "pruning": {
      "trim_tool_results": false
    }
  }
}