04.2 Session Memory 与长期 Memory

关注源码

  • src/services/SessionMemory/sessionMemory.ts
  • src/services/extractMemories/extractMemories.ts
  • src/memdir/*

两类记忆

1. Session Memory

Session Memory 维护的是“当前会话的持续笔记”:

  • 定期更新 markdown 文件
  • 服务当前对话
  • 不要求长期跨会话复用

2. Auto Memory / Durable Memory

extractMemories.ts 提取的是值得长期保存的项目记忆:

  • 写入 auto-memory 目录
  • 面向后续会话复用
  • 权限边界更窄

Session Memory 的运行方式

sessionMemory.ts 通过 post-sampling hook 触发后台更新,触发条件包括:

  • 会话累计 token 达到初始化阈值
  • 与上次更新相比增加了足够 token
  • 工具调用数达到阈值,或者到达自然停顿点

更新过程会:

  1. 确保 session memory 文件存在
  2. 读取当前内容
  3. 创建 forked subagent
  4. 让子 agent 更新 memory 文件

长期 Memory 的运行方式

extractMemories.ts 一般在完整 query loop 结束时触发,重点是从 transcript 中抽出值得沉淀的条目。

这里最重要的不是“怎么总结”,而是“允许它做什么”。

权限边界为什么这么窄

extractMemories.ts 通过 createAutoMemCanUseTool() 限制 memory agent 只允许:

  • Read
  • Grep
  • Glob
  • 只读 Bash
  • 对 auto-memory 目录内文件的 Edit/Write

这意味着它虽然复用了同一套 agent runtime,但不会拿到完整工作区写权限。

memdir 承担的职责

memdir 不是简单路径常量,它负责:

  • memory 目录布局
  • manifest / scan
  • freshness / age
  • relevant memory 检索
  • team memory 相关辅助

因此长期记忆系统并不依赖某个单文件实现,而是依赖一套目录协议。

设计上的关键点

1. 记忆系统复用 forked agent,而不是重写一个摘要器

这样可以直接继承:

  • prompt cache 共享
  • 工具系统
  • transcript 记录
  • usage 统计

2. 触发是阈值驱动,不是每轮强制执行

否则记忆提取会非常吵,而且容易和主线程争资源。

3. 长期 memory 的安全边界独立于主线程

这是这层最重要的工程约束之一。