以编程方式使用文档

A **快照** 是一个由 Docker 镜像支持的可复用文件系统包。当您想从自定义文件系统镜像启动沙盒时,请构建或捕获快照。

您也可以从运行中的沙盒捕获快照——安装软件包、写入数据文件或配置状态,然后对结果进行快照并将其作为新的起点复用。

!沙盒快照页面

从 Docker 镜像构建快照

通过指向任何 Docker 镜像来构建快照。调用会阻塞直到快照就绪(默认超时为 60 秒;对于大型镜像请增加超时时间)。

from langsmith.sandbox import SandboxClient

client = SandboxClient()

snapshot = client.create_snapshot(
    "python",
    docker_image="python:3.12-slim",
    fs_capacity_bytes=1 * 1024**3,  # 1 GiB
)

print(snapshot.id)
const client = new SandboxClient();

const snapshot = await client.createSnapshot(
  "python",
  "python:3.12-slim",
  1_073_741_824, // 1 GiB
);

console.log(snapshot.id);

私有镜像仓库

传递镜像仓库凭据(或预先注册的 registry_id / registryId)来从私有镜像仓库拉取。

snapshot = client.create_snapshot(
    "internal-python",
    docker_image="registry.example.com/internal/python:3.12",
    fs_capacity_bytes=2 * 1024**3,
    registry_url="https://registry.example.com",
    registry_username="me",
    registry_password=os.environ["REGISTRY_PASSWORD"],
    timeout=600,
)
const snapshot = await client.createSnapshot(
  "internal-python",
  "registry.example.com/internal/python:3.12",
  2_147_483_648,
  {
    registryUrl: "https://registry.example.com",
    registryUsername: "me",
    registryPassword: process.env.REGISTRY_PASSWORD,
    timeout: 600,
  },
);

从 Dockerfile 构建快照

当您有本地 Dockerfile 但不想先将镜像发布到镜像仓库时,请直接从 Dockerfile 及其构建上下文构建快照。LangSmith 会启动一个临时构建器沙盒,上传上下文,在其中运行构建并使用 BuildKit将生成的镜像捕获为快照。构建完成后,构建器沙盒会自动销毁。

调用会阻塞直到快照就绪(默认超时为 60 秒;对于大型或慢速构建请增加超时时间)。 fs_capacity_bytes 必须足够大以容纳构建上下文、中间层和最终镜像。

from langsmith.sandbox import SandboxClient

client = SandboxClient()

snapshot = client.create_snapshot_from_dockerfile(
    "my-app",
    dockerfile="Dockerfile",
    fs_capacity_bytes=2 * 1024**3,  # 2 GiB
    context=".",  # build context directory (default: current directory)
)

print(snapshot.id)
const client = new SandboxClient();

const snapshot = await client.createSnapshotFromDockerfile(
  "my-app",
  "Dockerfile",
  2_147_483_648, // 2 GiB
  { context: "." },
);

console.log(snapshot.id);

构建参数和目标阶段

传递 build_args / buildArgs 来设置 Docker ARG 值,以及 target 来在多阶段构建的特定阶段停止。

snapshot = client.create_snapshot_from_dockerfile(
    "my-app",
    dockerfile="Dockerfile",
    fs_capacity_bytes=2 * 1024**3,
    build_args={"PYTHON_VERSION": "3.12", "ENV": "prod"},
    target="runtime",
)
const snapshot = await client.createSnapshotFromDockerfile(
  "my-app",
  "Dockerfile",
  2_147_483_648,
  {
    buildArgs: { PYTHON_VERSION: "3.12", ENV: "prod" },
    target: "runtime",
  },
);

流式传输构建日志

on_build_log / onBuildLog 传递回调函数以接收构建运行时产生的 stdout 和 stderr,这在显示进度或调试构建失败时非常有用。

snapshot = client.create_snapshot_from_dockerfile(
    "my-app",
    dockerfile="Dockerfile",
    fs_capacity_bytes=2 * 1024**3,
    on_build_log=lambda line: print(line, end=""),
)
const snapshot = await client.createSnapshotFromDockerfile(
  "my-app",
  "Dockerfile",
  2_147_483_648,
  { onBuildLog: (line) => process.stdout.write(line) },
);

加速冷构建

vcpus / vCpusmem_bytes / memBytes 调整临时构建器沙盒的规格。构建在 BuildKit 加上原生 snapshotter 的层拷贝内运行,默认情况下它们会争用单个核心,因此为构建器额外分配一个 vCPU 可以大幅缩短冷构建的墙上时间。

snapshot = client.create_snapshot_from_dockerfile(
    "my-app",
    dockerfile="Dockerfile",
    fs_capacity_bytes=2 * 1024**3,
    vcpus=2,
    mem_bytes=4 * 1024**3,  # 4 GiB
    timeout=600,
)
const snapshot = await client.createSnapshotFromDockerfile(
  "my-app",
  "Dockerfile",
  2_147_483_648,
  {
    vCpus: 2,
    memBytes: 4_294_967_296, // 4 GiB
    timeout: 600,
  },
);

从运行中的沙盒捕获快照

从现有快照启动沙盒,安装软件包或准备数据,然后将结果捕获为新快照。返回的快照的 source_sandbox_id 会被设置为它所捕获自的沙盒,并且可以用作后续任何 snapshot_idcreate_sandbox call.

sb = client.create_sandbox(snapshot_id=base_snapshot_id, name="setup-box")
sb.run("pip install numpy pandas scikit-learn", timeout=180)
sb.write("/opt/config.yaml", "model: gpt-5\n")

# Capture the current filesystem as a new snapshot
snapshot = sb.capture_snapshot("ml-ready")
print(snapshot.id, snapshot.source_sandbox_id)

sb.delete()

# Boot fresh sandboxes pre-loaded with those dependencies
with client.sandbox(snapshot_id=snapshot.id) as sb:
    sb.run("python -c 'import numpy; print(numpy.__version__)'")
    assert sb.read("/opt/config.yaml") == b"model: gpt-5\n"
const running = await client.createSandbox(baseSnapshotId, { name: "setup-box" });
await running.run("pip install numpy pandas scikit-learn", { timeout: 180 });
await running.write("/opt/config.yaml", "model: gpt-5\n");

const snapshot = await running.captureSnapshot("ml-ready");
console.log(snapshot.id, snapshot.source_sandbox_id);

await running.delete();

const sandbox = await client.createSandbox(snapshot.id);
try {
  await sandbox.run("python -c 'import numpy; print(numpy.__version__)'");
  const cfg = await sandbox.read("/opt/config.yaml");
  console.log(new TextDecoder().decode(cfg));
} finally {
  await sandbox.delete();
}

调整捕获时间

capture_snapshot 会阻塞直到新快照准备就绪。请提高 timeout 参数(默认 60 秒)如果您的文件系统很大或存储后端很慢。

snapshot = sb.capture_snapshot("ml-ready-v2", timeout=600)
const snapshot = await sb.captureSnapshot("ml-ready-v2", { timeout: 600 });

列出、获取和删除快照

# List all snapshots in the workspace
snapshots = client.list_snapshots()
for s in snapshots:
    print(s.id, s.name, s.status)

# Fetch a single snapshot by ID
snapshot = client.get_snapshot("550e8400-e29b-41d4-a716-446655440000")

# Delete a snapshot (fails if any sandbox still references it)
client.delete_snapshot(snapshot.id)
const snapshots = await client.listSnapshots();
for (const s of snapshots) {
  console.log(s.id, s.name, s.status);
}

const snapshot = await client.getSnapshot("550e8400-e29b-41d4-a716-446655440000");

await client.deleteSnapshot(snapshot.id);

停止和启动沙箱

沙箱可以停止和重启而不会丢失文件系统状态。您在上一次运行期间写入的文件在沙箱重新启动后仍然存在。

sb = client.create_sandbox(snapshot_id=snapshot.id, name="my-vm")
sb.run("echo 'hello' > /tmp/state.txt")

# Stop the sandbox — preserves files on disk
sb.stop()

# Later: start it again (blocks until ready, default timeout=120s)
sb.start()

result = sb.run("cat /tmp/state.txt")
assert result.stdout.strip() == "hello"
const sb = await client.createSandbox(snapshot.id, { name: "my-vm" });
await sb.run("echo 'hello' > /tmp/state.txt");

await sb.stop();

await sb.start();

const result = await sb.run("cat /tmp/state.txt");
console.log(result.stdout.trim()); // "hello"

您也可以通过客户端直接按名称停止和启动(client.stop_sandbox(name) / client.start_sandbox(name) 在 Python 中, client.stopSandbox(name) / client.startSandbox(name) 在 TypeScript 中)。

后续步骤