
Monty四种快照类型详解FunctionSnapshot、NameLookupSnapshot、FutureSnapshot【免费下载链接】montyA minimal, secure Python interpreter written in Rust for use by AI项目地址: https://gitcode.com/GitHub_Trending/monty3/montyMonty是一个用 Rust 编写的极简、安全的 Python 解释器专为让 AI 安全运行代码而设计。它的杀手级特性是执行过程中可以随时暂停把整个解释器序列化成一段字节之后在任意进程甚至另一台机器上恢复。当你用feed_start启动一段代码时Monty 不会一路跑到底而是在每个暂停点返回一个快照对象——本文详解 Monty 快照的四种类型FunctionSnapshot、NameLookupSnapshot、FutureSnapshot和MontyComplete以及各自的恢复方式。为什么 Monty 的快照如此轻Monty 的沙箱不持有任何操作系统资源没有活动的文件描述符、没有套接字、没有线程。当执行暂停时所有重要状态都在解释器自己的堆上。这意味着快照不需要重建任何外部资源dump()出来的字节流就是整个 worker 的完整状态。理解这一点后四种快照类型就很好理解了——它们只是执行为什么停下的四种答案快照类型停止原因恢复方式FunctionSnapshot调用了外部函数或 OS 调用resume(result)、resume_not_handled()、resume_auto()NameLookupSnapshot读取了一个未定义的名称resume(value...)或resume()抛出NameErrorFutureSnapshot沙箱内所有任务都阻塞在宿主机 Future 上resume({call_id: result})MontyComplete没停——代码跑完了无需恢复直接读.outputFunctionSnapshot外部函数与 OS 调用这是最常见的快照类型。沙箱里的 Python 代码调用了你提供的宿主函数或文件系统这类 OS 调用Monty 就会暂停把调用细节摆在桌面上。你能看到什么function_name函数名、args位置参数、kwargs关键字参数、call_id调用编号、is_os_function是否为 OS 调用、is_method_call是否为 dataclass 方法调用。如何恢复resume()接受四种形态的回答——{return_value: value}调用返回该值{exception: 异常实例}调用抛出该异常{exc_type: ValueError, message: ...}按类型名构造异常适合在别处如另一语言、反序列化后恢复快照时拿不到原始异常对象{future: ...}调用返回一个待决 Future沙箱可以await它稍后在产生的FutureSnapshot上结算。另外两个便捷方法resume_not_handled()仅对 OS 调用快照有效按 Monty 默认的未处理 OS 调用行为继续resume_auto()自动应答本次调用再继续驱动到下一个快照。OS 调用会先交给 feed 的挂载目录再回退到feed_start时捕获的os处理器外部调用则通过external_lookup解析查不到的名称会让沙箱抛出NameError与feed_run行为一致。一个典型循环是while not isinstance(snapshot, MontyComplete): snapshot snapshot.resume_auto()。类型定义可参考 crates/monty-python/python/pydantic_monty/_monty.pyiRust 侧实现在 crates/monty-python/src/snapshot.rs。NameLookupSnapshot未定义变量名当代码读取了一个未定义的名称时产生。它只带一个关键属性variable_name——那个失踪的变量名。恢复方式二选一resume(value...)为该名称绑定一个值任何值包括None都是合法绑定resume()不带参数保持该名称未定义沙箱将抛出NameError。resume_auto()则会从feed_start时捕获的external_lookup中自动查找该名称查不到就抛出NameError。这是构建按需注入宿主值模式的基石——你在external_lookup里注册哪些名称沙箱就能看到哪些完全由你掌控。FutureSnapshot所有任务都阻塞了这是最特殊的一种。当沙箱内每一个任务都阻塞在宿主机 Future 上即外部函数返回了待决 Future且没有其他任务可以继续推进时执行才会整体暂停并返回它。你能看到什么pending_call_ids——所有待结算 Future 的调用编号列表。如何恢复resume(results)接收一个{call_id: 结果}字典为一个或多个Future 提供已结算的结果。注意一条硬规则Future 不能解析为另一个 Future——结算结果只能是返回值或异常传入{future: ...}会直接抛出TypeError。两个容易踩的坑同步会话中resume_auto()永远抛出RuntimeError——同步会话没有事件循环去驱动协程外部函数必须手动resume({call_id: ...})或改用AsyncMonty恢复出来的FutureSnapshot通过load_snapshot反序列化而来也不能用resume_auto()因为那些待决协程活在上一个进程里已经消失了同样只能手动结算。MontyComplete执行完成的终点前三种快照都意味着暂停而MontyComplete意味着代码跑完了。它没有resume方法唯一要做的就是读取.output——代码末尾表达式的值每次访问时从 Monty 内部表示转换回 Python 对象。所有resume调用的返回值链最终都以它收尾。快照的持久化与恢复dump 与 load_snapshot每个快照除MontyComplete外都有dump()方法把整个挂起的 worker序列化成不透明字节之后在一个全新会话上调用session.load_snapshot(blob)即可恢复并返回一个可继续resume的快照。几个重要细节快照只能恢复一次每个快照至多resume一次重复调用会报错配置随 dump 走script_name、资源限制、类型检查状态都来自 dump 本身累计的时间预算也一并迁移挂载不随 dump 走宿主路径永远不是 dump 的一部分恢复时要传入相同的mount否则文件系统调用会退化为未处理的 OS 调用dump 与版本绑定字节携带格式版本不同 Monty 版本之间互不兼容请在同一版本内使用。完整示例见官方文档 docs/snapshots.md 的 Storing and restoring 一节。四大使用场景长时间运行的 Agent在工具调用处挂起持久化字节工具返回后甚至换一台主机恢复审批关卡在敏感调用处暂停存储快照人类批准后恢复分叉探索同一个快照恢复到多个会话从同一状态探索不同分支跨越重启服务器因部署而排空时交出可在他处恢复的 dump。如果需要同步/异步两套类型名pydantic-monty包导出了全部 7 个类含Async前缀的三个异步版本与MontyComplete类型别名SyncSnapshot/AsyncSnapshot定义在 crates/monty-python/python/pydantic_monty/init.py行为测试在 crates/monty-python/tests/test_feed_start.py。小结Monty 用四种快照对象完整描述了沙箱为什么停下外部调用FunctionSnapshot、未定义名称NameLookupSnapshot、全部阻塞FutureSnapshot和跑完了MontyComplete。配合dump()/load_snapshot解释器状态变成可以存数据库、跨进程、跨机器搬运的字节流——这正是 Monty 作为 AI 代码执行引擎最核心的超能力。【免费下载链接】montyA minimal, secure Python interpreter written in Rust for use by AI项目地址: https://gitcode.com/GitHub_Trending/monty3/monty创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考