拓冰建站拓冰建站
首页 / 资讯中心 / 正文

smolagents 安全代码执行实战:从 LocalPythonExecutor 本地沙箱到 E2B、Blaxel、Modal 与 Docker 远程隔离

smolagents 安全代码执行实战从 LocalPythonExecutor 本地沙箱到 E2B、Blaxel、Modal 与 Docker 远程隔离【免费下载链接】smolagents smolagents: a barebones library for agents that think in code.项目地址: https://gitcode.com/gh_mirrors/smo/smolagentssmolagents 是一款让 Agent 用代码思考agents that think in code的精简库其核心机制是让 LLM 直接编写 Python 代码作为行动tool calls因此安全执行 LLM 生成的代码就成为整个库安全性的关键命题。本文以 docs/source/hi/tutorials/secure_code_execution.md 为主线完整讲解 smolagents 默认的本地解释器LocalPythonExecutor的防护机制与局限并逐步升级到 E2B、Blaxel、Modal、Docker 四种远程沙箱方案。读完后你将掌握代码 Agent 比 JSON 工具调用更优的原因、本地解释器的四道安全防线及其源码实现、远程沙箱的配置方法与适用边界以及如何在安全等级与搭建成本之间做出取舍。为什么让 Agent 用代码思考Code Agent 的安全前提代码优于 JSON 工具调用多项研究表明让 LLM 把动作工具调用写成代码远比行业通行的把工具名与参数写成 JSON格式更有效。代码是专门为表达计算机要执行的动作而设计的语言其优势体现在四个维度可组合性ComposabilityJSON 动作难以相互嵌套也难以定义一组可复用的动作而代码中只需定义一个 Python 函数即可随时复用。对象管理Object management像generate_image这类动作的输出对象在 JSON 里几乎无法存储与传递代码则天然支持变量绑定。通用性Generality代码本就是为了表达任意计算机操作而诞生的。LLM 训练语料中的代表性Representation in LLM training corpus大量高质量代码示例已经存在于 LLM 的训练数据中让模型写代码等于直接利用这份天赐的语料优势。正是基于这一判断smolagents 将重心放在代码 Agent本场景下即 Python Agent上也就意味着必须投入更高成本去构建安全的 Python 解释器。更高的代理权 更高的风险在代理权agency光谱上代码 Agent 把远高于普通工具调用方案的控制权交给了 LLM这必然伴随着更高的风险。LLM 生成的代码可能以多种方式造成危害LLM 自身的错误模型远非完美可能在试图帮忙时无意生成危险命令供应链攻击运行不可信或被攻陷的 LLM可能产出有害代码提示注入Prompt injectionAgent 浏览网页时可能落入包含恶意指令的站点从而把攻击注入 Agent 记忆公开 Agent 被滥用暴露在公网的 Agent 可能被攻击者构造对抗性输入利用其执行能力造成后果。一旦恶意代码被执行无论有意还是无意就可能破坏文件系统、滥用本地或云端资源、透支 API 服务甚至危及网络安全。因此 smolagents 提供了逐级提升安全等级、同时逐步提高搭建成本的一整套执行方案。需要先说明的前提是没有任何方案是 100% 安全的。默认执行路径LocalPythonExecutor 本地解释器不是 vanilla Python 解释器默认情况下CodeAgent会在你自己的本地环境中运行 LLM 生成的代码。但这一执行并非由原生 Python 解释器完成——smolagents 从零重写了一个更安全的LocalPythonExecutor见 src/smolagents/local_python_executor.py。从源码结构看这个解释器的工作方式是先用 Python 标准库ast把代码解析成抽象语法树Abstract Syntax Tree然后**逐操作operation by operation**地执行这棵树上的每个节点并在每一步都强制遵守若干安全规则。任何未被自定义解释器显式定义的操作都会直接抛出InterpreterError。四道安全防线含源码级实现防线一导入白名单机制默认情况下所有 import 都被禁止除非用户把包名显式加入授权列表。CodeAgent构造时通过additional_authorized_imports参数接收额外授权最终授权集合为self.authorized_imports sorted(set(BASE_BUILTIN_MODULES) | set(self.additional_authorized_imports))其中BASE_BUILTIN_MODULES定义在 src/smolagents/utils.py是解释器默认放行的 11 个人畜无害的标准库模块BASE_BUILTIN_MODULES [ collections, datetime, itertools, math, queue, random, re, stat, statistics, time, unicodedata, ]判断某个 import 是否被授权走的是build_import_treecheck_import_authorized这条路径src/smolagents/local_python_executor.py先把授权列表构建成前缀树再逐段匹配待导入的模块路径。匹配过程中一旦遇到*通配符即放行。防线二子模块默认禁用 危险模块黑名单即使某个包被授权其子模块访问在默认情况下也是关闭的必须逐个显式加入授权列表。例如授权numpy只能导入numpy根包而要同时允许numpy.random、numpy.a.b这类子包可以写numpy.*。测试 tests/test_local_python_executor.py 也验证了numpy.*能同时放行根包与子模块。值得警惕的是一些看似无害的包可能暴露危险子模块。例如random这类默认授权包通过random._os能触达操作系统层。为此解释器维护了两份显式黑名单src/smolagents/local_python_executor.pyDANGEROUS_MODULESbuiltins、io、multiprocessing、os、pathlib、pty、shutil、socket、subprocess、sysDANGEROUS_FUNCTIONSbuiltins.compile/eval/exec/globals/locals/__import__、os.popen、os.system、posix.system等。check_safer_resultsrc/smolagents/local_python_executor.py会在每次表达式求值后检查返回值如果结果是模块对象且未授权或结果是命中黑名单的危险函数立即抛出InterpreterError。这个检查通过safer_eval与safer_func两个装饰器src/smolagents/local_python_executor.py挂接到所有求值入口。同时nodunder_getattrsrc/smolagents/local_python_executor.py与evaluate_attributesrc/smolagents/local_python_executor.py会拦截以__开头和结尾的 dunder 属性访问仅放行__init__、__str__、__repr__三个白名单方法。防线三操作数、循环次数与执行时长上限为防止无限循环与资源膨胀解释器设置了多级上限src/smolagents/local_python_executor.py上限常量默认值作用MAX_OPERATIONS10,000,000单次执行累计基本操作总数上限MAX_WHILE_ITERATIONS1,000,000while循环最大迭代次数MAX_EXECUTION_TIME_SECONDS30单次执行最大耗时超时抛ExecutionTimeoutErrorDEFAULT_MAX_LEN_OUTPUT50,000print 输出最大长度evaluate_whilesrc/smolagents/local_python_executor.py在每轮迭代后计数一旦超过MAX_WHILE_ITERATIONS即抛出 Maximum number of ... iterations in While loop exceeded。执行超时则通过线程实现的timeout装饰器src/smolagents/local_python_executor.py完成该实现跨平台且线程安全。测试 tests/test_local_python_executor.py 通过把上限临时 patch 成 100 来验证无限循环确实会被打断。防线四未定义操作一律报错解释器只认识自己实现的那一组求值函数for、while、函数定义、lambda、内置函数等。任何没有显式实现的操作都会以InterpreterError拒绝执行——不会做任何未预定义的操作。动手验证四段攻击代码全部被拦截可以直接用LocalPythonExecutor亲手验证上述防线下面的示例修正了原文档示例中的一个变量名笔误使其可直接运行from smolagents.local_python_executor import LocalPythonExecutor # 设置自定义执行器授权 numpy 包 custom_executor LocalPythonExecutor([numpy]) # 便于美化打印错误的工具函数 def run_capture_exception(command: str): try: custom_executor(command) except Exception as e: print(ERROR:\n, e) # 未定义的命令根本不会被执行 harmful_command !echo Bad command run_capture_exception(harmful_command) # ERROR: invalid syntax (unknown, line 1) # 未显式加入 additional_authorized_imports 的 os 不会被导入 harmful_command import os; exit_code os.system(echo Bad command) run_capture_exception(harmful_command) # ERROR: Code execution failed at line import os due to: InterpreterError: Import of os is not allowed. Authorized imports are: [statistics, numpy, itertools, time, queue, collections, math, random, re, datetime, stat, unicodedata] # 即使在已授权包内危险子模块同样被拦截 harmful_command import random; random._os.system(echo Bad command) run_capture_exception(harmful_command) # ERROR: Code execution failed at line random._os.system(echo Bad command) due to: InterpreterError: Forbidden access to module: os # 无限循环在 N 次迭代后被中断 harmful_command while True: pass run_capture_exception(harmful_command) # ERROR: Code execution failed at line while True: pass due to: InterpreterError: Maximum number of 1000000 iterations in While loop exceeded除此之外CodeAgent在捕获到 Import of ... is not allowed 这类错误时还会贴心地提示开发者把该包加入additional_authorized_imports后重试src/smolagents/agents.py。本地沙箱的边界它并不绝对安全这些防护让解释器比原生 Python 解释器安全得多smolagents 团队也在多种使用场景中反复验证从未观察到环境受损。但必须清醒认识到任何本地 Python 沙箱都不可能做到完全安全。一个意志坚定的攻击者或一个针对恶意行为微调过的 LLM仍可能找到漏洞伤害你的环境。一个典型例子如果你为了处理图片而授权了Pillow这类包LLM 完全可以生成代码批量创建数千个大尺寸图片文件直接撑爆你的硬盘。更多高级逃逸手段还可能利用授权包内部更深的漏洞。因此结论是使用可信推理提供方的知名 LLM 时恶意攻击风险较低但并非为零。对于高安全需求场景或使用可信度较低的模型时应当改用远程执行沙箱。升级隔离等级E2B 远程代码执行器原理与前置准备为了获得最高等级的安全隔离smolagents 提供了与 E2B 的官方集成E2B 是一项远程执行服务把代码运行在隔离的容器中从物理上杜绝代码影响你的本地环境。你需要注册 E2B 账号把E2B_API_KEY配置到环境变量中安装依赖推荐用官方 extras 方式与当前仓库源码中E2BExecutor的报错提示一致见 src/smolagents/remote_executors.pypip install smolagents[e2b]原文档中给出的pip install e2b-code-interpreter python-dotenv同样可行前者更贴合当前版本。快速上手executor_typee2b配置好之后只需在初始化CodeAgent时传入executor_typee2b标志即可from smolagents import CodeAgent, VisitWebpageTool, InferenceClientModel agent CodeAgent( tools[VisitWebpageTool()], modelInferenceClientModel(), additional_authorized_imports[requests, markdownify], executor_typee2b ) agent.run(What was Abraham Lincolns preferred pet?)两个关键点additional_authorized_imports必须包含所有工具的依赖包。远程执行器初始化时会据此在沙箱内安装依赖——从源码看RemotePythonExecutor.send_tools会遍历每个工具的to_dict()[requirements]收集需要安装的包src/smolagents/remote_executors.py上面的requests、markdownify正是VisitWebpageTool的运行时依赖。未声明的依赖在远程环境会导入失败。推荐使用with上下文管理器或手动调用cleanup()来确保任务完成后沙箱被立即销毁。源码视角E2BExecutor 如何工作从 src/smolagents/remote_executors.py 可以看到E2BExecutor的实现脉络构造时导入e2b_code_interpreter.Sandbox同时兼容 v1 的Sandbox(...)与 v2 的Sandbox.create(...)并立即安装additional_imports中声明的包每次执行通过sandbox.run_code(code)把代码送往隔离容器为支持最终答案机制RemotePythonExecutor._patch_final_answer_with_exception会把FinalAnswerTool.forward替换为抛出自定义FinalAnswerException的版本异常中携带经SafeSerializer序列化前缀safe:的 JSON 或pickle:的最终答案由本地反序列化还原src/smolagents/remote_executors.py结果处理上除文本外还支持把沙箱内产生的jpeg/png图片解码为 PIL 图像以及chart、html、json、latex、markdown、pdf、svg等富格式输出。值得留意的是allow_pickle参数默认False关闭时仅允许安全 JSON 序列化对象无法安全序列化会直接报错开启后回退到 pickle——但 pickle 反序列化可以执行任意代码只有当完全信任执行环境时才应设为True。这一安全警告同样适用于下面提到的全部远程执行器。多智能体限制与应对E2B 代码执行目前不支持多智能体multi-agents场景因为对托管智能体managed agent的任何调用都需要模型请求而 smolagents 不会把密钥secrets传递给远程沙箱模型调用就会因缺少凭证而失败。官方正在着手解决这一问题。临时的完整解决方案是把整个智能体应用放进 E2B 沙箱内部运行——在沙箱里pip install smolagents通过环境变量传入HF_TOKEN然后直接执行定义CodeAgent与manager_agent的代码完整示例见英文版教程 docs/source/en/tutorials/secure_code_execution.md。更多沙箱选项Blaxel、Modal 与 Docker除 E2B 外smolagents 还内置了 Blaxel、Modal、Docker 三种远程执行器统一由 src/smolagents/agents.py 中的executor_type参数Literal[local, blaxel, e2b, modal, docker]调度默认local实际创建逻辑在create_python_executor见 src/smolagents/agents.py。Blaxel毫秒级唤醒的托管沙箱Blaxel 提供可从休眠状态在 25ms 内快速启动的虚拟机空闲后自动缩容回零并保持内存状态非常适合需要快速、安全代码执行的 Agent 应用。pip install smolagents[blaxel]from smolagents import InferenceClientModel, CodeAgent with CodeAgent(modelInferenceClientModel(), tools[], executor_typeblaxel) as agent: agent.run(Can you give me the 100th Fibonacci number?)从源码看BlaxelExecutorsrc/smolagents/remote_executors.py支持sandbox_name、image默认blaxel/jupyter-notebook、memory默认 4096 MB、ttl、region等配置内部通过创建 Jupyter Kernel 并经 WebSocket 传输代码。执行流程上每个agent.run()开始时把 Agent 状态发送到服务器模型调用仍在本地发起只有生成的代码被送往沙箱执行并仅回传输出。若追求更强的隔离也可把整个 Agent含模型与工具整体托管到 Blaxel。Modal云端沙箱快速上手pip install smolagents[modal]from smolagents import InferenceClientModel, CodeAgent with CodeAgent(modelInferenceClientModel(), tools[], executor_typemodal) as agent: agent.run(What is the 42th Fibonacci number?)ModalExecutorsrc/smolagents/remote_executors.py在 Modal Sandbox 中运行 Jupyter Kernel Gateway通过加密隧道与 WebSocket 通信支持app_name默认smolagent-executor、port、create_kwargs等参数并默认注入KG_AUTH_TOKEN随机密钥。Docker自建本地容器沙箱pip install smolagents[docker]from smolagents import InferenceClientModel, CodeAgent with CodeAgent(modelInferenceClientModel(), tools[], executor_typedocker) as agent: agent.run(Can you give me the 100th Fibonacci number?)DockerExecutorsrc/smolagents/remote_executors.py默认基于python:3.12-bullseye镜像构建镜像内安装jupyter_kernel_gateway、jupyter_client、ipykernel容器以 Jupyter Kernel Gateway 形式对外服务构造参数包括host默认127.0.0.1、port默认8888、image_name默认jupyter-kernel、build_new_image以及可自定义的dockerfile_content。如需在 Docker 中运行多智能体系统则需要自建沙箱解释器编写自定义 Dockerfile例如以python:3.10-bullseye为基础、安装smolagents、以nobody低权限用户运行再通过 Docker SDK 构建镜像并以安全约束内存上限、CPU 配额、no-new-privileges、cap_drop[ALL]等启动容器最后用exec_run执行 Agent 代码完整示例同样位于 docs/source/en/tutorials/secure_code_execution.md。两种沙箱模式对比与最佳实践模式一仅代码片段进入沙箱即前文executor_typee2b/blaxel/modal/docker的用法只有 Agent 生成的 Python 代码片段在沙箱中执行其余智能体系统仍留在本地。优点只需一个参数即可完成设置无需把 API 密钥传入沙箱对本地环境有更好的保护配合 Blaxel 的休眠唤醒技术启动极快。缺点暂不支持多智能体managed agents仍需要在本地环境与沙箱之间传递状态数据局限于代码执行这一环节。模式二整个智能体系统进入沙箱把 Agent、模型、工具整体运行在沙箱环境内如前面 E2B、Docker 的多智能体方案。优点支持多智能体对整个智能体系统实现完整隔离更适合复杂架构。缺点需要更多手动搭建可能需要把敏感凭证如 API 密钥传给沙箱环境链路更复杂潜在延迟更高。大多数简单架构的 Agent 应用模式一就能在安全与易用之间取得良好平衡需要完整隔离的复杂多智能体系统则应选择模式二。通用最佳实践以下实践对 Blaxel、E2B、Docker 沙箱同样适用资源管理设置内存与 CPU 上限实现执行超时持续监控资源占用。安全以最小权限运行禁用不必要的网络访问密钥一律通过环境变量传递。环境保持依赖最小化锁定固定包版本使用基础镜像时定期更新。清理务必保证资源被正确回收尤其是 Docker 容器——避免悬挂容器持续吞噬资源。smolagents 为此提供了双重保险CodeAgent支持with上下文管理器退出时自动调用cleanup()也可手动调用cleanup()方法从源码看远程执行器如E2BExecutor.cleanup调用sandbox.kill()DockerExecutor.cleanup停止并移除容器ModalExecutor.cleanup终止沙箱都会在清理时释放对应云端/本地资源。总结按需选择你的执行安全等级smolagents 的安全执行体系是一条逐级递进的决策链本地默认LocalPythonExecutor通过 AST 逐操作解释、导入白名单BASE_BUILTIN_MODULESadditional_authorized_imports支持numpy.*通配、危险模块/函数黑名单、操作数/循环/时长上限、未定义操作报错等机制拦截绝大多数意外恶意代码它足以应对日常开发但并非绝对安全的沙箱。远程沙箱executor_typee2b、blaxel、modal、docker把代码放进隔离容器执行密钥不随代码外传适合高安全需求或低信任度模型场景代价是搭建成本更高、暂不支持多智能体。整系统沙箱把 Agent 应用整体放进 E2B/Docker 等环境获得完整隔离适合多智能体与生产级部署。无论选择哪一档请始终记住没有 100% 安全的代码执行方案。理解LocalPythonExecutor的保护边界、正确使用additional_authorized_imports、善用with上下文管理器与cleanup()是让 smolagents Agent 在安全前提下发挥代码即行动全部潜力的关键。进一步可阅读 docs/source/hi/conceptual_guides/intro_agents.md、docs/source/hi/guided_tour.md 与 docs/source/hi/examples/multiagents.md 深化理解。【免费下载链接】smolagents smolagents: a barebones library for agents that think in code.项目地址: https://gitcode.com/gh_mirrors/smo/smolagents创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
分享:

看完干货,该让你的企业上线了

免费需求沟通 · 48 小时内出具建站方案 · 河南本地可上门