Skip to main content

作用

让 agent 能在跨请求、跨进程、多用户场景下恢复状态。一次 call() 结束后自动落盘两路产出:
  • StateModule 快照MemoryToolExecutionContext 等可序列化状态)——默认走 WorkspaceSession
  • 对话 JSONL(LLM 上下文 + 完整历史)——走 SessionTree,由 MemoryFlushManager.offloadMessages 触发
两者是**两个并行路径

触发

关键逻辑

双轨存储布局

  • context/WorkspaceSession 继承 JsonSession,base 在 agents/<agentId>/context/;sessionId 子目录里按 SessionKey → {key}.json 存每个 StateModule
  • sessions/SessionTree 在一个 JSONL 里按 id/parentId 组成一棵树;另一份同名的 <sessionId>.log.jsonl 从不被压缩,供审计和 session_search 使用。

RuntimeContext 怎么让二者对齐

HarnessAgent.bindRuntimeContext 会做几件事:
  1. 补默认session 为空时使用构建时的 defaultSession(默认是 WorkspaceSession(workspace, agentId));sessionKey 为空时依次试 SimpleSessionKey.of(sessionId)SimpleSessionKey.of(agentName)
  2. 传递到 hooksworkspaceContextHookmemoryFlushHooksessionPersistenceHookcompactionHook 都会同步该 ctx,他们在 offload / saveTo 时都能读到 sessionId
  3. 联动 userIdRefAtomicReference<String> 被顶下 userId,默认 NamespaceFactory → List.of(userId) 会以该 userId 作为路径前缀,从而多租户透明隔离。
  4. 预加载状态:若 session && sessionKey 都有,调用 delegate.loadIfExists 覆盖当前 Memory。不存在则什么都不动。

默认与自定义 Session

多用户隔离的两个层面

  • 会话层sessionId 决定 context/<sessionId>/sessions/<sessionId>.jsonl 独立。
  • 文件层userId + NamespaceFactory 决定文件操作路径前缀(默认 LocalFilesystemWithShell 会读 userIdRef)。

会话索引

MemoryFlushManager.offloadMessages 调完后,WorkspaceManager.updateSessionIndex(agentId, sessionId, summary) 会合并写 sessions/sessions.json,agent 在另一轮可以走 session_list 工具查看“该 agent 历史上都跟谁聊过”。

相关文档

  • 工具session_search / session_list / session_history 的入参
  • 记忆offloadMessages 什么时候被调,怎么反过来被 memory_search 利用
  • 文件系统userIdRef + NamespaceFactory 的多租户路径隔离
  • 架构SessionPersistenceHook 在 PostCallEvent / ErrorEvent 中的位置