
如何用Monty构建人类审批门禁快照暂停-审批-恢复完整实战【免费下载链接】montyA minimal, secure Python interpreter written in Rust for use by AI项目地址: https://gitcode.com/GitHub_Trending/monty3/montyMonty 是一个用 Rust 编写的极简安全 Python 解释器专为运行 AI 生成的代码而设计。它的杀手锏是快照机制沙箱在敏感调用处自动暂停你可以把它序列化成一串字节等人类审批通过后再恢复执行——这正是构建人类审批门禁Approval Gate的完整技术路径。为什么 AI 执行代码需要人类审批门禁 当 AI Agent 自己写代码并执行时代码会调用你的宿主函数Host Functions——发邮件、转账、查数据库。Monty 的安全模型保证沙箱只能触达你明确交给它的东西没有 socket、没有 subprocess、没有eval连危险的模块都不存在于解释器里详见 docs/security.md。但 Monty 官方文档也诚实地说它保证沙箱碰不到你没给的东西不保证你给的东西被安全地调用——因为宿主函数是以你进程的完整权限运行的。这就留下了一个缺口谁来审查每一次敏感调用答案就是本文的主题在暂停点和恢复点之间插入一个人。三大核心机制暂停、快照、恢复 ⏸️理解 docs/snapshots.md 里的三个 API就理解了整个门禁机制方法作用暂停session.feed_start(...)像feed_run一样执行代码但每次遇到外部调用都交还控制权快照snapshot.dump()把暂停中的整个解释器序列化成不透明字节可存磁盘、传网络恢复session.load_snapshot(blob)/snapshot.resume(...)在新会话中还原暂停现场注入审批结果继续执行为什么能序列化因为 Monty 是语言级沙箱不持有任何操作系统资源——没有活动文件描述符、没有 socket、没有线程。暂停时一切状态都躺在解释器自己的堆上。暂停后你会拿到不同类型的快照门禁只关心FunctionSnapshot快照类型暂停原因恢复方式FunctionSnapshot调用了宿主函数或 OS 调用resume({return_value: ...})或注入异常NameLookupSnapshot读取了未定义的名字resume(value...)FutureSnapshot所有沙箱任务都阻塞在宿主 future 上resume({call_id: result})MontyComplete代码执行完毕读.output即可FunctionSnapshot上你能拿到审批所需的全部信息function_name函数名、args/kwargs参数、call_id定义见 crates/monty-python/python/pydantic_monty/_monty.pyi。实战一进程内审批门禁代码级演示下面是一段完整的最小实现。沙箱里的 AI 代码可以调用get_order和send_email但只有send_email需要过门禁from pydantic_monty import FunctionSnapshot, Monty, MontyComplete code order get_order(1024) if order.total 1000: send_email(order.customer, Order str(order.id) approved) order.total TOOLS {get_order: lambda oid: {id: oid, total: 2300, customer: adaexample.com}} GATED {send_email} # 需要人类审批的敏感函数 with Monty() as pool: with pool.checkout() as session: snap session.feed_start(code, external_lookupTOOLS) while not isinstance(snap, MontyComplete): if isinstance(snap, FunctionSnapshot) and snap.function_name in GATED: # 人类审批门禁 print(f⚠️ 等待审批: {snap.function_name} 参数{snap.args}) approved input(批准这次调用[y/N] ).lower() y if approved: snap snap.resume({return_value: sent}) else: # 审批不通过把异常注入沙箱让 AI 代码自己去处理 snap snap.resume({exc_type: PermissionError, message: rejected by human reviewer}) continue snap snap.resume_auto() # 非敏感调用自动放行 print(最终结果:, snap.output)几个关键设计点分级放行resume_auto()会自动解析external_lookup里的普通工具只有命中GATED集合的调用才暂停等待人工。敏感面越窄门禁效率越高——这也是 docs/host-functions.md 里保持工具面窄read_customer(id)是工具read_file(path)就是文件系统的原则。拒绝也有讲究用resume({exc_type: ..., message: ...})把PermissionError注入沙箱AI 代码可以try/except捕获并改写策略而不是整个任务直接崩掉。resume还支持{exception: 异常实例}和{future: ...}两种形式。每个快照最多恢复一次所以恢复后要及时丢弃旧快照对象。实战二落盘快照——今天暂停明天审批真正的门禁往往跨越时间周五下午 AI 暂停在转账调用上周一你才打开审批工单。Monty 的dump()就是为这个场景设计的from pathlib import Path from pydantic_monty import FunctionSnapshot, Monty, MontyComplete with Monty() as pool: # —— 周五执行到敏感调用暂停并存盘 —— with pool.checkout() as session: snap session.feed_start(transfer(order_id, amount), inputs{order_id: 1024, amount: 888}) assert isinstance(snap, FunctionSnapshot) blob snap.dump() # 整个解释器 → 字节 Path(approval_1024.blob).write_bytes(blob) # 同时把 snap.function_name / snap.args 写进审批工单 # —— 周一人类批准在新会话中恢复并注入结果 —— with pool.checkout() as session: snap session.load_snapshot(Path(approval_1024.blob).read_bytes()) result snap.resume({return_value: transferred}) assert isinstance(result, MontyComplete) print(result.output) # transferred官方快照文档列出的四大典型用途里审批门禁与长时运行的 Agent并列在首位另一个隐藏福利是Forking一份快照可以恢复进多个会话从同一状态探索多个分支——相当于让审批人预演不同决策的后果。生产环境必知的 5 个限制 ⚠️这些坑都写在 docs/snapshots.md 的 What restoring does and does not carry 一节时间预算随行max_duration_secs的累计消耗和 dump 一起走恢复的会话不会获得新预算挂载不随行宿主路径永远不在 dump 里恢复时要给load_snapshot传相同的mount否则文件系统调用会退化成未处理的 OS 调用dump 与版本绑定字节带版本号和传输封装不同版本的 Monty 会拒绝它——跨版本存储前先规划升级策略恢复的FutureSnapshot不能用resume_auto()挂起的协程活在旧进程里只能用resume({call_id: ...})手动解决宿主回调要幂等如果 dump 时宿主正在应答某个调用恢复会重新宣告该调用并再次执行。审批场景下批准转账绝不能执行两次。另外快照来自不受信来源时应按不受信序列化数据对待——恢复进一个你愿意牺牲的 worker见 docs/security.md Deserializing snapshots。安全加固清单 ️给审批门禁穿上防弹衣对照 docs/resource-limits.md 和 docs/security.md 逐项检查设置双重超时max_duration_secs沙箱内累计执行时间request_timeout宿主侧看门狗注意暂停等待宿主时沙箱时钟是停走的审批花 3 天不消耗预算这正是门禁能落地的原因限制内存limits{max_memory: ...}触发后丢弃该会话不要复用验证参数为不可信输入审批人看到的是snap.args但真正执行的是你的宿主函数——参数校验一个都不能少固定 worker 二进制路径跑不受信代码时显式传路径别让PATH决定谁是你的沙箱用external_lookup传宿主函数它惰性解析AI 写了 10 个工具调用也只为你真正调用的买单延伸阅读 快照机制完整文档docs/snapshots.md宿主函数设计与安全边界docs/host-functions.md安全模型docs/security.mdPython 包安装与全部 APIpackages/pydantic-monty/README.mduv add pydantic-monty即可快照序列化格式实现crates/monty/src/dump_format.rs真实 Agent 沙箱执行参考web 爬虫 外部函数注入examples/web_scraper/main.py一句话总结feed_start暂停 → 人类看function_name和args→dump()存盘 → 批准后load_snapshotresume()放行。三行核心代码就是 AI 代码执行世界里那扇由人类控制的门。【免费下载链接】montyA minimal, secure Python interpreter written in Rust for use by AI项目地址: https://gitcode.com/GitHub_Trending/monty3/monty创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考