我花了一周时间优化 SayCraft 的 E2B 沙箱。最后发现,最该优化的地方根本不在沙箱里。
沙箱是什么、为什么要用
SayCraft 的核心能力是"边聊边建站"——用户在会议里说需求,AI 实时写代码、出预览。每场会议启动时,系统会在 E2B 云端开一个独立沙箱,里面跑 Vite 开发服务器和一个长驻的 Claude Code 进程。沙箱从预构建的模板镜像创建,Node.js、webapp skill、/workspace 目录、所有 npm 依赖都烤在里面,省掉了每次 npm install 的时间。
这个架构跑了几个月,基本稳定。但有两个问题一直卡着我。
60 分钟硬截止
E2B 沙箱有个硬限制:创建时设的 timeoutMs 到期后直接 kill,不商量。我最初设了 60 分钟,然后写了一套复杂的 keepalive 机制——每 15 分钟调一次 extendTimeout 续期,加上 throttle map 防止并发续期冲突。代码写了不少,逻辑也能跑通。
但有天我自己用产品的时候突然想到一件事:真实用户开会,中间一定会有自然停顿。不可能 60 分钟嘴不停地说需求。既然会停顿,那更合理的做法是——闲置 2 分钟就 pause 沙箱,用户回来时 resume,计时器自动重置。
pause/resume 本身就是 E2B 提供的 API。我把整个 keepalive 机制砍掉,timeout 改成 2 小时兜底,核心逻辑从几十行变成了一个 idle 检测。有时候复杂方案的对立面不是简单方案,是换个角度看问题。
19.5 秒的初始化到底花在哪
用户点"开始会议"到看到第一个预览,中间有一段等待。我在 Langfuse 里量了生产环境的全链路耗时:~19.5 秒。本地跑同样流程是 ~12.3 秒。差了 7 秒,完全是黑盒。
逐步拆解后,最大的单一开销浮出来了:Vite 首次启动时跑 esbuild optimizeDeps 预构建,吃掉了大约 11 秒。selectTemplateTool 本身只花 4 毫秒(同步返回模板配置),真正的 20 秒消耗在后台的 reinit 流程——解压模板、启动 Vite、等 dev server ready。
找到瓶颈后,我想了三个优化方案,分别丢给不同的 agent 做评估。
三个方案,两个被毙
方案一:在 bootstrap 阶段就预启 Vite,让 origin 模板提前完成 optimizeDeps。architect agent 否了——这个 1.5 秒的加速只对不换模板的场景成立,用户一旦选了别的模板就白跑了。
方案二:把 .vite/deps 缓存目录烤进 E2B 镜像。这个听起来最诱人,直接跳过 11 秒的预构建。code-explorer agent 查了 Vite 源码后判了死刑——缓存键包含完整的 import 图谱哈希,模板一换,依赖树变了,缓存必然失配,Vite 会全量重建。烤进去等于白烤。
方案三:给 reinit 每一步加 telemetry span。5 行代码,零风险。通过了。
选方案三不是因为它"最优",是因为我还不知道该优化什么。生产和本地差的那 7 秒,可能是网络延迟、可能是 E2B 冷启动、可能是 DNS、可能是磁盘 IO、可能是好几个因素叠加。先量再说。测量优先于优化,这个道理我知道,但每次还是忍不住想直接动手改。
真正的数据给了我一巴掌
我拉了一个完整会议(meeting 5U0DM3fWzqr)的全链路性能数据。
- 总耗时 1029 秒,大约 17 分钟
- trigger-classifier 判断用户意图:0.48 秒
- coordinator 做决策、拆任务:~24 秒
- 沙箱里 Claude Code 写代码:~998 秒
97% 的时间花在 LLM 写代码上。
我花一周精力盯着的沙箱初始化,就算全砍到 0,也只省 20 秒。对 17 分钟的总流程来说,不到 2%。
真正决定用户体验的是 Claude Code 在沙箱里写代码的速度——模型推理、文件读写、Vite HMR 热更新循环。这些不是我能通过调 E2B 参数或预构建缓存来解决的。它们取决于模型本身的速度,取决于 prompt 的效率,取决于一次写对还是来回改三轮。
我学到了什么
回头看,这一周不算浪费。keepalive 那套确实该砍,idle pause 方案更贴合真实使用场景。telemetry 加上了,后面有数据可追。三个优化方案的评审过程帮我建立了对 Vite 缓存机制和 E2B 生命周期的理解。
但最大的收获是那个数据:97% 的时间在 LLM 编码。这意味着下一步的优化方向很清楚——减少 Claude Code 的来回次数,提升单轮生成的准确率,优化 prompt 让模型一次写对更多代码。沙箱初始化的几秒钟,先放着。
做产品经常这样。你觉得瓶颈在 A,量完发现在 B。你花时间研究 A 不完全是浪费,因为排除错误答案本身就是进展。但如果一开始就量,能省不少弯路。
SayCraft 还在快速迭代中。如果你好奇"边聊边建站"是什么体验,来试试:saycraft.ai