云端 Agent 的差异不在“是不是跑在云上”,而在运行时(Runtime)与工作区(Workspace/Sandbox)是否绑定在同一个实例上。本文从这条主线出发,对比持久化 VM 与存算分离两条路线,并逐层拆解 Grok Bot 与 Cloudflare Computer 的实现。

你的理解非常精准,之前的“存算一体 vs 存算分离”这个二分法确实太粗糙了,掩盖了更本质的差异。根据你提供的分析,重新梳理后的准确框架应该是这样:

云端 Agent 的本质是“运行时”与“工作区”的解耦#

云端 Agent 架构有两类,区别在于 Agent 的推理/规划进程(Runtime) 与 Agent 的执行环境(Workspace/Sandbox) 是否绑定在同一个实例上,也就是“存算是否分离”。

维度Agent RuntimeWorkspace(工作区)
职责思考、规划、调用工具、决策(LLM 推理 + 编排逻辑)读写文件、执行命令、安装依赖、运行代码、访问浏览器
状态性无状态(不保存任何持久化数据)有状态(存储产物、文件、环境配置)
生命周期请求来则拉起,响应完即可销毁常驻云端,无 Agent 实例时自动休眠

模式一:运行时 + 工作区绑定(传统云端 Agent)#

传统云端 Agent 和本地单机 agent 一样,这是最直接的实现方式,也就是“存算一体”:

Grok Bot 确实部分解决了你提到的两个问题,但它的解决思路和你设想的“存算分离”模式不同。它选择了一条更直接的路径。

问题一:计算资源浪费#

你没有理解错,Grok Bot 确实解决了“VM 一直开着”的资源浪费问题,但方式不是“存算分离”,而是将成本完全转嫁给了用户。

所以,Grok Bot 没有在技术上解决资源浪费,而是在商业模式上解决了它——让愿意付费的用户来承担这个成本。

问题二:状态和产物丢失#

在这个问题上,Grok Bot 通过“持久化 VM”的设计,从根本上解决了问题。

它的 VM 不会在任务间重置,其核心设计就是持久化。所有状态——文件、浏览器登录态、终端会话、长期记忆等——都保存在这个持久化的云端环境里。

总结#

总而言之,Grok Bot 并没有采用“存算分离”的架构来解决问题。它的方案是:

  1. 针对资源浪费:用商业模式解决,将成本转嫁给付费用户,让“一直开着”成为一种付费服务。
  2. 针对状态丢失:用持久化云 VM 解决,通过一个永不重置的云端环境来保存所有状态和产物。

因此,可以把它看作 “运行时与工作区绑定”模式的一个商业化、高可用实现。它通过付费订阅和强大的基础设施,让“资源浪费”成为用户可以接受的“服务成本”,并确保了状态的持久性。

模式二:运行时 + 工作区分离(现代云端 Agent)#

这是你第一段描述的“进阶模式”,也是 Cloudflare Computer 等项目正在做的事:


最终总结(一句话区分)#

你之前说的“存算分离”是这种分离模式的一个子集(存储层分离),但更准确的表述应该是“运行时与工作区解耦”,因为 Workspace 不仅仅是存储层,它还可以执行命令、安装依赖,是一个完整的执行沙箱。

“Your agent needs a computer, not a container.”#

Agent Harness 通过 Tools 连接云端工作区:Grok Bot 的 Linux VM,与 Cloudflare Computer 的 Isolate / Container 执行后端

云端 Agent 比较直接的理解是存算分离,这里的算是 agent 运行所需的运算,存是各种状态、产物的存储,也就是将本地 Agent 的‘状态存储’与‘计算推理’从同一进程实例中解耦。

但实际上更准确来说云端 agent 是把 agent 运行中思考、规划、调用工具和执行工作的工作区 sandbox 分开。因为外部工作区不只是存储层,也可以是既能读写文件、又能执行命令、安装依赖的容器环境。云端 Agent 的无状态运行实例可以随时拉起,有状态的存储实例则常驻在云端,没有 Agent 实例运行时自动休眠。

至于为什么不是存算一体,那样的话 agent 运行时和执行工作区绑定在同一个实例上,由于 Agent 肯定不是一直在运行,常驻实例会导致计算资源的浪费,同时一旦实例崩溃了会导致持久化的状态包括存储产物丢失。

Agent Harness 是“大脑”,Tools 是“手”,Computer/Workspace/Sandbox 是“操作环境”。

Agent 有两部分工具,一部分是 Agent 自带的,一部分则是外部 sandbox 提供的,RPC、HTTP、MCP 等。

标题这句话不是说 Container 没用,而是说 Agent 需要的是一个持续存在、可观察、可操作的工作环境,而不只是一次性的命令执行器。

Computer 关注 Agent 的体验和状态:

Container 只是实现这些能力的一种底层后端,而且通常比较重。

对比维度ContainerCloudflare Computer
本质隔离的 Linux 命令执行环境面向 Agent 的完整电脑抽象
主要能力Shell、进程、系统工具、依赖安装文件系统、持久化工作区、命令执行、Git、工具封装
状态默认随容器生命周期变化工作区状态由 DO SQLite/R2 持久化
关系可以作为 Computer 的运行后端可以选择 Container,也可以选择其他运行后端

隔离层次#

Sandbox、Container、Linux VM、Computer/Workspace 不是同一层概念:

Linux VM 运行环境 / 虚拟硬件边界
Container 运行环境 / 共享宿主内核
Sandbox 权限与影响范围的控制机制或产品封装
Computer / Workspace Agent 可持续工作的用户抽象

其中 Sandbox 是最容易被误解的词:它可能由操作系统权限、Container、MicroVM 或完整 VM 实现。

运行流程#

  1. 网关接收用户 WebSocket / SSE 请求
  2. 从数据库加载 Prompt 和配置
  3. 创建临时的 Worker
  4. 从向量库检索记忆,拼接上下文
  5. 调用 LLM,调用工作区/Sandbox 提供的各类工具
  6. 中间状态写入 Checkpoint(支持断点恢复)
  7. 空闲时回收 Sandbox Worker,产物上传对象存储

用户关闭前端不会停止云端 Agent 的运行,唯一终端的方式是用户发起中断或者云端的任务执行完成、结果写入存储,当用户端不在运行时,可以配置主动通知通过邮件或者 IM(Instant Messaging) 主动推送。

存算分离#

存算分离,简单来说就是把 Agent 的”记忆和状态”(存)与”思考和执行”(算)从同一个进程/实例中拆分开来,让它们各自独立管理、独立伸缩。

1、为什么要分离?

在本地或早期的 Agent 架构中,提示词、工具、对话记录、推理逻辑全部跑在同一个进程里——存算一体。这种方式简单直接,但一旦放到云端、面向多用户、长时间运行的场景,就会暴露出一系列根本性矛盾:

维度存算一体存算分离
弹性存储和计算一起扩缩,不灵活各自按需伸缩
成本实例常驻,资源浪费严重计算按需使用,存储按量付费
可靠性连接断开即任务死亡状态持久化,支持断点续跑
安全工具执行可能影响宿主机沙箱隔离,零信任管控
升级牵一发动全身各层独立升级,互不影响

2、分离之后是什么样子?

宏观上,云端 Agent 的架构被拆成两大层:

1、存储层(“存”)

负责一切需要持久化的东西,按数据类型进一步细分:

2、计算层(“算”)

负责一切需要”动起来”的东西:

计算层通常是无状态的,运行在云端沙箱(Sandbox)中,按需创建、用完即回收。

mini-swe-agent#

mini-SWE-agent 本质上是“让语言模型持续生成 Bash 命令,并在某个执行环境中运行这些命令”。用来验证一个问题:

如果给语言模型一个 Shell,并提供可靠的执行环境,模型本身是否已经能够完成大部分软件工程任务?

执行环境可以是:

核心循环是:

任务
↓
模型生成 Bash 命令
↓
沙箱环境执行命令
↓
环境返回 stdout、stderr、return code
↓
模型根据结果生成下一条命令

沙箱环境的生命周期:

Agent 初始化
└── docker run 创建一个长期存活的容器
每个动作
└── docker exec 在同一个容器中执行
Agent 结束
└── stop / rm 清理容器

不过“沙箱”主要解决的是执行隔离,不代表系统自动具备完整安全性。实际安全程度取决于 Docker 权限、网络、挂载目录、环境变量和用户权限配置。

这种设计可以概括为:

命令行 / 运行脚本
│
▼
一个 Agent: 控制循环、历史、限制、终止
+ 一个 Model 接口: 请求模型、解析动作、格式化观察结果
+ 一个 Environment 接口: 执行 Bash 命令
├── LocalEnvironment
└── DockerEnvironment
+ 一个 Bash 动作
+ 一条线性消息历史
minisweagen
├── agents/ Agent 控制流程
├── environments/ 命令执行环境
├── models/ 大模型接口和动作处理
├── run/ CLI 和批处理入口
└── config/ 默认配置和提示词

典型的 Python 调用方式如下:

agent = DefaultAgent(
model=LitellmModel(...),
env=LocalEnvironment(),
)
result = agent.run("修复项目中的 bug")

Cloudflare Computer#

  1. DO 是 Cloudflare 的有状态基础设施,提供实例身份、生命周期和 SQLite 持久化存储;
  2. Cloudflare Computer SDK 基于 DO 的持久化层(额外的 R2)及具体运行后端,封装一套统一的文件、命令和 Git 操作 API 作为 Workspace 工作区,即 Agent 的“云端电脑”;
  3. Agent 不直接操作 DO,也不直接操作 SQLite/R2,而是通过 Workspace API 控制云端电脑,操作文件、执行命令和调用 Git。

1、Worker、DO(Durable Object)#

Cloudflare 在全球有成千上万台物理机,收到你的请求后,它会随机抓一个闲着没事干的“临时工”(Worker 进程)来跑你的代码。

普通 Worker 更像一次性的无状态请求处理器:请求来了就执行,执行结束后内存中的状态不能依赖。而 Durable Object(DO)是一种特殊类型的 Cloudflare Worker。

这里的“特殊”,主要在于它是按唯一名称或 ID 寻址的、有状态(带持久化存储)的 Worker:

Worker 配置中的绑定,就是 Worker 访问 DO 的“门禁卡”:

wrangler.jsonc
{
"compatibility_flags": ["nodejs_compat"],
"durable_objects": {
"bindings": [
{ "name": "Agent", "class_name": "Agent" }
]
},
"migrations": [
{ "tag": "v1", "new_sqlite_classes": ["Agent"] }
]
}

定位和调用 DO 的过程可以概括为:

  1. Worker 用 env.Agent.idFromName("user-123") 为用户生成稳定的实例 ID。
  2. Worker 用 env.Agent.get(id) 取得 DurableObjectStub。
  3. Worker 通过 stub 调用 DO 的方法;实例如果尚未运行,会被 Cloudflare 唤醒。
  4. DO 在自己的执行环境中完成逻辑,并把状态写入 SQLite。
  5. DO 返回结果;空闲后实例可以回收,数据下次仍可继续使用。

因此,Worker 是无状态的入口和路由层,DO 是有状态的执行和协调层。Worker 可以负责鉴权、参数校验和定位,DO 负责修改自己的持久化状态。

2、Cloudflare Computer#

Cloudflare Computer 则是一个 npm SDK,基于 DO 的持久化层(额外的 R2)及具体运行后端,封装一套统一的文件、命令和 Git 操作 API 作为 Workspace 工作区,即 Agent 的“云端电脑”。让 Agent 可以像使用一台电脑一样完成工作,并把工作产物持久化下来。

能力作用
Workspace一台云端电脑的总控台
ws.fs读取、写入和编辑文件
ws.runtime.exec把命令交给 Isolate、Container 等 runtime 后端执行 Shell 或程序
ws.git执行 Git 相关操作
createAITools(workspace)把电脑能力包装成 LLM 工具

Cloudflare Computer:Durable Object 内的虚拟文件系统与可插拔执行运行时

Workspace 与执行运行时之间通过 exec、push/pull、binding 三种方式对接

工作区还支持可选的执行运行时 Workspace.runtime,使您能够在文件系统上运行代码。所有运行时都支持相同的接口 exec(string, options),提供了两种默认选项:

FUSE(Filesystem in Userspace,用户态文件系统)允许程序在用户空间实现文件系统,不需要修改 Linux 内核。它可以把远端工作区表现成沙箱或容器中的普通目录。

computerd 是 Cloudflare Computer 在 Container 后端里的一个沙箱内文件系统守护进程。

名字可以理解为:

computer + daemon

也就是“Computer 的后台服务”。

它主要做三件事:

DO SQLite
↑↓ RPC
computerd
↑↓ FUSE
容器里的 /workspace 目录
  1. computerd 在容器/沙箱里运行。

  2. 它通过 FUSE 把 /workspace 挂载成一个普通目录。

  3. 容器执行:

    Terminal window
    echo "hello" > /workspace/a.txt
  4. Linux 将这个文件写入操作交给 FUSE。

  5. computerd 捕获变更,通过 RPC 发回 Workspace/DO。

  6. DO 将变更提交到 SQLite;大文件场景再写入 R2。

SQLite、R2#

在 Cloudflare 的设计文档中,文件系统的核心就是 SQLite 中的一张表:

CREATE TABLE cf_workspace_{namespace} (
path TEXT PRIMARY KEY, -- 文件路径
parent_path TEXT NOT NULL, -- 父目录路径,用于加速目录列表
name TEXT NOT NULL,
type TEXT NOT NULL, -- 'file' | 'directory' | 'symlink'
size INTEGER DEFAULT 0,
storage_backend TEXT DEFAULT 'inline', -- 'inline' 或 'r2'
r2_key TEXT, -- 当 storage_backend = 'r2' 时,存储 R2 的 Key
content TEXT, -- 小文件的内容 (inline)
created_at INTEGER,
modified_at INTEGER
-- ... 其他元数据
);

可以看到,content 字段既可以直接存小文件的文本或 Base64 编码的二进制数据,也可以配合 storage_backend 和 r2_key 字段,指向存储在 R2 的大文件。

为什么 SQLite 能支撑整个文件系统?#

因为文件系统本质上就是一张“巨大的映射表(元数据)”,而 SQLite 正是存储“映射关系”的绝佳数据库。

一个文件系统(如 ext4/NTFS)在硬盘上无非就是两样东西:

在 Cloudflare Computer 的架构中,SQLite 直接把“硬盘物理地址”替换成了“数据库行(Row)”

并且 SQLite 支持 BLOB(二进制大对象) 类型,可以直接存储文件的内容(字节流)。加上 SQLite 是嵌入式数据库,不需要独立的服务器进程,且支持 ACID 事务(保证写入原子性,防止断电丢数据),所以在单机或单租户场景下,它完全可以充当“文件系统的存储引擎”。

分层存储(Tiered Storage)策略#

配合机制:

3、云端 Agent#

1、项目结构与部署:

本地项目
├── frontend/ # 聊天框、终端 UI
│ ├── src/
│ └── package.json
│
├── src/
│ ├── index.ts # Worker 入口、Agent 循环
│ └── agent-do.ts # Durable Object 类
│
├── package.json # @cloudflare/computer、ai 等依赖
├── wrangler.jsonc # Worker、DO、SQLite、R2 配置
└── tsconfig.json
↓
npm install
npm run build / wrangler deploy
↓
Cloudflare 部署产物
├── Worker 代码
├── DO 代码
├── 打包后的 Computer SDK
└── 前端静态资源(如果由 Worker 托管)
↓
请求到来或 DO 被唤醒
↓
直接加载已部署代码运行

同一个项目只需要安装一次:

Terminal window
npm install @cloudflare/computer ai

Computer SDK 会部署到 Worker 和 DO 类,但两边的代码职责不同:

2、运行形态与流程:

Terminal window
用户界面
└── 浏览器里的聊天框 / 终端 UI
↓ HTTP / WebSocket / SSE
Cloudflare Worker 接收请求、鉴权、运行 Agent 循环
├── env.Agent.idFromName(userId):根据用户 ID 找到对应的 DO id
├── env.Agent.get(id) → DurableObjectStub:获得 DO stub
└── getWorkspace(stub):把 DO stub 包装成可操作的 Workspace
└── createAITools(workspace):把电脑能力包装成 LLM 工具
└── 调用 Computer Workspace 工具
├── ws.fs.writeFile():读写文件
↓ RPC
DO 文件 API → 持久化到 DO SQLite / R2(较大的二进制)
├── ws.runtime.exec("npm test"):选择运行后端执行命令
↓ RPC
Isolate / Container / Worker JavaScript
└── git:Git 操作

因此,Cloudflare Computer 在这里主要承担的是工作产物的存储和执行环境,而不是 LLM 本身。它让云端 Agent 拥有一台可恢复的云端电脑:Worker 可以回收,DO 实例可以休眠,Agent 下次仍能从同一个用户的工作区继续工作。

4、代码示例#

定义 Agent DO 和 Workspace#

import { withWorkspace } from "@cloudflare/computer";
import { DurableObject } from "cloudflare:workers";
export class Agent extends withWorkspace(
class extends DurableObject<Env> {},
(self) => ({ storage: self.ctx.storage }),
) {}

在 Worker 中运行 Agent#

import { getWorkspace } from "@cloudflare/computer";
import { createAITools } from "@cloudflare/computer/tools";
import { generateText } from "ai";
export default {
async fetch(req, env) {
const userId = "user-123"; // 实际项目中应来自鉴权结果
const id = env.Agent.idFromName(userId);
const stub = env.Agent.get(id);
using workspace = await getWorkspace(stub);
const tools = createAITools({ workspace });
const { text } = await generateText({
model,
tools,
prompt: "读取当前工作区,完成用户交代的任务。",
});
return new Response(text);
},
} satisfies ExportedHandler<Env>;

idFromName(userId) 使每个用户拥有稳定的工作区;createAITools(workspace) 把 read、write、edit、exec 等能力交给模型;using 用于在调用完成后释放 Workspace/stub 资源。

Grok Bot#

Grok Bot 界面:左侧 Bot 列表、中间对话、右侧 Bot 自己的云端桌面

Grok Bot 的官方定义是:每个用户拥有一台持久化的托管 Linux VM,里面有 browser、filesystem、terminal;多个有名字、有持久状态的 Agent Bot 共享这台电脑、文件和登录会话。Grok Bot 官方说明

Cloudflare Computer 更像一层“Agent 工作空间运行时”:文件状态由 Durable Object + SQLite 持久化;简单任务可以在 isolate 中执行,需要真实 Linux、npm 或原生二进制时,再挂到 Container 中运行。官方 README 也明确把它定义为 virtual filesystem,并提供 container、isolate shell、isolate JavaScript 三种后端。Cloudflare 官方博客

所以一句话:

Grok Bot 是“给 Agent 一台已经存在的云端电脑”;Cloudflare Computer 是“给开发者一套组装 Agent 电脑的基础设施”。

存算分离如何落地#

笔记的核心论点——把「状态存储」和「计算推理」从同一进程解耦——Grok Bot 用「一台持久电脑 + 无状态大脑」来实现:

笔记里的概念Grok Bot 的对应实现
存算一体(进程绑定)传统「工作流 builder / 一次性会话」:任务结束环境即销毁,上下文清零
存储层(持久状态)一台持久化云端 VM:浏览器、文件系统、终端、登录态、记忆、偏好
计算层(无状态执行)Bot 的推理 + 工具/电脑操作;关闭 App 或笔记本不停止,云端继续跑
断点续跑 / CheckpointUpdate / Recover / Reset Agent Computer,三者都「preserve durable state」

存储层:一台「电脑」就是全部状态#

Grok Bot 没有把存储拆成 Redis / Postgres / 向量库暴露给用户,而是把整个状态抽象成一个文件系统:

这和 Cloudflare Computer 的「对外暴露普通文件系统、内部持久化状态」思路相近;FUSE 是否参与,取决于具体执行后端是否把工作区挂载成容器内目录。

计算层:双通道执行#

笔记里执行层是「沙箱里跑工具」,Grok Bot 把执行拆成两条优先级明确的路径:

  1. Connector / MCP(首选)——结构化调用,比「点网页」可靠
  2. Browser Use / Computer Use(兜底)——对没有干净 API 的应用/网站,直接操作浏览器和桌面,browser use 使用 playwright-core + Chrome CDP

文档明确说 “Prefer a connector when one is available”,这回答了「什么时候用 API、什么时候用电脑操作」的工程取舍。

多 Agent 协作:人不当路由器#

自动化:Skill / Routine / 演示学习#