Skip to main content
Modal 提供支持 GPU 的无服务器容器基础设施。最适合 ML/AI 工作负载和 Python 开发。

设置

npm install @langchain/modal

身份验证

modal.com/settings/tokens 获取您的令牌。
export MODAL_TOKEN_ID=your_token_id
export MODAL_TOKEN_SECRET=your_token_secret
或者直接传递凭据:
const sandbox = await ModalSandbox.create({
  auth: {
    tokenId: "your-token-id",
    tokenSecret: "your-token-secret",
  },
});

与 deepagents 一起使用

import { createDeepAgent } from "deepagents";
import { ChatAnthropic } from "@langchain/anthropic";
import { ModalSandbox } from "@langchain/modal";

const sandbox = await ModalSandbox.create({
  imageName: "python:3.12-slim",
  timeoutMs: 600_000, // 10 minutes
});

try {
  const agent = createDeepAgent({
    model: new ChatAnthropic({ model: "claude-sonnet-4-20250514" }),
    systemPrompt: "You are a coding assistant with sandbox access.",
    backend: sandbox,
  });

  const result = await agent.invoke({
    messages: [{ role: "user", content: "Install numpy and calculate pi" }],
  });
} finally {
  await sandbox.close();
}

独立使用

import { ModalSandbox } from "@langchain/modal";

const sandbox = await ModalSandbox.create({
  imageName: "python:3.12-slim",
  timeoutMs: 600_000,
});

const result = await sandbox.execute("python --version");
console.log(result.output);

await sandbox.close();

配置

选项类型默认值描述
imageNamestring"alpine:3.21"要使用的 Docker 镜像
timeoutMsnumber300000最大生命周期(毫秒)
workdirstring-工作目录
gpustring-GPU 类型("T4""A100""H100" 等)
cpunumber-CPU 核心数(允许小数)
memoryMiBnumber-内存分配(MiB)
volumesRecord<string, string>-卷名称映射(挂载路径到卷名称)
secretsstring[]-要注入的 Modal Secret 名称
initialFilesRecord<string, string | Uint8Array>-启动时要创建的文件
envRecord<string, string>-环境变量
blockNetworkboolean-阻止网络访问
namestring-沙盒名称(在应用内唯一)

GPU 支持

Modal 支持 NVIDIA GPU 用于 ML 工作负载:
const sandbox = await ModalSandbox.create({
  imageName: "python:3.12-slim",
  gpu: "T4",  // 或 "L4", "A10G", "A100", "H100"
});

卷和密钥

挂载 Modal 卷以实现持久存储,并将密钥作为环境变量注入:
// 卷和密钥必须首先在 Modal 中创建
const sandbox = await ModalSandbox.create({
  imageName: "python:3.12-slim",
  volumes: {
    "/data": "my-data-volume",
    "/models": "my-models-volume",
  },
  secrets: ["my-api-keys", "database-credentials"],
});

// /data 和 /models 中的文件在沙盒重启后仍然存在
await sandbox.execute("echo 'Hello' > /data/test.txt");

// 密钥可作为环境变量使用
await sandbox.execute("echo $API_KEY");

初始文件

在创建期间预填充沙盒文件:
const sandbox = await ModalSandbox.create({
  imageName: "python:3.12-slim",
  initialFiles: {
    "/app/main.py": 'print("Hello from Python!")',
    "/app/config.json": JSON.stringify({ name: "my-app" }, null, 2),
  },
});

const result = await sandbox.execute("python /app/main.py");

访问 Modal SDK

对于 BaseSandbox 未公开的高级功能,访问底层 Modal SDK:
const modalSandbox = await ModalSandbox.create();

const client = modalSandbox.client;     // ModalClient
const instance = modalSandbox.instance;  // Sandbox

// 直接 SDK 操作
const process = await instance.exec(["python", "-c", "print('Hello')"], {
  stdout: "pipe",
  stderr: "pipe",
});

重新连接到现有沙盒

// 通过 ID 重新连接
const reconnected = await ModalSandbox.fromId(sandboxId);

// 通过名称重新连接
const reconnected2 = await ModalSandbox.fromName("my-app", "my-sandbox");

工厂函数

import { createModalSandboxFactory, createModalSandboxFactoryFromSandbox } from "@langchain/modal";

// 每次调用创建新沙盒
const factory = createModalSandboxFactory({ imageName: "python:3.12-slim" });

// 或跨调用重用现有沙盒
const sandbox = await ModalSandbox.create();
const reuseFactory = createModalSandboxFactoryFromSandbox(sandbox);

错误处理

import { ModalSandboxError } from "@langchain/modal";

try {
  await sandbox.execute("some command");
} catch (error) {
  if (error instanceof ModalSandboxError) {
    switch (error.code) {
      case "NOT_INITIALIZED":
        await sandbox.initialize();
        break;
      case "COMMAND_TIMEOUT":
        console.error("Command took too long");
        break;
      case "AUTHENTICATION_FAILED":
        console.error("Check your Modal token credentials");
        break;
    }
  }
}

错误代码

代码描述
NOT_INITIALIZED沙盒未初始化 - 调用 initialize()
ALREADY_INITIALIZED无法初始化两次
AUTHENTICATION_FAILEDModal 令牌无效或缺失
SANDBOX_CREATION_FAILED创建沙盒失败
SANDBOX_NOT_FOUND沙盒 ID/名称未找到或已过期
COMMAND_TIMEOUT命令执行超时
COMMAND_FAILED命令执行失败
FILE_OPERATION_FAILED文件读/写失败
RESOURCE_LIMIT_EXCEEDED超出 CPU、内存或存储限制
VOLUME_ERROR卷操作失败

环境变量

变量描述
MODAL_TOKEN_IDModal API 令牌 ID
MODAL_TOKEN_SECRETModal API 令牌密钥