CheinTian / notes
Clipping · 27 分钟

容器沙盒知识点补充

容器沙盒知识点补充

本文档为 2026-04-29 容器沙盒方案深度对比 的配套知识库,从底层原理出发帮助小白理解容器沙盒涉及的核心技术。

知识来源:知乎专栏、AWS 官方文档、Google gVisor 博客、Linux 内核文档、Red Hat 技术博客等。


一、容器隔离的底层"积木"

容器不是虚拟机。它本质上是一个被施加了多重限制的普通 Linux 进程。理解容器沙盒,首先要理解 Linux 内核提供的这几块"积木":

plaintext
┌─────────────────────────────────────────────┐
│              应用进程 (PID 1001)              │
├─────────────────────────────────────────────┤
│  Namespaces  │  cgroups  │  seccomp  │ Cap  │  ← 四大限制机制
├─────────────────────────────────────────────┤
│              Linux 内核                      │
├─────────────────────────────────────────────┤
│              硬件 / KVM                       │
└─────────────────────────────────────────────┘

1.1 Linux Namespaces(命名空间)— "看不见别人"

核心概念

  • Namespace 是内核级的资源隔离机制,每个命名空间内都有独立的资源实例
  • 一个进程可以拥有多个命名空间(PID、Net、Mount 等),也可以与其他进程共享某些命名空间
  • 同一 namespace 中的进程可以互相影响,不同 namespace 中的进程互不干扰
  • 即使用 chroot 限制了根目录,也不能阻止进程创建设备文件(需要 device namespace)

八种命名空间(Linux 3.8+ 完整支持)

命名空间 隔离内容 实际效果 引入版本
Mount 文件系统挂载点 容器有自己的根文件系统,看不到宿主的其他挂载 2.4.19
UTS 主机名和域名 容器可以有自己的 hostname 2.6.19
IPC 进程间通信资源 信号量、消息队列、共享内存相互隔离 2.6.19
PID 进程 ID 容器内 PID 从 1 开始,看不到宿主进程 2.6.24
Network 网络栈 独立的网卡、IP、路由表、端口范围 2.6.29
User 用户和组 ID 容器内 root (UID 0) 映射到宿主的普通用户 3.8
Cgroup cgroup 根目录 容器看不到宿主的 cgroup 层级 4.6
Time 系统时钟 容器可以有独立的系统时间(Linux 5.6+) 5.6

clone() 系统调用

创建命名空间的核心方式是通过 clone() 系统调用的标志位:

c
// 创建一个拥有独立 PID 和 Network 命名空间的子进程
clone(child_func, stack,
      CLONE_NEWPID | CLONE_NEWNET | SIGCHLD, NULL);

在已有进程上也可以通过 setns() 加入已有命名空间,或 unshare() 在当前进程上创建新命名空间。

深入理解

为什么需要 Network Namespace?


1.2 cgroups v2(控制组)— "限制资源用量"

核心概念

  • cgroups 限制进程组的资源使用:CPU、内存、磁盘 IO、网络带宽等
  • Linux 有两种 cgroups 版本:v1(旧)和 v2(新),v2 是现代标准
  • cgroups v2 是 Linux 内核 4.5 开始引入的,RHEL 9 等新发行版已默认使用
  • cgroups 的配置体现为文件系统的目录和文件(通常挂载在 /sys/fs/cgroup)

cgroups v2 vs v1

特性 v1 v2
层级结构 每种资源控制器独立层级 统一层级,所有控制器共享
进程归属 进程可以属于不同层级 每个进程只属于一个 cgroup
线程支持 有限 更完善的线程级控制(threaded mode)
PSI(Pressure Stall Information) ❌ ✅ 监控 CPU/内存/IO 压力
内存管理 每个控制器独立管理 统一的内存管理

cgroup 文件系统示例

bash
# cgroups 的配置本质就是写文件
# 限制某个进程组最多使用 512MB 内存
echo 536870912 > /sys/fs/cgroup/my-container/memory.max

# 限制 CPU 配额
echo "50000 100000" > /sys/fs/cgroup/my-container/cpu.max  # 50% CPU

# 把一个进程加入 cgroup
echo $PID > /sys/fs/cgroup/my-container/cgroup.procs

主要资源控制器

控制器 功能
cpu CPU 时间分配(CFS 配额)
cpuset 绑定到特定 CPU 核心
memory 内存使用限制
io 块设备 IO 带宽限制
pids 限制进程/线程数量
rdma RDMA 资源限制
hugetlb 大页内存限制

与安全的关系


1.3 seccomp(安全计算模式)— "禁用危险系统调用"

发展历史

plaintext
2005  Linux 2.6.12  引入 seccomp(严格模式)
      只允许 read/write/exit/sigreturn 四个系统调用
      目的:把服务器闲置 CPU 出借给不可信程序

2012  Linux 3.5      引入 seccomp-BPF(过滤模式)
      允许自定义 BPF 规则过滤任意系统调用
      真正实用化

2015  Docker          默认启用 seccomp profile
      禁用约 44 个危险系统调用,允许约 300+ 个

至今   成为容器安全标配

两种模式

严格模式(SECCOMP_MODE_STRICT):

  • 只允许 4 个系统调用:read()、write()、exit()、sigreturn()
  • 调用其他任何系统调用 → 进程直接被 SIGKILL 终止
  • 适用场景极窄(如纯计算任务)

过滤模式(SECCOMP_MODE_FILTER):

  • 使用 BPF(Berkeley Packet Filter)程序定义过滤规则
  • 可以精确匹配系统调用号和参数
  • 不匹配的调用可以:返回错误码、发送信号、通知追踪器、直接杀进程

seccomp-BPF 的返回值

返回值 行为
SECCOMP_RET_KILL_PROCESS 立即终止整个进程
SECCOMP_RET_TRAP 发送 SIGSYS 信号给进程
SECCOMP_RET_ERRNO 返回指定的错误码(如 EPERM)
SECCOMP_RET_USER_NOTIF 通知用户空间程序处理(用于容器管理器拦截特定调用)
SECCOMP_RET_TRACE 通知 ptrace 追踪器
SECCOMP_RET_LOG 允许调用但记录日志
SECCOMP_RET_ALLOW 允许调用

Docker 默认 seccomp profile 实战

Docker 的默认配置文件是一个白名单:

  • defaultAction: SCMP_ACT_ERRNO(默认拒绝)
  • 逐一列出允许的系统调用(约 300+ 个)
  • 禁用了约 44 个危险系统调用

被禁用的典型系统调用:

系统调用 禁用原因
mount / umount 防止挂载/卸载文件系统
reboot 防止重启宿主机
swapon / swapoff 防止操作交换空间
ptrace 防止追踪其他进程(可能泄露宿主信息)
kexec_load 防止加载新内核
keyctl 防止使用未命名空间的内核密钥环
bpf 防止加载 BPF 程序
unshare 防止创建新命名空间
userns 防止创建用户命名空间

在 Kubernetes 中使用 seccomp

yaml
# 使用容器运行时的默认 seccomp profile
apiVersion: v1
kind: Pod
spec:
  securityContext:
    seccompProfile:
      type: RuntimeDefault

# 使用自定义 seccomp profile
apiVersion: v1
kind: Pod
spec:
  securityContext:
    seccompProfile:
      type: Localhost
      localhostProfile: profiles/audit.json

seccomp 的局限性


1.4 Linux Capabilities(能力)— "细分 root 权限"

核心概念

传统 Linux 只有两种权限:普通用户和 root(全能)。Capabilities 将 root 权限拆分为独立的能力单元:

Capability 控制的能力
CAP_NET_BIND_SERVICE 绑定 1024 以下端口
CAP_SYS_ADMIN 超级大杂烩:mount、namespaces、设备操作等
CAP_NET_RAW 使用原始套接字(ping、网络嗅探)
CAP_SYS_PTRACE 追踪其他进程
CAP_DAC_OVERRIDE 绕过文件权限检查
CAP_CHOWN 修改文件所有者

Docker 默认赋予容器的 Capabilities(约 14 个),远少于完整的 root 权限。可以通过 --cap-drop 和 --cap-add 精确控制。


二、容器逃逸:为什么需要更强的隔离?

2.1 容器逃逸的三种典型路径

① 内核漏洞(最严重)

  • CVE-2016-5195(Dirty COW):Linux 内核竞态条件漏洞,容器内普通用户可以修改只读内存映射获得 root 权限
  • CVE-2022-0185:文件系统层堆溢出漏洞,非特权用户利用 mount() 系统调用创建嵌套挂载,触发溢出逃逸到宿主

② 特权容器

  • 使用 --privileged 启动的容器拥有宿主的全部 Capabilities
  • 可以访问宿主设备文件(如 /dev/sda)
  • 攻击者可以直接挂载宿主磁盘

③ 危险配置

  • 挂载了 Docker socket(/var/run/docker.sock)
  • 挂载了宿主敏感目录(/etc、/root)
  • seccomp=unconfined 禁用了系统调用过滤

2.2 容器安全的防御层次

plaintext
┌─────────────────────────────────────────┐
│  第 1 层:Namespace(可见性隔离)         │  ← 看不到别人
├─────────────────────────────────────────┤
│  第 2 层:Capabilities(权限裁剪)        │  ← 权限受限
├─────────────────────────────────────────┤
│  第 3 层:seccomp(系统调用过滤)         │  ← 危险操作被拦
├─────────────────────────────────────────┤
│  第 4 层:cgroups(资源限制)             │  ← 资源耗尽攻击
├─────────────────────────────────────────┤
│  ❌ 共享内核(根本性风险)                │  ← 内核漏洞 = 逃逸
└─────────────────────────────────────────┘

  对比:MicroVM 方案

┌─────────────────────────────────────────┐
│  第 1 层:硬件虚拟化(KVM)              │  ← 独立内核,逃逸需突破虚拟化层
├─────────────────────────────────────────┤
│  第 2 层:Jailer(seccomp + namespace)  │  ← VMM 进程自身也被限制
├─────────────────────────────────────────┤
│  第 3 层:极简设备模型                    │  ← 攻击面极小
└─────────────────────────────────────────┘

三、gVisor — 用户态内核

3.1 核心架构

plaintext
传统容器:                    gVisor:
┌──────────┐              ┌──────────┐
│ 应用     │              │ 应用     │
│ libc     │              │ libc     │
├──────────┤              ├──────────┤
│ Linux 内核│              │ Sentry   │  ← 用户态内核(Go 实现)
│ (共享!) │              │ (Go)     │     拦截 ~237 个系统调用
├──────────┤              ├──────────┤
│ 硬件     │              │ Linux 内核│
└──────────┘              ├──────────┤
                          │ 硬件     │
                          └──────────┘

三个核心组件:

组件 功能
Sentry 应用内核,拦截并实现所有系统调用(Go 实现,~237 个 syscall)
Gofer 文件系统代理,负责宿主机文件 IO(独立进程,通过 9P 协议通信)
Runsc OCI 兼容运行时,管理沙箱生命周期

3.2 工作原理

拦截方式:

系统调用类型 拦截方式
快速路径(read/write/close 等) 通过 PTRACE_SYSEMU ptrace 方式拦截
慢速路径(open、connect、mmap 等) 需要额外 IPC 到 Gofer
信号处理 Sentry 利用 Linux 信号机制,通过 SIGSYS 注入处理逻辑

关键数据:

  • Sentry 实现了约 237 个 Linux 系统调用,覆盖绝大多数应用需求
  • 每个容器(Sandbox)运行在独立的 Sentry 内核中
  • 每个 Sentry 拥有独立的内核地址空间和虚拟文件系统

3.3 KVM 平台模式(更深度的隔离)

gVisor 最初使用 ptrace 拦截,后来增加了 KVM 平台模式:

plaintext
ptrace 模式:gVisor 和应用共享同一进程地址空间,通过 ptrace 拦截
KVM 模式:应用运行在 KVM 虚拟化的 guest ring3,
         guest ring0 运行 Sentry(gVisor 自己的 ring0 代码)
         系统调用触发 VM Exit → Sentry 在 host ring0 处理

3.4 gVisor 的局限性

局限 说明
性能损耗 快速路径损耗 2x-3x,慢速路径(open/close/mmap)损耗高达 4x-20x
兼容性 只实现 237 个 syscall,复杂应用可能不兼容(如使用 io_uring 的应用)
功能缺失 不支持 SCM_RIGHTS、部分 socket 选项、io_uring 等
ptrace 模式的安全问题 不能有效阻止 TOCTOU 攻击
适合场景有限 最适合非持久化、无状态、可扩展的计算型工作负载(如 AWS Lambda)

3.5 gVisor vs Kata Containers

维度 gVisor Kata Containers
本质 用户态内核(拦截 syscall) 完整虚拟机(独立 Linux 内核)
启动速度 快(无需启动完整内核) 较慢(需要启动 guest 内核)
内存开销 低 较高(每个容器一个内核)
兼容性 受限(237 个 syscall) 好(完整 Linux 内核,兼容所有 syscall)
适用负载 无状态、短生命周期 有状态、长运行、传统应用
性能 IO 密集型场景损耗大 接近原生 VM 性能
安全性 用户态隔离 + 可选 KVM 硬件虚拟化隔离

四、Firecracker — 极简 MicroVM

4.1 为什么需要 Firecracker?

AWS Lambda 的演进之路:

plaintext
2014  Lambda 发布 → 每个租户独立 EC2 实例(太重、太慢)
2015  尝试 Docker 容器 → 安全隔离不足(共享内核)
2017  开发 Firecracker → 兼具 VM 安全性 + 容器速度
2018  开源 Firecracker
至今   Lambda + Fargate 全面使用 Firecracker MicroVM

4.2 架构设计

plaintext
┌──────────────────────────────────────┐
│          Firecracker 进程             │
│  ┌─────────────────────────────────┐ │
│  │  API Server (RESTful)           │ │  ← 配置网卡、磁盘、启动参数
│  ├─────────────────────────────────┤ │
│  │  VMM (Virtual Machine Manager)  │ │  ← 管理 MicroVM 生命周期
│  ├─────────────────────────────────┤ │
│  │  设备模型(极简)               │ │  ← 只保留必要设备
│  │  - virtio-net                   │ │
│  │  - virtio-blk                   │ │
│  │  - virtio-vsock                 │ │
│  │  - serial console               │ │
│  │  - 仅关机键的键盘               │ │
│  ├─────────────────────────────────┤ │
│  │  KVM                            │ │  ← 硬件虚拟化
│  └─────────────────────────────────┘ │
└──────────────────────────────────────┘
         │
         ▼
┌──────────────────────────────────────┐
│  MicroVM (Guest)                      │
│  ┌─────────────────────────────────┐ │
│  │  精简 Linux 内核                 │ │  ← AWS 定制裁剪
│  │  最小化 rootfs                   │ │
│  │  单个应用容器 / 函数              │ │
│  └─────────────────────────────────┘ │
└──────────────────────────────────────┘

4.3 Firecracker 的"减法哲学"

与 QEMU 对比,Firecracker 做了大量裁剪:

组件 QEMU Firecracker 裁剪原因
BIOS SeaBIOS ❌ 移除 MicroVM 不需要传统 BIOS 启动流程
PCI 总线 ✅ ❌ 移除 只用 virtio 直通,不需要 PCI 枚举
VGA 显示 ✅ ❌ 移除 无头计算不需要图形输出
USB / Sound ✅ ❌ 移除 服务器工作负载不需要
设备模型 140+ 设备 ~5 个设备 最小化攻击面

保留的设备:

  • virtio-net:网络
  • virtio-blk:块存储
  • virtio-vsock:宿主 ↔ 客户机通信(替代 Docker socket)
  • 串口控制台(/dev/ttyS0)
  • 可编程间隔计时器、KVM 时钟
  • 仅包含关机键的键盘

4.4 性能数据

指标 数值
冷启动时间 < 125ms
启动吞吐 每秒 150 台 MicroVM
内存开销 < 5MB
单机并发 4000 台(AWS i3.metal EC2)
API 延迟 < 5ms

4.5 Jailer:Firecracker 的安全加固

Firecracker 通过 Jailer 进程实现生产环境的安全加固:

plaintext
Firecracker 进程
    │
    ├── seccomp BPF 过滤器(每个线程独立配置)
    ├── cgroups 资源限制
    ├── namespace 隔离
    ├── chroot 监狱
    └── 权限降级(drop privileges)

4.6 Firecracker 的局限

局限 说明
不支持热迁移 MicroVM 状态无法迁移,只能销毁重建
不支持设备热插拔 运行时不能动态添加设备
设备模型极简 不支持 GPU 直通、VFIO 等高级特性
仅 Linux 不支持 Windows guest
存储限制 只支持 virtio-blk,不支持 virtio-scsi

五、Kata Containers — 安全容器的"正规军"

5.1 架构

plaintext
┌─────────────────────────────────────┐
│  Kubernetes (CRI)                   │
├─────────────────────────────────────┤
│  containerd + kata-runtime          │
├─────────────────────────────────────┤
│  Kata Shim                          │
│  ┌───────────────────────────────┐  │
│  │  hypervisor (QEMU/CHV/FC)     │  │
│  │  ┌─────────────────────────┐  │  │
│  │  │  Guest Kernel           │  │  │
│  │  │  ┌───────────────────┐  │  │  │
│  │  │  │  Kata Agent       │  │  │  │
│  │  │  │  ┌─────────────┐  │  │  │  │
│  │  │  │  │  容器 (OCI)  │  │  │  │  │
│  │  │  │  └─────────────┘  │  │  │  │
│  │  │  └───────────────────┘  │  │  │
│  │  └─────────────────────────┘  │  │
│  └───────────────────────────────┘  │
└─────────────────────────────────────┘

5.2 关键技术点

Hypervisor 选择(Kata 3.0+):

Hypervisor 特点
QEMU 最成熟,功能最全,但最重
Cloud Hypervisor (CHV) Rust 实现,轻量,Kata 3.0+ 默认
Firecracker 最轻,但功能受限(不支持 VFIO/热迁移等)
Dragonball 蚂蚁集团贡献,针对 Kata 优化

kata-agent:运行在 guest 内部的守护进程,接收 shim 的 gRPC 请求来创建/管理容器。

3.0 重大改进:

  • 底层从 QEMU 切换到 Cloud Hypervisor(Rust 重写)
  • 使用 rust-runtime,进一步提升性能和安全性
  • 原生支持 Confidential Containers(机密容器)

5.3 局限

  • 每个 Pod 一个完整 VM → 内存开销大
  • 启动时间比普通容器慢(需要启动 guest 内核)
  • 需要嵌套虚拟化支持或裸金属服务器
  • 比 Firecracker 更重(保留了更多兼容性)

六、OCI 运行时规范 — 容器标准

6.1 核心概念

OCI 运行时规范定义了:

  • 容器的文件系统 bundle 如何组织
  • 容器生命周期的各个阶段(创建、运行、销毁)
  • 配置文件格式(config.json)

6.2 三种运行时类型

plaintext
OCI Runtime
    │
    ├── 传统隔离型(共享内核)
    │   └── runc(参考实现)
    │
    ├── 轻量虚拟化型(独立内核)
    │   ├── kata-runtime(内置 hypervisor)
    │   ├── firecracker-containerd
    │   └── cloud-hypervisor
    │
    └── 内核定制型(限制系统调用)
        ├── gVisor (runsc)
        └── Nabla Containers(已不活跃)

6.3 三种方案对比

维度 runc(传统) gVisor(内核定制) Kata(轻量虚拟化)
隔离机制 内核特性(namespace + cgroups + seccomp) 用户态内核拦截 syscall 硬件虚拟化(KVM)
资源占用 低 中 高
安全性 低(共享内核) 中(用户态内核) 高(独立内核)
启动速度 快 快 慢
兼容性 完美 受限(237 个 syscall) 好
适用场景 传统容器化应用 无状态计算(Serverless) 有状态、安全敏感

6.4 安全总结

plaintext
安全性:runc < gVisor < Kata
兼容性:gVisor < Kata < runc
启动速度:Kata < gVisor ≈ runc
资源开销:Kata > gVisor > runc

七、容器安全的"最小权限原则"

7.1 普通用户 vs root

普通用户:

  • 只能访问自己的文件
  • 不能修改其他用户的文件或进程
  • 不能监听 1024 以下的端口
  • 不能修改系统关键文件

root:可以绕过所有权限检查(这就是为什么容器逃逸到 root 如此危险)

7.2 容器安全的分层防御

yaml
# 一个安全加固的容器配置示例
apiVersion: v1
kind: Pod
spec:
  securityContext:
    # 非 root 运行
    runAsNonRoot: true
    runAsUser: 1000
    runAsGroup: 3000
    fsGroup: 2000
    # 禁止权限提升
    allowPrivilegeEscalation: false
    # 只读根文件系统
    readOnlyRootFilesystem: true
    # seccomp profile
    seccompProfile:
      type: RuntimeDefault
  containers:
    - name: app
      image: my-app:latest
      # 最小 Capabilities
      securityContext:
        capabilities:
          drop:
            - ALL    # 丢弃所有 Capabilities

7.3 各安全机制的定位

机制 防什么 不防什么
Namespace 进程看到不该看的资源 内核漏洞
cgroups 资源耗尽攻击 代码执行漏洞
seccomp 危险系统调用 应用层逻辑漏洞
Capabilities 越权操作 内核漏洞
User Namespace 容器内 root 映射到宿主普通用户 内核漏洞
gVisor 大部分内核漏洞(用户态拦截) 性能敏感场景
MicroVM 内核漏洞(硬件隔离) 侧信道攻击(需要额外措施)

八、关键术语速查表

术语 全称 解释
OCI Open Container Initiative 定义容器镜像和运行时的标准(由 Docker、CoreOS 等发起)
KVM Kernel-based Virtual Machine Linux 内核的硬件虚拟化模块,需要 CPU 支持 VT-x/AMD-V
VMM Virtual Machine Monitor 虚拟机监视器,管理虚拟机的生命周期
virtio Virtual I/O 半虚拟化 IO 标准,比全模拟设备性能更好
vsock Virtual Socket 虚拟机与宿主机之间的套接字通信机制
BPF Berkeley Packet Filter 内核级的字节码执行引擎,seccomp 和 eBPF 的基础
eBPF Extended BPF 扩展版 BPF,可以在内核中运行自定义程序(网络、安全、监控)
Guest OS — 运行在虚拟机内部的操作系统
Host OS — 宿主机操作系统
TOCTOU Time-of-Check to Time-of-Use 检查-使用竞态攻击,安全检查和实际操作之间的竞态条件
Jailer — Firecracker 的安全加固进程,应用 cgroup/namespace/chroot
Shim — 容器运行时的中间层,处理容器生命周期

九、沙盒与外部工具集成 — "工具丢了怎么办?"

9.1 问题拆解

plaintext
Agent 需要调用工具
        │
        ├── 工具在哪运行?
        │   ├── 方案 A:工具装在沙盒内(临时,重启丢失)
        │   ├── 方案 B:工具装在沙盒外(持久,通过网络调用)
        │   └── 方案 C:预烘焙到镜像中(持久,但需重建镜像才能更新)
        │
        ├── 密钥怎么管理?
        │   ├── 放沙盒内 → 不安全(恶意代码可窃取)
        │   ├── 放沙盒外 + 代理注入 → 安全
        │   └── 放沙盒外 + MCP Server → 安全 + 标准化
        │
        └── 工具版本怎么保证一致性?
            ├── 镜像预装 → 版本固定,更新需重建
            ├── 快照恢复 → 版本随快照
            └── 外部代理 → 版本由外部管理

9.2 五种集成模式

模式一:镜像预烘焙(Template Baking)

把工具直接打包进沙盒的基础镜像(OCI Image)。

plaintext
┌─────────────────────────────────────┐
│  OCI 镜像                           │
│  ├── Ubuntu base                    │
│  ├── Python 3.11 + pip packages     │
│  ├── Node.js + npm packages         │
│  ├── Git / curl / jq / ...          │
│  └── 自定义工具(已安装)            │
└─────────────────────────────────────┘
         │
         ▼  创建沙盒
┌─────────────────────────────────────┐
│  沙盒实例(工具已就绪)              │
└─────────────────────────────────────┘

代表项目:CubeSandbox Template、E2B Custom Template

CubeSandbox 的三阶段模板构建:

  1. Init:OCI 镜像 → rootfs(Buildkit 构建)
  2. Boot & Snapshot:冷启动 rootfs 到 MicroVM → 快照内存状态
  3. Deploy:注册快照,后续创建沙盒直接克隆快照(热启动,毫秒级)

优点:工具开箱即用;版本可控;配合快照克隆启动极快 缺点:更新工具需要重建镜像;镜像体积增大;灵活性差


模式二:快照与持久化(Snapshot & Persistence)

沙盒停止时自动保存状态,重启时恢复,工具不会丢失。

plaintext
沙盒运行中(工具已安装)
    │
    ▼  停止
┌──────────────────┐
│ 快照(内存+磁盘) │  ← 自动保存
└──────────────────┘
    │
    ▼  重启(~10s)
┌──────────────────┐
│ 沙盒恢复         │  ← 工具还在!
│ (工具+状态保留) │
└──────────────────┘

代表项目:

  • BoxLite:有状态持久化,Box 停止/重启后保留包、文件和环境
  • Vercel Sandbox (OpenClaw):persistent: true 创建的沙盒,停止时自动快照,恢复时保留全部状态
  • CubeSandbox:快照克隆(Coming Soon 正式版本)

Vercel Sandbox 的生命周期:

plaintext
uninitialized → creating → setup → booting → running
                                              │
                                         ┌────┴────┐
                                         ▼         ▼
                                      stopped    error
                                      (快照保存)  (可恢复)

优点:工具和中间状态全部保留;恢复比从头创建快(~10s vs 完整引导) 缺点:快照占用存储;快照可能过期(配置变更后需重建);长时间停止后快照可能不一致


模式三:MCP 作为工具代理(MCP Tool Proxy)

MCP(Model Context Protocol)是连接 Agent 和外部工具的标准协议。工具运行在沙盒外部的 MCP Server 中,沙盒通过 MCP 协议调用工具。

plaintext
┌────────────┐    MCP 协议     ┌────────────────┐
│  Agent     │ ◄──────────────► │  MCP Server    │
│  (沙盒内)  │                  │  (沙盒外)      │
│            │    stdio/HTTP    │  ┌──────────┐  │
│            │                  │  │ GitHub   │  │
│            │                  │  │ Slack    │  │
│            │                  │  │ DB       │  │
│            │                  │  │ 自定义   │  │
│            │                  │  └──────────┘  │
└────────────┘                  └────────────────┘

代表项目:

  • OpenSandbox MCP Server:将沙盒生命周期和文件操作暴露为 MCP 工具(sandbox_create、command_run、file_read 等),任何 MCP 客户端(Claude Code、Cursor)都可以调用
  • E2B MCP Gateway:提供 200+ 预构建的 MCP Server 集成,创建沙盒时声明需要的 MCP 工具

E2B 的 MCP 集成示例:

python
# 创建沙盒时声明需要 GitHub MCP 工具
sandbox = Sandbox.create(
    mcp={"github": {"token": "..."}}
)
# 沙盒内自动获得本地 MCP endpoint,可直接调用 GitHub API

OpenSandbox 的架构:

plaintext
┌─────────────────────────────────────┐
│  MCP 客户端(Claude Code / Cursor) │
├─────────────────────────────────────┤
│  OpenSandbox MCP Server(沙盒外)    │  ← 密钥在这里,不在沙盒内
│  ├── sandbox_create                 │
│  ├── sandbox_command_run            │
│  ├── sandbox_file_read              │
│  └── server proxy(网络代理)        │
├─────────────────────────────────────┤
│  沙盒实例(沙盒内)                  │  ← 只执行代码,不持有密钥
└─────────────────────────────────────┘

优点:工具与沙盒生命周期完全解耦;密钥不进入沙盒;标准化协议,生态丰富 缺点:需要额外部署 MCP Server;网络调用增加延迟;MCP 生态仍在早期


模式四:工具网关 / 代理(Tool Gateway Pattern)

工具运行在沙盒外部的网关/代理后面,沙盒通过代理 URL 调用工具,凭证永远不进入沙盒。

plaintext
┌──────────┐     ┌───────────────┐     ┌──────────────┐
│  沙盒    │────►│  工具网关     │────►│  外部工具    │
│          │     │  (代理层)      │     │              │
│  无密钥  │     │  ├── 凭证注入  │     │  GitHub API  │
│  只有    │     │  ├── 域名过滤  │     │  Slack API   │
│  代理URL │     │  ├── 审计日志  │     │  数据库      │
│          │     │  └── 速率限制  │     │              │
└──────────┘     └───────────────┘     └──────────────┘

代表项目:agentgateway.dev(Linux Foundation)、Vercel Sandbox

Vercel 的凭证注入方式:

plaintext
沙盒内代码: fetch("https://ai-gateway.vercel.sh/...")
                    │
                    ▼  网络策略层自动注入
请求实际变成: GET https://ai-gateway.vercel.sh/...
              Authorization: Bearer <token>   ← 网关注入,沙盒内不可见

优点:凭证安全级别最高;细粒度访问控制;审计和监控 缺点:增加架构复杂度;网关成为单点故障;需要运维网关服务


模式五:Session-Harness-Sandbox 三元分离(Anthropic 架构)

Anthropic 提出的最新架构模式,将 Agent 系统拆分为三个独立的原语:

plaintext
┌─────────────────────────────────────────────────┐
│  Session(会话日志)                              │
│  ├── append-only 事件流                          │
│  ├── 记录每个工具调用和结果                       │
│  └── 任何 Harness 都可以接管恢复                  │
├─────────────────────────────────────────────────┤
│  Harness(编排层,无状态)                        │
│  ├── 驱动 Agent 循环(调用 LLM + 工具)           │
│  ├── 崩溃后可被任何新 Harness 接管                │
│  └── 凭证通过 Vault 代理获取,不经过沙盒          │
├─────────────────────────────────────────────────┤
│  Sandbox(执行层,临时)                          │
│  ├── 执行不可信代码                              │
│  ├── 不持有任何凭证                              │
│  └── 崩溃不影响 Session 和 Harness               │
└─────────────────────────────────────────────────┘

关键设计:

  • Session 是真理之源:所有事件(工具调用、结果、模型输出)都记录在 Session 日志中
  • Harness 无状态:任何 Harness 实例都可以接管任何 Session,实现水平扩展和崩溃恢复
  • 凭证不进沙盒:两种方式 —— Resource-bundled auth(provision 阶段注入后丢弃)或 Vault-proxied auth(通过 MCP 代理)

崩溃恢复流程:

plaintext
沙盒崩溃
    │
    ▼
新 Harness 调用 wake(sessionId)
    │
    ▼
从 Session 日志获取所有历史事件
    │
    ▼
从最后一个成功的工具调用处继续
    │
    ▼
用户看到短暂暂停,而不是从头开始

性能收益:TTFT(首 token 时间)降低约 60%(p50)和 90%(p95),因为推理可以与沙盒准备并行进行。

优点:最强的解耦;天然支持崩溃恢复和水平扩展;凭证安全级别最高 缺点:架构最复杂;需要维护 Session 存储;目前主要在 Anthropic 内部使用


9.3 五种模式对比总结

维度 镜像预烘焙 快照持久化 MCP 工具代理 工具网关 三元分离
工具持久性 ✅ 在镜像中 ✅ 在快照中 ✅ 在外部 Server ✅ 在外部 ✅ 在外部
重启后工具是否保留 ✅ ✅ ✅ ✅ ✅
密钥安全性 ❌ 在沙盒内 ❌ 在沙盒内 ✅ 在 MCP Server ✅ 在网关 ✅ 结构性分离
工具更新灵活性 ❌ 需重建镜像 ❌ 需重建快照 ✅ 更新 Server ✅ 更新网关 ✅ 更新 Server
架构复杂度 低 低 中 高 最高
代表项目 CubeSandbox BoxLite / Vercel OpenSandbox / E2B agentgateway Anthropic
适合阶段 MVP / 原型 本地开发 生产 Agent 企业级 Agent 大规模 Agent 平台

9.4 选型建议


十、agentgateway 深度剖析 — "AI 原生网关如何工作"

10.1 为什么传统 API 网关不够用?

维度 传统 API 网关 agentgateway
请求模型 无状态请求/响应 有状态 JSON-RPC 会话,长连接
路由方式 一个请求 → 一个后端 一个请求 → 扇出到多个 MCP Server
通信方向 客户端发起 双向:服务端可通过 SSE 推送事件
路由决策 基于路径/头部 协议感知:理解 JSON-RPC 消息体
后端映射 静态 动态工具虚拟化(per-client)
会话管理 不需要 必须维护 Mcp-Session-Id 绑定

10.2 整体架构

plaintext
┌─────────────────────────────────────────────────────────────┐
│                    Control Plane (Go)                        │
│  ┌──────────┐  ┌──────────────┐  ┌────────────────────┐    │
│  │ Config   │  │ Translation  │  │ xDS Server         │    │
│  │ Watcher  │→ │ Engine       │→ │ (gRPC 配置分发)    │    │
│  │ (K8s CRD)│  │ (资源翻译)    │  │                    │    │
│  └──────────┘  └──────────────┘  └─────────┬──────────┘    │
│                                             │ xDS snapshot  │
├─────────────────────────────────────────────┼───────────────┤
│                    Data Plane (Rust)         │               │
│  ┌──────────────────────────────────────────▼─────────────┐ │
│  │              Gateway Proxy (agentgateway)               │ │
│  │  ┌──────────┐  ┌──────────┐  ┌──────────┐             │ │
│  │  │ LLM GW   │  │ MCP GW   │  │ A2A GW   │             │ │
│  │  │ (LLM 路由)│  │ (工具联邦)│  │ (Agent间)│             │ │
│  │  └────┬─────┘  └────┬─────┘  └────┬─────┘             │ │
│  │       │             │              │                    │ │
│  │  ┌────▼─────────────▼──────────────▼────────────────┐  │ │
│  │  │           Policy Engine (CEL)                    │  │ │
│  │  │  Auth │ RBAC │ Rate Limit │ Guardrails │ CORS   │  │ │
│  │  └─────────────────────────────────────────────────┘  │ │
│  │  ┌─────────────────────────────────────────────────┐  │ │
│  │  │           Observability (OpenTelemetry)          │  │ │
│  │  │  Metrics │ Logs │ Distributed Tracing           │  │ │
│  │  └─────────────────────────────────────────────────┘  │ │
│  └───────────────────────────────────────────────────────┘ │
└─────────────────────────────────────────────────────────────┘
         │              │              │
         ▼              ▼              ▼
   ┌──────────┐  ┌──────────┐  ┌──────────┐
   │ LLM      │  │ MCP      │  │ A2A      │
   │ Providers│  │ Servers  │  │ Agents   │
   │ (OpenAI, │  │ (GitHub, │  │ (其他    │
   │  Anthropic│  │  Slack,  │  │  Agent)  │
   │  Gemini) │  │  自定义) │  │          │
   └──────────┘  └──────────┘  └──────────┘

技术栈:

  • Data Plane(Rust 59%):高性能代理,管理有状态长连接和扇出
  • Control Plane(Go 28%):Kubernetes 控制器,监听 CRD 变更,翻译为 xDS 配置
  • UI(TypeScript 10%):内置自服务门户,Playground 测试

10.3 MCP Gateway 核心机制

10.3.1 工具联邦(Tool Federation)

多个 MCP Server 的工具聚合到一个端点。

plaintext
Agent 客户端(只看到一个 MCP endpoint)
    │
    │  GET /mcp → tools/list
    │
    ▼
┌─────────────────────────────────────────┐
│         agentgateway MCP Gateway         │
│                                          │
│  ┌────────────┐    ┌────────────┐       │
│  │ MCP Server │    │ MCP Server │       │
│  │ "filesystem"│    │ "memory"   │       │
│  │ (stdio)    │    │ (stdio)    │       │
│  └────────────┘    └────────────┘       │
│                                          │
│  工具列表自动聚合 + 名称前缀:           │
│  ├── filesystem_read_file                │
│  ├── filesystem_write_file               │
│  ├── memory_create_entities              │
│  └── memory_search                       │
└─────────────────────────────────────────┘

配置示例:

yaml
binds:
- port: 3000
  listeners:
  - routes:
    - backends:
      - mcp:
          targets:
          - name: filesystem        # 第一个 MCP Server
            stdio:
              cmd: npx
              args: ["-y", "@modelcontextprotocol/server-filesystem", "/tmp"]
          - name: memory            # 第二个 MCP Server
            stdio:
              cmd: npx
              args: ["-y", "@modelcontextprotocol/server-memory"]

工作机制:

  1. 启动时,agentgateway 分别连接每个 MCP Server,获取其工具列表
  2. 将所有工具聚合,自动添加 {server_name}_ 前缀避免命名冲突
  3. 客户端调用 tools/list 时,返回聚合后的完整工具列表
  4. 客户端调用某个工具时,agentgateway 根据前缀路由到对应的后端 MCP Server

10.3.2 多路复用与扇出(Multiplexing & Fan-out)

一个客户端连接 → 扇出到多个后端 MCP Server → 聚合响应返回。

传统 API 网关:一个请求打一个后端 agentgateway:一个 tools/list 请求扇出到 N 个 MCP Server,合并结果

plaintext
客户端: tools/list
    │
    ▼  agentgateway
    ├──► filesystem Server → 返回 10 个工具
    ├──► memory Server     → 返回 5 个工具
    └──► github Server     → 返回 8 个工具
    │
    ▼  合并(23 个工具,自动去重+前缀)
    │
客户端: 收到 23 个工具的统一列表

Kubernetes 模式下支持标签选择器动态发现 MCP Server:

yaml
apiVersion: agentgateway.dev/v1alpha1
kind: AgentgatewayBackend
spec:
  mcp:
    targets:
    - name: mcp-server-everything
      selector:                          # 动态发现
        services:
          matchLabels:
            app: mcp-server-everything
    - name: mcp-website-fetcher
      static:                            # 静态配置
        host: mcp-website-fetcher.default.svc.cluster.local
        port: 80
        protocol: SSE

10.3.3 OpenAPI → MCP 自动翻译

零代码改造:把现有的 REST API 自动变成 MCP 工具。

plaintext
                    启动时                        运行时
                    
OpenAPI Spec  ──►  解析每个  ──►  MCP Tool     MCP Client  ──►  call_tool("addPet")
(YAML/JSON)       path+method    定义           │                │
                                               ▼                ▼
                                         agentgateway    翻译为 HTTP 请求
                                               │         POST /pet
                                               │         {"name": "Fido", ...}
                                               ▼
                                         REST Backend

翻译规则:

OpenAPI 字段 → MCP 字段
operationId → 工具名(如 addPet);若无则用 {method}_{path}
summary + description → 工具描述
parameters(query/path/header)+ requestBody → 工具输入 schema
HTTP method + path + query string → 请求构造

请求翻译 10 步流水线(源码级):

步骤 动作 代码位置
1 根据工具名查找 (Tool, UpstreamOpenAPICall) self.tools IndexMap
2 解析参数到 path_params、query_params、header_params、body_value call_tool()
3 路径模板替换 {param} → 实际值(百分号编码防注入) PathParamReplacer
4 拼接 URL:prefix + path + query string normalize_url_path()
5 构造 HTTP 请求(method、Accept header、body) http::Request::builder()
6 注入网关级头部(auth policy 等) ctx.apply(&mut request)
7 添加用户头部(仅白名单内的 header) allowed_headers 过滤
8 执行 HTTP 调用 self.http_client.call(request)
9 解压响应(gzip/deflate/brotli/zstd)+ JSON 反序列化 to_bytes_with_decompression()
10 包装为 MCP CallToolResult 返回 JSON object / wrapped in {"data": ...}

安全措施(内建):

  • 路径遍历防护:路径参数百分号编码,"../admin" → "..%2Fadmin"
  • 查询注入防护:查询参数值全部编码,"true&admin=true" → "true%26admin%3Dtrue"
  • Header 白名单:只转发 OpenAPI spec 中声明的 header,content-length/content-type/transfer-encoding/host 永远被阻止
  • URL 规范化:防止双斜杠 /api/v1//pets 问题

10.3.4 MCP 会话管理(Session Management)

MCP 是有状态协议,agentgateway 必须管理会话生命周期。

plaintext
客户端连接
    │
    ▼
agentgateway 创建 Session(绑定 Mcp-Session-Id)
    │
    ├──► 会话路由:后续请求自动路由到同一个后端
    ├──► 会话扇出:一个会话可以跨多个后端 MCP Server
    ├──► 会话持久化:支持跨请求的会话状态
    └──► 会话认证:per-session 的 RBAC 策略

Session Layer 请求路由:

plaintext
MCP Client → tools/call "filesystem_read_file"
    │
    ▼  Session Layer (session.rs)
    │  parse_resource_name("filesystem_read_file") → target="filesystem"
    │
    ▼  Relay Layer (handler.rs)
    │  send_single(request, target="filesystem")
    │
    ▼  UpstreamGroup
    │  get("filesystem") → Upstream::Stdio(handler)
    │
    ▼  Handler
       generic_stream() → 发送到 filesystem MCP Server

10.4 A2A Gateway 机制

Agent-to-Agent 协议让多个 Agent 互相发现、协商、协作。

plaintext
Agent A                    agentgateway                  Agent B
  │                            │                           │
  │ 1. 发现能力                │                           │
  │ ─────────────────────────► │                           │
  │    "你能做什么?"          │ ────────────────────────► │
  │                            │                           │
  │ 2. 协商交互模态            │                           │
  │ ◄───────────────────────── │ ◄──────────────────────── │
  │    "支持文本、表单、媒体"  │                           │
  │                            │                           │
  │ 3. 分配任务                │                           │
  │ ─────────────────────────► │ ────────────────────────► │
  │    "帮我分析这个数据集"    │                           │
  │                            │                           │
  │ 4. 长任务协作              │                           │
  │ ◄───────────────────────── │ ◄──────────────────────── │
  │    持续返回中间结果...      │                           │

A2A 网关的核心功能:

  • 能力发现:Agent 通过 AgentCard 描述自己的能力
  • 模态协商:协商支持的交互格式(文本/表单/媒体)
  • 任务协作:支持长时间运行的任务,状态由网关管理
  • 隐私保护:Agent 之间不暴露内部状态或工具

10.5 LLM Gateway 机制

plaintext
Agent 代码
    │  fetch("https://gateway/v1/chat/completions")
    ▼
┌─────────────────────────────────────────┐
│         agentgateway LLM Gateway         │
│                                          │
│  1. 统一 OpenAI 兼容 API                 │
│  2. Provider 路由:                      │
│     ├── /models/gpt-4*    → OpenAI      │
│     ├── /models/claude-*  → Anthropic   │
│     └── /models/gemini-*  → Google      │
│  3. 预算控制 + Token 计费                │
│  4. 负载均衡 + 故障转移                  │
│  5. Prompt 增强(注入系统提示等)        │
│  6. Guardrails(内容过滤)              │
└─────────────────────────────────────────┘

10.6 策略引擎与安全

CEL 策略引擎

agentgateway 使用 CEL(Common Expression Language) 作为策略语言,支持细粒度 RBAC:

yaml
# 只允许特定客户端访问 GitHub MCP 工具
policies:
- name: github-access
  type: authorization
  rules:
  - match: "request.headers['x-client-id'] == 'agent-001'"
    allow:
    - tool: "github_*"     # 允许所有 github_ 开头的工具

多层认证

plaintext
请求进入
    │
    ├── JWT 验证 → 提取 claims
    ├── API Key 验证 → 匹配客户端身份
    ├── Basic Auth → 用户名密码验证
    └── MCP Auth Spec → OAuth 2.0(Auth0 / Keycloak)
    │
    ▼
CEL 策略引擎评估 RBAC
    │
    ├── 允许 → 路由到后端
    └── 拒绝 → 返回 403 + JSON-RPC error

工具投毒防护

agentgateway 提供的防护:

  • 工具注册的来源验证
  • 工具描述的完整性校验
  • per-client 的工具可见性控制

10.7 部署模式

独立部署(Standalone)

bash
# 安装
curl https://raw.githubusercontent.com/agentgateway/agentgateway/main/common/scripts/get-agentgateway | bash

# 启动
agentgateway -f config.yaml

Kubernetes 部署

plaintext
┌─────────────────────────────────────────────┐
│  Kubernetes Cluster                          │
│                                              │
│  Control Plane (agentgateway-system ns)      │
│  ├── Config Watcher(监听 CRD 变更)         │
│  ├── Translation Engine(CRD → xDS)         │
│  └── xDS Server(gRPC 配置分发)             │
│                                              │
│  Data Plane                                  │
│  ├── agentgateway-proxy Pod                  │
│  │   ├── LLM Gateway                        │
│  │   ├── MCP Gateway                         │
│  │   └── A2A Gateway                         │
│  │                                           │
│  ├── MCP Server Pods(各工具服务)            │
│  └── Application Pods(Agent 应用)           │
│                                              │
│  CRDs                                        │
│  ├── Gateway                                 │
│  ├── HTTPRoute                               │
│  ├── AgentgatewayBackend                     │
│  ├── AgentgatewayPolicy                      │
│  └── AgentgatewayParameters                  │
└─────────────────────────────────────────────┘

配置流转:

plaintext
用户创建 CRD(Gateway/HTTPRoute/AgentgatewayBackend)
    │
    ▼  Config Watcher 检测到变更
    │
    ▼  Translation Engine 翻译为 xDS snapshot
    │
    ▼  xDS Server 通过 gRPC 推送到 Data Plane
    │
    ▼  agentgateway-proxy 热更新配置(无重启)

10.8 与沙盒场景的结合


十一、Agent 文件系统(VFS)— "一切皆文件" 的新范式

11.1 为什么 Agent 需要专属文件系统?

传统文件系统为人类设计,Agent 面临的问题不同:

问题 人类的解法 Agent 需要的解法
"我做了什么操作?" 自己记得 完整审计日志(tool call history)
"回到上一步" Ctrl+Z / git 文件系统级快照 + 时间旅行
"访问 S3、Slack、GitHub" 分别用不同 SDK 统一的文件树挂载
"记住这次对话的上下文" 大脑 持久化记忆层(history / memory / scratchpad)
"多个 Agent 互不干扰" 独立电脑 Copy-on-Write 隔离
"在浏览器/Serverless 中工作" 不可能 SQLite / 内存文件系统

11.2 三个项目:三种哲学

plaintext
                        Agent VFS 光谱

    执行层隔离               服务层统一              记忆层治理
   (sandbox-oriented)    (service-oriented)    (memory-oriented)
         │                     │                     │
     AgentFS               Mirage               AIGNE/AFS
   (Turso)              (strukto-ai)            (论文)
         │                     │                     │
    "用 SQLite 记录        "把 S3/Slack/GitHub    "用文件系统抽象
     Agent 的一切"         挂载成一棵文件树"       管理 Agent 记忆"

11.3 AgentFS — SQLite 即文件系统

Turso 出品,3.1k stars,核心理念:把 Agent 的全部状态存进一个 .db 文件。

架构

plaintext
┌─────────────────────────────────────────┐
│  Agent 应用层                            │
├─────────────────────────────────────────┤
│  AgentFS SDK(Python / TS / Rust)       │
│  ├── fs  — POSIX 文件操作               │
│  ├── kv  — 键值存储                     │
│  └── tools — 工具调用审计               │
├─────────────────────────────────────────┤
│  SQLite + WAL(Write-Ahead Log)         │
│  └── 单个 .db 文件包含一切              │
├─────────────────────────────────────────┤
│  挂载层                                  │
│  ├── Linux: FUSE(挂载为 /agent)        │
│  ├── macOS: NFS                         │
│  └── Firecracker VM: NFSv3              │
└─────────────────────────────────────────┘

核心机制:Copy-on-Write 隔离

plaintext
Base 文件系统(只读)
    │
    ▼  Overlay
┌─────────────────────────────────────┐
│  Agent A 的 CoW 层(SQLite WAL)     │  ← 只看到自己的修改
├─────────────────────────────────────┤
│  Agent B 的 CoW 层(SQLite WAL)     │  ← 看不到 A 的修改
├─────────────────────────────────────┤
│  共享只读基础层                      │
└─────────────────────────────────────┘

关键特性:

特性 实现方式 意义
快照 cp agent.db snapshot.db 一行代码冻结 Agent 全部状态
时间旅行 WAL 记录每次变更 回溯任意时刻的文件系统状态
可查询 SQL 查询文件系统 SELECT * FROM files WHERE path LIKE '/output/%'
审计 工具调用记录在表中 完整的 tool call history + 耗时 + 输入输出
可移植 单文件即全部状态 机器间迁移 = 拷贝一个文件
跨环境 FUSE/NFS/浏览器 WASM Serverless、浏览器、VM 都能用

SDK 用法

typescript
import { AgentFS } from 'agentfs-sdk';

const agent = await AgentFS.open({ id: 'my-agent' });

// 文件操作
await agent.fs.writeFile('/output/report.pdf', pdfBuffer);
const files = await agent.fs.readdir('/output');

// 键值存储
await agent.kv.set('user:preferences', { theme: 'dark' });

// 工具调用审计
await agent.tools.record('web_search', startTime, endTime, input, output);

与其他方案的对比

维度 AgentFS Docker 沙盒 Git Worktree
隔离方式 文件系统级 CoW 内核级 namespace 目录级复制
能否绕过隔离 ❌ 系统级强制 ❌ 内核强制 ✅ Agent 可以访问外部
快照/恢复 一行代码 需要容器快照工具 git commit/checkout
可查询性 SQL 查询 ❌ ❌
审计能力 内建 需要外部工具 git log
持久化 天然持久(SQLite) 容器销毁即丢失 天然持久
适用环境 任何(含浏览器) 需要 Docker/KVM 需要 git

11.4 Mirage — 万物皆可挂载的统一 VFS

strukto-ai 出品,1.1k stars,核心理念:把 S3、Slack、GitHub、Gmail 等一切服务挂载成一棵文件树,Agent 用 bash 操作一切。

架构

plaintext
┌──────────────────────────────────────────────────────┐
│  AI Agent(用 bash 命令操作一切)                      │
│  ls /s3/my-bucket/                                   │
│  cat /slack/general/messages.json                    │
│  cp /gdrive/report.pdf /local/                       │
│  grep "error" /s3/logs/*.log | wc -l                 │
├──────────────────────────────────────────────────────┤
│  Mirage VFS 层                                       │
│  ├── Bash 解析器(命令解析 + 路由)                   │
│  ├── Dispatcher(路由到对应资源适配器)               │
│  └── Cache(Index Cache + File Cache)               │
├──────────────────────────────────────────────────────┤
│  资源适配器(Resource Adapters)                      │
│  ┌────────┐ ┌────────┐ ┌────────┐ ┌────────┐        │
│  │  S3    │ │ Slack  │ │ GitHub │ │ GDrive │ ...    │
│  │        │ │        │ │        │ │        │        │
│  └────────┘ └────────┘ └────────┘ └────────┘        │
├──────────────────────────────────────────────────────┤
│  远程服务(S3 / Slack API / GitHub API / ...)        │
└──────────────────────────────────────────────────────┘

核心理念:复用 LLM 最擅长的技能

支持挂载的资源

类别 资源
存储 RAM、Disk、Redis、S3、R2、GCS、OCI、Supabase
Google Gmail、GDrive、GDocs、GSheets、GSlides
项目管理 GitHub、Linear、Notion、Trello
通信 Slack、Discord、Telegram、Email
数据库 MongoDB
远程 SSH

双层缓存

plaintext
请求 /s3/my-bucket/data.csv
    │
    ▼  Index Cache(目录元数据)
    │  ├── 命中 → 直接返回
    │  └── 未命中 → 调用 S3 API → 缓存(TTL 10min)
    │
    ▼  File Cache(文件内容)
    │  ├── 命中 → 直接返回
    │  └── 未命中 → 流式读取 S3 → 缓存(512MB 上限)
    │
    返回文件内容

缓存后端可选:RAM(默认,进程内)或 Redis(跨进程/跨机器共享)。

跨服务管道

bash
# 用例:从 Slack 搜索消息,过滤,保存到 S3
grep "deploy" /slack/engineering/messages.json | \
  jq '.[] | select(.ts > "2026-05-01")' | \
  tee /s3/my-bucket/deploy-log.json

# 用例:读取 Google Doc,总结,写回
cat /gdocs/project-spec.md | summarize > /local/summary.md

Agent 只需要知道 bash,不需要学 Slack SDK、S3 SDK、Google Docs SDK。

SDK 用法

python
from mirage import Workspace
from mirage.resource.s3 import S3Config, S3Resource
from mirage.resource.slack import SlackConfig, SlackResource

ws = Workspace(
    mounts={
        "/s3": S3Resource(S3Config(bucket="my-bucket")),
        "/slack": SlackResource(SlackConfig()),
    }
)

# 执行 bash 命令
result = await ws.execute("ls /s3/logs/")
result = await ws.execute("cat /slack/general/last-message.json")

# 快照
ws.snapshot("workspace.tar")

11.5 AIGNE/AFS — 文件系统作为上下文工程基础设施

论文 "Everything is Context" 提出,核心理念:用 Unix "一切皆文件" 哲学管理 Agent 的全部上下文——记忆、历史、工具、人类输入。

三层持久化模型

plaintext
┌─────────────────────────────────────────────────┐
│              Context Repository                  │
│                                                  │
│  ┌──────────────────────────────────────────┐   │
│  │  /context/history/        ← 不可变       │   │
│  │  原始交互记录,永久保存                   │   │
│  │  带 timestamp、origin、model version     │   │
│  ├──────────────────────────────────────────┤   │
│  │  /context/memory/{agentID}/  ← 可变      │   │
│  │  结构化记忆,按类型分类                   │   │
│  │  ├── scratchpad/     临时推理空间        │   │
│  │  ├── episodic/       会话摘要            │   │
│  │  ├── fact/           原子事实(KV/三元组)│   │
│  │  ├── procedural/     工具/函数定义        │   │
│  │  └── user/           用户偏好/画像        │   │
│  ├──────────────────────────────────────────┤   │
│  │  /context/pad/{taskID}/    ← 临时        │   │
│  │  任务级草稿纸,会话结束后                 │   │
│  │  有价值的晋升为 memory,其余丢弃          │   │
│  └──────────────────────────────────────────┘   │
│                                                  │
│  /modules/github-mcp/   ← MCP 工具挂载          │
│  /tools/analyser.py     ← 可执行工具            │
│  /config/settings.yaml  ← 配置数据              │
└─────────────────────────────────────────────────┘

七大记忆类型

记忆类型 时间范围 结构单元 表示形式 文件路径
Scratchpad 临时,任务内 对话轮次 纯文本/嵌入 /context/pad/{taskID}
Episodic 中期,会话级 会话摘要 摘要+嵌入 /context/memory/episodic/
Fact 长期,细粒度 原子事实 KV/三元组 /context/memory/fact/
Experiential 长期,跨任务 观察-行动轨迹 结构化日志 /context/memory/experiential/
Procedural 长期,系统级 函数/工具定义 API/代码引用 /context/memory/procedural/
User 长期,个性化 用户属性/偏好 用户画像/嵌入 /context/memory/user/
History 永久,不可变 原始日志 纯文本+元数据 /context/history/

上下文工程流水线

plaintext
                    ┌─────────────────────┐
                    │  Token Window       │  ← 128K/200K 硬限制
                    │  (推理空间)          │
                    └─────────┬───────────┘
                              │
              ┌───────────────┼───────────────┐
              ▼               ▼               ▼
    ┌─────────────┐  ┌─────────────┐  ┌─────────────┐
    │ Constructor │  │  Updater    │  │  Evaluator  │
    │ (选择+压缩) │  │ (注入+刷新) │  │ (验证+治理) │
    └──────┬──────┘  └──────┬──────┘  └──────┬──────┘
           │               │               │
           ▼               ▼               ▼
    ┌──────────────────────────────────────────┐
    │         持久化上下文仓库                  │
    │  /context/history/ + /context/memory/    │
    └──────────────────────────────────────────┘
  • Constructor:从仓库中选择、优先排序、压缩上下文 → 生成 manifest
  • Updater:将构造好的上下文注入 token window(静态快照 / 增量流 / 自适应刷新)
  • Evaluator:验证输出(检测幻觉/矛盾/漂移)→ 写回 memory → 触发人类审查

11.6 三种方案对比

维度 AgentFS Mirage AIGNE/AFS
核心抽象 SQLite DB = 文件系统 服务 = 挂载点 上下文 = 文件
解决的问题 Agent 执行隔离 + 审计 多服务统一访问 记忆管理 + 上下文治理
隔离机制 Copy-on-Write (SQLite WAL) 命名空间隔离 沙盒访问控制
快照 cp agent.db ws.snapshot("tar") 文件级版本控制
审计 SQL 查询 tool call history 命令日志 事务日志 + 元数据
记忆管理 KV store(简单) ❌ 无内建 7 层记忆体系(完整)
多服务集成 ❌ 专注文件 ✅ S3/Slack/GitHub 等 20+ ✅ 通过 MCP 挂载
挂载机制 FUSE / NFS 适配器模式 可编程 Resolver
Agent 交互方式 SDK API bash 命令 文件操作 API
适用环境 任何(含浏览器 WASM) macOS / Linux Node.js 运行时
成熟度 Beta(3.1k ⭐,58 releases) 早期 v0.0.1(1.1k ⭐) 论文阶段(AIGNE 框架)
语言 Rust 核心 + 多语言 SDK TypeScript / Python TypeScript(AIGNE)

11.7 Agent VFS 与容器沙盒的关系

plaintext
┌─────────────────────────────────────────────────┐
│  Agent 应用                                      │
├─────────────────────────────────────────────────┤
│  Agent VFS 层                                    │
│  ├── AgentFS(执行审计 + 快照恢复)              │
│  ├── Mirage(多服务统一访问)                    │
│  └── AIGNE/AFS(记忆管理 + 上下文治理)          │
├─────────────────────────────────────────────────┤
│  容器沙盒层                                      │
│  ├── MicroVM(CubeSandbox / BoxLite)            │
│  ├── Docker / gVisor                             │
│  └── Bubblewrap(用户态隔离)                    │
├─────────────────────────────────────────────────┤
│  工具集成层                                      │
│  ├── agentgateway(MCP/A2A 网关)                │
│  └── MCP Server(外部工具)                      │
├─────────────────────────────────────────────────┤
│  Linux 内核 + 硬件                               │
└─────────────────────────────────────────────────┘
层次 解决的问题 代表技术
Agent VFS Agent 怎么访问和管理数据 AgentFS / Mirage / AIGNE
容器沙盒 在哪里安全地执行代码 CubeSandbox / BoxLite / gVisor
工具网关 怎么连接外部工具 agentgateway / MCP
内核隔离 底层安全边界 namespace / cgroups / KVM

11.8 选型建议


参考资料