跳到主要内容

Agent 会话运行时

AgentSession 是 ai4j-agent 的长程运行态入口。它不是另一个模型客户端,也不是 CLI 会话的替代品,而是把一次 Agent 任务的状态收拢到一个可保存、可恢复、可观测的容器里。

1. 它解决什么问题​

普通 agent.run(...) 适合一次性调用:宿主把请求交给 runtime,拿到 AgentResult 后结束。

agent.newSession() 适合长程任务:

  • 每个 session 有稳定 sessionId。
  • 每个 session 有独立 memory。
  • runtime 事件会进入 session event log。
  • session 可以生成 snapshot。
  • 配置了 AgentSessionStore 后可以保存和恢复。
  • 旧的 Agent.run(...) 语义保持不变。

这让上层产品可以把 Agent 当作一个可持续运行的任务容器,而不是一串散落的模型请求。

2. 当前最小能力​

P0-A 先落地基础容器,不一次性塞入 sandbox、artifact、fork、rewind 等远期能力。

当前最小结构是:

Agent
├─ run(...) // 兼容的一次性运行入口
└─ newSession()
└─ AgentSession
├─ sessionId / metadata
├─ independent AgentMemory
├─ AgentSessionEventLog
├─ snapshot / restore
└─ optional AgentSessionStore

相关类:

类职责
AgentSession面向使用者的 session 运行入口
AgentSessionMetadatasessionId、创建/更新时间和业务 attributes
AgentSessionEventLogsession 内 runtime 事件日志接口
InMemoryAgentSessionEventLog默认内存事件日志实现
AgentSessionSnapshotmetadata、memory、events 的可携带快照
AgentSessionStore保存、读取、删除和列出 session snapshot
InMemoryAgentSessionStore进程内 store,适合测试和轻量 demo

3. 最小用法​

Agent agent = Agents.react()
.modelClient(modelClient)
.model("gpt-4.1")
.memorySupplier(InMemoryAgentMemory::new)
.build();

AgentSession session = agent.newSession();
session.putMetadata("project", "demo");

AgentResult result = session.run("先分析这个问题");

System.out.println(session.getSessionId());
System.out.println(result.getOutputText());
System.out.println(session.getEventLog().getEvents().size());
memorySupplier 必须返回独立实例

重点是 memorySupplier(...):每次 newSession() 都应该拿到独立 memory。否则多个 session 可能共享同一个 memory 实例。

3.1 异步运行:runAsync​

Agent.runAsync(request) 把一次运行调度到共享 daemon 线程池,返回 CompletableFuture<AgentResult>:

CompletableFuture<AgentResult> future = agent.runAsync(
AgentRequest.builder().input("分析这个问题").build());

// 需要自控线程池时传入自己的 Executor
CompletableFuture<AgentResult> onMine = agent.runAsync(request, myExecutor);

runAsync 是 Agent 上的薄封装——语义与 agent.run(request) 一致(不创建 session),只是换了执行线程;运行异常经 CompletableFuture 以异常完成传播。默认池线程是 daemon 的 ai4j-agent-async-N,长时间阻塞调用建议传业务自己的 Executor。

4. 保存和恢复​

如果需要让 session 跨请求或跨进程边界恢复,给 Agent 配置 AgentSessionStore。

InMemoryAgentSessionStore store = new InMemoryAgentSessionStore();

Agent agent = Agents.react()
.modelClient(modelClient)
.model("gpt-4.1")
.memorySupplier(InMemoryAgentMemory::new)
.sessionStore(store)
.build();

AgentSession session = agent.newSession();
session.run("记住这次任务上下文");
session.save();

AgentSession resumed = agent.resumeSession(session.getSessionId());
InMemoryAgentSessionStore 不适用于生产

InMemoryAgentSessionStore 只适合本地测试和 demo。生产环境应实现自己的 AgentSessionStore,例如 JDBC、Redis、对象存储或业务自有 session 表。

5. Snapshot 包含什么​

session.snapshot() 会生成:

字段内容
metadatasession id、created/updated 时间、attributes
memoryMemorySnapshot,由当前 AgentMemory 提供
eventsAgentSessionEvent 列表

snapshot 会做防御性复制。读取 snapshot 后修改返回对象,不应该反向污染当前 session。

6. Event Log 和 Trace 的关系​

AgentSessionEventLog 记录的是 session 内发生过的 runtime events,例如:

  • STEP_START
  • MODEL_REQUEST
  • MODEL_RESPONSE
  • TOOL_CALL
  • TOOL_RESULT
  • FINAL_OUTPUT
  • STEP_END
  • ERROR

它和 trace 不是同一个东西:

能力主要用途
Event Log恢复、调试、产品 UI 时间线、session 事实历史
Trace可观测性、外部 tracing/exporter、性能和调用链分析

session 创建时会从基础 AgentEventPublisher 复制已有 listener,并额外挂载 event log listener。因此已有 trace listener 不会因为使用 session 而失效。

7. 与 Memory / Compact 的边界​

P0-A 先提供 session 容器边界;P0-B 已补上基础 compact/context projection 能力。

推荐心智是:

SessionEventLog = 完整事件历史
AgentMemory = 可投喂模型的状态和历史
Compact = 把 event / memory / artifact 投影成更短的工作上下文

P0-B 已补上:

  • CompactPolicy
  • CompactResult
  • ContextProjector
  • ContextBudget
  • ContextReport
  • AgentSession.compact(...)
  • AgentSessionSnapshot.compactResult

使用细节见 记忆压缩与上下文投影器。

8. 会话事件契约(每次 memory 变更必有事件)​

会话事件日志不只是观测面——它是会话状态的可重建记录。runtime 对 memory 的每一次写入都会同步发布一条事件,因此把事件流按顺序折叠(fold)就能重建出与 memory.snapshot() 完全一致的 items + summary。

在新窗口打开全屏大图(含双主题、缩放与导出功能;右上角视角切换可分别聚焦写点事件化、restore 统一漏斗、投影与一致性)。

变更语义事件一览:

事件触发点payload
USER_INPUTmemory.addUserInput原始输入对象
MEMORY_ITEMS_APPENDEDmemory.addOutputItems追加的 item 列表
TOOL_RESULTmemory.addToolOutput(复用既有事件)AgentToolResult
TOOL_OUTPUT_REPLACEDsession.replaceToolOutput 异步补丁{callId, output}
MEMORY_COMPRESSsession.compact / autoCompactCompactResult(含压缩后 memory 快照)
SESSION_RESTOREDsession.restore(snapshot)——resume、fork、harness 快照补丁的统一入口安装的 MemorySnapshot 基线

配套投影器 SessionEventProjector:deriveSnapshot(events) / deriveItems(events) / deriveSummary(events) 把事件流折叠回 memory 状态,可用于审计、fork、离线分析与一致性校验(SessionEventConsistencyTest 断言投影==快照)。

注意两点:

  • MEMORY_COMPRESS 有两种 payload:携带 CompactResult 的是真正的 memory 重写;携带投影报告的是请求级 ContextProjection(只影响当次 prompt,不改 memory),投影器按 payload 类型区分。
  • 内存实现内部的压缩器(InMemoryAgentMemory.setCompressor)在 add* 内部重写,不单独发事件——该路径不在事件契约内。

8.1 离线读取:SessionLogReader​

审计、调试与 eval 场景不需要拉起 runtime——SessionLogReader.of(store) 在 AgentSessionStore 之上提供统一读入口:

SessionLogReader reader = SessionLogReader.of(store);

reader.listSessionIds(); // 全部会话 id
AgentSessionSnapshot s = reader.read(id); // 持久化快照(含 memory + events)
List<AgentSessionEvent> all = reader.events(id); // 全量事件(append 序)
reader.search(id, AgentEventType.USER_INPUT); // 按类型过滤
reader.search(id, e -> e.getSequence() > 100); // 谓词过滤
MemorySnapshot m = reader.project(id); // 折叠事件流回 memory 状态
reader.fork(id, "audit-copy"); // 复制快照为新会话,源不动

读操作全部不改存储;fork 在新 session id 下写入快照副本(事件历史一并深拷贝),是审计回放与分支实验的安全起点。project 与 SessionEventProjector 同源——对遵循事件契约写入的会话,投影结果与运行期 memory.snapshot() 一致。

9. 与 Coding Agent / CLI 的关系​

AgentSession 是通用 SDK 层能力。

ai4j-coding 和 ai4j-cli 后续可以在它之上继续绑定:

  • workspace
  • file/shell/git/browser tool state
  • approvals
  • checkpoint
  • compact
  • sandbox
  • TUI session timeline

但这些不应该反向污染 ai4j-agent 的通用运行时。SDK 层只保留通用会话、事件、memory、snapshot 和 store 合同。

10. 生产实现建议​

生产侧实现 AgentSessionStore 时建议注意:

  • session id 必须按租户或项目隔离。
  • snapshot 中不要保存明文 provider token。
  • event payload 可能包含 prompt、工具参数和模型输出,必要时应脱敏。
  • store 写入应该由业务决定同步或异步,不要让每个事件都强制阻塞主 loop。
  • 如果 memory 或 event 很大,应结合 compact / retention policy。

11. 下一步​

P0-A 只是运行态容器基础。完整 Agent SDK 还会继续推进:

  1. Plugin lifecycle hooks
  2. YAML Agent Blueprint
  3. Sandbox SPI
  4. Coding Agent sandbox routing
  5. CLI /sandbox 体验
  6. 远端 Agent Runner

完整路线见 AI4J Agent SDK 路线图。