云端 Agent 基础设施两条硬经验:CreaoAI 联合创始人的状态/代码解耦 + 凭据隔离¶
Ch11.013 云端 Agent 基础设施两条硬经验:CreaoAI 联合创始人的状态/代码解耦 + 凭据隔离¶
📊 Level ⭐⭐ | 26.8KB |
entities/cloud-agent-infrastructure-creaoai-state-code-credential-isolation-20260606.md
概述¶
CreaoAI 联合创始人总结的云端 Agent 基础设施两条硬经验——把桌面端 Agent 假设(用户 = 同一台机器 = 同一受信边界)搬到云端时踩出的两个核心设计原则:① 状态与代码解耦(frozen snapshot + hot-swap Runner,类比 OS 内核 vs 用户 home 目录)② 凭据隔离在执行边界之外(API bridge + IP 白名单 + 每次运行的短期 JWT)。这两条是云端 Agent 平台区别于桌面框架的根本性架构差异,而不是"加几个云服务就行"。
第一性原理:为什么桌面假设在云上失效¶
桌面 Agent 假设(隐含的"一次性都成立")¶
- 一个用户、一台机器、一个进程
- Agent 跟着笔记本电脑一起活
- 写本地文件系统
- API 密钥放在环境变量里
- 终端一关进程就没了
- 出了问题用户自己重试,缺个包就
pip install装进本地 Python - 状态 / 密钥 / 生命周期全在同一个受信边界里——不需要额外操心
云端 Agent 现实¶
- Agent 跑在每次全新启动的沙箱里
- 底下是多租户共享硬件
- 触发它的可能是:定时任务 / HTTP 请求 / 另一个 Agent
- 运行的时候用户多半不在线
- 沙箱里的代码不一定可信(LLM 根据可能带恶意的 prompt 生成)
- 文件系统要扛得住反复部署
- 凭据不能跟 Agent 放在一起
- 桌面端那些理所当然的东西——持久化 / 身份 / 网络信任 / 重试——到了云上全得自己建
关键判断:今天大部分 Agent 框架的设计前提是桌面环境——搬到云上必须重新设计,不是简单迁移。
教训一:把变化慢的和变化快的分开(状态/代码解耦)¶
第一版方案:粗鲁的"全重建"导致用户环境丢失¶
第一版实现:启动时检查快照里的 Runner 版本是否和最新部署一致,不一致就丢掉快照、从干净模板重建。 - 确实能用 - 也没人投诉 - 代价只是每次部署后第一次运行要重建环境 - 但——无人值守运行(unattended runs)暴露了这个方案的问题
失败场景:周一早上 9 点的定时任务不应该因为我们 8:55 做了一次部署就把用户环境搞丢。 - 我们实际上一直在违背一个隐含的约定:"你的环境会保持冻结,直到你自己去改它。"
根因诊断¶
用户环境和 Runner 代码的变更频率完全不同: - 用户自己决定什么时候改环境(可能 1 个月 1 次) - 我们每天要部署平台好多次
把两者打包在一起,每次部署都得做一个两难选择: - 要么容忍过时的 Runner(有安全风险) - 要么毁掉用户辛苦搭建的环境(违背承诺)
解决方案:借鉴 OS 的内核/home 分离¶
内核升级不影响用户的 home 目录,打安全补丁不需要格式化硬盘。
CreaoAI 在沙箱上画了同样的线:
启动流程: 1. 启动时照常从用户的冻结快照加载,不做任何修改 2. 然后单独热替换(hot-swap)Runner——这是关键创新
Hot-swap 步骤(6 步保证原子性): | 步骤 | 动作 | 目的 | |------|------|------| | 1 | 把新版 Runner 放到沙箱内的临时目录 | 准备 | | 2 | 用 node --check 做语法校验 | 保证在触碰运行中的代码之前就能发现问题 | | 3 | 原子替换:先解锁旧 Runner 的不可变标志 | 解除锁定 | | 4 | 把新文件复制过去 + chattr +i 锁上 | 写入 + 重新锁定 | | 5 | 把 chattr 命令本身藏起来 | 防止沙箱内的代码反向解锁 | | 6 | 清掉 V8 编译缓存(/home/user/.cache/v8-compile-cache/*) | 确保加载的是新文件而不是旧字节码 |
关键不变量: - 以上任何一步出错,直接杀掉沙箱换一个新的重试——不允许出现半升级的状态 - 整个替换耗时约 300 毫秒 - 当一次运行中发生了 Runner 替换,运行成功后会重新生成快照,把更新后的代码固化到用户镜像中,后续运行就不再需要替换了 - 平台部署永远不会丢弃用户的状态,只是把新版 Runner 融合进去——用户的包 / 文件 / 定制化配置全部原样保留
核心判断标准¶
对于云平台上持久化的每一样东西,都要问清楚,谁控制它的变更节奏? 如果用户和平台都要改同一个制品,迟早会出问题。按所有权边界把它拆开,让各自按自己的节奏演进。
应用启示: - 状态层 = 用户所有 = 冻结快照(用户主动改才动) - 代码层 = 平台所有 = 热替换(平台主动部署就动) - 两者通过 hot-swap 协议连接(保证原子性 + 可回滚) - 所有权清晰 → 各自的演化节奏独立 → 不会相互冲突
教训二:把凭据隔离在执行边界之外¶
云端 Agent 的安全前提¶
- 桌面 Agent:用用户的身份运行 + 用用户的密钥 + 在用户的机器上 + 访问用户的网络
- 云端 Agent:跑在共享硬件上 + 以无特权身份运行 + 面对开放互联网 + 执行的代码由 LLM 根据可能带有恶意的提示词生成
CreaoAI 原则:沙箱内的代码已经不可信。这是与桌面模型完全相反的安全前提。
核心原则¶
长生命周期的凭据绝不进入沙箱。
当 Agent 需要调用有认证要求的外部服务(Slack / GitHub / 用户自己的 API)时: - 它不持有令牌 - 而是向沙箱外部的 API 桥接层(API bridge)发一个本地 HTTP 请求 - 桥接层在宿主侧把 OAuth 令牌挂上去,再转发调用 - 响应返回的全程中,令牌从未进入过沙箱的内存或环境变量
桥接层身份验证:两层校验,刻意叠加¶
第一层:IP 白名单(网络层) - 桥接层只接受沙箱宿主所在内网网段的连接 - 其他来源的请求在网络层就被丢掉,不会走到应用代码 - 等于把桥接层绑定在了特定的物理基础设施上 - 外部拿到地址也没用
第二层:每次运行生成的短期 JWT(应用层) - 沙箱启动时,平台签发一个专属于本次运行的令牌 - 限定了用户 / 应用 / 会话和有效期 - 沙箱在每次调用桥接层时都要出示这个令牌 - 桥接层验签 + 检查有效期,通过后才去查用户存储的凭据并在服务端附上 - 即使沙箱被劫持,攻击者拿到的也只是一个随运行结束即失效、且只对当前会话有效的令牌 - 没有长期凭据可以泄露
边界归一:唯一双向通道¶
- 同一个桥接层也承载计费扣款 / 日志 / 指标的传出
- 所以它是沙箱边界(execution boundary)上唯一的双向通道
- 沙箱内部的一切,默认视为已被攻破
实战假设¶
假设明天有一次提示词注入(prompt injection)成功让 Agent 把
process.env发到外部 webhook,攻击者拿到的也只是一个短期 JWT,只在内网有效,运行结束即作废。
这个性质是 CreaoAI 能在共享基础设施上放心跑不可信代码的底气。
底层设计模式:4 条铁律¶
可靠、安全的云端 Agent 基础设施不需要什么新发明,它就是几条严格执行的原则:
- 状态在沙箱里,冻结到用户主动改变为止。(用户所有 = 慢变)
- 代码可热替换,不依赖状态。(平台所有 = 快变)
- 凭据在宿主侧,永远不进 Agent。(执行边界外)
- 同一条执行管道服务所有调用方,不管触发源是人 / 调度器 / 其他程序。
第 4 条最值得说: - 一个 executeAgent 函数同时处理 UI 点击 / 定时触发 / API 调用 - 计费 / 额度扣减 / 日志 / 可观测性信号,不管谁触发的运行,走的都是同一套逻辑 - 新增一种触发方式只是加一条路由,不涉及架构改动 - Agent 本身不知道、也不需要知道是谁启动了它
与桌面框架的本质区别¶
| 维度 | 桌面 Agent | 云端 Agent |
|---|---|---|
| 生命周期 | 跟着笔记本 | 跟着运行(沙箱) |
| 状态 | 本地文件系统 | 冻结快照 |
| 凭据 | 环境变量 | 沙箱外 API bridge + 短期 JWT |
| 代码更新 | pip install | 平台部署(带 hot-swap) |
| 触发源 | 唯一(用户交互) | 多样(人 / 调度 / Agent) |
| 用户在线 | 几乎一直在线 | 多半不在线 |
| 重试责任 | 用户 | 平台(计费/扣减/日志统一) |
| 多租户 | 不需要 | 必须(共享硬件) |
关键洞见:笔记本上的 Agent 跟那台笔记本绑死了。云端的 Agent 是技术栈里其他系统可以随时调用的函数。用户只需要写一次,平台负责让它扛住部署、在共享硬件上安全运行、接纳用户没有预想过的调用方。
实践启示¶
对 Agent 平台建设¶
- 所有权边界优先于技术实现:先问"谁控制变更节奏",再决定技术方案
- 代码与状态必须解耦:把"快变"和"慢变"分开演进,不要让平台部署打掉用户环境
- 凭据 = 永远不进沙箱:API bridge + 短期 JWT + IP 白名单 = 沙箱内部不可信前提下的可执行安全模型
- 统一执行管道:一个
executeAgent服务所有触发源,避免 N×M 复杂度
对 Agent 框架设计者¶
- 桌面假设 ≠ 云端现实:今天大部分 Agent 框架的设计前提是桌面环境,搬到云上必须重新设计
- 沙箱里跑的是不可信代码:LLM 生成的代码可能带 prompt injection 风险,凭据绝不能进沙箱
- Hot-swap 协议是核心工程:300ms 原子替换 + 失败立即换沙箱 + V8 缓存清理——这是"既能快迭代又不毁用户环境"的最小可行解
对 Agent 应用开发者¶
- 用户环境是承诺:平台每次部署都不应该丢用户的状态——这是隐含但绝对不能违反的约定
- 多触发源 = 同一管道:用 UI 触发的 Agent 应该和用 cron 触发 / 跨 Agent 触发走同一套逻辑,避免架构分裂
对安全架构师¶
- 零信任在沙箱边界 = 必要前提:把沙箱内部"默认已被攻破"作为安全模型起点
- 短期 JWT > 长期 API Key:即使 token 泄露也只对单次运行有效,不会造成大范围损失
- 唯一通道 = 唯一审计点:所有进出沙箱的流量都走桥接层,日志/计费/可观测性集中可查
核心命题¶
Agent 本质上是一个带自然语言接口的函数。实现归用户,触发面、运行时、安全边界归平台。关键在于把这些层建好,让每一层按自己的节奏演进,并且赶在别人之前找到层与层之间的缝隙。
这就是让下一个触发面能快速、安全上线的根本。
深度分析¶
1. 所有权边界是云端 Agent 基础设施的设计原语,而不是实现细节¶
文章的核心判断标准是"谁控制变更节奏"——这个设问方式本身就是一种设计原语,而非技术选型建议。在桌面环境里,所有权边界是模糊的(用户 = 机器 = 进程),所以不需要思考这个问题。云端多租户环境下,平台和用户对同一个制品有方向相反的更新需求,这个问题就被强制暴露出来了。
把这条原则一般化:云端 Agent 平台上的每一份持久化制品,都必须有且只有一个变更节奏控制器。如果两个控制器竞争同一份制品,要么损失安全性(用过时的 Runner),要么损失可复现性(摧毁用户环境)。CreaoAI 的 hot-swap 协议,本质上是在 OS 内核/home 目录分离这个成熟模式里找到了一个特化实现,但驱动这个实现的底层逻辑是所有权边界原则。
2. Hot-swap 协议把"平台迭代"和"用户状态"从耦合态解耦为独立演化树¶
文章揭示的工程对局是:平台需要快速迭代安全补丁和功能更新,用户需要环境永远可复现。第一版"全重建"方案的失败,不是因为实现有 bug,而是架构上就不可行——它要求每次平台部署都在"安全性"和"用户承诺"之间二选一。
Hot-swap 的工程意义在于:它把"平台升级"和"用户状态"从必须同时发生的耦合事件,变成了可以独立发生的事件。平台可以在任何时候发布新版 Runner(通过热替换注入),用户状态可以在任何时候被用户修改(通过冻结快照固化)。两者通过一个轻量协议(6 步原子替换)连接,保证任何一步失败都走向可观测的降级路径(换沙箱重试),而不是静默的半升级状态。
这个模式的更深远启示是:平台工程团队和用户之间的接口,不是代码,而是协议。这个协议规定了谁在什么时候可以对什么东西做什么操作——这是 API 设计层面的问题,不仅仅是运维层面的问题。
3. "沙箱内代码不可信"是云端 Agent 的核心安全公理,它翻转了桌面 Agent 的整个信任模型¶
桌面 Agent 的安全前提是代码来自用户本地进程,安全边界实际上是用户的笔记本电脑——攻击面是外部的。云端 Agent 的安全前提是沙箱里的代码由 LLM 根据可能带有恶意的提示词生成,安全边界必须从物理边界转向身份边界。
这个翻转的影响是架构性的:桌面 Agent 的安全模型是"内网可信,外网危险";云端 Agent 的安全模型是"沙箱内部默认已被攻破"。这意味着零信任必须在执行边界(execution boundary)内落地,而不仅仅是在网络入口处。API bridge 作为唯一双向通道,正是这个安全公理的可执行实现——它把"沙箱内不可信"变成了一条有工程约束的 invariant。
4. 短期 JWT + IP 白名单的双层校验,是把"零信任"从概念变成可执行工程约束的最小方案¶
零信任是一个被广泛引用的安全概念,但文章给出了一个在云端 Agent 场景下可执行的最小实现:网络层 IP 白名单 + 应用层短期 JWT。两层叠加的目的是让每一层的失效都有独立的兜底。
IP 白名单解决的问题是:网络层拒绝所有非内网来源的请求,即使有人拿到了沙箱地址也無法绕过这一层。这绑定了桥接层对特定物理基础设施的依赖,消除了"地址泄露 → 外部直连"这条攻击路径。
短期 JWT 解决的问题是:即使沙箱被完全攻破,攻击者拿到的也只是一个随运行结束就失效的令牌,而且这个令牌只在本次会话内有效。这意味着 credential 的泄露窗口被压缩到了单次运行的时长,而不像长期 API Key 那样是一颗定时炸弹。
这两层的叠加不是过度设计,而是把零信任原则具体化为工程约束的必然要求——每一层独立校验,失效路径独立可见。
5. "统一执行管道"是把 Agent 从"产品"变成"基础设施"的关键架构决策¶
文章把 Agent 定义为"带自然语言接口的函数",并指出这个函数必须通过一个统一的 executeAgent 管道服务所有触发方。这个定义不是一个隐喻,而是一个架构约束:如果 Agent 对不同的触发源有不同的执行路径,它就不再是一个函数,而是一个需要维护 N×M 复杂度矩阵的产品。
这个架构决策的商业含义是:平台可以低成本地引入新的触发源(加一条路由,不需要改 Agent 本身),而 Agent 开发者可以假设运行时行为与触发方式无关。这把 Agent 从一个"用户交互产品"提升为"技术栈内部可随时调用的基础设施函数"——这是云端 Agent 平台能够形成网络效应的技术基础。
实践启示¶
对 Agent 平台建设者¶
- 先问所有权,再定技术方案:在设计任何共享制品(镜像、配置、Runner)的变更机制之前,先明确"谁控制它的变更节奏"。如果两个主体都需要修改同一个制品,架构上一定会出问题——解决方案是拆分所有权边界,而不是优化协商机制。
- Hot-swap 是平台的基础设施投资,不是优化项:300ms 原子替换 + 失败换沙箱 + V8 缓存清理,这套机制让平台可以在任何时候发布新版 Runner 而不丢失用户状态。这是"既能快迭代又不毁用户环境"的最小可行解,不是可选项。
- API bridge 是安全模型的可执行版本,不是安全附加项:凭据永远不进沙箱 + 唯一双向通道 + 双层校验,这三条一起构成了"沙箱内代码不可信"这个安全公理的可执行工程约束。
对 Agent 框架设计者¶
- 桌面假设是当前大多数框架的隐含前提,迁移到云端必须重新设计架构:不是加几个云服务,而是重新定义生命周期、状态管理、身份和网络信任模型。桌面框架和云端框架的根本差异不是部署位置,而是谁控制变更节奏和信任边界在哪里。
- 在框架设计阶段就要考虑多触发源:如果框架只考虑了用户交互触发的场景,后续引入定时任务或跨 Agent 调用时会面临架构分裂的成本。在设计阶段就把"执行管道归一"作为约束,可以显著降低未来的扩展成本。
对 Agent 应用开发者¶
- 用户环境是承诺,不是实现细节:平台对用户的核心承诺是"你的环境会保持冻结,直到你自己去改它"——这个承诺在无人值守运行(定时任务、API 调用等用户不在线的场景)下会直接暴露架构设计是否尊重了这个承诺。任何平台部署都不应该因为自身的迭代而违背这个承诺。
- 理解执行边界归一的含义:Agent 不知道自己是被 UI 用户、定时任务还是另一个 Agent 启动的——这是设计意图,不是实现限制。开发者应该假设运行时行为与触发方式无关,这使得相同的 Agent 可以安全地横跨多个触发面。
对安全架构师¶
- 零信任在沙箱边界内是必要前提,不是额外加固:把"沙箱内部默认已被攻破"作为安全模型的起点,意味着所有进出沙箱的流量都必须经过显式授权和校验,而不能依赖"这个沙箱是安全的"这个前提。
- 短期 JWT 优于长期 API Key:即使 token 泄露也只对单次运行有效,不会造成大范围损失。结合 IP 白名单的双层校验,把 credential 泄露的窗口压缩到了单次运行的时长,同时绑定了桥接层对特定物理基础设施的依赖。
- 唯一通道 = 唯一审计点:所有外部认证调用、日志、计费、指标都走 API bridge,使得安全审计和可观测性在一个集中的地方落地——这是"沙箱内部不可信"前提下保持全局可观测性的最小方案。
与现有 Wiki 的关系¶
与 Cloud Agent 基础设施¶
- Development environments for your cloud agents = Cursor 视角:dev environment 配置工具 + 多 repo 环境——关注 dev tooling,本文关注 production runtime 隔离与凭据
- Cloudflare + Claude Managed Agents = "脑手分离"架构:推理在 Anthropic 平台 + 代码执行在 Cloudflare Sandboxes——关注架构分工,本文关注 平台自身的 hot-swap + 凭据隔离
- Claude Managed Agents 企业边界更新 = 同一系列,关注企业 hybrid control plane(self-hosted + Anthropic 推理)
与多租户 / Serverless Agent¶
- OpenClaw → Bedrock AgentCore 多租户迁移 = 阿里云/AWS 的多租户 serverless 路径,关注迁移路径
- AgentScope Builder = 阿里云 Harness 框架 + 平台化,关注 harness 框架
- Stripe Agent 经济基础设施 5 套图谱 = 关注 agent 经济层基础设施(支付/钱包/订阅),与本文 runtime 隔离互补
与 RAG / Agent 评估¶
- RAG 技术框架的演进方向 = 关注 retrieval 充分性(充分上下文智能体 = 信息的"够不够"判断)
- 本文 = 关注 runtime 充分性(状态 / 代码 / 凭据的"够不够"判断 + ownership 边界)
与上下文隔离¶
- 上下文隔离 = 关注 context window 内的多任务隔离
- 本文 = 关注 execution boundary 内的多租户隔离——两者维度不同,但思想相通:"默认不可信 + 强制隔离 + 边界归一"
与阿里云 Agentic Cloud¶
- 阿里云 Agentic Cloud = 关注 云平台级别的 agent-as-a-service(Bailian/Qwen/MaaS)——关注平台对外的能力
- 本文 = 关注平台对内的工程化(snapshot + hot-swap + 凭据隔离)——关注平台自身的建设
实战检查清单(4 条铁律 → 9 项检查)¶
- 状态层:用户环境冻结快照,平台部署不重置用户数据
- 代码层:Runner 代码独立热替换机制(< 500ms 原子替换 + 失败回滚)
- 变更所有权:明确每个制品的"变更节奏控制器"是谁
- 凭据隔离:长生命周期凭据绝不进沙箱
- API Bridge:所有外部认证调用走桥接层
- 双层校验:IP 白名单(网络层)+ 短期 JWT(应用层)
- 执行边界归一:所有触发源走同一
executeAgent入口 - 可观测性:所有进出沙箱的流量在桥接层集中审计
- 失败兜底:任何 hot-swap 失败立即换新沙箱,不允许半升级状态
→ 原文存档