• 简体中文
  • v6.5.2
  • 持久化

    持久化让会话可以跨进程恢复,也让产品界面拥有稳定的会话标识。

    恢复后的会话可以重新填充任务列表、执行记录、制品和交付摘要,不必重放已经完成的运行。

    A3S Code 会持久化三种相关但不同的对象:

    对象写入方恢复入口用途
    SessionSnapshotV1session.save()autoSaveagent.resumeSession(id, options)恢复一个带版本号的完整代次,其中包含对话、制品、追踪、运行记录、验证报告与子智能体任务快照。
    循环检查点智能体循环运行期间session.resumeRun(runId)从上一个完成的工具回合边界继续被中断的运行。进程内正常完成的运行会删除这个检查点。
    工作流检查点parallelResumable / 工作流阶段parallelResumable(specs, workflowId)进程重启后跳过已经完成的编排步骤。

    文件会话存储

    Rust
    Node.js
    Python
    Go
    Rust
    use a3s_code_core::{Agent, SessionOptions};
    let options = SessionOptions::new()
    .with_session_id("release-review")
    .with_file_session_store("./.a3s/sessions")
    .with_auto_save(true);
    let session = agent
    .session_builder("/repo")
    .options(options)
    .build()
    .await?;
    session.send("审查发布就绪情况", None).await?;
    session.save().await?;

    Go 通过 FileSessionStoreDir 选择内置文件存储;自定义 SessionStore trait 实现仍属于 Rust 嵌入能力。

    原子快照代次

    session.save() 会把当前持久化状态收集成一个 SessionSnapshotV1,并且只调用一次 SessionStore::save_snapshot。信封包含:

    • schema_versionSessionData
    • 工具制品
    • 追踪事件与运行记录
    • 验证报告
    • 委派的子智能体任务快照

    文件存储会把完整 JSON 信封写入并同步临时文件,然后原子替换 <session-id>.json。因此读取方看到的是上一代或下一代,不会读到“新对话搭配旧 运行或追踪分片”的组合。内存存储在同一把锁下发布同一个聚合快照。两者都报告 SessionStoreCapabilities { atomic_session_snapshots: true }

    历史文件仍可读取。裸 SessionData 会在加载时与旧制品、追踪、运行、验证和 子智能体分片位置合并,再通过 v1 内存形状恢复。保存新聚合快照后,单个信封会成为 权威代次。已经具有聚合外形、但模式损坏或版本不支持的文档会直接被拒绝,不会重新 解释成旧式数据。

    自定义存储必须显式实现 save_snapshot。默认实现返回错误,不会把聚合快照拆成 多次独立写入,也不会把空操作当成成功。默认 load_snapshot 只用于尽力组装旧式 数据;宿主可以通过 capabilities() 区分这种行为与原子后端。

    恢复

    Rust
    Node.js
    Python
    Go
    Rust
    use a3s_code_core::SessionOptions;
    let resumed = agent
    .resume_session_async(
    "release-review",
    SessionOptions::new().with_file_session_store("./.a3s/sessions"),
    )
    .await?;

    resumeSession 恢复的是已保存的会话快照。它不同于 resumeRun:用户继续一个 已保存对话时用 resumeSession;只有存在中断运行的检查点时,才用 resumeRun(runId)。恢复操作会在恢复任何历史或运行时证据前先校验快照模式。

    记忆与会话

    会话持久化保存对话和可回放证据;记忆保存可复用任务事实。当你需要既可 恢复、又能从重复任务中学习的工作流时,两者一起使用。

    循环检查点与运行恢复

    配置了 SessionStore 后,智能体循环会在每个完成的工具回合之后持久化一个 LoopCheckpoint。边界策略很严格:检查点在工具回合之间产生,绝不在工具 执行中途产生。如果进程在某个工具执行时崩溃,那一轮的工作会在恢复时丢失,由 大语言模型从上一个检查点重新推演——在错误边界一侧重跑非幂等工具(写入、命令行) 比让模型重新思考更糟。

    session.resumeRun(runId)(Node)/ session.resume_run(run_id)(Python)/ session.ResumeRun(ctx, runID)(Go)—— 对应核心的 AgentSession::resume_run(checkpoint_run_id)——会加载该运行标识下 最新的检查点,并从最后一个边界回放循环。由于检查点存放在共享存储中,恢复可以 发生在任何共享该存储的节点上。累计计量会延续而不是从零重启:total_usagetool_calls_count 从检查点继续累加。恢复出的工作会分配新的运行标识;新旧运行 的关系由宿主通过元数据表达,框架不予解释。

    已正常完成的运行不通过 resumeRun 恢复;它们的最终状态应通过 runs()runEvents(runId)、制品、验证报告和会话快照查看。

    TypeScript
    const result = await session.resumeRun('run-abc123');
    console.log(result.totalTokens);
    Python
    result = session.resume_run('run-abc123')
    print(result.total_tokens)
    Go
    result, err := session.ResumeRun(ctx, "run-abc123")
    if err != nil {
    return err
    }
    fmt.Println(result.Usage.TotalTokens)

    Go 也通过 ParallelResumable(ctx, specs, workflowID) 暴露工作流检查点编排。

    当会话没有配置 sessionStore(或给定标识下不存在检查点)时, resume_run 会拒绝。SessionStore 新增了 save_loop_checkpoint / load_loop_checkpoint / delete_loop_checkpoint;文件存储采用崩溃安全的原子 写入。LoopCheckpoint::ensure_loadable() 在反序列化之后立即被调用,会拒绝 来自未来且不兼容的检查点模式版本,因此 resume_run 和实时运行的接收端都不会 对无法读取的检查点采取行动。

    参见 CHANGELOG [3.3.0]——"Loop checkpoints + run resumption"——以及 [3.4.0] 的 "LoopCheckpoint::ensure_loadable()"。

    工作流检查点

    WorkflowCheckpoint 是工具回合 LoopCheckpoint 在上一层的步骤边界对应物: 它把已完成的编排步骤记入日志,使被中断的工作流从最长的已完成前缀恢复。它的 字段是 schema_versionworkflow_idstepscheckpoint_ms,模式由 WORKFLOW_CHECKPOINT_SCHEMA_VERSION 常量固定。恢复的运行会跳过已记录的步骤, 只重新派发其余的。

    SessionStore 新增了 save_workflow_checkpoint / load_workflow_checkpoint / delete_workflow_checkpoint(默认为空操作;文件存储采用崩溃安全的原子写入)。 来自未来且不兼容的模式版本会在加载时通过 WorkflowCheckpoint::ensure_loadable() 被拒绝。

    这与编排语法配套使用——参见 编排多机执行

    参见 CHANGELOG [3.4.0]——"WorkflowCheckpoint"。

    在其他节点恢复

    两种检查点类型都是可序列化的。配合共享的 SessionStore 和可插拔执行器,宿主 就能在与启动节点不同的节点上恢复被中断的运行或工作流——框架持有可序列化 契约,宿主负责放置与传输。

    运维注意事项

    包含私有提示词、工具输出或路径的存储不应公开提交。