RDS Supabase 沙箱 Code Interpreter 使用指南

更新时间:
复制 MD 格式

本文介绍如何在 RDS Supabase 沙箱中使用 Code Interpreter(代码解释器)能力,通过 e2b-code-interpreter SDK 在安全隔离的云端环境中执行 Python 代码,涵盖 5 个典型使用场景。

前提条件

  • 已创建 RDS Supabase 实例,且实例处于运行中状态。

  • 实例所在地域为华北2(北京)、华东2(上海)、华东1(杭州)、华南1(深圳)或西南1(成都)。

  • 已完成关联角色 AliyunServiceRoleForRDSAISupabase 授权。

  • 已在 RDS 控制台的沙箱和边缘函数页面启用沙箱功能。具体操作,请参见使用沙箱和边缘函数

使用限制

  • 单个沙箱的默认生命周期由 timeout 参数控制(示例中最长 600 秒),超时后沙箱自动销毁,长任务需按需拆分或延长参数值。

  • 场景五(AI 驱动的数据分析 Agent)需自备大语言模型服务,通过 LLM_API_KEYLLM_BASE_URL 环境变量接入。RDS Supabase 沙箱本身不提供大模型能力。

配置 Code Interpreter

依次完成以下 6 个配置项,准备 Code Interpreter 运行环境。

步骤一:创建 Code Interpreter 沙箱模板

  1. 登录 RDS 管理控制台,进入目标 RDS Supabase 实例的详情页。

  2. 在左侧导航栏,单击组件 > 沙箱和边缘函数

  3. 确认页面顶部的启用沙箱和边缘函数开关处于开启状态。

  4. 在页面右侧的沙箱模板区域,定位 code-interpreter 行,复制该行模板ID列的值。后续所有代码示例中 Sandbox.create(template="<模板ID>")<模板ID> 占位符均需替换为该值。

说明

产品预置的沙箱模板包括 claude-code、code-interpreter、deno、desktop、steel-browser,分别对应不同的 AI 场景。本文档聚焦 code-interpreter,其他模板的使用方式请参见对应场景文档。

步骤二:绑定域名

Code Interpreter 通过实例专属域名 <实例ID>.sb.rds.com 访问沙箱。在本地 /etc/hosts 中添加以下映射:

<实例IP地址> <实例ID>.sb.rds.com

实例 IP 地址在 RDS Supabase 实例的基本信息页可以获取。

说明

开发测试场景直接写入 /etc/hosts;生产环境建议通过 DNS 解析统一管理域名。

步骤三:下载 e2b SDK 的 patch 代码

从 GitHub 仓库 aliyun-rds-pg/e2b-sdk-patch 下载 patch 代码,该 patch 用于适配 RDS Supabase 的路由方式。

步骤四:(可选)配置 SSL 实现 HTTPS 访问

如需通过 HTTPS 访问沙箱,请先为 Supabase 实例配置 SSL 证书。具体操作,请参见RDS Supabase 配置 SSL 实现 HTTPS 访问

配置 SSL 后,设置以下环境变量,指向可信的根证书文件:

# rootCA.pem 为生成 Supabase 实例 SSL 证书对应的 CA 证书。
export SSL_CERT_FILE="/xxx/rootCA.pem"
export REQUESTS_CA_BUNDLE="/xxx/rootCA.pem"

步骤五:配置环境变量

配置以下环境变量,供 SDK 建立与沙箱及 LLM 服务的连接:

export E2B_DOMAIN=<实例ID>.sb.rds.com
export E2B_API_KEY=<your_service_key>
export LLM_API_KEY=<your_llm_api_key>
export LLM_BASE_URL=<your_llm_base_url>

环境变量

说明

E2B_DOMAIN

沙箱访问域名,即步骤二绑定的域名。

E2B_API_KEY

沙箱鉴权用 ServiceKey。在实例详情页右上角,单击获取 API Key,复制 ServiceKey 字段的值。

LLM_API_KEY

大语言模型服务的 API Key,仅场景五(AI Agent)需要;其他场景可留空。

LLM_BASE_URL

大语言模型服务的 Base URL,仅场景五需要;其他场景可留空。

步骤六:安装 e2b-code-interpreter SDK

pip install e2b-code-interpreter openai

Code Interpreter 使用示例

Code Interpreter 的核心工作流程依次为:创建沙箱、执行代码或文件操作、获取结果、销毁沙箱。与本地 Python REPL 相比,沙箱提供安全隔离的云端执行环境,支持有状态多轮执行、并发上下文隔离和二进制结果回传。以下 5 个使用场景各自提供一份完整可运行的 Python 脚本,复制后按运行示例代码的说明保存为 .py 文件即可执行。

场景一:有状态的多轮代码执行

同一个沙箱内多次调用 run_code,变量、导入的模块会在多轮之间持续保留,适合分步骤构建分析流程。使用 with 语句可以在退出时自动销毁沙箱。

from e2b_code_interpreter import Sandbox
from patch_e2b import patch_e2b
patch_e2b(True)

with Sandbox.create(template="<模板ID>") as sbx:
    sbx.run_code("x = 10")
    execution = sbx.run_code("x += 5; print(f'x = {x}')")
    print(execution.logs.stdout)  # x = 15
    sbx.run_code("import math")
    execution = sbx.run_code("print(f'pi = {math.pi}')")
    print(execution.logs.stdout)  # pi = 3.141592653589793

场景二:文件读写操作

通过 sbx.files.writesbx.files.read 与沙箱内文件系统交互,再让 run_code 中的 pandas 等库直接消费本地文件,实现文件与代码执行的一体化。

from e2b_code_interpreter import Sandbox
from patch_e2b import patch_e2b
patch_e2b(True)

with Sandbox.create(template="<模板ID>") as sbx:
    sbx.files.write("/home/user/data.csv", "name,age,city\nAlice,30,Beijing\nBob,25,Shanghai")
    content = sbx.files.read("/home/user/data.csv")
    execution = sbx.run_code("""
import pandas as pd
df = pd.read_csv('/home/user/data.csv')
print(df.describe())
""")
    print(execution.logs.stdout)

场景三:代码上下文隔离(Code Contexts)

Code Contexts 允许在同一个沙箱中创建多个独立的代码上下文,每个上下文维护独立的变量和状态。适合需要在不同任务间隔离状态的场景,例如数据分析上下文和报告生成上下文并行运行、互不干扰。

示例 1:创建、使用与验证隔离

from e2b_code_interpreter import Sandbox
from patch_e2b import patch_e2b
patch_e2b(True)

sandbox = Sandbox.create(template="<模板ID>")
try:
    # 创建两个独立的代码上下文
    data_ctx = sandbox.create_code_context()
    report_ctx = sandbox.create_code_context()

    # 在 data_ctx 中准备数据
    sandbox.run_code("""
import pandas as pd
import numpy as np
np.random.seed(42)
dates = pd.date_range('2025-01-01', periods=30)
data = pd.DataFrame({'date': dates, 'revenue': np.random.randint(1000, 5000, 30)})
print(data.head())
""", context=data_ctx)

    # 在 report_ctx 中生成报告(独立环境,不受 data_ctx 影响)
    sandbox.run_code("""
report_lines = [
    '=== 数据分析报告 ===',
    f'生成时间: 2025-07-02',
    '状态: 数据上下文与本上下文互相隔离',
]
for line in report_lines:
    print(line)
""", context=report_ctx)

    # 验证隔离性:data_ctx 中的 data 变量在 report_ctx 中不存在
    result = sandbox.run_code("print('data' in dir())", context=report_ctx)
    print(f'report_ctx 中是否存在 data 变量: {result.logs.stdout[0]}')  # False

finally:
    sandbox.kill()

示例 2:列出、重启与删除上下文

SDK 提供了管理上下文的完整 API,支持列出所有活跃上下文、重启上下文(清空状态)、删除上下文。这些操作有助于在复杂场景中灵活管理多个执行环境。

from e2b_code_interpreter import Sandbox
from patch_e2b import patch_e2b
patch_e2b(True)

sandbox = Sandbox.create(template="<模板ID>")
try:
    data_ctx = sandbox.create_code_context()
    report_ctx = sandbox.create_code_context()

    # 列出所有活跃上下文
    contexts = sandbox.list_code_contexts()
    print(f'当前活跃上下文数量: {len(contexts)}')

    # 重启上下文(清空状态,重新开始)
    data_ctx = sandbox.restart_code_context(data_ctx)
    print(f'已重启上下文: {data_ctx.id}')

    # 删除上下文(通过对象)
    sandbox.remove_code_context(report_ctx)
    print('已删除 report_ctx')

    # 也可以通过 context_id 删除
    sandbox.remove_code_context(data_ctx.id)
    print('已删除 data_ctx')

finally:
    sandbox.kill()
说明

管理上下文的 API(list_code_contextsrestart_code_contextremove_code_context)均支持通过上下文对象或 context_id 字符串调用。

场景四:数据分析与可视化

在沙箱内用 matplotlib 生成图表,再通过 sbx.files.read(..., format="bytes") 把 PNG 二进制回传本地并落盘。

from e2b_code_interpreter import Sandbox
from patch_e2b import patch_e2b
patch_e2b(True)

sandbox = Sandbox.create(template="<模板ID>", timeout=300)
try:
    execution = sandbox.run_code("""
import numpy as np
import matplotlib
matplotlib.use('Agg')
import matplotlib.pyplot as plt
np.random.seed(42)
days = np.arange(1, 31)
prices = 120 + np.cumsum(np.random.randn(30) * 2)
fig, ax = plt.subplots(figsize=(12, 6))
ax.plot(days, prices, 'b-', linewidth=2, marker='o')
ax.set_title('Simulated 30-Day Price Trend')
plt.tight_layout()
plt.savefig('/home/user/chart.png', dpi=150)
print(f'Price range: {prices.min():.2f} - {prices.max():.2f}')
""")
    print(execution.logs.stdout)
    chart_bytes = sandbox.files.read("/home/user/chart.png", format="bytes")
    with open("chart.png", "wb") as f:
        f.write(chart_bytes)
    print("图表已保存")
finally:
    sandbox.kill()
说明

沙箱是无 GUI 环境,必须在代码中强制指定 matplotlib.use('Agg') 后端;否则调用 plt.savefig 时可能因缺失显示后端而报错。

场景五:AI 驱动的数据分析 Agent

结合大模型的 tool calling 能力和 Code Interpreter 构建智能数据分析助手,流程依次为:上传数据文件、由大模型生成分析代码、沙箱执行代码并产出图表、将结果保存到本地。以下示例使用 TMDB 电影数据集(约 1 万条记录),通过 LLM 生成可视化代码并在沙箱中执行。

安装依赖

pip install e2b-code-interpreter openai python-dotenv

完整代码

import sys
import os
import json
import base64
from dotenv import load_dotenv
load_dotenv()

from e2b_code_interpreter import Sandbox
from patch_e2b import patch_e2b
from openai import OpenAI

patch_e2b(True)

client = OpenAI(
    api_key=os.getenv("LLM_API_KEY"),
    base_url=os.getenv("LLM_BASE_URL"),
)

# 创建沙箱并上传数据集
sbx = Sandbox.create(template="<模板ID>", timeout=300)
with open("dataset.csv", "rb") as f:
    dataset_path = sbx.files.write("/home/user/dataset.csv", f)

def run_ai_generated_code(ai_code: str):
    """执行 AI 生成的代码,保存产出的图表"""
    print("正在沙箱中执行代码...")
    execution = sbx.run_code(ai_code)
    print("代码执行完成!")
    if execution.error:
        print(f"执行错误: {execution.error.value}")
        print(execution.error.traceback)
        return
    # 提取图表(PNG)并保存
    for idx, result in enumerate(execution.results):
        if result.png:
            with open(f"chart-{idx}.png", "wb") as f:
                f.write(base64.b64decode(result.png))
            print(f"图表已保存至 chart-{idx}.png")
    if execution.logs.stdout:
        print(f"输出:{execution.logs.stdout}")

# 构建 prompt:描述数据和分析需求
prompt = f"""
我有一个关于电影的 CSV 文件,大约 1 万条记录,已保存在沙箱的 {dataset_path.path} 路径下。
文件的列名及含义如下:
- id: 数字类型,电影的唯一标识
- original_language: 字符串,原始语言,如 "eng"、"es"、"ko" 等
- original_title: 字符串,电影的原始标题
- overview: 字符串,电影简介
- popularity: 浮点数,流行度评分,范围约 0 到 9137.939,未做归一化且存在异常值
- release_date: 日期,格式为 yyyy-mm-dd
- title: 字符串,电影的英文标题
- vote_average: 浮点数,观众评分均值,范围 0 到 10
- vote_count: 整数,投票人数

请编写 Python 代码,绘制一条折线图,展示 vote_average(观众评分均值)随年份的变化趋势。
不需要打印或探索数据,直接进行可视化即可。

重要:代码的最后一行必须是以下语句,用于展示图表:
display(plt.gcf())
"""

# 通过 tool calling 让大模型生成代码
print("等待大模型响应...")
msg = client.chat.completions.create(
    model="qwen3.7-plus",
    messages=[{"role": "user", "content": prompt}],
    tools=[{
        "type": "function",
        "function": {
            "name": "run_python_code",
            "description": "在沙箱中运行 Python 代码",
            "parameters": {
                "type": "object",
                "properties": {
                    "code": {"type": "string", "description": "要执行的 Python 代码"},
                },
                "required": ["code"],
            },
        },
    }],
)

# 解析响应并执行生成的代码
for tool_call in msg.choices[0].message.tool_calls:
    if tool_call.function.name == "run_python_code":
        code = json.loads(tool_call.function.arguments)["code"]
        print("AI 生成的代码:")
        print(code)
        run_ai_generated_code(code)

sbx.kill()
print("沙箱资源已清理")

工作流程说明

  1. 上传数据:将本地 CSV 文件上传到沙箱的 /home/user/dataset.csv 路径。

  2. Prompt 构建:向 LLM 描述数据列含义和分析需求,并要求代码以 display(plt.gcf()) 结尾。

  3. Tool Calling:通过 OpenAI function calling 协议,让 LLM 将代码作为工具参数返回。

  4. 沙箱执行:调用 sbx.run_code() 执行代码,从 execution.results 中的 png 字段提取 base64 编码的图表。

  5. 保存结果:通过 base64.b64decode 解码 PNG 并保存到本地。

运行示例代码

按以下步骤保存并运行上述任意一个场景的示例代码。

步骤一:创建脚本文件

将示例代码保存为 .py 文件,必须与「配置 Code Interpreter」步骤三下载的 patch_e2b 源码放在同一目录,否则会报 ModuleNotFoundError: No module named 'patch_e2b'。目录结构示例:

e2b-sdk-patch/
├── patch_e2b/          # 「配置 Code Interpreter」步骤三下载的 patch 源码
├── main.py             # 您的示例脚本
├── .env                # 仅场景五需要,存放 LLM 凭证
└── dataset.csv         # 仅场景五需要,待分析数据集

如需将脚本放在其他目录,请将 patch_e2b 源码路径加入 PYTHONPATH

export PYTHONPATH="/path/to/e2b-sdk-patch:$PYTHONPATH"
说明

其中 /path/to/e2b-sdk-patch 为占位符,需替换为本地 patch_e2b 源码所在的实际绝对路径(例如 /Users/yourname/code/e2b-sdk-patch);:$PYTHONPATH 用于保留原有路径,避免覆盖。设置完成后,在同一终端窗口中运行脚本即可生效。

步骤二:替换代码中的占位符

示例代码中的 <模板ID> 需替换为「配置 Code Interpreter」步骤一记录的模板 ID。

patch_e2b(True) 必须在任何 Sandbox 相关调用之前执行,否则 SDK 会走官方默认路由,而非 RDS Supabase 的自定义路由。

步骤三:确认环境变量已生效

在启动脚本前,确保配置章节步骤五定义的 4 个环境变量已加载:

E2B_DOMAIN=<实例ID>.sb.rds.com
E2B_API_KEY=<your_service_key>
LLM_API_KEY=<your_llm_api_key>
LLM_BASE_URL=<your_llm_base_url>

步骤四:运行脚本

在工作目录中执行:

python3 demo.py

首次运行时,控制台会输出沙箱 ID(sandbox_id),表示沙箱已创建成功。执行完成后,确认沙箱已通过 sbx.kill()with 语法被销毁,避免占用配额残留。

常见启动问题

Q1:执行时提示 SSL: CERTIFICATE_VERIFY_FAILED 怎么办?

A:未配置 SSL 证书。请回到配置章节步骤四,设置 SSL_CERT_FILEREQUESTS_CA_BUNDLE 指向可信的根证书文件。

Q2:Sandbox.create 报告「模板不存在」怎么办?

A:检查 <模板ID> 是否为控制台沙箱模板表格中 code-interpreter 行的完整模板ID(不是配置项名称 code-interpreter),且实例已启用沙箱和边缘函数

Q3:域名解析失败提示 Name or service not known

A:检查本地 /etc/hosts 中已加入 <实例IP> <实例ID>.sb.rds.com 映射,且 E2B_DOMAIN 环境变量与之完全一致。

相关文档