最近在圈子里看到不少人在讨论同一件事:像 Muse、Grok Bot 这一类的智能体应用,官方和玩家社区都开始尝试一种新的部署方式——给每个 Agent 分配一台云电脑,让它 7x24 小时不关机的跑着。有人直接开喷:以前我们千辛万苦从单机演进到 Web 集群,图的就是一台服务器能扛几千个用户,现在倒好,一个 Agent 就要占一台云电脑,资源利用率直接被打回解放前,这算什么技术进步,分明是架构倒退。
说这话的朋友,大概率是只站在了“请求并发”这一个维度看问题。我自己前后折腾了快两个月的 Agent 部署,从传统的 Web 集群到云电脑方案都试了一遍,可以明确地说:这还真不是非黑即白的技术退步,而是负载模型发生了根本变化,过去的尺子已经量不了现在的需求了。这篇文章我不打算站队,纯粹把两种架构的底层逻辑、Agent 的真实运行需求、以及我踩坑跑通的全过程摊开来聊一聊,适合正在做 Agent 应用落地、AI 基础设施设计,或者单纯好奇“云电脑跑机器人”到底图个啥的人参考。
1. 先搞清楚两种架构在争什么
1.1 Web 集群的底层逻辑:共享一切,按需分配
Web 集群这套架构,本质上是把“计算能力”当成一个公共食堂。你不需要知道今天是哪个厨师给你打的饭,也不需要记得上次那个窗口的师傅手艺好不好,你只需要拿着餐盘来了就打菜,吃完就走。整个系统对人的假设是:每一顿饭都差不多,每个进来的人都没有记忆,吃完饭谁也不认识谁。
技术上对应的就是三个关键词:无状态、负载均衡、水平扩展。一个典型的 Web 集群,外面挂 Nginx,后面跟多个应用实例,所有实例共用一个数据库、一个缓存、一套消息队列。用户的请求随便打到哪台机器上都能处理,因为处理逻辑不依赖本机状态。这也是为什么它能扛住高并发——来 1000 个请求,我就把 1000 个请求平均扔给 10 个实例,每个只要扛 100 个就行。
这套架构的核心优势是资源利用率奇高。因为请求是短连接,一个用户占用 CPU 的时间可能只有几百毫秒,其余时间资源可以释放给下一个人。你可以在非常有限的硬件上,服务大量用户。我记得以前做过一个资讯类站点,高峰期 10 万在线,后端总共也就 6 台 8 核 16G 的机器,一点问题没有。
但注意,这套模型的隐含前提是:用户的每一次访问都是独立的、短暂的、可重入的。把请求处理完,返回结果,然后这个用户对集群来说就什么都不剩了。
1.2 云电脑的底层逻辑:独占一切,就是一台真电脑
云电脑的思路恰好反过来。它的每一个用户或者说每一个 Agent,都拥有一台完整的、独立运行的电脑环境,有自己的 CPU、内存、磁盘、操作系统,甚至自己的显卡算力。打个比方,它不是一个食堂,而是给了你一个独立的家庭厨房,冰箱是你的、灶台是你的、调味料也是你的,你甚至可以把一道菜炖到一半,关火去睡觉,第二天回来继续炖,这锅汤还在。
支撑这种模式的技术,最早的形态是虚拟机加远程桌面协议,后来演进到容器加 WebRTC、KasmVNC 这类轻量化方案。也就是最近热词里那个“云电脑不关机 docker”背后的东西——大家确实在用 Docker 去跑一个又一个的桌面容器,通过 Keep-alive 机制让它们长期在线,专门给 Agent 当“身体”用。
云电脑这种方案的优势是状态持久化、环境隔离、行为完整。Agent 在一个独占环境里可以随便写文件、装依赖、开浏览器、挂后台进程,不会有其他用户的请求来干扰它,也不会因为容器被集群调度而丢失正在进行的任务。但代价也很明显:一台物理服务器可能只够开几台到几十台这种云电脑,资源利用率听起来确实比 Web 集群“难看”不少。
1.3 争论的核心:衡量的根本不是同一件事
之所以有人觉得这是“架构倒退”,是因为大家习惯性地拿 Web 集群的“单机服务人数”去套云电脑,然后发现数字一下子降了几十上百倍。但这里有一个很容易被忽略的事实:Web 集群优化的是请求吞吐量,云电脑优化的是任务完成率和状态连续性。
拿打游戏来类比。如果一个玩家只是偶尔上线签到一下,全世界人共用一个服务器大厅是完全合理的;但如果这个玩家要长期挂机、种田、养号,每天 24 小时都要保持角色在线,那服务器大厅这种模式就不行了,你只能给每个玩家单独开一个“房间”,哪怕这个房间大部分时间是空闲的。
Agent 这种负载天然就属于后者。它要执行任务、要记忆、要持续观察环境变化,它不是一个短连接请求,而是一个长时间运行的“数字员工”。所以,拿 Web 集群的指标去批判云电脑,本质上是用发动机的油耗去衡量电动车的电耗,看着都是“能耗”,底层逻辑完全不是一回事。
2. Agent 架构为什么偏偏盯上了“一人一台电脑”
2.1 Agent 的真实运行需求:不是一个请求,而是一段连续的工作期
我一开始做 Agent 应用,想法特别天真:Agent 不就是把大模型接上 API,像普通 Web 后端那样,接收用户请求,调模型,返回结果就完事了吗?结果第一批测试用例一跑就翻车了。
问题出在 Agent 的工作方式上。一个完整的 Agent 任务往往不是一次 API 调用能完成的。比如我让 Grok Bot 去帮我搜集某个行业的公开报道,然后整理成周报,它的执行路径大致是:理解需求 → 搜索网页 → 阅读文章 → 提取要点 → 生成初稿 → 根据格式要求调整 → 输出。这一个完整流程可能要持续超过 20 分钟,并且每一步之间都依赖之前的结果。
如果我用传统 Web 集群那套形态去承载这个任务,每调用一次搜索工具就发一个新的 HTTP 请求,每次请求都是全新的,那么状态放哪里?搜索完的结果存 Redis?还是塞回请求参数?就算强行塞回去,做到第五步的时候还是会出现过期的上下文、丢失的环境变量、超时的链路等待。更别提 Agent 真实的场景里还有用户中途发来修正指令这种操作,无状态设计根本接不住。
云电脑在这方面是天生的合适,因为它本质上是把一个 Agent 的工作台完整地固定下来了。工作做了一半,会话中断了,机器还在那里,内存还在,后台任务还在跑,Agent 可以随时捡起来继续,不需要重新铺摊子。
2.2 浏览器自动化与 GUI 操作:集群很难给到的东西
另一个非常实际的痛点,是现在的 Agent 越来越依赖真实的浏览器环境。
比如 Muse 在做页面数据采集、报表渲染、自动化点击操作时,需要打开一个真实的 Chromium 浏览器去执行 JavaScript、截图、等待页面渲染、处理弹窗。这类操作对执行环境是有硬性要求的:要有一个可用的 GPU 或者至少足够的 CPU 来完成渲染,要有完整的用户目录来存放 Cookie 和本地存储,要有图形环境来展示验证码或交互式确认。
这些需求放在 Web 集群里非常尴尬。集群里的应用容器大多是无图形界面的,DevTools 协议可以启动 headless 浏览器,但一旦遇到需要真人交互的验证码,headless 模式就抓瞎了,更不用说复杂页面的渲染兼容问题。而云电脑环境就是一个带桌面的操作系统,你甚至可以直接通过远程桌面看它当前卡在哪一步,手动点一下确认按钮,再让 Agent 继续往下跑。
我用 Grok Bot 跑过一条链路,它需要截图验证某个页面在移动端布局下的展示效果。在云电脑里开一个带移动端模拟器的 Chromium,搞定通知、点击、截图、返回,整个过程非常顺畅;这件事如果放到纯 Web 集群的 headless 环境里,光是一个用户代理模拟就可能耗掉半天调试时间。
2.3 环境隔离与安全边界:出了问题炸一台不炸一片
还有一点常常被忽略,就是安全边界。Agent 要执行的是不可完全预测的代码,它会安装第三方依赖、调用外部工具、访问不可信的网页。如果把多个互不信任的 Agent 放到同一个集群容器里跑,依赖冲突、资源抢占、甚至是恶意代码逃逸,任何一个问题爆出来,影响的都是一整片实例。
云电脑模式天然把不同的 Agent 隔离开来。一人一个容器,一人一个桌面环境,权限边界非常清晰。最坏的情况是一台云电脑被搞坏了,重启一台、回滚一个快照就行,不牵连其他服务。这种“爆炸半径最小化”的架构思想,在 Agent 场景里价值远远大于资源利用率的收益。
虽然从表面看,资源从“共享一份”变成了“独占一份”,好像倒退到原始的 PC 时代了。但如果把故障隔离、状态隔离、依赖隔离这些隐性收益算进去,你会发现云电脑方案的综合成本不一定比集群方案高。
3. 实操:用 Docker 把一台云电脑跑起来,给 Agent 当“身体”
3.1 方案选型:为什么用 Docker 而不是新买物理机
既然要“每人一台云电脑”,第一步当然是选基底。不可能真的给每个 Agent 配一台物理机器,那价格和机房空间都吃不消。现在主流的做法就是用 Docker 容器模拟一个完整的桌面环境。
我选择 Docker 的原因是三点。第一,镜像即模板。我把一个包含桌面环境、常用工具链、Agent 运行框架的容器打成镜像,想开几台云电脑就复制几台,秒级拉起。第二,快照和回滚非常方便,容器出问题直接重新拉一份镜像,工作区数据单独挂卷。第三,资源配额好控制,CPU 和内存可以通过 docker-compose 文件精确指定,单台物理服务器上可以开多台轻量云电脑。
有人可能会问,那直接用虚拟机行不行?也可以,但虚拟机开销要大不少,而且要管理虚拟化层,自动化编排起来不如容器顺手。对于大多数 Agent 场景,容器完全够用,反倒是最佳平衡点。
3.2 一个最小可跑的云电脑 Agent 环境
我来给一个可以直接抄作业的最小方案。假设你的宿主机是 Linux,装了 Docker,目标是在 8080 端口跑一个带桌面的容器,给 Agent 提供图形化操作环境。
# 拉取带桌面和浏览器的镜像,这里以 kasmweb 的 chrome 镜像为例 docker pull kasmweb/chrome:latest # 创建持久化数据目录 mkdir -p /opt/agent-desktop/data # 启动容器,映射端口,挂载数据卷,设置自动拉起 docker run -d --name agent-001 \ -p 8080:6901 \ -v /opt/agent-desktop/data:/home/kasm-user/.local/share \ --restart=always \ --cpus=2 --memory=4g \ kasmweb/chrome:latest启动之后,浏览器访问宿主机的 8080 端口,输入默认的 kasm 用户和密码,就能看到一个带 Chrome 的完整桌面。这个桌面就是 Agent 的“身体”,你可以让它在这里执行所有需要图形界面的操作。
注意几个参数的选择。第一,--restart=always一定要加,这对应了热词里那个“不关机”的需求,宿主机重启之后容器要自动拉起来,Agent 才能保持在线。第二,数据目录必须挂载出来,如果把数据放在容器内部,容器一重建,Agent 的记忆、浏览器的登录状态、历史数据全部会丢,到时候哭都来不及。第三,CPU 和内存要按实际跑的任务给,我给 Grok Bot 用的最低配置是 2 核 4G,如果只是跑纯文字处理可以降到 1 核 2G;如果涉及图像渲染或者大规模爬取,直接加到一个物理机的全部资源也不算浪费。
3.3 让 Agent 和云电脑“聊起来”
有了云电脑,下一步就是让 Agent 能驱动它。这里不是让你把 Agent 丢进去就完事,而是要在云电脑里跑一个常驻的 Agent 服务进程,然后通过 API 或者消息队列和它通信。
我搭的链路大致是这样的。核心的调度逻辑放在主控端,它负责接收用户需求、规划任务、拆解步骤。第一步,主控端判断这个任务是否需要“长上下文 + 图形化执行环境”,需要的话就调用云电脑管理接口,从容器池里挑一台空闲云电脑,把任务参数通过 HTTP/WebSocket 下发进去。云电脑里面的 Agent Runner 收到指令后,开始执行浏览器自动化、文件操作、命令行调用,每一步的中间结果再通过消息回调回报给主控端。主控端聚合结果,继续调度下一步或者直接返回给用户。
这个模式的灵活性在于,云电脑本身的配置可以随时调整,Agent Runner 和主控端是解耦的。你甚至可以同一套主控管理多台不同规格的云电脑,有的侧重 CPU 密集计算,有的侧重浏览器渲染,有的跑 GPU 加速的模型微调。按需调度,比无脑给每个 Agent 都配一台顶配云电脑要实在得多。
4. 常见问题与排查技巧实录
4.1 “不关机”的资源焦虑:是常驻不是全速
很多人一听云电脑不关机,第一反应是“那得浪费多少电和算力啊”。实际跑下来你会发现,云电脑不关机不代表它一直在满负荷运转。Agent 在等待任务的时候,CPU 占用率通常只有 1% 到 2%,内存占着但不会频繁读写,跟你电脑挂一个聊天软件挂着不关是一个道理。
害怕资源浪费的话,可以给容器加一层自动休眠机制。比如设置一个 30 分钟空闲阈值,没有任务进来的云电脑自动挂起状态,把内存镜像写到磁盘,需要的时候通过 API 再次唤醒,恢复时间在秒级。我实测过,一个 20 台的云电脑池,实际长期全速运行的往往只有三五台,其余都在休眠待命。
4.2 状态丢失:容器一重启,Agent 失忆
这个是我踩过最深的坑。刚开始我图省事,没有把数据目录挂载出去,结果有一次宿主机内存不足,Docker 自动重启了容器。重启完一看,好家伙,Agent 之前爬完的几千条数据全没了,浏览器里的登录 Cookie 也清了,任务直接从头再来。那心情,跟打了三个小时游戏没存档一个样。
后来我总结出一条铁律:云电脑只当“外设”用,关键状态一定要持久化到外部。Agent 的最终产物、重要中间结果、会话上下文,全部通过 Agent Runner 回传到主控端,再写入数据库或者对象存储。云电脑本地只留临时目录和算力所需的运行时缓存。这样一来,哪怕云电脑整个崩了,拉起一个新的,下载一下状态,Agent 又能无缝续跑。
4.3 多 Agent 并发:是共享一台还是各开各的
理论上你可以在同一台云电脑里跑多个 Agent,只要给它们开不同的用户会话就能互不干扰。但我不推荐这么做,原因有两个。一个是桌面体验容易串场,两个 Agent 同时操作同一个浏览器的时候,哪怕分属不同的窗口,也会出现焦点错乱、资源抢占的情况。另一个是故障隔离失效,一个 Agent 把系统依赖弄坏了,另一个也得跟着遭殃。
我的建议始终是一个 Agent 对应一台轻量云电脑,哪怕一台物理机上开多个容器,也不要在一个容器里塞多个 Agent。容器本身的开销很小,多开几台的成本远低于一次任务因为环境互相污染而失败的重试成本。
4.4 网络与延迟的坑:别在本地和远程之间反复横跳
Agent 在云电脑里操作本地文件、跑浏览器渲染这些都是本地操作,速度飞快。但一旦需要和外部系统交互,比如拉取远程接口、下载大文件、同步云端数据,带宽和延迟就变成瓶颈了。
我这里有一个小技巧:把 Agent 的所有“亲近数据”提前拉到云电脑本地,让整个任务尽量在本地闭环。比如要处理一个 1G 的文件,不要一边处理一边从远程对象存储里分段读取,而是先交给云电脑的初始化流程把文件拉下来,处理完后再把结果压缩上传。数据传输次数越少,整体任务时间越可控。
4.5 关于“状态存储入口混乱”的联想:别让 Agent 环境也这样
最近热词里有句挺有意思的话,说“我的电脑有 WPS 云盘图标还有 WPS 网盘图标”。这其实反映出很多真实用户面对多个相似产品时的困惑:看起来是两个入口,到底该存哪个?同步到哪?会不会两边不一致?
Agent 的云电脑环境非常容易出现类似问题。你给它配了一个本地工作目录,又挂载了一个外部数据卷,还留了一个对象存储的客户端,然后 Agent 每次写文件前都纠结:这次该存哪?我见过有人的 Agent 任务跑完,数据分散在三个存储位置,最后汇总的时候发现漏了一批。
所以从一开始就要定好规则:本地临时目录只管运行期数据,容器重启就清空;一切需要长期保留的东西必须走唯一一个持久化接口,比如统一通过 Agent Runner 送回主控数据层。入口越少,心智负担越轻,Agent 也不容易钻牛角尖。
5. 回到开头那个问题:技术进步还是架构倒退
5.1 用需求反推架构:没有最好,只有合适
现在我可以说结论了。以 Agent 架构为代表的负载,往云电脑模式走,不是倒退,而是某种意义上的“螺旋式上升”。人类计算架构本来就是沿着“集中”和“分散”两个方向往返摇摆的。大型机时代是集中,PC 时代是分散,Web 时代又集中到数据中心,现在 Agent 需要持久在线和状态完整,于是又把个人计算环境搬回云端,只不过加上了更灵活的调度能力。
真正的智慧不是固守某一种架构,而是学会按需求拆分。短平快的请求交互,比如聊天问答、关键词查询、订阅推送,Web 集群依然是最优解,我没有见过比它更省资源的方案。长时多步、依赖记忆、需要图形化交互的任务,比如数据采集、文档撰写、报表生成,云电脑模式会是常态。混合形态才是未来绝大多数系统的真实写照。
5.2 我的判断:以后做 Agent 架构可以套用的三条原则
第一条,按请求类型分。只跟用户进行一次信息交换的任务,走无状态集群;需要执行一连串动作、中途还要看中间结果修正方案的任务,走云电脑。第二条,按状态依赖分。没有记忆容错,任务中断也不怕的服务,集群;状态丢了任务就前功尽弃的,坚决云电脑加外部持久化。第三条,按成本核算分。不要只看一台物理机服务多少人,要算“完成一个任务的综合成本”,包括机器成本、人力调试成本、失败重试成本。很多时候看起来利用率变低了,但任务成功率上去了,综合成本反而是下降的。
5.3 我个人操作中的体会
踩了几次坑之后,我现在默认的架构设计思路已经变成了“先短后长”。一个新功能上马,先按传统 Web 集群的思路把最小闭环跑通,只要发现这个负载开始出现会话复用、状态连续性、浏览器操作这些迹象,就毫不犹豫地把它迁到云电脑模式。我自己手里的 Agent 池现在稳定维持在二十台云电脑左右,配合集群做路由,整体跑下来,任务成功率比纯集群方案提升了好几个档次,资源开销也没有想象中那么失控。这个方向后续还可以扩展出更精细的云电脑规格调度、GPU 资源池化、以及 Agent 工作负载的自动迁移策略,但核心思想始终不变:让负载决定架构,而不是让架构绑架负载。