deltabox,给AI编程Agent用的沙箱

给AI编程Agent用的开源沙箱,我做了多Agent并发提交和发布流水线,3个PR已合并。8个会话抢同一个文件时,被拒次数从约60次降到0,落地p95从接近2 s降到约185 ms。

时间
2026-08 至今
类型
科研
状态
进行中
我做了什么
IPADS实验室开源项目deltabox-lite的贡献者。我负责多Agent并发会话和发布锁仲裁(PR #4)、macOS会话的几处正确性修复(PR #2)、npm/Homebrew/一行安装的发布流水线(PR #29),还写了Pi和DeepSeek Harness两个Agent插件里的多Agent自动提交。沙箱本体(隔离后端、DeltaFS文件系统、三种文件模式)是项目组其他成员做的。
用到的技术
Rust、Landlock / seccomp(经Sandlock)、FUSE、macOS Seatbelt / APFS / FSEvents、JSON-RPC、Node-API、TypeScript、GitHub Actions、npm / Homebrew
代码
github.com/delta-box/deltabox-lite
commit
github.com/delta-box/deltabox-lite/commit/46c313f5634e5c56dd259a430dc1ad69fb023843
参考
数字都出自我自己的commit说明:816411b、2c67d3c、91a9ee1、d4a3897
AI 用在哪
开发时用了Claude等AI编程工具帮忙。这一页根据git记录整理,Claude帮忙起草。
最后更新
2026-10-15
关键数字
项目数值说明
8个会话抢同一个文件,被拒次数约60 → 0每个会话落地3次,共24次落地。commit 816411b的说明,本人测量
同一场景,落地p95接近2 s → 约185 mscommit 816411b,本人测量
macOS 8个会话并发启动,最坏情况661 → 182 msp50从300 ms到135 ms。commit 2c67d3c,本人测量
Linux 4个会话并发启动,总耗时1112 → 515 mscommit 2c67d3c,本人测量
64 MiB单文件commit145 → 22 msM4上测。commit 91a9ee1,本人测量
硬件
macOS的数字在Apple M4上测(commit说明里写的)
软件
deltabox-lite在feat/multiagent分支上的对应commit
方法
commit说明里只给了改动前后的结果,没有留下计时脚本
基线
同一分支改动之前的版本

这是什么

deltabox-lite是给AI编程Agent用的沙箱运行时,IPADS实验室的开源项目。

Agent在里面照常跑命令、改文件。所有改动都记在一个会话里,可以先看diff,再决定commit到真实项目,或者abort整体回滚。粒度可以是一个任务,也可以是一次工具调用。README里的比喻是「给Agent会话用的Git」,但对二进制和大文件没有负担。

它不是容器。Linux上用Sandlock(Landlock加seccomp)隔离进程,用项目自己写的DeltaFS(FUSE)记录改动;macOS上用Seatbelt、APFS克隆和FSEvents。没有常驻的守护进程,会话状态以磁盘上的文件为准。Agent通过JSON-RPC或Node-API接入。代码是Rust。

为什么做

原来一个项目同一时间只能开一个会话。想让几个Agent在同一个项目上并行干活,各自能diff、commit、abort,就要解决它们同时往宿主写的时候谁先谁后、冲突怎么办。

我做了什么

项目组其他成员做了沙箱本体:隔离后端、DeltaFS、三种文件模式、持久化和崩溃恢复。下面是我做的,都能在公开仓库里找到。

1. 多Agent并发提交(PR #4,13个commit,2026-08-31合并)

  • 每个项目一把排他的发布锁。谁先提交谁赢。
  • 每次发布在锁里追加一条发布日志:序号、会话、路径、内容摘要。
  • 后提交的会话,对自己没碰过的路径直接快进基线;碰到冲突,用deltabox sync把对方版本拉成<文件名>.deltabox-theirs,交给Agent合并。
  • commit --sync把「被拒、同步、合并、再提交」收进一次调用。--ours在锁里按发布日志的摘要判断哪些是兄弟会话的改动,可以直接接受;deltabox以外的改动仍然算冲突,不放行。
  • 会话启动时扫描宿主改拿共享锁,几个会话可以同时启动。

加锁顺序是写死的,避免死锁:

cbcow.lock -> session.lock -> operation lock -> publish.lock -> registry.lock

2. 正确性修复(PR #2和顺手修的几处)

  • 一次重构之后,macOS原生会话启动完,后面所有操作都报session not found。改成和其他后端一样走外部状态目录。
  • 默认策略里写死了/lib64,arm64的Debian/Ubuntu没有这个目录,受限命令一启动就失败,已经发布的linux-arm64预编译包也受影响。改成跳过不存在的路径。
  • 发布日志的序号原来只看一个head缓存文件,它丢了或者写到一半崩溃,序号会重复。改成以日志本身为准,读的时候忽略写坏的尾巴。
  • 为了测并发,加了测试用的暂停点:进程停在指定位置,等测试放行。这样交错顺序是确定的,不靠sleep碰运气。

3. 发布流水线(PR #29,11个commit,2026-09-22合并)

  • npm包加了启动器,全局安装后才有deltabox命令,并转发信号。
  • release.mjs一条命令改齐所有版本号,失败回滚,tag和main一起原子推送。
  • 每个平台出纯二进制包加sha256文件;Homebrew formula;curl | sh一行安装,校验sha256,不用sudo。
  • GitHub Actions改成打tag触发,先建草稿release,4个平台都构建、冒烟测试通过后再公开,失败可以重跑。

预编译包覆盖macOS(arm64、x64)和Linux(x64、arm64)。npm上的0.1.0和0.1.1是项目组在2026-10-14用这套流水线发的,发布前其他成员又改过脚本。

4. Agent插件和演示

  • 给Pi编程Agent的插件加了多Agent模式:任务结束自动提交,冲突时让Agent合并再提交,最多3轮;可以设成测试通过才提交,测试产生的文件不会被发布。插件自带39个测试。
  • 给DeepSeek Harness的插件做了同样的自动提交策略。
  • 搭了一个双Agent演示:两个终端同时让Agent改同一个文件,先提交的赢,输的那个自己合并后重新提交。

结果

下面的数字都出自我自己commit里的说明,是改动前后的对比。

场景 改之前 改之后 出处
8个会话抢同一个文件,被拒次数(共24次落地) 约60次 0次 816411b
同上,最长重试链 16 0 816411b
同上,落地p95 接近2 s 约185 ms 816411b
macOS,8个会话并发启动,最坏 / p50 661 / 300 ms 182 / 135 ms 2c67d3c
Linux,4个会话并发启动,总耗时 1112 ms 515 ms 2c67d3c
64 MiB单文件commit(M4) 145 ms 22 ms 91a9ee1

还有一个取舍:发布日志要给文件算摘要,在提交窗口里大约2 ms/MiB。先把上限定在4 MiB,后来开了硬件SHA-256,上限提到16 MiB。M4上16 MiB的提交p50是32 ms,比原来4 MiB用软件哈希的38 ms还快(d4a3897)。

README里另有一组性能数字(no-op命令13.7 ms对8.1 ms等),是项目组其他成员测的,不在这一页。

没做好的地方

  • 上面的数字只写在commit说明里,没有留下基准脚本和原始数据,重复次数也没写。
  • 并发启动的优化让单个会话启动在macOS上多了6 ms。
  • macOS的集成测试套件并行跑时不稳定,8次里有3次失败。我修编译问题时确认过这不是我引入的,但也没修好它。
  • Pi和DeepSeek Harness两个插件的改动目前还在功能分支上。
  • 内容摘要要读两遍文件(发布日志一遍,索引指纹一遍)。去掉重复是再提高上限的办法,还没做。

接下来

先把基准脚本补上,让上面这些数字能复现;再看能不能去掉内容摘要的重复读取,把单次提交的上限再往上提。

更正记录

暂无。

想聊这个项目,欢迎发邮件或在小红书私信我。