最近很多人在聊 Agent 的“长期运行”。一个很自然的想法是,既然要 long-running,那就把 Agent 当成长期进程托管起来,让它一直活着。这样一来,之前的上下文、工作目录、浏览器状态似乎都能留在原地,下一次用户回来时继续跑就行了。这个方案的直觉上没有问题,但它也恰好踩中了 Agent 系统里最昂贵的一部分:把“等待”当成“计算”去付费。
许多 Agent Session 看起来会持续 8 小时、24 小时、甚至几天,但真正发生计算的时间其实并不长。用户会离开,审批要等人点确认,外部事件不会立刻到来,定时任务也可能要过几个小时才触发。也就是说,Session 的长期,大多数时候只是墙上时钟意义上的长期,而不是 CPU 一直忙碌的长期。这个区别如果不先分清楚,后面的架构设计几乎一定会走偏。
0x00 > 问题
如果把 Agent 直接做成常驻进程,首先牺牲掉的其实不是“架构优雅性”,而是成本效率。因为只要进程常驻,计算资源就必须一直为它留着,不管它此刻有没有真的在工作。平时没什么人用的时候,机器会空转;高峰期突然很多 Session 一起活跃,资源又会变紧张,因为一部分容量早就被那些“虽然在线但实际上在等待”的 Agent 占住了。
这其实正好和云计算的优势反着来。云计算最值钱的地方,从来不是“帮你托管更多常驻进程”,而是让你在有活的时候快速拿到资源,在没活的时候 scale to zero,不为闲置状态持续付费。如果 Agent 被建模成一个必须一直热运行的对象,那么你等于主动放弃了云最有价值的一部分:弹性。一个系统如果在低峰期浪费资源、在高峰期又缺乏扩展能力,那它从一开始就很难同时做到极致体验和极致成本优化。
0x01 > 用户真正想要什么
但更关键的是,用户其实并不关心某个进程是不是一直活着。用户真正关心的是,自己回来时,工作还能不能顺着上次停下来的地方继续做下去。仓库是不是还在,浏览器是不是停在上次的页面,下载下来的文件、整理到一半的草稿、跑到一半的环境,是不是都还保留在原来的位置。
换句话说,用户想要的不是“永远在线的进程”,而是“不会丢的工作台”。这两者看上去很像,实际上是完全不同的系统目标。前者要求你持续保活某个执行单元,后者要求你保住那个对用户真正有意义的工作环境。一旦目标从“保活进程”切换成“保留工作环境”,整个系统的设计方向就会清晰很多。
0x02 > Runtime、Agent 和 Sandbox
这也是为什么在 Brazosd 里,我们会把 Runtime、Agent 和 Sandbox 拆开来看。Agent 是长期身份,它承载配置、指令、工具、技能、权限、凭证,以及和用户、团队、Session 的关系。Session 是长期记录,它保存用户说了什么、Agent 做了什么、流程推进到了哪一步。Runtime 是执行层,有工作时接手执行,把结果写回去,没工作时就不必继续占着资源。
Sandbox 则是工作环境,而且它不是一个抽象概念,而是运行在虚拟机里的隔离环境。文件系统、工作目录、浏览器状态、下载产物,以及任务做到一半时留下来的本地上下文,都放在这一层。这样做不只是为了保留工作台,也是为了安全。Agent 在执行浏览网页、下载文件、运行脚本、处理不受信任输入时,风险最高的部分天然就在这一层。如果这些事情直接发生在平台托管的长期进程里,风险边界会非常模糊;而放进虚拟机里的 Sandbox 之后,执行环境和平台控制层之间就有了清晰隔离。
这样拆开的好处在于,真正需要长期保存的东西可以稳定地保留下来,真正需要弹性伸缩的东西又不必被迫长期在线,而真正需要接触外部环境、处理复杂输入的部分,也被收进了隔离边界里。Agent 不再等于一个进程,Session 也不再绑死在某台机器上,系统才有机会同时拿到连续性、安全性和云端应有的弹性。
0x03 > Sandbox 休眠
接下来最关键的一步,就是让 Sandbox 支持休眠。因为只要工作环境可以休眠,我们就不必在体验和成本之间做一个很粗暴的二选一。Session 暂时空闲时,Sandbox 不需要继续消耗活跃计算资源,但它里面的工作环境也不需要被销毁。目录可以继续保留,文件可以继续保留,浏览器状态和中间产物也都可以留在原地。
等到下一条用户消息到来,或者某个定时任务触发,或者外部事件终于发生,再把 Sandbox 唤醒,工作就能从原来的位置继续往下走。这个过程更像是把笔记本电脑合上盖子,而不是把整个办公室拆掉重建。对用户来说,体验是连续的;对平台来说,空闲时间不再持续烧算力。这恰恰是 long-running agent 最需要的能力:不是一直热运行,而是随时能回来。
0x04 > 价值
把 Runtime 做成无状态,把 Agent 和 Sandbox 拆开,再让 Sandbox 支持休眠,最后得到的其实就是两件事。第一件事是体验。用户不用理解底层发生了什么,也不需要关心中间有没有重新分配资源,用户只会感受到这个 Agent 像本地工作台一样一直在原地,回来就能接着做。第二件事是成本。平台只在真正发生工作的时候消耗计算资源,空闲时可以休眠,没活时可以 scale to zero,高峰期又可以把执行层扩出去。
所以,Brazosd 说 Runtime 是无状态的,并不是为了追求一种抽象上的架构美感,也不是为了把系统讲得更“高级”。我们的出发点非常朴素:给用户尽可能连续的体验,同时把等待时间的成本降到最低。云计算最好的地方,本来就应该是按需使用资源;而对 Agent 产品来说,最好的体验,本来也不应该建立在“永远养着一个热进程”之上。真正值得长期保留的,不是进程本身,而是那个不会丢的工作环境。