- 开发工具
- CLI
- 机器学习
【免费下载链接】huggingface_hub
The official CLI and Python client for the Hugging Face Hub.
导读:Sandbox 是
huggingface_hub提供的一项实验性能力——基于 Hugging Face Jobs,在云端以秒级启动一台隔离机器,支持实时流式执行命令、文件双向传输、内部服务代理,并可一键扩展到上百个廉价并行环境。读完本指南,你将掌握两种沙箱形态(专用 VM 与共享 Pool)的选型与完整 API 用法,能够安全地运行不受信任或 AI 生成的代码、复现构建与实验,以及用线程池展开 RL rollout / 批量评估等 fan-out 工作负载。
[!NOTE] 沙箱是实验性功能:API、默认值与行为可能随时变更。共享沙箱面向同一信任边界内的工作负载,其隔离并不保证抵御所有跨沙箱攻击;互不信任的工作负载请使用专用沙箱,并避免向沙箱工作负载授予长期、大范围的凭据。
1. 什么是 Sandbox:一条 Job 之上的隔离机器
Sandbox 是一台云端的隔离机器:几秒内拉起、实时流式执行命令、自由移入移出文件——全部通过 Python 或 CLI 完成。从实现角度看,沙箱构建在 Jobs 之上:一个沙箱本质上就是一个运行着小型 HTTP 服务器的 Job,该服务器通过 HTTP 暴露命令执行与文件传输能力。
它适合所有"代码需要跑在自己机器之外"的场景:
- 运行不受信任或 AI 生成的代码——让 Agent 执行任意代码而不接触你的文件系统。此时应使用专用(dedicated)沙箱:它是一台独立的 VM。
- 可复现的构建与实验——在干净、定义明确的镜像上运行,支持 CPU 或 GPU。
- 大规模并行(fan-out)——低成本地一次性拉起数百个并行环境(RL rollout、评估、批量工具执行)。
镜像只需包含/bin/sh即可,无需预装 Python、pip 或 Agent——启动时会注入一个很小的静态服务器二进制文件。
[!TIP] 想了解底层机制——Job 内的服务器、无状态鉴权、单个 Job 如何承载多个相互隔离的沙箱——可阅读 Sandboxes 概念指南。
1.1 两种沙箱形态速览
获取沙箱有两种途径,二者返回同一个Sandbox对象(同样的run、files、connect、kill),仅在底层机器的分配方式上不同:
Sandbox.create—专用 | SandboxPool—共享 / Pool | |
|---|---|---|
| 映射 | 一个 Job =一个沙箱(整台 VM) | 一个 Job =多个沙箱(一台 VM,密集打包) |
| 隔离 | 完整 VM | uid + Landlock(同用户信任) |
| 冷启动 | 每个沙箱约 6 秒 | 首个宿主约 6 秒,之后每个约 1 次网络往返 |
| 成本 | 每个沙箱一台 VM | 每个宿主一台 VM,由众多沙箱分摊 |
| GPU | ✅ | ❌(仅 CPU) |
| 适合场景 | 单个沙箱、GPU 负载、不受信任的代码 | 大量廉价 CPU 沙箱(RL rollout、fan-out) |
经验法则:需要 GPU 或运行互不信任的代码 → 用专用沙箱;需要数百个廉价 CPU 沙箱 → 用 Pool。隔离机制的具体差异(uid + Landlock在共享模式下的边界与已知局限)在概念指南的 隔离原理 与 已知局限 中有详细说明。
2. 快速上手
创建沙箱会阻塞直至就绪(cpu-basic下约 6 秒):
>>> from huggingface_hub import Sandbox >>> with Sandbox.create() as sbx: # ready in ~6s ... result = sbx.run("python -c 'print(40 + 2)'") # ~100ms per command ... print(result.stdout) 42with块退出时会自动kill()沙箱。默认镜像为python:3.12、默认硬件 flavor 为cpu-basic(见 源码默认值)。
2.1 任意镜像与硬件
沙箱可以在任意含/bin/sh的 Docker 镜像(Docker Hub 或hf.co/spaces/...)上运行,并选择任意硬件 flavor(完整列表见 Jobs 指南):
>>> sbx = Sandbox.create(image="alpine:3.20") >>> sbx = Sandbox.create(image="pytorch/pytorch:2.6.0-cuda12.4-cudnn9-devel", flavor="a10g-small")常用硬件 flavor(节选自 自动生成表,完整列表可运行hf jobs hardware或list_jobs_hardware()获取):
| name | 规格 | 加速器 |
|---|---|---|
cpu-basic | 2 vCPU / 16 GB / 50 GB | 无 |
cpu-upgrade | 8 vCPU / 32 GB / 50 GB | 无 |
t4-small | 4 vCPU / 15 GB / 50 GB | 1x T4 (16 GB) |
a10g-small | 4 vCPU / 15 GB / 110 GB | 1x A10G (24 GB) |
a100-large | 12 vCPU / 142 GB / 1000 GB | 1x A100 (80 GB) |
h200 | 23 vCPU / 256 GB / 3000 GB | 1x H200 (141 GB) |
GPU 负载仅适用于专用沙箱;SandboxPool的宿主只支持 CPU flavor。
3. 运行命令
Sandbox.run执行命令并等待其完成。参数可以是 shell 字符串或 argv 列表:
>>> sbx.run("pip install -q numpy") # string → runs through /bin/sh -c >>> sbx.run(["python", "-c", "import numpy; print(numpy.__version__)"]) # list → exec'd directly # Live output streaming, plus env, cwd, timeout, stdin >>> sbx.run("make -j4", cwd="/app", env={"CC": "gcc"}, timeout=600, on_stdout=print, on_stderr=print)3.1shell=参数:显式指定执行方式
默认根据类型推断执行模式(字符串走/bin/sh -c,列表直接作为 argv exec)。显式传shell=可以规避一个经典陷阱——单元素列表如["echo hi"]会被 exec 为一个名为"echo hi"的单一程序:
>>> sbx.run("echo $HOME && ls | wc -l", shell=True) # force the shell (pipes, globs, $VARS) >>> sbx.run(["git", "commit", "-m", msg], shell=False) # force argv (no quoting surprises)约束:shell=True要求字符串,shell=False要求列表;类型不匹配会抛出ValueError。该一致性校验由_exec_payload在构造请求体时强制执行,并有对应测试覆盖(test_run_rejects_mismatched_shell_and_cmd)。
3.2 退出码与非零退出
命令以非零状态退出时会抛出SandboxCommandError,异常携带stdout、stderr与exit_code。传check=False则返回SandboxCommandResult而非抛错:
>>> result = sbx.run("test -f /tmp/missing", check=False) >>> result.exit_code 1SandboxCommandResult还带有signal、timed_out、duration_ms字段与ok属性(数据类定义)。关于流式输出的两个重要细节(源码实现):
- 输出经 NDJSON 事件流传输(
stdout/stderr/exit,跳过ping心跳),on_stdout/on_stderr回调随分块实时触发; - 默认会累积输出到结果中,上限为 64 MiB(
MAX_CAPTURED_OUTPUT_CHARS);大量输出时应传capture_output=False配合回调消费,避免无界内存占用——对应测试见 TestResourceBounds。
3.3 后台进程
传background=True可启动长驻进程(服务器、监视器、训练任务)而无需等待。run立即返回SandboxProcess而非SandboxCommandResult:
>>> proc = sbx.run("python -m http.server 8000", background=True) >>> proc SandboxProcess(pid=1234, cmd='python -m http.server 8000', tag=None, started_at_ms=1700000000000, running=True, exit_code=None)用sbx.processes()列出沙箱进程、用proc.kill()停止(幂等操作,见 SandboxProcess.kill)。已完成的进程会保留在列表中(running=False并带exit_code),直到沙箱被删除,因此可以据此判断进程是仍在运行还是已退出:
>>> sbx.processes() [SandboxProcess(pid=1234, cmd='python -m http.server 8000', tag=None, started_at_ms=1700000000000, running=True, exit_code=None)] >>> proc.kill()注意:后台模式下只有env、cwd与shell生效——timeout、stdin、on_stdout、on_stderr、check等流式/等待型选项不适用。
4. 文件操作
SandboxFiles通过sbx.files提供完整的沙箱文件系统操作:
>>> sbx.files.write("/app/script.py", "print('hi')") # str | bytes | file-like >>> sbx.files.read_text("/app/script.py") "print('hi')" >>> sbx.files.upload("local_data.csv", "/data/data.csv") # local -> sandbox >>> sbx.files.download("/data/results.bin", "results.bin") # sandbox -> local >>> sbx.files.list("/data") [FileEntry(name='data.csv', path='/data/data.csv', type='file', size=5324, ...)]其他辅助方法:stat、exists、mkdir、delete。
值得了解的实现细节(源码注释):
- 路径语义因模式而异:专用模式下路径为容器文件系统上的绝对路径;共享(Pool)模式下所有路径都锚定在沙箱私有 home(其唯一可写区域)中,前导
/也相对 home 解析,..无法逃逸(详见概念指南的 Pool 文件模型)。 - 大文件并行传输:超过 2 MiB 的文件会被拆分为 1 MiB 的分片,通过最多 16 个并行连接进行 range 请求传输(
PARALLEL_THRESHOLD/PARALLEL_CHUNK_SIZE/PARALLEL_MAX_WORKERS),以突破单一 TCP 流经 Jobs 代理的带宽-延迟积限制。 - 下载安全性:字节先写入目标目录下的私有临时文件(
O_EXCL防竞争、O_NOFOLLOW防符号链接、0600权限),完成后才os.replace到最终路径——中断的传输不会留下截断文件,符号链接目标会被替换而非写入(_open_download_target)。 - 读入内存有上限:
read/read_text超过 512 MiB(MAX_READ_BYTES)会抛出SandboxError,超大文件请改用流式写盘的download。 - 目录列表跟随分页:
list会自动跟随服务器的游标返回完整目录(SandboxFiles.list)。
5. 访问沙箱内的服务器:端口代理
先在沙箱内(后台)启动一个服务器,再从外部通过Sandbox.proxy_url_for访问它——请求由 Job 内沙箱服务器转发到你的内部服务器,无需额外暴露公网端口。它支持普通 HTTP、Server-Sent Events 与 WebSocket。将 URL 与Sandbox.proxy_headers配对用于鉴权(你的 WebSocket / HTTP 客户端必须携带这些头):
>>> import httpx2 >>> with Sandbox.create() as sbx: ... sbx.files.write("app.py", "...") # a server exposing e.g. /hello and /ws ... sbx.run("uvicorn app:app --host 127.0.0.1 --port 8000", background=True) ... # plain HTTP ... r = httpx2.get(sbx.proxy_url_for(8000, "/hello"), headers=sbx.proxy_headers) ... # WebSocket: ask for a wss:// URL ... ws_url = sbx.proxy_url_for(8000, "/ws", scheme="wss://")使用proxy_headers时,必须在 HTTP 客户端中禁用重定向(httpx 用follow_redirects=False,requests 用allow_redirects=False)。应用可能重定向到其他源,这些自定义鉴权头绝不能转发到那里。底层传输也强制follow_redirects=False(_SandboxServer),因为 Jobs 代理直接服务 Job 内服务器,协议中不存在重定向。
5.1 内部服务器按沙箱类型区分监听方式
- 专用(
Sandbox.create):在127.0.0.1:<port>上绑定普通 TCP 端口。 - Pool / 共享(
SandboxPool):共享沙箱无法绑定 TCP 端口(Landlock 限制),因此须监听$SBX_PROXY_DIR/<port>.sock上的unix socket(该环境变量在每个沙箱中都会设置),例如uvicorn app:app --uds $SBX_PROXY_DIR/8000.sock。客户端一侧(proxy_url_for/proxy_headers)两种模式完全一致。
Pool 沙箱要求服务器返回每沙箱能力令牌;缺少令牌视为错误,此时应升级并回收宿主,而不是使用宿主管理令牌(客户端拒绝用宿主凭据替代缺失的作用域令牌,见 Token scope)。
6. 生命周期:持久化与重连
沙箱的生命周期长于创建它的进程——你现在创建、稍后在任何持有相同 HF token 的机器上重连,无需拷贝任何状态:
>>> sbx = Sandbox.create() >>> sbx.id '687f911eaea852de79c4a50a' # Later, from anywhere: >>> sbx = Sandbox.connect("687f911eaea852de79c4a50a") >>> sbx.kill() # terminate now无状态重连之所以可行,源于底层无状态鉴权设计(概念指南):
nonce = random 128-bit hex # 存储在 Job 标签 "hf-sandbox-nonce" 中 token = HMAC-SHA256(key=your_hf_token, msg="hf-sandbox:" + nonce)nonce 是公开的,HMAC 密钥是你的 HF token——任何持有该 token 的机器都能重算出沙箱 token(实现见_derive_sandbox_token),这正是重连无状态的原因。每个沙箱 Job 还带有稳定标签hf-sandbox=1与hf-sandbox-mode=dedicated|pool,便于服务端筛选(标签常量)。
6.1 计费与超时规则
idle_timeout(默认 10 分钟)是真正的守护者:当没有任何 API 调用且没有进程在运行时,沙箱自动关闭,因此被遗弃的沙箱会停止计费。可在创建时设置(Sandbox.create(idle_timeout="30m")),或传None禁用。默认值见DEFAULT_IDLE_TIMEOUT。- Job 还有固定的24 小时最大生命周期作为硬性兜底(不可配置,
SANDBOX_MAX_LIFETIME)。 forward_hf_token=True会显式地把你的 HF token 作为HF_TOKEN暴露给沙箱内运行的代码。即使不传该参数,也不要把沙箱当作凭据的硬边界——参见本页开头的警告。
注意一个细节:前台命令目前不计入"活动"——单个run()若耗时超过idle_timeout且无其他 API 流量,沙箱可能在它下面被关闭;长时间单条命令请调大超时或传None(Sandbox.create文档)。
7. 一次要很多沙箱:SandboxPool
当需要大量沙箱(并行 RL rollout、fan-out 评估、批量工具执行)时,每个沙箱一个 Job 很浪费:每次都要付整台 VM 的冷启动费用,并为只需几 MB 内存的工作负载独占整台机器。SandboxPool将众多轻量沙箱打包进少数共享宿主 Job——一台计费 VM 服务数十个沙箱,单沙箱成本按该因子下降,单沙箱冷启动约为一次网络往返。
>>> from huggingface_hub import SandboxPool >>> with SandboxPool(image="python:3.12", flavor="cpu-basic", warm_up=2) as pool: ... boxes = [pool.create() for _ in range(100)] # packed across the 2 warm host VMs ... print(boxes[0].run("echo hi").stdout) # each box is a normal Sandbox hi每个create()返回一个完整的Sandbox;重复调用即可 fan-out。Pool 按需启动宿主 Job,每个宿主打包sandboxes_per_host(默认 50)个沙箱,并在close()(或宿主闲置时,作为计费兜底)终止一切。典型 fan-out 模式:
>>> from concurrent.futures import ThreadPoolExecutor >>> with SandboxPool(image="python:3.12", warm_up=4) as pool: ... boxes = [pool.create() for _ in tasks] ... with ThreadPoolExecutor(32) as ex: ... outputs = list(ex.map(lambda b, t: b.run(t.cmd).stdout, boxes, tasks))7.1 参数归属:哪些属于沙箱、哪些属于 Pool
Env 与idle_timeout是每沙箱级别的(属于create()而非 Pool),因此同一 Pool 中的沙箱可以有不同的环境:
>>> sbx = pool.create(env={"SEED": "42"}, idle_timeout="5m", forward_hf_token=True)Pool 沙箱是完整的Sandbox,但少数输入由宿主固定而非每沙箱设置——因此SandboxPool.create接受的参数集小于Sandbox.create:
| 输入 | Sandbox.create(专用) | SandboxPool.create(共享) |
|---|---|---|
image、flavor | 每沙箱 | 由 Pool 固定(宿主上设置一次) |
volumes | 每沙箱 | 不可用(在宿主启动时挂载) |
env | 每沙箱 | 每沙箱 |
idle_timeout | 每沙箱 | 每沙箱 |
forward_hf_token | 每沙箱 | 每沙箱 |
关于 env 的语义差异(源码说明):共享沙箱共享一个长驻宿主 Job,因此没有专用沙箱那种加密 Job 机密通道;但共享沙箱的env是在创建沙箱时(而非 Job 启动时)送达宿主服务器的,从不存储在任何 Job 元数据中——可将拟用机密直接作为普通env传递。需要加密存储的值,请使用专用沙箱的secrets。
7.2 按需扩容与预热
pool.create()一次只创建一个沙箱,优先复用仍有空闲容量的宿主,满了才启动新宿主——工作到来时逐个生成沙箱,它们会自动打包进热宿主:
>>> pool = SandboxPool(image="python:3.12", flavor="cpu-basic") >>> sbx = pool.create() # boots the first host (~6s) >>> sbx = pool.create() # packs onto the same warm host (~one round-trip, no new VM)为避免头几次调用承担宿主冷启动,可用warm_up=N预置宿主(在第一次create()时启动),或预先调用pool.warm(N)。宿主在构造时并行预启动,数量受max_hosts成本上限约束(_provision_hosts);达到上限且所有宿主满载时create()会抛错。打包密度由宿主服务器权威执行:宿主拒绝超过sandboxes_per_host的创建并返回{"rejected": N},客户端将溢出打包到另一宿主或启动副本(_create_one)。
7.3 跨进程、跨机器复用 Pool
热宿主通过 Job 标签被发现,因此跨进程复用有效:一个全新的SandboxPool(相同image/flavor/name)会挂到早前运行遗留的宿主上,而不是启动自己的宿主。传入name=可防止不同 Pool 共享宿主(未指定时自动生成pool-<随机>名称,源码)。
要从另一台机器、无本地状态地重连,用SandboxPool.connect按 Pool id 重连——它找到运行中的宿主,从该宿主 Job 重建 Pool 配置(image、flavor、打包密度),即可继续create():
>>> pool = SandboxPool.connect("pool-ae9f7efe0bc7") # from anywhere, no config needed >>> sbx = pool.create()connect() 得到的 Pool 并不拥有共享宿主(其他客户端可能正在使用),因此——如同Sandbox.connect——退出其with块(或调用close())只会释放本地 HTTP 客户端而让宿主继续运行。用hf sandbox pool delete <id>显式终止 Pool 的宿主。
[!NOTE] 宿主内的沙箱通过不同的 uid 与每沙箱 Landlock 规则集隔离。共享沙箱面向同一用户自己的并行工作负载,不保证抵御所有跨沙箱攻击。互不信任的代码或 GPU 负载,请使用
Sandbox.create(每沙箱独立 VM)。两种模式权衡的完整分析见概念指南:隔离如何工作 与更重要的——已知局限 清单。
7.4 本地缓存:让create --pool保持快速
Pool 刻意不持有权威本地状态(概念指南),但冷启动 CLI 进程若每次都要重新发现一切会太慢。因此客户端维护一个best-effort 缓存,位于$HF_HOME/sandbox/pools/<context>/<pool-id>.json(实现见 src/huggingface_hub/_sandbox_cache.py):一次 create/warm 后,进程会记录 Pool 配置与各宿主的代理 URL、鉴权 nonce 与最近空闲槽位;下一进程直接从文件重建宿主传输(零 HTTP)直达POST。
<context>是端点 + 凭据 + 命名空间的摘要(凭据仅存指纹,token 从不落盘,CacheContext);三方不匹配即为缓存未命中。缓存文件0600、目录0700。缓存值得注意的性质:宿主容量始终以服务器为准;超过 15 分钟(HOST_TRUST_TTL)的条目必须经inspect_job复核仍在运行且仍暴露同一 URL 才被采信;缓存可安全删除(删除即缓存未命中,冷路径照常工作)。也正因如此,创建 Pool 时使用了--namespace的话,hf sandbox create --pool <id>需要同样的--namespace,否则走冷路径。
8. 从 CLI 使用
hf sandbox命令镜像 Python API。创建专用沙箱:
>>> hf sandbox create ✓ Sandbox ready id=687f911eaea852de79c4a50a image=python:3.12 elapsed=6.0s # 给底层 Job 附加标签 >>> hf sandbox create --label controller-run=run-42 --label team=data-infra >>> hf sandbox exec 687f911eaea852de79c4a50a -- python -c "print('hi')" hi >>> hf sandbox cp data.csv 687f911eaea852de79c4a50a:/data/data.csv >>> hf sandbox kill 687f911eaea852de79c4a50ahf sandbox exec实时流式输出并以命令的退出码退出,因此可组合进脚本:
hf sandbox exec $ID -- pytest && echo "tests passed"后台长驻进程用hf sandbox spawn启动(打印其 pid),再列出或停止进程。列表显示每个进程的状态(running或exited (<code>)):
>>> hf sandbox spawn $ID -- python -m http.server 8000 ✓ Process started sandbox=687f... pid=1234 >>> hf sandbox process ls $ID pid status cmd 1234 running python -m http.server 8000 >>> hf sandbox process kill $ID 12348.1 CLI 操作 Pool
对大量廉价共享沙箱,先预热一个 Pool 再按需创建:
# 预热 Pool -> 打印 pool id(计费开始:宿主 VM 已运行) >>> hf sandbox pool create python:3.12 --flavor cpu-basic ✓ Pool created id=pool-ae9f7efe0bc7 image=python:3.12 flavor=cpu-basic host=687f... elapsed=5.7s # 每次 create 打包到有空间的宿主(凭 pool id,从任意机器可找); # 仅当所有宿主都满时才启动副本。Env 是每沙箱的(共享沙箱共用宿主, # 没有加密机密通道——请用 --env)。 >>> hf sandbox create --pool pool-ae9f7efe0bc7 --env LOG_LEVEL=debug >>> hf sandbox create --pool pool-ae9f7efe0bc7 >>> hf sandbox pool ls >>> hf sandbox pool delete pool-ae9f7efe0bc7 # 终止 Pool 的宿主(及其所有沙箱)hf sandbox create --pool产生共享沙箱,其 id 形如<host_job_id>.<local_id>,凡专用 id 可用之处(exec、cp、kill)它都能用。一个 Pool没有本地状态——它就是其运行中的宿主 VM 集合,凭 pool id 定位,因此可从任意机器使用,且当所有宿主消失(被 kill 或闲置超时)时即不复存在。CLI 的完整实现见 src/huggingface_hub/cli/sandbox.py,其中pool create支持--per-host(默认 50)与--max-hosts成本上限参数,kill支持--all终止命名空间内全部沙箱。
9. 底层原理速览(加深理解)
从概念指南(Sandboxes under the hood)可确认以下实现事实,帮助你评估信任模型与排查问题:
- 没有独立的"沙箱服务":沙箱就是一个 HF Job(VM),其中运行单个小型静态二进制
sbx-server(监听不常用的端口 49983,常量)。客户端通过 Jobs 代理(Job 暴露的*.hf.jobsURL)与它通信;鉴权、发现、打包全部建立在 Jobs 的 labels / env / secrets 原语之上。 - 服务器启动引导:Job 启动命令是一个
/bin/sh -c脚本,下载sbx-server(约 640KB 静态 musl 构建,零运行时依赖)、校验 SHA256 后exec(脚本见_BOOTSTRAP_DOWNLOAD)。下载优先走wget/curl(快),镜像两者皆无时回退到始终挂载的服务器 bucket(冷启动增加约 2-3 秒)。镜像唯一硬性要求是/bin/sh。二进制按摘要(SANDBOX_SERVER_SHA256)固定,且校验先于chmod +x;镜像无sha256sum/openssl且未显式SBX_ALLOW_UNVERIFIED_SERVER=1时默认拒绝运行(对应测试见 TestServerBinaryPinning)。 - 协议协商:客户端在
/health上核对服务器声明的protocol(当前为 3)——只接受"更新"服务器、拒绝"更旧"的,避免协议不匹配在无关路由上以 403 形式延后爆发(_check_server_protocol)。Pool 宿主会保留启动时下载的二进制最长 24h,遇到旧服务器需回收宿主升级。 - 双重鉴权:Jobs 代理要求携带对命名空间有读权限的 HF token(公网无法触达);
sbx-server在除/health外的每个请求上额外校验X-Sandbox-Token(防御纵深)。HF token 本身不会作为环境变量或 Job 机密进入沙箱(除非forward_hf_token=True)——但这不是硬保证:不可信镜像可能观察到客户端发送的请求(含Authorization头)。 - Pool 的隔离基元:共享沙箱是"专属 uid(≥20000)+ 私有
0700home + 净化环境(env_clear)+NO_NEW_PRIVS+ rlimits + 每沙箱 Landlock 规则集"。创建沙箱约 1ms 服务端(mkdir + chown + build ruleset),无第二次 VM 启动。Landlock 提供:沙箱间无法读取进程environ、无法信号/调试/读内存、无法访问/tmp与/dev/shm、无法绑定 TCP 端口,跨沙箱抽象 unix socket 亦被阻断(LANDLOCK_SCOPED_ABSTRACT_UNIX_SOCKET)。
10. 选型与安全底线
最后总结两种模式的适用边界:
- 专用沙箱(
Sandbox.create):每沙箱独立 VM,隔离最强,支持任意硬件含 GPU。注意 VM内部sbx-server与你的代码同以 root 运行——服务器并不替命令做沙箱,只是用 HTTP 暴露它。因此一旦不可信代码在专用沙箱内执行过,就把整台 VM(含其控制面)视作属于该代码:它对沙箱的一切后续操作都将受其摆布。建议"一个不受信任负载一个专用沙箱,用完即 kill",而不要在信任边界间复用。 - 共享 Pool(
SandboxPool):uid + Landlock隔离,面向同一信任边界的廉价并行。共享内核、VM 与控制面意味着不保证抵御所有跨沙箱攻击,资源与部分进程列表元数据仍共享,且不支持 GPU。
衡量选择时,概念指南提供了实测性能数据(Performance,基于真实cpu-basicJobs):专用沙箱冷启动中位数约 5.8s,run()往返 p50 约 110ms;1000 个沙箱经 Pool(20 宿主、每宿主 50 个)完成 provision + create + exec + kill 合计约 16s。这些数据可帮助你按工作负载规模估算成本与延迟。
无论哪种模式,都要牢记开篇警告:这是实验性 API,行为可能变化;共享沙箱隔离不保证抵御所有跨沙箱攻击;避免把长期、大范围凭据暴露给沙箱工作负载。需要进一步理解信任模型时,概念指南 的威胁模型表格与 已知局限 是最权威的参考。
- 开发工具
- CLI
- 机器学习
【免费下载链接】huggingface_hub
The official CLI and Python client for the Hugging Face Hub.
相关推荐
深蓝词库转换(IME WL Converter)词频管理(Word Rank)机制全解析:从 LLM 批量生成到 CLI/ GUI 配置实践
深蓝词库转换(IME WL Converter)词频管理(Word Rank)机制全解析:从 LLM 批量生成到 CLI/ GUI 配置实践 导读 本文围绕“深
桌面应用CLI开发工具Ralph E2B 云沙箱执行指南:在云端隔离环境运行 Claude Code 自主循环
Ralph E2B 云沙箱执行指南:在云端隔离环境运行 Claude Code 自主循环 本篇技术指南围绕 Ralph 项目(Autonomous AI dev
人工智能AI 应用自主智能体CLI开发工具mise exec 命令深度指南:在隔离环境中运行带工具集的任意命令
mise exec 命令深度指南:在隔离环境中运行带工具集的任意命令 mise exec (别名 x )是 mise 的核心命令之一,用于在 不修改当前 she
开发工具CLI
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考