smolvm 完整教學:用硬體隔離 VM 安全執行不受信任的 Python/JavaScript 程式碼(AI Agent 沙箱實戰)

smolvm 是開源的輕量 VM 工具(GitHub 4.6k stars、Apache 2.0),用 KVM/Hypervisor.framework 建立硬體隔離的微型虛擬機,冷啟動不到 200ms,網路預設關閉、支援 CPU/RAM/磁碟上限與 timeout——特別適合 AI Agent 執行 LLM 生成的不受信任程式碼。本文從安裝、Smolfile 到沙箱實戰完整教學,並附 Simon Willison 實測數據與 Docker/Firecracker/QEMU 比較表。

  • Dennis
  • 8 分鐘閱讀
smolvm 完整教學:用硬體隔離 VM 安全執行不受信任的 Python/JavaScript 程式碼(AI Agent 沙箱實戰)

結論:smolvm 是一款開源的輕量級 VM 工具(Apache 2.0、GitHub 4.6k stars),用 KVM 或 macOS Hypervisor.framework 把每個工作負載放進「硬體隔離」的微型 Linux 虛擬機,冷啟動 <200ms、記憶體彈性伸縮,網路預設關閉、可設 CPU/RAM/磁碟上限與執行 timeout——是目前把 AI Agent 產生的不受信任程式碼關進沙箱最簡單的選擇。

如果你的工作流已經進階到「讓 AI 寫程式碼、自己直接執行」,那你遲早會遇到這個問題:你敢直接跑 LLM 生成的程式碼嗎? 答案應該是不敢——你不知道它會不會 while true 吃光 CPU、會不會偷讀你的 ~/.ssh、會不會偷偷連上某個外部伺服器把資料傳出去。

傳統解法是 Docker 容器,但容器共用主機核心,隔離強度有限;完整 VM(QEMU)隔離夠強但啟動要 15–30 秒,跑一次任務等半天。smolvm 就是在這個縫隙裡冒出來的新選擇:硬體虛擬化隔離、但啟動快到可以當指令跑。這篇文章用 Simon Willison 8 月 19 日的實測數據 + 官方 README,帶你把 smolvm 完整玩一遍。

smolvm 是什麼?

smolvm(GitHub: smol-machines/smolvm)是一個 CLI 工具,讓你「本機建立並執行自訂 Linux 虛擬機」,核心賣點三個:

  1. 硬體隔離:每個工作負載有自己的 VM 和 guest 核心,不是共用核心的 namespace
  2. 極速啟動:冷啟動 <200ms,暖執行約 50ms——快到你感覺不出來它是 VM
  3. 跨平台:macOS(Apple Silicon/Intel)、Linux(KVM)、Windows(WHP)全支援

底層技術是 libkrun(VMM)+自訂 guest 核心(libkrunfw),macOS 用 Hypervisor.framework、Linux 用 KVM、Windows 用 Windows Hypervisor Platform。鏡像格式就是 Docker 的 OCI 格式——Docker Hub、ghcr.io 上的任何鏡像都能直接開成 microVM,不需要 Docker daemon。

graph LR
    A[smolvm CLI] --> B[libkrun VMM]
    B --> C{KVM / Hypervisor.framework / WHP}
    C --> D[硬體虛擬化隔離的 microVM]
    D --> E[自己的 guest 核心]
    D --> F[預設無網路]
    D --> G[CPU/RAM/磁碟上限]

安裝:一行指令

# macOS + Linux
curl -sSL https://smolmachines.com/install.sh | bash

# 安裝後確認
smolvm --help

裝完會放在 ~/.smolvm~/.local/bin 有 symlink,沒有常駐 daemon——這是它跟 Docker 很不同的地方,用完即走。

⚠️ Linux 前提:需要 /dev/kvm。雲端 VPS、巢狀虛擬化環境可能沒有(Simon 在測試時就遇到 Claude Code 容器內無 KVM 的狀況,最後改用 GitHub Actions runner 跑完整測試)。先檢查:

ls -l /dev/kvm

快速開始:跑一個指令

# 在臨時 VM 裡跑指令(結束自動清理)
smolvm machine run --image alpine -- sh -c "echo 'Hello from microVM' && uname -a"

# 互動式 shell
smolvm machine run -it --image alpine -- /bin/sh

這就跟 docker run 一樣直覺,差別是背後真的開了一台 VM。

Smolfile:把 VM 環境寫成檔案

Smolfile 是 smolvm 的「Dockerfile 對應物」——用 TOML 宣告整台機器的規格:鏡像、資源、網路策略、掛載、啟動指令,全部放進一個可簽入 git 的檔案:

image = "python:3.12-alpine"
net = true
cpus = 4
memory = 4096

ports = ["8000:8000"]
volumes = ["./src:/app"]
init = ["pip install -r /app/requirements.txt"]

[network]
allow_hosts = ["api.stripe.com", "pypi.org"]

[auth]
ssh_agent = true
smolvm machine create --name myvm -s Smolfile
smolvm machine start --name myvm

設計上很貼心的一點:未知的 key 會被拒絕而不是忽略——打錯字在 create 時就報錯,不會像某些工具靜默失敗。

核心用法:把不受信任的程式碼關進沙箱

這才是 smolvm 真正發光發熱的場景。LLM 生成的程式碼、使用者上傳的 Python 腳本、第三方套件的安裝腳本……這些「我沒逐行檢查過」的程式碼,全部適合丟進 smolvm 跑。看官方 README 的安全設計:

威脅smolvm 的防禦機制
while true 吃到 CPU--cpus(預設 4)+ --timeout 10s 強制結束
記憶體爆炸--mem 256(預設 8192 MiB,virtio-balloon 彈性伸縮)
偷偷連外部伺服器網路預設關閉;要連只能 --allow-host 白名單
偷讀主機檔案掛載是 opt-in:-v HOST:GUEST[:ro],沒掛就看不到
塞爆磁碟--storage(預設 20 GiB,真正的寫入上限)
惡意能力--unprivileged:限制 capabilities、guest 內 read-only cgroup

實戰 1:無網路沙箱執行使用者腳本

# 網路預設關閉——不受信任程式碼無法「打電話回家」
smolvm machine run --image alpine -- nslookup example.com
# 失敗:network is unreachable(完美)

# 只允許特定主機(egress 白名單)
smolvm machine run --net --image alpine \
  --allow-host registry.npmjs.org -- \
  wget -q -O /dev/null https://registry.npmjs.org
# 成功——白名單內的主機

smolvm machine run --net --image alpine \
  --allow-host registry.npmjs.org -- \
  wget -q -O /dev/null https://google.com
# 失敗——不在白名單

實戰 2:限時限資源跑 LLM 生成的 Python

# 最多 10 秒、256 MiB 記憶體、無網路
smolvm machine run --image python:3.12-alpine \
  --mem 256 --timeout 10s -- \
  python3 /dev/stdin <<'EOF'
while True: pass   # 惡意/失控程式碼
EOF
# 11 秒後 rc=124 被強制結束,無殘留 process

實測驗證(Simon Willison 的 CI 測試):--timeout 10s 的 spin 任務在 11 秒被殺掉、沒有殘留 process;--mem 256 下 1 GiB 配置請求被拒絕、主機記憶體幾乎沒動;fork bomb 1 秒內回傳 rc=2、主機負載僅 0.69——隔離真的有效

實戰 3:只給指定檔案,其餘看不見

# 只掛載 input 目錄(唯讀)與 output 目錄(可寫)
smolvm machine run --image python:3.12-alpine \
  -v ./input:/in:ro -v ./output:/out \
  -- python3 /in/transform.py --input /in/data.csv --output /out/result.csv

掛載用 virtiofs,guest 裡只會看到你明確給的目錄——主機的 /root/home/etc 一概不存在。

效能實測:Simon Willison 的數據

Simon Willison 8 月 19 日用 GitHub Actions(ubuntu-latest,有 KVM)跑了完整測試套件,以下是實測結果:

指標實測值
冷啟動(本機 alpine tar 鏡像)577–643ms(端到端)
建立 + 啟動 VM1524ms
暖執行(建立後 exec)48–162ms
超過 timeout 強制結束11 秒(rc=124),無殘留
記憶體上限防禦256 MiB 上限成功擋下 1 GiB 請求
fork bomb 防禦1 秒內 rc=2,主機 load 0.69
fork 池(CoW 複製)50–130ms 產出可用 VM

冷啟動不到 1 秒、暖執行 50ms 等級——這已經接近「直接在本機跑」的體感,卻有 VM 級的隔離。Simon 的測試也抓出幾個值得知道的坑:

  • 磁碟上限要用 --storage 不是 --overlay:實測 --overlay 1 沒綁住 / 的寫入(dd 寫了 4GB 照樣成功),改用 --storage 3 後 dd 在 2.9GB 被擋下、guest 滿載——寫入上限看 --storage
  • HTTP API 的 timeout 欄位是 timeoutSecs(camelCase),用 timeout_secs 會被靜默忽略——API 設計上的一個小地雷
  • 鏡像拉取在 guest 內進行:沒開 --net 時用 registry 鏡像會被拒絕或拉取失敗,離線環境請用 docker save 的 tar 檔

比較:smolvm vs Docker vs QEMU vs Firecracker

官方 README 有一張很實用的比較表,整理如下:

面向smolvmDocker 容器QEMUFirecrackerKata
隔離邊界VM + guest 核心Namespace + 共用核心VM + guest 核心VM + guest 核心每容器一 VM
啟動時間<200ms~100ms15–30 秒<125ms~500ms
架構Library(libkrun)DaemonProcessProcessRuntime stack
macOS 原生需 Docker VM
可嵌入 SDK
可攜成品.smolmachine 單檔鏡像(需 daemon)
許可證Apache 2.0Apache 2.0GPLApache 2.0Apache 2.0

什麼時候選誰?

  • 跑不受信任的 AI 生成程式碼 → smolvm(隔離 + 啟動速度兼得)
  • 需要 process 級隔離、資源最省 → Docker(但共用核心的風險要自己承擔)
  • 要跟 Kubernetes 生態整合 → Kata/Firecracker 那條路
  • 追求極致隔離、不在乎啟動慢 → QEMU

另外補一個生態系:如果你只是想在瀏覽器裡跑 Linux 做演示,可以看本站的 WebVM:在瀏覽器中執行的 Linux 虛擬機器——那是 WebAssembly 方案,跟 smolvm 的本機硬體虛擬化是完全不同的取捨。

進階:把整個環境打包成單一檔案

smolvm 一個很有特色的功能:把設定好的 VM 打包成 .smolmachine 單檔,推到任何 OCI registry,別人 pull 下來就是一模一樣的機器:

# 把機器打包成可攜成品
smolvm machine shell --name myvm        # 互動式設定環境
smolvm machine stop --name myvm
smolvm pack create --from-vm myvm -o myvm
smolvm pack push --file myvm.smolmachine ghcr.io/you/myvm:v1

# 別人直接開
smolvm pack pull ghcr.io/you/myvm:v1

# 或把 Python 環境打包成「可執行檔」
smolvm pack create --image python:3.12-alpine -o ./python312
./python312 run -- python3 --version
# Python 3.12.x —— 不需要 pyenv/venv/conda

這對團隊協作、CI、air-gapped 環境特別好用——依賴全部預烘焙,不需要安裝步驟,200ms 內開機

安全模型:要知道的界線

官方文件很誠實地劃了安全邊界,使用前建議讀一遍:

  1. smolvm CLI 與 VMM 以你主機使用者的權限執行——它假設你的主機帳號、OS、hypervisor 後端都在可信基礎內
  2. 掛載的目錄是「故意暴露」的:不要把密鑰、敏感路徑掛進不受信任的工作負載
  3. --ssh-agent 不會把私鑰複製進 guest,但會讓 guest 在 VM 運行期間請求簽名——只對你信任的工作負載啟用
  4. 把 guest 的 root 視為不受信任:VM 邊界限制它直接碰主機,但你明確轉交的能力(掛載、網路、port、SSH agent)都會變成它的權限
  5. 它「不是」一個硬化的多租戶控制平面——多租戶場景需要主機層的帳號隔離與 OS 層限制
  6. 釋出檔有 SHA-256 checksum 驗證,但目前沒有簽章與 provenance attestation

適合誰?AI Agent 開發者的沙箱新選擇

總結來說,smolvm 最殺的應用場景就是 AI Agent 的執行沙箱——無論是:

  • 讓 Agent(Claude Code、Codex、自建框架)執行它自己生成的程式碼
  • 把使用者上傳的 Python/JS 腳本跑在隔離環境
  • 資料轉換、批次處理等「輸入不可信」的任務
  • 把 CI 測試丟進乾淨的 VM 而不是共用 runner

如果你已經在用 Herdr 這類工具管理整群 AI Agent,或著迷於 Claude Code Auto Mode 的自動執行時代,smolvm 正好補上最後一塊拼圖:讓 Agent 真的可以「放手去跑」而不怕它搞壞你的機器。本站的 2026 精選 AI 開源專案地圖 也持續追蹤這類「Agent 安全基礎設施」工具,值得一併收藏。

有興趣深入的話,推薦直接讀 smolvm 官方 README 和 Simon Willison 的完整實測筆記——後者連原始碼層級的細節(timeout 強制、egress 過濾、fork 池)都驗證過,是目前最扎實的第三方評估。


資料來源:

📬 訂閱 most.tw 電子報

每週精選 AI 工具教學與技術乾貨,直接送到你的信箱。免費、隨時可退訂。

💬 有問題想討論?加 LINE 聯絡我

歡迎透過 LINE 官方帳號直接留言,我會盡快回覆你的問題。

加入 LINE 好友