跳转到内容

状态与存储

State & Storage 是 Build Agents 的第二步:在 构建 Agent 之后阅读,并在 服务与集成 之前完成。它把一个可运行 runtime 变成有明确 memory、recovery 和 distribution 边界的 runtime。

状态和存储属于 Build Agents,因为存储选择会在运营前定义 agent 的 runtime contract。在暴露给运营者前,应先由代码接好这些边界:managed config、mailbox dispatch、thread state、profile state 和 event history 都依赖已注册的 store。

  • thread / run 数据放在哪里
  • runtime config、mailbox job 与 profile/shared state 放在哪里
  • 哪些 state 属于 StateKey、Thread state、ProfileKey 或外部存储
  • 哪些 context 应通过插件注入,而不是硬编码进 prompt
  • 状态键和合并策略怎么组织
  • 每一轮究竟把多少上下文送给模型
  • sub-agent 派生子 thread 时,父子层级如何建模

Thread 携带可选的 parent_thread_id。当 sub-agent run 第一次物化子 thread 时,runtime 会用 RunActivationSnapshot.trace.parent_thread_id(或旧记录里的 RunRequestSnapshot.parent_thread_id)填充该字段。 ThreadStore 暴露 list_child_threadsvalidate_thread_hierarchydelete_thread_with_strategy(reject | detach | cascade),让调用方显式选择子 线程的处理策略。默认 Detach 会保留子线程并清空它们的 parent_thread_id。 默认的 delete_thread_with_strategy 在「子线程更新 + 最终删除」之间不是原子 操作;并发写场景下应当用事务或栅栏化的实现覆盖;file、PostgreSQL 与 NATS-buffered 后端已经有原生覆盖。

分页:list_threads_query(&ThreadQuery) 支持 parent_filterAnyRootParent(parent_id))与 resource_id 过滤,游标在 decode 时会校验原始 query 形状。list_message_records(thread_id, &MessageQuery) 提供带序号窗口、 asc/desc 排序、可见性过滤与产生 run 过滤的消息分页。

  1. 先从 构建 Agent 开始,确认 runtime、provider、tools 和 plugins。
  2. 状态管理,选择 run、thread、shared 或 profile state。
  3. 状态与快照模型,理解插件如何通过 PhaseContextStateCommand 和 snapshot mutation 管理状态。
  4. 使用文件存储使用 Postgres 存储NATS Store 确定持久化后端。
  5. Shared State 跨 thread 与 agent 类型共享持久状态。
  6. mailbox、config、profile、trace/eval 和 event durability 边界明确后,再进入 服务与集成

当前内置 store 覆盖 memory、file、PostgreSQL、SQLite mailbox 与 NATS JetStream。按需要的持久化边界选择最小后端:

能力MemoryFilePostgreSQLSQLiteNATS
Thread/run projectionsyesyesyesno通过 NatsBufferedThreadStore decorator
Managed configyesyesyesnono
Profile/shared stateyesyesnonono
Canonical eventsyesnoyesnono
Protocol replay logyesnoyesnono
Outbox/checkpoint repairyesnoyesnono
Stream checkpointsyesnoyesnono
Versioned registryyesyesyesnono
Mailbox jobsyesnono单节点持久分布式持久

NatsBufferedThreadStore 可以包裹任意 thread/run 后端,通过 JetStream WAL 合并 checkpoint 写入。

Awaken 区分 runtime execution state 和 server control plane。Runtime 开发可以 只用进程内 AgentRuntime、commit coordinator,以及 profile/shared state store。 Server 开发会在同一个 runtime 外围增加 mailbox dispatch、canonical events、 protocol replay、config versioning、audit,以及 eval/trace 持久化。

数据契约Runtime-only 使用Server 使用
Thread 与 run 投影ThreadRunStore + CommitCoordinatorAgentRuntime 的 checkpoint 读写边界同一批投影,通常通过 server staged coordinator 提交
待处理用户输入与 dispatch 生命周期MailboxStore除非应用自己构建队列,否则不需要持久后台 run、resume、cancel、interrupt、HITL、protocol delivery
Canonical eventsEventStore基础进程内运行不需要持久 event list/SSE resume 与 protocol replay
Outbox/staged idsStagedCommitCoordinator / ThreadCommitStagedOutcomeRuntime 不观察 event/outbox idsServer/store 实现提交后发布 event 与 outbox ids
托管 registry configConfigStoreConfigRuntimeManager可选;代码可以直接构造 registry/v1/config/*、管理控制台编辑、audit restore、hot publication
Admin auditAuditLogStore可选版本历史、restore 与操作者追踪
Profile/shared stateProfileStore、shared-state store跨 run memory 与 learned priors通常由所有 served runs 共享
Trace/eval 数据trace store、eval stores可选测试/运维工具Admin trace views、trace-to-fixture curation、eval datasets/runs

Runtime commit outcome 会刻意保持窄边界:ThreadCommitOutcome 只表示 runtime commit 成功/失败。需要 canonical event ids、server event ids 或 outbox ids 的 server-side 实现应使用 server-contract staged outcome。

只实现你需要的边界,并确保 runtime 写入走拥有同一份底层数据的 coordinator:

  • ThreadRunStore:thread messages、run records、projections 和 checkpoint reads。
  • CommitCoordinator:durable runtime writes;不要用不相关的 handle 写 runtime checkpoint。
  • ConfigStoreVersionedRegistryStore:managed config、publication、restore 和 pinned registry replay。
  • ProfileStore 或 shared-state store:跨 run memory。
  • MailboxStorePendingMessageStore:resumable dispatch、HITL 和 pending input steering。

新增后端前,先参考已有 store 和测试: crates/awaken-doctest/examples/thread_store_trait.rscrates/awaken-stores/src/memory/crates/awaken-stores/src/postgres.rscrates/awaken-stores/src/pending_message_store.rscrates/awaken-stores/tests/

Mailbox job 是 run-dispatch 控制面记录,和 thread/run checkpoint store 是两套边界。因此可以组合使用,例如 PostgreSQL 保存 thread/run 数据,同时用 NATS mailbox 负责分布式调度。

Mailbox dispatch status 是 delivery lifecycle。Acked 表示 dispatch 已被接受或 消费;执行是否成功要看关联的 RunRecord.status、termination reason 和 canonical events。

后端适用场景边界
InMemoryMailboxStore测试、本地开发、嵌入式单进程运行。只在进程内有效;进程退出后 queued dispatch 会丢失。
SqliteMailboxStore单节点服务需要持久 mailbox job,但不想运行 NATS。使用本地存储持久化,但不是水平扩展 mailbox 后端。
NatsMailboxStore多个 server 实例需要共享 dispatch 所有权、wakeup 和 lease recovery。需要 JetStream 和 KV;所有实例必须使用同一组 stream、bucket 和 durable consumer。