适用于:
- LLM / Agent 执行不可信 Python 代码
- 在线 Python 运行环境
- LangChain / 自动化工具沙箱
- 多租户系统安全执行
一、背景介绍
在 LLM Agent、在线代码执行、插件系统等场景中,我们经常面临一个问题:
如何安全地执行用户提供的 Python 代码?
传统方案(exec/ 子进程 / Docker)要么不安全、要么太重。
LangChain 官方给出了一种更优雅的方案:
Pyodide + Deno Sandbox
其中核心组件就是:
jsr:@langchain/pyodide-sandbox它允许我们在WebAssembly(WASM)级别安全执行 Python 代码,并且具备:
- 强隔离
- 权限控制
- 低资源占用
- 易于集成 Agent / LangChain
二、什么是 jsr:@langchain/pyodide-sandbox?
2.1 核心技术栈
| 组件 | 作用 |
|---|---|
| Pyodide | Python → WebAssembly |
| Deno | 沙箱运行时 |
| WASM | 系统级隔离 |
| micropip | Python 包安装 |
整体结构:
Python Code ↓ Pyodide (WASM) ↓ Deno Sandbox ↓ Host OS(隔离)2.2 为什么不用 Docker?
| 对比 | Docker | Pyodide Sandbox |
|---|---|---|
| 启动速度 | 慢 | ⚡ 极快 |
| 资源占用 | 高 | 低 |
| 安全粒度 | 容器级 | WASM 级 |
| Agent 集成 | 一般 | 非常友好 |
三、环境准备
3.1 安装 Deno
curl-fsSL https://deno.land/install.sh|sh加入环境变量:
exportPATH="$HOME/.deno/bin:$PATH"验证:
deno --version四、最基础用法(CLI)
4.1 执行 Python 代码
deno run -A jsr:@langchain/pyodide-sandbox\-c"print('Hello, World')"输出:
{"stdout":"Hello, World","stderr":null,"result":null,"success":true,"sessionMetadata":{"created":"2026-01-22T02:13:43.619Z","lastModified":"2026-01-22T02:13:43.660Z","packages":[]}}4.2 执行计算
deno run -A jsr:@langchain/pyodide-sandbox\-c"print(2 + 3)"{"stdout":"5","stderr":null,"result":null,"success":true,"sessionMetadata":{"created":"2026-01-22T02:09:58.747Z","lastModified":"2026-01-22T02:09:58.794Z","packages":[]}}五、自动安装 Python 包(micropip)
Pyodide无需 pip / venv,而是使用micropip。
5.1 使用 numpy 示例
deno run -A jsr:@langchain/pyodide-sandbox\-c"import numpy as np; print(np.arange(5))"首次执行会看到:
{"stdout":"Loading numpyDidn't find package numpy-2.0.2-cp312-cp312-pyodide_2024_0_wasm32.whl locally, attempting to load from https://cdn.jsdelivr.net/pyodide/v0.27.7/full/Package numpy-2.0.2-cp312-cp312-pyodide_2024_0_wasm32.whl loaded from https://cdn.jsdelivr.net/pyodide/v0.27.7/full/, caching the wheel in node_modules for future use.Loaded numpy[0 1 2 3 4]","stderr":null,"result":null,"success":true,"sessionMetadata":{"created":"2026-01-22T02:14:13.300Z","lastModified":"2026-01-22T02:14:17.036Z","packages":["numpy"]}}这是正常行为,表示:
- Pyodide 正在下载依赖
- 下载完成后会缓存到
node_modules - 后续执行不会再下载
六、Stateful 会话(保持执行状态)
默认情况下,每次执行是无状态的。
如果你希望多次执行共享变量,需要开启stateful 模式。
6.1 创建 state
deno run -A jsr:@langchain/pyodide-sandbox\-s -c"x = 42"会返回sessionBytes。
{"stdout":null,"stderr":null,"result":null,"success":true,"sessionBytes":[128,4,149,168,0,0,0,0,0,0,0,140,10,100,105,108,108,46,95,100,105,108,108,148,140,14,95,105,109,112,111,114,116,95,109,111,100,117,108,101,148,147,148,140,8,95,95,109,97,105,110,95,95,148,133,148,82,148,125,148,40,140,8,95,95,110,97,109,101,95,95,148,104,3,140,7,95,95,100,111,99,95,95,148,78,140,11,95,95,112,97,99,107,97,103,101,95,95,148,78,140,8,95,95,115,112,101,99,95,95,148,78,140,15,95,95,97,110,110,111,116,97,116,105,111,110,115,95,95,148,125,148,140,13,95,112,121,111,100,105,100,101,95,99,111,114,101,148,104,2,140,13,95,112,121,111,100,105,100,101,95,99,111,114,101,148,133,148,82,148,140,1,120,148,75,42,117,98,46],"sessionMetadata":{"created":"2026-01-22T02:14:55.543Z","lastModified":"2026-01-22T02:14:56.955Z","packages":["dill"]}}6.2 恢复 state
jsr:@langchain/pyodide-sandbox的 stateful 会话由两部分组成:
| 字段 | 作用 |
|---|---|
sessionBytes | Python VM 的二进制快照(dill 序列化) |
sessionMetadata | 会话上下文(创建时间 / 包信息 / 兼容性校验) |
CLI 在恢复 session 时需要:
sessionBytes → 还原 Python 对象 sessionMetadata → 校验 & 环境一致性deno run -A jsr:@langchain/pyodide-sandbox\-s -b'<sessionBytes>'\-m'<sessionMetadata>'\-c"print(x)"例子
deno run -A jsr:@langchain/pyodide-sandbox\-s\-b'[128,4,149,168,0,0,0,0,0,0,0,140,10,100,105,108,108,46,95,100,105,108,108,148,140,14,95,105,109,112,111,114,116,95,109,111,100,117,108,101,148,147,148,140,8,95,95,109,97,105,110,95,95,148,133,148,82,148,125,148,40,140,8,95,95,110,97,109,101,95,95,148,104,3,140,7,95,95,100,111,99,95,95,148,78,140,11,95,95,112,97,99,107,97,103,101,95,95,148,78,140,8,95,95,115,112,101,99,95,95,148,78,140,15,95,95,97,110,110,111,116,97,116,105,111,110,115,95,95,148,125,148,140,13,95,112,121,111,100,105,100,101,95,99,111,114,101,148,104,2,140,13,95,112,121,111,100,105,100,101,95,99,111,114,101,148,133,148,82,148,140,1,120,148,75,42,117,98,46]'\-m'{"created":"2026-01-22T02:14:55.543Z","lastModified":"2026-01-22T02:14:56.955Z","packages":["dill"]}'\-c"print(x)"输出:
{"stdout":"42","stderr":null,"result":null,"success":true,"sessionBytes":[128,4,149,168,0,0,0,0,0,0,0,140,10,100,105,108,108,46,95,100,105,108,108,148,140,14,95,105,109,112,111,114,116,95,109,111,100,117,108,101,148,147,148,140,8,95,95,109,97,105,110,95,95,148,133,148,82,148,125,148,40,140,8,95,95,110,97,109,101,95,95,148,104,3,140,7,95,95,100,111,99,95,95,148,78,140,11,95,95,112,97,99,107,97,103,101,95,95,148,78,140,8,95,95,115,112,101,99,95,95,148,78,140,15,95,95,97,110,110,111,116,97,116,105,111,110,115,95,95,148,125,148,140,13,95,112,121,111,100,105,100,101,95,99,111,114,101,148,104,2,140,13,95,112,121,111,100,105,100,101,95,99,111,114,101,148,133,148,82,148,140,1,120,148,75,42,117,98,46],"sessionMetadata":{"created":"2026-01-22T02:14:55.543Z","lastModified":"2026-01-22T02:18:31.879Z","packages":["dill"]}}七、Python 正确执行模板(非常重要)
⚠️很多人踩坑就在这里
❌ 错误写法
2+3或者:
print(2+3)这样不会返回 result,只会进 stdout。
✅ 正确写法(标准模板)
asyncdefmain(args):return2+3✅ 同时 print + return
asyncdefmain(args):print("hello")return{"sum":2+3}返回结构:
{"stdout":"hello\n","result":{"sum":5}}八、在 Python 中集成(推荐)
LangChain 官方提供了 Python 封装包:
8.1 安装
pipinstalllangchain-sandbox8.2 Python 示例
fromlangchain_sandboximportPyodideSandboximportasyncioasyncdefrun():sandbox=PyodideSandbox(allow_net=False,allow_read=False,allow_write=False,)result=awaitsandbox.execute(""" async def main(args): print("hello from pyodide") return 1 + 2 await main({}) """)print("status:",result.status)print("stdout:",result.stdout)print("result:",result.result)asyncio.run(run())结果
status: success stdout: hello from pyodide result:3九、权限控制(安全关键)
| 参数 | 说明 |
|---|---|
| allow_net | 是否允许联网 |
| allow_read | 文件读取白名单 |
| allow_write | 文件写入 |
| allow_env | 读取环境变量 |
| allow_run | 执行子进程 |
| memory_limit_mb | 内存限制 |
示例:
sandbox=PyodideSandbox(allow_net=False,allow_read=["data"],allow_write=False,memory_limit_mb=32,)十、典型应用场景
✔ LLM Agent 执行代码
✔ LangChain Tool Sandbox
✔ 在线 Python 解释器
✔ 插件系统
✔ 教育 / 判题系统
十一、常见问题
Q1:stdout 很乱正常吗?
✅ 正常
第一次会输出 Pyodide 包安装日志
生产环境请只信result字段
Q2:能安装 pandas / numpy 吗?
⚠️ 只能安装pure Python / WASM 兼容包
❌ 不支持 CPython C 扩展(如 torch)
十二、官方资源汇总
JSR 文档
https://jsr.io/@langchain/pyodide-sandboxGitHub 源码
https://github.com/langchain-ai/langchain-sandboxPyodide 官方文档
https://pyodide.orgPython 封装
https://pypi.org/project/langchain-sandbox
十三、总结
jsr:@langchain/pyodide-sandbox是目前LLM 场景下最优雅的 Python 沙箱方案之一:
轻量、安全、Agent 友好
非常适合用在:
- AI Agent
- 多租户执行
- 自动化平台