Skip to content

DeerFlow Backend Sandbox 执行环境分析

本文档分析了在 deer-flow 后端体系中,代码沙箱执行环境(Sandbox)的架构设计与实现原理。沙箱主要用于让 AI 或用户安全、隔离地执行代码块(Shell 命令、读写文件等)。

后端的沙箱系统被设计为一个标准的面向对象接口体系,具有极高的解耦和可替换性:

定义在 packages/harness/deerflow/sandbox/sandbox.py。 它是一个标准的接口层,规定了所有沙箱必须提供以下能力:

  • execute_command(command):执行终端命令。
  • read_file(path) / write_file(path, content) / update_file:文本与二进制文件的 I/O 操作。
  • list_dir(path, max_depth):目录遍历。

1.2 SandboxProvider (生命周期、路由与缓存引擎)

Section titled “1.2 SandboxProvider (生命周期、路由与缓存引擎)”

定义在 sandbox_provider.py,但在 aio_sandbox_provider.py 中有极其高级的实现。 它是单例管理器,负责沙箱生命周期的调度:

  • acquire:获取或新建一个特定线程的沙箱空间。在 AIO Provider 中,它实现了一个极致的三层缓存架构
    • 第一层 (In-process cache):极速复用当前进程已挂载的活跃沙箱。
    • 第二层 (Warm pool):将释放的沙箱置于“保暖池”(容器不销毁,只解除绑定),以便同一个 Thread 再次申请时“零冷启动”秒速复用。
    • 第三层 (Cross-process Discovery):通过确定性哈希 ID(Deterministic ID)和跨进程文件锁(File Lock),让不同进程甚至不同 Pod 能够发现彼此启动的共享底层沙箱,解决多进程冲突。
  • get:根据 ID 提取已挂载的沙箱实例并在后台自动续签闲置过期时间 (Idle Timeout)。
  • release:将闲置沙箱退回到保暖池,只有超过系统限定副本数(Replicas)或超时时才会真正执行销毁任务。

2. 具体实现机制 (Concrete Implementations)

Section titled “2. 具体实现机制 (Concrete Implementations)”

目前系统中存在两种截然不同的沙箱实现策略:

2.1 本地宿主机伪沙箱 (LocalSandbox)

Section titled “2.1 本地宿主机伪沙箱 (LocalSandbox)”

定义在 sandbox/local/local_sandbox.py。 这是一种非容器化的轻量级实现形式,直接在后端进程宿主机通过原生进程执行命令。

  • 执行原理:底层使用了 Python 原生的 subprocess.run(command, shell=True) 来直接执行 Bash/Zsh 脚本,这代表着它并没有真正的物理隔离,执行的是宿主机的直接命令。
  • 智能路径映射机制(Path Mapping):为了让从外部或者习惯了容器化路径的工具能够平滑运行,它包含了一个精妙的正则拦截系统。
    • 它在内存里维护了一套映射表(如把虚拟容器路径 /mnt/skills 映射到真实的宿主物理路径 /Users/...)。
    • 在把用户的命令喂给 subprocess.run 执行之前,它会先通过正则,把命令里出现的虚拟路径全部**替换(Resolve)**成真实的绝对路径。
    • 当真实命令吐出 Output 日志时,它又会把这些真实的、可能泄漏隐私的绝对物理路径,全部**反向替换(Reverse Resolve)**回虚拟容器路径。实现了对大模型视角下的“路径伪装隔离”。

2.2 容器化云原生沙箱 (AioSandboxSandboxBackend)

Section titled “2.2 容器化云原生沙箱 (AioSandbox 与 SandboxBackend)”

定义在社区模块 community/aio_sandbox/ 下。这是一套真正的物理级别的容器化隔离方案,被拆分为执行者(AioSandbox)和驱动引擎(SandboxBackend)两个维度:

  • 执行器 (AioSandbox) 通信隔离:所有的 execute_command 并不是本地 Subprocess,而是被转化为长超时的 HTTP REST API,发送给内部运行了 agent-infra/sandbox 服务的 Docker 容器。
  • 底层驱动引擎 (SandboxBackend):负责产生并调度这些隔离容器。它支持两种模式:
    • RemoteSandboxBackend:连接远程 K8s / K3s 的 Provisioner,动态生成远端 Pod。
    • LocalContainerBackend:直接按需在物理机上启动新的 Docker 容器,并分配闲置端口。特别地,在 macOS 系统下,它会优先检测并采用苹果官方原生支持的轻量级虚拟化方案 (Apple Container),仅在找不到时降级回退给 Docker。此设计极大优化了 Mac 上的 I/O 与执行速度。
    • 请求将指令发往由 agent-infra/sandbox 提供的一个运行在大后方的 Docker 容器内部服务(默认为 HTTP API 监听)。
    • 由该远程 Docker 容器内部安全地执行这些指令代码,并将结果 JSON(通常包含 result.data.output)返回给后端的 AioSandbox 包装实例。

通过这套抽象实现,当 AI 大模型提出如 在命令行执行 python script.py 的需求时:

  • 系统不需重构大模型逻辑,即可通过配置自由决定是采用零成本的本地直连替换(LocalSandbox),还是高规格的容器 HTTP 远程直连(AioSandbox)。
  • 两套底层驱动均共享同一个上层执行接口,达到了业务代码的高度复用。