本教學從 JavaScript 或 TypeScript 中執行一個沙箱。您會啟動一台隔離的 Firecracker 微虛擬機器,用三種語言執行程式碼、傳輸檔案,並檢視長任務的輸出。每一步都是一小段程式碼。
您需要 Node.js 18+(或 Deno、Bun)以及一個 EQVPS 帳戶。
1. 取得權杖
SDK 使用普通的帳戶權杖進行認證。連線帳戶頁面介紹瞭如何從控制面板、API 或 MCP 伺服器取得權杖。
export EQVPS_API_KEY="your-token"
沒有餘額的新帳戶第一次建立沙箱時會獲得 1 美元沙箱額度,足夠把本教學跑很多遍。
2. 安裝 SDK
npm i @eqvps/sdk
範例使用 ES 模組和頂層 await。請儲存為 .mjs 檔案,或儲存為 .ts 並用 npx tsx 執行。
3. 啟動沙箱並執行程式碼
import { Sandbox } from "@eqvps/sdk";
await Sandbox.with({ tariff: "small" }, async (sb) => {
console.log(sb.id);
const r = await sb.run("import platform; print(platform.python_version())");
console.log(r.exit_code, r.stdout);
});
輸出是沙箱 id(sb_ 加 24 個字元),然後是 0 3.12.x。回撥結束時 Sandbox.with 會刪除沙箱,即使回撥丟擲異常也一樣。
預設語言是 Python,另外兩種只差一個選項:
await Sandbox.with({}, async (sb) => {
const js = await sb.run("console.log(process.version)", { language: "node" });
const sh = await sb.run("uname -r && nproc", { language: "bash" });
console.log(js.stdout, sh.stdout);
});
失敗的指令碼不會丟擲異常。請檢查 r.ok:exit_code 為 0 且指令沒有超時,它才為 true。
4. shell 指令和套件
exec 接受 shell 字串或 argv 陣列。沙箱可以存取網際網路,所以 npm 和 pip 安裝都能用:
await Sandbox.with({ tariff: "small" }, async (sb) => {
await sb.exec("mkdir -p /root/app && cd /root/app && npm init -y && npm i lodash", { timeout: 55 });
const r = await sb.exec(["node", "-e", "console.log(require('/root/app/node_modules/lodash').VERSION)"]);
console.log(r.stdout);
});
一次同步呼叫最多 55 秒,更長的任務放到背景任務裡(第 6 步)。
5. 檔案
await Sandbox.with({}, async (sb) => {
await sb.upload("/root/input.json", JSON.stringify({ values: [3, 5, 8] }));
await sb.run("import json; d = json.load(open('/root/input.json')); open('/root/out.txt', 'w').write(str(sum(d['values'])))");
console.log(await sb.downloadText("/root/out.txt")); // 16
});
upload 接受字串或 Uint8Array。download 返回 Uint8Array,downloadText 返回字串。單次傳輸上限 5 MB。
6. 帶即時輸出的長任務
await Sandbox.with({ tariff: "standard" }, async (sb) => {
const task = await sb.exec("for i in 1 2 3 4 5; do echo step $i; sleep 20; done", { background: true });
const res = await task.wait({ onOutput: (out) => process.stdout.write(out) });
console.log(res.state, res.exit_code); // done 0
});
任務會立即返回,沒有 55 秒的限制。wait 預設每 2 秒輪詢一次(可用 pollIntervalMs 修改)。task.kill() 停止任務;sb.task(id) 可以從另一個程式重新連線。
錯誤
import { Sandbox, InsufficientBalanceError, RateLimitError } from "@eqvps/sdk";
try {
await Sandbox.with({}, async (sb) => console.log((await sb.run("print(1)")).stdout));
} catch (e) {
if (e instanceof InsufficientBalanceError) console.log("Top up the balance");
else if (e instanceof RateLimitError) console.log("Busy, retry in", e.retryAfter);
else throw e;
}
伺服器傳送 Retry-After 時,SDK 會自動重試 429 和 503,最多 3 次。最常見的 429 來自同一帳戶同時執行超過兩條指令。所有錯誤型別見 SDK 參考。
本教學的花費
每個範例只存在了幾秒,按最低 60 秒計費:small 上 0.00055 美元,standard 上 0.0011 美元。第 6 步的任務在 standard 上執行約 100 秒,約 0.002 美元。全部加起來遠不到 1 美分。完整價目見沙箱限制與計費。
下一步
- 同樣的內容用 Python:5 分鐘上手沙箱 Python SDK。
- 接入一個模型,讓它執行自己寫的程式碼:在沙箱中完成第一個代理任務。
- 方案和 1 美元試用:沙箱頁面。
評論
目前還沒有評論。歡迎成為第一位。