只要 AI agent 从“团队内部工具”走到“平台能力”,多租户隔离就会立刻从安全附加项变成主系统问题。因为你不再只是运行一个 agent,而是在同时运行成百上千个租户的 workspace、缓存、工具能力和私有数据。
很多系统前期把多租户理解成“每个租户一个目录”。这远远不够。真正的问题往往出在看不见的共享层:包缓存、模型缓存、日志检索、临时文件、网络出口和失败后的清理策略。目录隔离做对了,系统照样可能因为这些共享层把租户边界打穿。
建议先结合 AI agent Workspace 状态分层、AI agent 缓存与失效策略、AI agent Admission Control 与配额闸门 和 AI agent Worker Lease 与心跳机制 一起看。
多租户问题往往先出在共享层,而不是业务层
最常见的隔离面可以先拆成 5 类:
| 隔离面 | 要隔离什么 |
|---|---|
| 文件系统 | repo、草稿、artifact、临时文件 |
| 缓存 | dependency cache、tool cache、retrieval cache |
| 网络 | 出口策略、私网访问、域名白名单 |
| 观测 | 日志查询范围、trace 可见性、报表口径 |
| 资源配额 | CPU、内存、并发、磁盘和队列容量 |
如果你只盯着“工作目录”,却没定义缓存与网络边界,系统很快就会在共享层出现脏读、串租户和 noisy neighbor。
Workspace provisioning 不是创建目录,而是发放一整套受控执行契约
一个更稳的 workspace provisioning 至少要同时决定:
- 这次任务属于哪个 tenant 和哪个 run
- 它拿到什么基础镜像或环境模板
- 它能用哪些缓存、哪些只能私有
- 它允许访问哪些网络资源
- 完成后如何回收、如何保留证据、如何清理残留
把 provisioning 想成“创建目录”会太轻;更准确的理解,是给这次执行发一份环境契约。
失败案例:依赖缓存没分租户,A 租户的私包元数据出现在 B 租户任务里
某平台为了节省安装时间,把依赖缓存做成了全局共享。结果某个租户的私有包索引和认证信息被下一个租户任务命中。虽然最终没有直接下载成功,但 trace 里已经暴露了包名和内部 registry 结构。
这类事故说明,缓存从来不是“纯性能层”,而是安全边界的一部分。只要缓存键没有 tenant 维度,或者回收策略不完整,系统就很容易把前一个租户的上下文残留给后一个租户。
修复通常要同时做三件事:
- 缓存键引入 tenant 或 policy scope
- 高敏任务禁用共享缓存或转私有缓存槽
- 回收阶段加入残留扫描和强制清理
资源隔离和 admission control 应该联动,而不是各自独立
多租户隔离的另一个常见盲区,是把资源隔离交给容器配额,把 admission control 交给队列系统,二者互不沟通。这样一来,系统虽然“形式上”有配额,但高价值租户仍可能被低价值大批量任务挤爆。
更稳的做法通常是:
- provisioning 时带入 tenant tier 与 protected capacity
- admission control 结合租户等级决定是否立即分配 workspace
- 观测层单独跟踪 per-tenant 的队列时间、失败率和资源耗用
隔离不是只防越权,也要防资源被挤占。
Tenant Isolation Checklist
- 文件、缓存、网络、观测和资源是否都定义了租户隔离边界
- workspace provisioning 是否包含 tenant、run、policy scope 和 cleanup plan
- 高敏任务是否不会落到共享缓存或开放网络出口
- admission control 是否与租户等级和资源供给联动
- 任务结束后是否会清理残留文件、认证材料和临时缓存
- 是否能对单租户做审计、限流和紧急收缩,而不影响全局系统
真正该担心的,不只是串数据
多租户 agent 平台最难的地方,不是“如何把每个租户放进独立目录”,而是如何控制那些不容易被看见的共享面。平台一旦在缓存、网络、日志或资源队列上缺少 tenant 维度,后面出的就不只是安全事故,还会是调度不公和系统性抖动。
延伸阅读:


