把最快上手方式:用HarnessAgent在你笔记本上跑起来很容易,搬到生产环境是另一回事——多副本要共享会话、要隔离用户、要支持不可信代码执行、要在 pod 重启后接着上次跑。本页只讲单机 → 分布式生产的差异:哪些组件必须换、换成什么、为什么 builder 会在你漏配时直接抛IllegalStateException。
DistributedStore 一键配置所有分布式组件:
备选:aistio 托管 Store
若已部署 aistio 控制面,可由其托管 BaseStore / 沙箱锁与快照 / MessageBus / AsyncToolRegistry / TaskRepository / 可选 SessionTurnGate。仍需自备一个AgentStateStore(Redis/MySQL/Postgres/OSS);core 提供 getVersioned / saveIfVersion,但存储不在控制面:
--enable-hosted-store(生产建议 Postgres)。withAgentStateStore 已含托管 TaskRepository;SandboxFilesystem 模式下的子 agent 后台任务需此路径。AgentStateStore 的 Redis/Postgres/MySQL/InMemory 支持 versioning CAS,其余后端仍为 LWW;多副本可选 turn gate + ConflictPolicy.FAIL 减少重复 turn,正确性靠 CAS。鉴权为共享 internal token,租户取自请求体——不适用于同一控制面上互不信任的多租户。queueDrain 为 destructive(读即 ack)。详见 分布式存储 — aistio 托管 Store。
一图速览:单机默认 vs 分布式生产
DistributedStore 能力矩阵
这些组件分别解决不同的生产问题:
AgentStateStore:保存 Agent 的运行时会话状态,包括对话历史、压缩摘要、权限规则、Plan Mode 状态和 tool state。它决定一个请求落到另一台机器、或进程重启后,Agent 能不能继续同一个(userId, sessionId)。BaseStore:给RemoteFilesystemSpec提供共享 KV 文件存储,用来承载MEMORY.md、memory/、skills/、sessions/等 workspace 路径。多副本部署时,它让不同 pod 看到同一份长期记忆和共享文件。SandboxSnapshotSpec:保存沙箱 workspace 快照。沙箱容器销毁、pod 重启、下一次请求落到新节点时,它负责把上一次的工作区恢复回来,避免pip install、生成文件、临时项目状态全部丢失。SandboxExecutionGuard:对同一个 sandbox slot 的命令执行做跨节点串行化。AGENT/GLOBAL等共享 scope 下,多个副本可能同时对同一个沙箱执行命令;guard 用 Redis/MySQL 锁避免并发写 workspace、并发启动/停止 sandbox 等竞态。
OSS 不提供核心校验链路:SandboxExecutionGuard——对象存储不适合做分布式锁。需要 sandbox 并发控制的 OSS 用户,用DistributedStore.builder()混入 Redis 的 guard 即可。
filesystem(RemoteFilesystemSpec)+ 没换stateStore(...)也没配distributedStore(...)→build()抛IllegalStateException。filesystem(SandboxFilesystemSpec)+ 本地AgentStateStore→build()正常通过但打一条 warning 日志,提醒你沙箱状态不能跨 JVM 恢复;生产环境务必配distributedStore。
1. 状态存储:先把 AgentState 放对地方
推荐:直接用distributedStore(...)一键配置,不需要手动设置stateStore。下面的详细表格供需要单独控制AgentStateStore的高级用户参考。
AgentState(对话上下文、压缩摘要、权限规则、Plan Mode 状态、tool state)跨进程恢复的唯一通路就是 AgentStateStore。
Redis 三种 client adapter 都通过
RedisAgentStateStore.builder() 切换:
sessionId 只够单租户。生产应在每次调用的 RuntimeContext 上同时设置 userId 与 sessionId,防止跨用户串读——存储按 (userId, sessionId) 二元组寻址每个槽位(RedisAgentStateStore 把 userId 折进 Redis key,MysqlAgentStateStore 折进主键)。其他维度(租户、agent)自行拼进 sessionId 字符串:
2. Filesystem 模式 & IsolationScope:决定”谁和谁共享文件”
三种模式快速回顾(详见 filesystem):IsolationScope 是多用户隔离的核心钥匙。共享存储和沙箱两种模式都用同一套 scope 决定命名空间分桶:
anonymousUserId 是个生产细节——很多场景下 RuntimeContext.userId 可能为 null(系统任务、调度器触发、admin 操作),fallback 别用空字符串,否则所有匿名调用会聚到一个共享桶。
3. Remote 模式的 BaseStore:KV 选型与”不要把 OSS 当 KV 用”
RemoteFilesystemSpec 建在一个 BaseStore 接口之上。内置实现两种:
那 OSS / NAS / S3 怎么放进来?
不要为了 OSS 写一个BaseStore 实现——MEMORY.md / memory/YYYY-MM-DD.md / agents/<id>/context/<sid>/ 每秒可能写几次,OSS 的延迟与 per-request 成本会立刻失控。正确分工是:
RemoteFilesystemSpec 的路由表
为避免不同子系统的 key 撞车,spec 把工作区路由切成多个命名空间段(每段独立):
每段下面再按
IsolationScope 切桶(USER → agents/<agentId>/users/<userId>/)。Redis key 大致长成 agentscope:store:item:agents\0X\0users\0alice\0memory\0memory/2026-06-02.md。
CompositeFilesystem:两层读+写穿透
RemoteFilesystemSpec.toFilesystem(...) 实际产出的是 CompositeFilesystem:底层一个不带 shell 的 LocalFilesystem(兜底读本地模板),顶层每条路由是一个 OverlayFilesystem(上层 RemoteFilesystem + 下层只读 LocalFilesystem 模板)。
效果:写永远落 Remote,读优先 Remote、没有再退回本地模板。这就是 Workspace 文档里讲的”两层读架构”在 Remote 模式下的具体形态——本地 <workspace>/AGENTS.md 是种子(团队 git 同步),Remote 一旦写入就接管。
WorkspaceIndex:可选 SQLite 索引
ls / glob / exists / grep——不开的话每次都全表扫 KV。WorkspaceIndex 是 best-effort 的 SQLite 文件(落在 <workspace>/.index/),失败会自动降级,不影响功能。
4. Skill 集中管理:选哪种 SkillRepository
Skill 优先级从低到高合成(详见 技能):Marketplace 存储源选型
skillRepository(...) 可重复调用;后注册的优先级更高,同名覆盖。
生产 checklist
- 优先
MysqlSkillRepository(writeable=false)或NacosSkillRepository——平台集中治理,agent 端只读;写回走管理台 + 审核流。 - 不希望 agent 看到
workspace/skills/?.disableDefaultWorkspaceSkills()。 - 开
enableSkillManageTool让 agent 自己起草新 skill 时,必须配enableSkillPromotionGate(...);生产严禁autoPromote=true。 NacosSkillRepository是AutoCloseable——Spring@PreDestroy或者try-with-resources关掉它,否则会泄露订阅。
5. 需要 shell:选 Sandbox + 必配 Snapshot
什么场景必走沙箱:- 模型可能跑不可信代码(Python / shell /
npm install/ 编译) - 需要跨调用恢复整个工作目录状态(
node_modules、生成文件、pip install后的环境) - 多用户硬隔离(不能让一个用户的进程看到另一个用户的)
五种沙箱实现
Snapshot 是沙箱的”分布式生命线”
推荐:使用沙箱默认是”瞬时”的——下一次distributedStore(...)后,SandboxSnapshotSpec和SandboxExecutionGuard都会自动注入到SandboxFilesystemSpec,不需要手动配置。下面的表格供需要单独控制快照实现或使用LocalSnapshotSpec的场景参考。
call() 可能起在另一个节点的新容器里,之前 pip install / 写入的所有产物全丢。SandboxSnapshotSpec 把工作区打成 tar 持久化,下次 call() 自动 hydrate 回新容器。
distributedStore(...) 后,快照和执行锁都会自动注入,不需要在 SandboxFilesystemSpec 上手动配置。如果只是要改 OSS bucket / prefix,优先在创建 OssDistributedStore 时配置;只有需要完全自定义 SandboxSnapshotSpec 时,才在 SandboxFilesystemSpec 上显式覆盖。
沙箱执行节点串行化:SandboxExecutionGuard
SESSION / USER scope 下天然按 session/user 分桶,并发不会撞。但 AGENT / GLOBAL scope 多副本部署时,可能同时有 N 个节点要在同一个 sandbox slot 上 exec——会撞。distributedStore(...) 会自动注入对应 store 的执行锁:
推荐仍然通过
DistributedStore 注入执行锁:
SandboxFilesystemSpec 上显式覆盖:
SandboxExecutionGuard 接口接入 Zookeeper、etcd 等其他锁。
Workspace projection:把工作区里的种子投到沙箱
SandboxFilesystemSpec 默认会把 AGENTS.md, skills, subagents, knowledge, .skills-cache 五个 root 打 tar 在沙箱启动时 hydrate 进去(内容 hash 比对、增量重写)。要调整:
AgentRun 特有:NAS / OSS mount
AgentRunFilesystemSpec 是唯一原生支持多 sandbox 实例共享同一个目录的实现(通过 NAS mount);如果业务是”一个用户在不同 session 里看到同一份 workspace”,用 AgentRun 比每次 hydrate snapshot 更高效:
AgentRunNasMountConfig / AgentRunOssMountConfig 源码。
6. 多副本部署 checklist(综合)
把上面单点替换串成一张表:7. 一个完整的生产 builder 模板
Agent 在调用之间是无状态的——单例即可服务并发请求。每次call() 通过 RuntimeContext 的 (userId, sessionId) 定位状态,互不干扰。
RuntimeContext 标识用户和会话。不同 session 在同一个 agent 实例上自动并行:
8. 常见坑位
- 忘记传
RuntimeContext——不传sessionId时所有请求共享defaultSessionId的状态,造成串台。在多用户场景下,每次call()都应通过RuntimeContext.builder().userId(...).sessionId(...).build()传入,确保各会话状态隔离。参见 Agent — 多用户并发。 java.nio.Files写工作区——在沙箱 / Remote 模式下落到错的位置。永远走agent.getWorkspaceManager()。例外:builder 装配时的种子文件(initWorkspaceIfAbsent之类)那时还没有运行时上下文,用java.nio.Files是 OK 的。tools.json的allow会过滤内置工具——用白名单时务必把read_file/memory_search/agent_spawn这些保留下来,否则整套内置工具一起被砍。IsolationScope改了,旧数据不会自动迁移——上线前定下来,别上线后改。改了等同于”换了一个命名空间”。- 本地
AgentStateStore单机限制:K8s 多副本部署里如果把分布式文件系统和本地JsonFileAgentStateStore搭配,第一次 build 就抛IllegalStateException,这是设计如此——告诉你别把 agent 状态留在某个 pod 的本地磁盘上。 NacosSkillRepository不关闭——会泄露订阅,集群规模大了 Nacos 会喊。Spring 注入用@PreDestroy或destroyMethod="close"。- OSS / NAS 走完 IAM 再上线——
OssSnapshotSpec的 AK/SK 是平台凭证;用 RAM Role + STS 临时凭证更稳。 - 本地
AgentStateStore+ 沙箱模式仅用于开发——构建时的 warning 日志是故意的,生产环境别忽略。
相关文档
- Quickstart —— 端到端跑通第一个
HarnessAgent - Harness 架构 —— 各能力如何协作
- 上下文与 AgentState ——
AgentState/AgentStateStore/ 跨节点恢复 - 上下文压缩 —— 对话摘要、工具结果卸载、溢出恢复
- Workspace —— 目录布局、两层读、
tools.json - Filesystem —— 三种部署模式、
IsolationScope - Sandbox —— 沙箱细节、五种实现、快照机制
- 技能 —— 四层合成、市场存储源、自学习闭环
- Middleware —— 自定义观测 / 限流 / fallback 中间件