python沙箱和docker沙箱你选对了吗?

Python 沙箱和 Docker 沙箱,你选对了吗?

在做 RAG / Agent 项目时,"让大模型执行 Python 脚本"几乎是必经之路------技能(Skill)系统要跑数据分析脚本、知识库处理要跑转换脚本。随之而来的问题是:脚本在什么环境里执行? Python 沙箱还是 Docker 沙箱?很多人第一反应是"Docker 更安全,直接上 Docker",也有人觉得"就是个执行脚本,Python 沙箱够了"。这篇文章从一个真实项目(WeKnora 风格的知识库 Agent)的选型过程出发,把两者的本质讲清楚。

一、先看场景:为什么需要沙箱

大模型 Agent 的工具集里有一个很常见的能力:执行技能脚本。比如:

  • 用户说"帮我统计知识库里的销售数据" → Agent 检索到数据 → 调用 analyze.py 做统计
  • 用户说"把这份 JSON 转成 CSV" → 调用 format_converter.py
  • 用户说"把检索结果生成一份课程需求" → 调用 rag-to-requirement.py

这些脚本是技能(SKILL.md)的一部分,由模型决定何时调用、传什么参数。代码不是我们预先审核后固定执行的,而是模型按需驱动的------这就有了安全隐患:脚本可能读到服务器上的敏感文件、可能外传数据、可能死循环吃光资源。

于是有了"沙箱":把脚本执行隔离在一个受限环境里。

二、两种沙箱的本质:同一执行体,不同厚度的壳

先说结论,避免误区:

Python 沙箱和 Docker 沙箱,执行方式完全一样------都是 python script.py + 标准输入传参。区别只在于外面套的隔离壳有多厚。

纯 Python 沙箱(薄壳)

python 复制代码
# 伪代码:进程级薄壳
result = subprocess.run(
    ["python", script_path],
    input=data_json,          # stdin 传参
    capture_output=True,
    timeout=60,               # 超时限制
    text=True,
)
if len(result.stdout) > MAX_OUTPUT:   # 输出大小限制
    raise OutputTooLarge()

隔离能力:

维度 能力
超时限制 ✅ 可限制
输出/输入大小 ✅ 可限制
文件系统 ❌ 脚本可读宿主机文件
网络 ❌ 脚本可联网
资源配额(CPU/内存) ⚠️ 依赖系统级限制

一句话:只管"跑不死",不管"看不见"

Docker 沙箱(厚壳)

bash 复制代码
# 伪代码:容器级厚壳
docker run --rm \
  --network none \           # 禁网
  --memory 512m \            # 内存配额
  --cpu-shares 256 \         # CPU 配额
  --read-only \              # 只读文件系统
  -i python:3.11-slim \
  python script.py <<< "$data_json"

隔离能力:

维度 能力
超时限制 ✅ 可限制
输出/输入大小 ✅ 可限制
文件系统 ✅ 容器内只读,宿主机文件不可见
网络 ✅ 默认禁网(--network none
资源配额 ✅ 内存/CPU/磁盘全可配
权限 ✅ 容器内 root 也是受限的

一句话:既管"跑不死",也管"看不见、连不上、写不进"

关系图

复制代码
纯 Python 沙箱(薄壳)          Docker 沙箱(厚壳)
┌─────────────────────┐      ┌─────────────────────┐
│ subprocess 进程      │      │ Docker 容器          │  ← 隔离壳
│   └ python script.py│      │   └ python script.py│  ← 执行体相同
│ 限制:超时/输出大小   │      │ 限制:超时/输出/文件/网络/资源 │
└─────────────────────┘      └─────────────────────┘

所以准确的说法是:不是"在 Python 沙箱外套一层 Docker",而是同一个执行方式,选择了不同强度的隔离壳。

三、Docker 沙箱到底防什么

很多人以为 Docker 沙箱是防"脚本崩溃"------其实超时、资源限制这两件事 Python 沙箱也能做。Docker 壳多防的是信息安全和越权

  1. 文件系统隔离 :脚本只能看到容器内的文件,读不到宿主机的 config.yaml.env、数据库凭证。恶意脚本想偷 token?门都没有。
  2. 网络隔离:默认无网络,脚本无法把数据外传到攻击者服务器,也无法扫描内网。
  3. 资源配额:内存/CPU/磁盘配额,脚本失控也不会拖垮整个服务。
  4. 权限收口:容器内即使拿到 root,权限也被限制在容器边界内。

一句话:Docker 壳防的是"不可信的代码",Python 壳防的是"失控的进程"。

四、选型:什么时候够用,什么时候必须上 Docker

判断标准一:代码可信度(最关键)

  • 单租户 / 内部系统 :脚本输入是服务端可控的(比如 Agent 的检索结果),不是用户上传的任意代码 → Python 沙箱够用
  • 多租户 / 开放技能市场 :任何人都能上传脚本给平台执行 → 必须 Docker(甚至要加更多加固:seccomp、无 root、镜像签名)

判断标准二:脚本的依赖与行为

  • 脚本只用标准库(json / re / csv / sys...),纯数据处理 → Python 沙箱够
  • 脚本需要第三方库(pandas、numpy...)→ Python 沙箱需要预装依赖;Docker 可以让每个技能自带 requirements,互不污染
  • 脚本需要联网 → 需要明确的网络策略;更好的做法是脚本不联网,网络能力由 Agent 工具(如 MCP)提供,沙箱保持无网

判断标准三:部署复杂度

  • 本地开发阶段装 Docker、拉镜像、容器编排,成本不小;Python 沙箱零依赖、即写即用
  • 生产环境 Linux 服务器上,两者的能力与操作系统无关,选择只取决于前两个标准

决策表

场景 推荐
本地开发 / 单租户 / 标准库脚本 ✅ Python 沙箱
生产部署 / 单租户 / 标准库脚本 ✅ Python 沙箱
多租户 / 用户上传脚本 ⚠️ Docker 沙箱
脚本需第三方库且互相冲突 ⚠️ Docker 沙箱(或预装依赖的 Python 环境)
需要网络隔离审计 ⚠️ Docker 沙箱

五、工程实践:接口抽象,换壳不换芯

无论选哪种,上层接口都要抽象成同一个,这样未来升级隔离强度时一行业务代码都不用改:

go 复制代码
// 沙箱接口:与实现无关
type Sandbox interface {
    Execute(ctx context.Context, code string) (*SandboxResult, error)
}

// 实现一:纯 Python(进程级薄壳)
type PythonSandbox struct{ ... }

// 实现二:Docker(容器级厚壳)------接口不变,换实现即可
type DockerSandbox struct{ ... }

工具层(如 execute_skill_script)只依赖 Sandbox 接口;技能(SKILL.md)只描述"调哪个脚本、传什么参数"。将来从 Python 沙箱切换到 Docker 沙箱,对上层完全透明------这就是"换壳不换芯"。

六、总结

  1. Python 沙箱和 Docker 沙箱执行的是同一件事python script.py),区别只是隔离壳厚度:薄壳管超时和输出大小,厚壳管文件、网络、资源、权限。
  2. 不是"套一层"的关系,而是同一执行方式的两档隔离强度,接口抽象好就可以随时换档。
  3. 选型看代码可信度:单租户、脚本输入服务端可控、纯标准库------Python 沙箱一劳永逸;多租户、开放脚本上传------Docker 沙箱是底线。
  4. Docker 沙箱防的是不可信的代码,Python 沙箱防的是失控的进程------先想清楚你防的是哪种,再决定用哪档。

项目实践参考:我们的知识库 Agent(技能脚本均为纯标准库 JSON 处理、单租户架构、网络能力由 MCP 工具提供)选择了 Python 沙箱,本地开发与 Linux 部署均适用;Docker 沙箱作为多租户场景的升级选项,接口已预留。

相关推荐
Python私教1 小时前
签名 URL 刷新导致审批失效?别急着删掉所有 query
python·安全
CodeDevMaster1 小时前
关于PaddleOCR-VL部署与使用说明
docker·llm
牧羊人.3331 小时前
Python 办公自动化从入门到入土|09 数据容器之字典
开发语言·python
小僧景贤1 小时前
嵌入式C语言 第二篇:基础语法|嵌入式C与标准C的核心差异
c语言·开发语言·嵌入式c语言
Zane19941 小时前
类变量与实例变量:一个共享列表引发的线上事故
后端·python
阿pin1 小时前
Android随笔-AIDL
android·开发语言·aidl
Python私教2 小时前
一次性批准令牌:挡住旧授权误发新版本的工程设计
python·安全
for_ever_love__2 小时前
python基础语法学习: 数据容器
windows·python·学习
aiqianji2 小时前
文风接近真人的AI生成短篇小说软件有哪些?
人工智能·python