做 AI agent 时,很多人会自然地给它一个工作目录,然后把生成文件、检索结果、临时 JSON、日志、缓存都往里面塞。最开始看起来没什么问题,但一旦出现恢复、回放、多 worker、权限隔离或人工 review,这种“什么都放一起”的 workspace 会很快失控。
Workspace 不是一个文件夹名字,而是 Agent 运行时状态的边界设计。
建议先配合 AI agent Artifact 设计、AI agent 数据脱敏实践、AI agent 缓存与失效策略 和 AI agent Checkpoint 与断点恢复 一起看。
先给结论:Workspace 至少分 5 层
| 层级 | 放什么 |
|---|---|
| source | 允许读取的源文件和业务上下文 |
| artifacts | plan、evidence、draft、decision 等中间产物 |
| runtime | 当前 Run 的临时状态、checkpoint、锁、lease |
| cache | 可复算但为了性能保留的数据 |
| outbox | 真实外发前待确认或待发送的结果 |
如果这 5 层混在一起,恢复、清理和权限都会变得困难。
真正到了多租户、多任务并发和人工 review 现场,分层还不够,还需要把“谁的状态、哪次 Run 的状态、能被谁看到”编码进路径和命名规则里。否则目录虽然分了,边界依然模糊。
一、Source 层应该尽量只读
Source 层是 agent 用来理解业务上下文的输入来源,比如:
- 项目文档
- 用户上传文件
- 已授权的业务数据快照
这层最稳的默认策略是只读。即使 agent 可以产生新文件,也应写入 artifacts 或 runtime 层,而不是直接覆盖 source。
如果确实有“基于 source 生成修订建议并回写”的场景,建议也先写入单独的 patch artifact 或 outbox,而不是直接覆盖原文件。这样人工审批、版本回退和差异比较才有抓手。
二、路径约定要显式,别让目录结构靠习惯演化
分层只有落到可执行的路径约定里,才真正能被系统依赖。一个常见布局可以是:
/workspace/{tenantId}/{projectId}/{runId}/
source/
artifacts/
plan/
evidence/
draft/
decision/
runtime/
checkpoints/
locks/
lease/
cache/
outbox/
audit/
这里有两个关键收益:
tenantId/projectId/runId让隔离边界从文件命名阶段就开始成立runtime/checkpoints、runtime/locks、outbox这些目录让恢复和外发逻辑可以直接依赖路径约定
如果没有路径 contract,脚本、后台任务和审批页面最终都会各自假设目录位置。
三、Artifacts 层负责保存“值得被复用和审查”的结果
Artifacts 层不是缓存,也不是日志。它保存的是会被:
- 人工 review
- checkpoint 恢复
- 最终输出引用
- 后续任务复用
的中间产物。
目录示意:
/workspace/{runId}/artifacts/
plan/
evidence/
draft/
decision/
按类型拆目录,后续权限控制和清理都会更容易。
更进一步,artifacts 层最好不要和 runtime 共用文件名。例如 draft/current.json 这种命名很容易让“可审版本”和“当前过程态版本”混淆。对于可审对象,建议直接用不可变命名,如 draft/draft_004.json,再通过 decision 或索引声明谁当前生效。
四、Runtime 层只为当前 Run 服务
这层典型内容包括:
- 当前 step state
- checkpoint snapshot
- worker lease
- 任务锁
- 临时拼装结果
这部分数据最容易过期,也最不适合被人工长期依赖。一个实用原则是:runtime 层的数据应该可以在合理情况下被重建。
也正因为 runtime 可重建,它就更适合放这些强时效对象:
- worker lease 文件
- 当前 step cursor
- 临时拼装 prompt 上下文
- 尚未提交的工具原始响应
这些内容如果被审批台直接依赖,界面看到的就会是“过程中的某一瞬间”,而不是稳定对象。
五、并发和隔离规则要写进 workspace 设计里
当多个 worker 或人工节点同时访问 workspace 时,问题往往不在目录有没有分层,而在并发规则没有写出来。至少要回答:
| 问题 | 建议 |
|---|---|
| 谁能写 runtime | 只有当前持有 lease 的 worker |
| 谁能写 artifacts | agent 与人工审批通过统一 API,不直接覆盖 |
| 谁能发 outbox | 只有通过 policy 和 review 的 dispatcher |
| 谁能删 cache | 只允许后台清理器按规则执行 |
如果这些规则只是口头约定,最后很容易出现“人工顺手改了 runtime 文件”或“清理任务把还在用的 cache 删掉”。
六、Cache 层要和 Artifact 明确分开
很多团队会把 evidence 和 cache 混为一谈。区别在于:
| 项目 | Artifact | Cache |
|---|---|---|
| 是否为业务过程产物 | 是 | 否 |
| 是否需要审查 | 经常需要 | 通常不需要 |
| 丢失后能否重算 | 有时不该重算 | 通常可以 |
| 是否受版本影响 | 强相关 | 也相关,但更偏性能 |
把 artifact 当 cache 清掉,会让审查和恢复失效;把 cache 当 artifact 留太久,又会制造脏数据和权限风险。
因此 cache key 最好至少带上这些维度:
- tool 或 data source 版本
- 权限上下文或租户身份
- 输入摘要 hash
- 过期时间或 invalidation token
否则同样一条查询,在不同权限或不同 schema 下,可能命中同一份错误缓存。
七、Outbox 需要单独存在,别混进 draft
所有准备对外发送的内容,都值得进入 outbox:邮件、Webhook、状态变更、正式发布内容。这样能明确区分:
- 只是生成了草稿
- 已经准备发送
- 已经真正发出
如果 outbox 混在 draft 里,系统很难知道一个外发动作到底进行到哪一步。
一个更工程化的 outbox 记录通常会明确状态:
| 状态 | 含义 |
|---|---|
prepared | 内容已生成,尚未审核 |
approved | 已通过人工或 policy 审核 |
dispatched | 已交给外发器 |
acked | 外部系统确认接收 |
aborted | 被取消或废弃 |
这样恢复系统、审计系统和人工审批台就能围绕同一组状态工作。
八、清理策略要按层设计,而不是一键删 workspace
| 层级 | 清理建议 |
|---|---|
| source | 不由 agent 清理 |
| artifacts | 按保留期或业务完成状态清理 |
| runtime | Run 结束后短期清理 |
| cache | 按 TTL、版本和权限失效清理 |
| outbox | 发出或废弃后归档 |
最常见的事故是“为了解决空间问题,把整个 workspace 删了”,结果历史 artifact 和恢复线索一起丢了。
清理如果做得更细一点,通常会分成两类作业:
- 在线瘦身:清理过期 runtime、无主锁、过期 cache
- 离线归档:归档 superseded artifact、已完成 outbox、审计快照
这样既能控制空间,也不会误删那些仍然对恢复和审计有价值的对象。
九、上线后要看 workspace 健康指标
Workspace 分层是否有效,不是看目录多漂亮,而是看运行后有没有减少混乱。可以重点看:
| 指标 | 说明 |
|---|---|
| runtime 残留量 | 判断 Run 结束后是否及时清理 |
| orphan outbox 数量 | 判断是否存在悬而未决的外发项 |
| cache 命中率与误命中率 | 判断缓存边界是否合理 |
| artifacts 与 runtime 交叉引用异常数 | 判断边界是否被破坏 |
| 多 worker 冲突次数 | 判断 lease 与锁是否生效 |
如果 workspace 设计上线后这些指标没有改善,说明结构分层还停留在文档层,没有真正进入系统行为。
十、失败案例:临时结果和正式草稿混在一起,审批界面显示错版本
一个内容 Agent 会生成多轮草稿,但全部放在同一个 draft.json 里覆盖更新。审批界面有时看到的是最新临时草稿,有时看到的是已审核版本,根本分不清哪份才该生效。
修复后,团队把 artifacts 和 runtime 分层:
- runtime 保存当前临时拼装结果
- artifacts/draft 保存可审版本
- decision 保存审批结果
问题的关键不是多一个目录,而是明确“哪些东西只是过程态,哪些东西已经值得被人看”。
十一、Workspace Checklist
- source、artifacts、runtime、cache、outbox 是否分层
- source 是否默认只读
- 是否定义了 tenantId / projectId / runId 级别的路径约定
- artifact 和 cache 是否边界清楚
- runtime 数据是否允许重建
- 并发写入、外发和清理规则是否明确
- outbox 是否单独记录外发状态
- cache key 是否包含版本、权限和输入摘要
- 清理策略是否按层定义,而不是一刀切
- 是否监控 runtime 残留、orphan outbox 和冲突次数
- 人工 review 和恢复是否都能依赖 workspace 结构
结语
AI agent 的 workspace 设计,本质上是在设计“哪些状态值得长期存在,哪些状态只是暂时存在”。分层清楚后,恢复、审查、清理、权限和性能问题都会更容易处理。
延伸阅读:


