Monty 安装与集成指南:为AI代理提供安全的Python执行环境
Monty 是一个用 Rust 编写的最小化、安全的 Python 解释器,专为执行由 AI 代理(LLM)生成的代码而设计。它避免了传统容器沙箱的复杂性和延迟,让您能以微秒级的启动速度,安全地运行 LLM 生成的 Python 代码。同时,它提供了对文件系统、网络和资源的细粒度控制。
1. 什么是 Monty 以及它的设计目标
Monty 的设计目标是提供一个 轻量级、安全、可嵌入的 Python 解释器。它不是一个完整的 Python 实现,而是实现了 Python 的一个合理子集,足以让 AI 代理表达其意图(如数据处理、API 调用、逻辑判断)。
核心特性包括:
- 安全隔离:完全阻断对宿主机文件系统、环境变量和网络的直接访问,所有外部操作通过开发者控制的外部函数调用实现。
- 极速启动:从代码到执行结果的启动时间 <1μs,性能与 CPython 相近(在 5 倍快至 5 倍慢之间)。
- 状态可序列化:可以在外部函数调用时对解释器状态进行快照(snapshot),便于存储、恢复或迁移。
- 资源控制:可追踪内存使用、栈深度和执行时间,并在超出预设限制时取消执行。
- 多语言绑定:可从 Rust、Python 或 JavaScript 调用。
Monty 当前支持:基础 Python 语法、现代类型提示、asyncio、collections、json、math、re 等部分标准库。
Monty 不支持:大部分标准库、第三方库(如 Pydantic)、类继承和元类、match 语句。
2. 安装与集成
Monty 的设计是作为您项目的一个组件被集成,而不是独立服务。
2.1 在 Python 项目中使用
安装:
1 | uv add pydantic-monty |
pydantic-monty 是一个元包,它会安装 pydantic-monty-client(Python 客户端库)和 pydantic-monty-runtime(Monty 工作进程二进制文件)。
基本用法(异步):
Monty 在工作进程池中执行代码,即使恶意代码导致崩溃,也不会影响您的主进程。
1 | import asyncio |
同步 API:
如果您不需要异步,Monty 也提供了同步接口:
1 | import pydantic_monty |
2.2 在 JavaScript / TypeScript 项目中使用
安装:
1 | npm install @pydantic/monty |
此包提供原生(napi)绑定,并包含 monty 工作进程二进制文件。
基本用法:
1 | import { Monty } from '@pydantic/monty' |
在浏览器中使用(通过 WebAssembly):
1 | import { Monty } from '@pydantic/monty/wasm' |
2.3 在 Rust 项目中使用
对于 Rust 项目,推荐使用 monty-pool 包来利用工作进程池的隔离优势。
在您的 Cargo.toml 中添加:
1 | [dependencies] |
基本用法(使用 monty-pool):
1 | use monty_pool::{MontyPool, RuntimeConfig}; |
如果您需要更底层的、进程内的解释器,可以使用 monty crate:
1 | use monty::{MontyRun, MontyObject}; |
Monty 还支持使用 dump() 和 load() 对 REPL 会话状态进行序列化和恢复。
3. 与 Pydantic AI 集成(代码模式)
Monty 的典型应用场景之一是作为 Pydantic AI 的“代码模式”(Code Mode)后端。在这种模式下,LLM 不再进行传统的工具调用,而是直接编写 Python 代码,Monty 则安全地执行这些代码并调用您提供的工具函数。
1 | from pydantic_ai import Agent |
之后,代理就能生成代码,通过 Monty 执行,并安全地调用 weather_toolset 中定义的工具。
4. 核心概念与高级用法
- 池 (Pool) 与会话 (Session):
Monty对象管理一个工作进程池,每个checkout()可获得一个独立的会话,会话状态在执行多个feed_run调用间保持。 - 外部函数 (External Functions):您可以将自己的同步或异步函数注册到 Monty 会话中,供沙箱内的 Python 代码调用。这是 Monty 实现可控外部交互的唯一方式。
- 资源限制:您可以在创建会话时设置
max_memory、max_execution_time等限制,防止恶意或错误的代码耗尽资源。 - 序列化 (Snapshotting):
dump()和load()功能允许您将整个解释器状态(包括变量、执行位置)序列化为字节,存储起来,后续再从该点恢复执行。
5. 替代方案对比(如何选择)
| 技术 | 适用场景 | 与 Monty 的对比 |
|---|---|---|
| Monty | 轻量、安全的 AI 代理代码执行 | 专为此场景设计,平衡了功能与安全。 |
| Docker | 完整的、隔离的环境,需要全功能 Python | 安全但启动慢(~195ms),资源开销大。 |
| Pyodide | 在浏览器中运行 Python | 启动慢(~2800ms),服务器端隔离能力弱。 |
| Starlark | 配置语言,非 Python | 语言能力非常有限,不支持 Python 语法。 |
| WASI / Wasmer | 沙箱化 Python,接近全功能 | 启动稍慢(~66ms),生态成熟度仍在发展中。 |
6. 总结
Monty 是一个为特定场景(AI 代码执行)打造的高性能、嵌入式安全 Python 运行时。
核心使用路径:
- 选择您的语言:在 Python、JavaScript 或 Rust 项目中安装对应的包。
- 创建 Monty 池:
Monty.create()(JS) 或pydantic_monty.AsyncMonty()(Python)。 - 签出会话:
pool.checkout()。 - 准备代码:编写(或让 LLM 生成)Python 代码字符串。
- 注入外部依赖:通过
inputs和external_lookup参数,安全地提供输入数据和可调用的函数。 - 执行:使用
feed_run()执行代码片段,可多次调用以保持状态。 - (可选)序列化:使用
dump()保存会话状态,以供后续恢复。
建议:开始使用前,请通过阅读项目示例和测试用例来了解其支持的语言子集。Monty 的功能集是高度聚焦的,请勿期待它能运行完整的、有复杂依赖的 Python 应用。它最适合作为 AI 代理执行逻辑和工具调用的高效、安全引擎。










