今年冒出来的一批Agent托管产品,解决的都是同一个前置问题:没人愿意让模型在自己电脑上执行删除命令,所以模型被塞进别处的容器里。这部分已经成了标配。没成为标配的,是当你中途不再盯着一个长时间运行的Agent时,它身上会发生什么。
DigitalOcean的Managed Agents最近进入公开预览,文档里有一句声明,比它第一眼看上去要重:暂停会话会保留进程、内存和工作区文件系统,恢复时把它们带回来。一个被停止的容器会丢掉所有没写进卷的东西,所以如果这句话字面成立,它就是另一种东西了。而找不到有人真去测过。于是有人花了一个上午和大约七美分,把这件事测了。
一个只活在内存里的计数器
最直白的测试版本毫无价值。写个文件、暂停、恢复、把文件读回来,你只证明了磁盘还在,而这一点从来没人怀疑过。关于内存的声明,需要一个只存在于内存里、从不从任何地方读回来的东西。
于是有了一个最笨的进程:一个bash循环,把计数器存在shell变量里,每秒加一,把当前数值和时间戳追加进日志。从进程的角度看,这个日志是只写的,没有任何东西会把它读回来。所以如果会话被销毁又重建、只是恢复了文件系统,计数器会从1重新开始,旧日志后面只会接上一段新的序列。
启动它需要一点小心,因为进入沙箱的执行通道关闭时会杀掉它的子进程。最后活下来的是setsid nohup加disown那一套写法。
然后让它跑大约一分钟,暂停会话,去冲了杯咖啡,再恢复。
日志里相邻的两行,就是全部结果:47,08:05:42;48,08:10:10。
四十七,然后四十八。同一个进程,PID 590,握着它之前就持有的同一个shell变量。唯一能证明中间发生过什么的,是那个本该每秒跳一次、却空了四分二十八秒的洞。
暂停调用本身0.86秒返回,恢复用了1.16秒。这两个数字其实不太说明问题,因为真正有意思的量是中间那四分半钟——那段时间里,这个会话没有消耗任何东西。
两种状态都回来了
同样的检查也对着Agent自己的上下文跑了一遍,而不是shell变量。暂停之前,让Agent生成一个随机工单标识符HARBOUR-7742,写进一个文件。恢复之后问它工单叫什么,它从对话历史里回答出来,用了八个输出token,没有碰文件系统。操作系统层面的状态和Agent层面的状态,两种都回来了。
值得确认一下这个进程实际跑在什么上面,因为“沙箱”这个词覆盖的范围,从chroot一直到虚拟机。检测到的结果是:KVM虚拟机监控程序,2个vCPU,3939 MB内存,磁盘/dev/vda,内核6.1.176。
这是一个带自己内核、自己块设备、底层有硬件虚拟化的microVM,不是共享主机上的命名空间。从API调用到状态变为READY,会话创建耗时15.97秒,比容器慢,大致就是一个Firecracker级别虚拟机的代价。规格从mars-1vcpu-1gb一直到mars-16vcpu-32gb。
里面的Agent由DigitalOcean自家的推理端点驱动,而不是第三方密钥。一个提示词走DeepSeek v4 Pro,7.3秒返回,输入15,793个token,输出91个,期间写好了要求的文件。推理和沙箱的账单进同一个账户,这比暂停那件事的便利性小,但也不是没有。
fork不是快照
还有一个fork命令。按checkpoint-and-restore类产品的惯例,会以为它是给磁盘拍个快照,再给你一个文件相同的第二个沙箱。
结果不是。把运行中的父会话fork了两次,两次一共30.98秒,然后去三个沙箱里检查那个计时进程。
每一个里面都有同一个进程、同一个PID,正在计数,而且是从fork发生那一刻所持有的数值开始数。一个运行中程序的三份拷贝,从一个共同祖先开始分叉。如果你曾经想过把Agent跑到某个决策点,然后从那个确切状态出发去探索四条不同路径,而不用把走到这里的工作重放一遍,这就是能做到它的原语。
单独做checkpoint耗时25.25秒,报告的大小约为111 GB,这是稀疏分配,而不是你真的存了这么多东西。
把所有操作的墙上时钟成本收在一处,因为它们之间的差距才是会决定你怎么用它的东西:创建会话是最贵的一项,15.97秒。暂停和恢复快到几乎可以忽略,你不会围绕它们做设计,而这正是暂停值得被拿来用的原因。
全新沙箱的出站流量是开放的,这一点通过在一个沙箱里不做任何配置就访问example.com和api.github.com得到了确认。往清单里加一个主机,行为就完全翻转:
egress:
- api.github.com
之后,api.github.com返回200,其他一切都不返回任何东西。这是正确的设计,因为点名一个主机就等于明确表示你要的是默认拒绝的姿态。但一个未配置的会话有一个……
热门跟贴