运行 Python 技能
ZeroClaw 可以运行 Python 技能,但实际的 Python 工作通常需要在以下两种明确的部署方案中选择其一:
- 在受信任主机的 Python 环境中运行该技能,或
- 在已包含 Python 和该技能所需软件包的自定义 Docker 运行时镜像中运行它。
默认配置有意保持保守。它会阻止许多复制粘贴的 Python 模式,直到你确定希望采用哪种信任边界。
本页介绍通过内置 shell 工具调用的 Python 脚本。如果某个 SKILL.toml 定义了自己的 [[tools]] 条目并设置 kind = "shell" 或 kind = "script",则该技能工具目前会在 shell 策略下作为宿主子进程执行,而非通过 runtime.kind = "docker"。要在当前实现容器化的 Python 执行,可以让技能指令通过内置 shell 工具调用 Python 脚本,或者让技能工具命令显式运行你所需的容器边界。
三层架构
Python 技能执行由三个独立的层级控制。
| 层 | 配置界面 | 它决定什么 |
|---|---|---|
| 技能审计 | [skills].allow_scripts | 是否允许从技能包中加载类 shell 的辅助文件。Python .py 辅助文件默认允许加载。 |
| Shell 策略 | [risk_profiles.<alias>].allowed_commands | shell 工具是否可以调用 python、python3、pip 或其他可执行文件。 |
| 执行边界 | [risk_profiles.<alias>].sandbox_* 和 [runtime] | 允许的命令实际运行的位置,以及适用的文件系统、网络和资源限制。 |
Python 辅助文件不需要 allow_scripts = true。仅在你审查过 skill 源代码后再启用类 shell 辅助文件,并在风险配置文件的 allowed_commands 中允许相应解释器(python、python3、pip)。allowed_commands 非空时是一个严格的可执行文件允许列表。shell 策略仍会在该允许列表之上检查破坏性模式和解释器参数风险。
优先在镜像构建时、经过审查的本地虚拟环境中,或在 agent 轮次之外的其他设置步骤中安装 Python 包。仅当运行时安装包是该部署有意为之的一部分时,才将 pip 添加到受信任的配置文件中。
哪些内容仍被阻止
ZeroClaw 会刻意阻止内联解释器执行,例如:
sh
python3 -c print("hello")
python3 -m http.server
python3 -m pip install requests
node -e console.log(process.env)
对于 Python 技能,将代码放在可审查的脚本文件中并运行该文件:
sh
python3 skills/portfolio/run.py
这样可使该可执行文件能够通过 skill 审计路径进行审查,并避免将 shell 命令字符串变为任意代码的容器。
诸如 PYTHONPATH=... python3 script.py 这样的环境变量前缀也属于策略敏感项。当你需要稳定的运行时环境配置时,建议使用封装脚本、项目本地的虚拟环境,或在脚本内部进行显式配置。
模式 A:可信原生 Python
当技能可信,且希望它们使用主机的 Python 安装、软件包、文件系统权限和网络时,请使用本机执行。
此设置适用于本地开发、单用户工作站,或你自行编写技能的家庭实验室环境。它会移除该配置下工具运行时的操作系统级沙箱,因此普通用户权限和 ZeroClaw 策略检查将成为仅存的防护机制。
请勿将此模式用于未经审查的第三方技能或多租户部署。
模式 B:自定义 Docker 运行时镜像
当你希望 Python 依赖项存在于可复现的容器镜像中,同时又希望为内置 shell 执行保留运行时边界时,请使用 Docker。
创建一个包含您的技能所需软件包的镜像:
# Dockerfile.skill-exec
FROM python:3.12-slim
RUN pip install --no-cache-dir \
pandas \
polars \
requests
WORKDIR /workspace
构建它:
sh
docker build -f Dockerfile.skill-exec -t zeroclaw-python-skills:local .
通过 runtime.kind = "docker" 将 ZeroClaw 指向该镜像,它会在临时容器中运行 shell 调用。Docker 专用的镜像、网络、内存、CPU、只读 rootfs 以及工作区挂载设置位于 runtime.docker 下。
设置 sandbox_backend = "none",以避免将 Docker 运行时包装在第二个独立的沙箱容器中。在这种模式下,Docker 运行时是内置 shell 调用的执行边界,而 runtime.docker 则是配置镜像和容器限制的位置。
如果某个技能需要发起出站 HTTP 请求,请慎重修改 runtime.docker.network。如果某个技能需要在挂载的工作区之外写入包缓存、报告或临时状态,请先评估它是否应改为写入 /workspace 下;只有在这样做仍不够时,才放宽 read_only_rootfs。
工作区挂载
当 runtime.docker.mount_workspace = true 时,ZeroClaw 会将配置的工作区挂载到容器中的 /workspace,并将容器工作目录设置为该路径。技能脚本应尽可能使用相对于工作区的路径。
如果需要进一步限制工作区路径,请配置工作区白名单。ZeroClaw 会在添加 Docker 卷挂载之前,根据该白名单验证主机工作区路径。
挂载验证在失败时会拒绝操作。即使允许列表为空,工作区也必须存在并解析为规范路径。每个配置的允许列表根目录也必须存在并规范化;即使另一个根目录匹配,只要有一个过时或无效的条目,命令就会在 Docker 启动前被拒绝。升级前请删除过时条目或创建预期的目录。
选择模式
- 当你编写或审查过相关技能,并且希望在单用户主机上获得最低延迟时,请使用受信任的原生 Python。
- 当你需要可复现的依赖项、生产环境打包,或为内置 shell 调用设置明确的容器边界时,请使用自定义 Docker 运行时镜像。
- 对于未经审核或多租户的技能来源,应使用更严格的风险配置、更窄的命令允许列表以及容器化执行。