全部

Anthropic's Hidden Vercel Competitor "Antspace"

2026-03-18Anthropic, Claude Code, Firecracker, PaaS, Antspace
Anthropic's Hidden Vercel Competitor "Antspace"

我在 Claude Code Web 中发现了什么:一个未 strip 的 Go 二进制、Anthropic 秘密的部署平台,以及一个 AI 原生 PaaS 的完整架构


起点

我们正在开发 ArcBox——一个从 Desktop 到 Platform 的完整平台,类似 Railway 和 E2B 的定位。我们的核心理念是本地与云端的一致性:用完全开源的 ArcBox Desktop 替代 OrbStack,在本地就能提供 Sandbox 能力。最近我们注意到,越来越多的 Coding Agent 平台开始推出 Web 端入口,而出奇一致的是——它们底层几乎都选择了 Firecracker。Claude Code Web 也不例外。作为同赛道的从业者,我对它的运行环境产生了强烈好奇,于是开始挖掘。最初只是随手一个 strace -p 1,最终却演变成一场完整的逆向工程,揭开了 Anthropic 尚未公开的基础设施——包括一个在互联网上完全没有任何信息的应用托管平台。

本文所有发现均通过标准 Linux 工具(stracestringsobjdumpgo tool objdump)在我自己的 Claude Code Web 会话中获得。没有利用任何漏洞,没有提权,没有跨越任何网络边界。那个二进制就静静躺在那里,未做 strip,带着完整的调试符号。


第一层:这是一个 Firecracker 微虚拟机

第一个问题: Claude Code Web 到底跑在什么环境里?

$ dmesg | grep FIRECK
ACPI: RSDP 0x00000000000E0000 000024 (v02 FIRECK)
ACPI: XSDT ... (v01 FIRECK FCMVXSDT ... FCAT 20240119)
ACPI: FACP ... (v06 FIRECK FCVMFADT ... FCAT 20240119)
ACPI: DSDT ... (v02 FIRECK FCVMDSDT ... FCAT 20240119)

ACPI 表的 OEM ID 为 FIRECK,创建者 ID 为 FCAT——这些值硬编码在 Firecracker 的源码中。这正是驱动 AWS Lambda 和 Fargate 的微虚拟机技术。

Firecracker MicroVM Architecture

硬件规格:4 个 vCPU(Intel Xeon Cascade Lake @ 2.80GHz)、16GB 内存、252GB 磁盘、Linux 6.18.5 内核。不支持嵌套虚拟化——Firecracker 有意从客户机中移除了 vmx/svm 标志。

进程树极其精简:

PID 1: /process_api --firecracker-init --addr 0.0.0.0:2024 ...
  └─ PID 517: /usr/local/bin/environment-manager task-run --session cse_...
       └─ PID 532: claude(CLI 本身)

没有 systemd,没有 sshd,没有 cron,没有日志守护进程。PID 1 是一个自研二进制,同时充当 init 进程和 WebSocket API 网关。内核启动参数印证了这一点:

rdinit=/process_api init_on_free=1 -- --firecracker-init
reboot=k panic=1 nomodule

strace 追踪 PID 1,可以看到它运行着一个 epoll 事件循环,周期性检查 /proc/*/children/proc/*/status 来监控子进程——一个最小化的 init 监控器。它在端口 2024(WebSocket API)和 2025(辅助端点)上监听。


快照架构

会话并非从零启动——而是从冻结的 VM 快照中恢复。dmesg 输出揭示了模板创建和会话恢复之间 48.5 小时的时间间隔:

[  30.731516] Run /process_api as init process    ← 模板创建: 2026-03-16 13:53 UTC
    ~~~ 48.5 小时间隔 — VM 被冻结为快照 ~~~
[174695.927758] virtio_blk: [vdc] new size: ...   ← 会话恢复: 2026-03-18 14:24 UTC
[174695.953952] random: crng reseeded due to virtual machine fork
[174695.980760] tokio-runtime-w: drop_caches: 3
[174695.993628] EXT4-fs (vda): mounted filesystem r/w without journal

恢复过程中,Firecracker 宿主机热替换块设备

设备模板阶段恢复后内容
vda占位符256 GiB ext4会话根文件系统(Ubuntu 24.04)
vdb占位符63.7 MB squashfs/opt/claude-code
vdc占位符12.1 MB squashfs/opt/env-runner

initramfs 刻意做到最小化:一个 3.1MB 的 cpio 归档,仅包含 /process_api。真正的 Ubuntu 根文件系统在 ext4 块设备(vda)上,在恢复时注入。ext4 的挂载计数为 11,说明该镜像已在 11 个会话中被复用。

Snapstart:延迟挂载模式

模板创建阶段:

  1. Firecracker 启动:内核 + 3.1MB initramfs
  2. process_api 执行最小初始化:挂载 /proc/sys/dev、cgroups;配置网络(IP=192.0.2.2/24, GW=192.0.2.1, MTU=1400)
  3. 向宿主机发送 SNAPSTART_READY 信号
  4. 宿主机调用 PUT /snapshot/create → 保存整个 VM 状态

会话恢复阶段:

  1. 宿主机准备会话专用的块设备(vda/vdb/vdc)
  2. 宿主机调用 PUT /snapshot/load 加载新的设备后端
  3. VM 恢复运行——内核检测到设备变更,重新播种 CRNG
  4. process_api 检测到恢复并执行:
    • 丢弃页缓存 —— 模板的陈旧缓存会导致读取到垃圾数据
    • 重新挂载 devtmpfs —— 刷新设备节点
    • 挂载 ext4pivot_root 切换到新根文件系统
    • 挂载 squashfs 叠加层(claude-code、env-runner)
    • 修正时钟 —— 通过 clock_settime() 校准,否则时间停留在模板创建时刻
    • 丢弃 CAP_SYS_RESOURCE —— 安全加固
    • 接受连接 —— WebSocket 服务器就绪

安全措施

措施目的
init_on_free=1会话间清零已释放的内存页
丢弃 CAP_SYS_RESOURCE限制 PID 1 初始化后的能力
CRNG 重新播种防止快照分叉间的密码学可预测性
--block-local-connections阻止本地 WebSocket 访问
JWT 认证WebSocket 连接验证
Token 擦除使用后从配置中移除密钥

process_api:线协议

PID 1 暴露了两个网络接口——用于进程管理的 WebSocket API 和用于容器控制的 HTTP API。与典型的 init 系统不同,process_api 是一个 Rust/tokio 二进制,实现了完整的远程进程管理器。

WebSocket API(端口 2024)

连接握手流程:可选的 JWT 认证 → ProcessConnection JSON → 创建进程或重连。

进程创建接受一个 CreateProcess 结构体:

{
  "cmd": "/bin/bash",
  "args": ["-l"],
  "env": {"KEY": "VALUE"},
  "cwd": "/home/user",
  "rows": 24, "cols": 80,
  "timeout": 300,
  "memory_limit_bytes": 1073741824,
  "uid": 1000, "gid": 1000,
  "allow_process_id_reuse": false
}

I/O 使用两阶段二进制协议:

  • StdinExpectStdIn(文本帧)→ 二进制帧
  • Stdout/StderrExpectStdOut/ExpectStdErr(文本帧)→ 二进制帧 → StdOutEOF/StdErrEOF
Client                              Server
  |--- WS Connect ------------------->|
  |--- JWT(可选)------------------->|
  |--- ProcessConnection JSON ------->|
  |<-- ProcessCreated ----------------|
  |                                    |
  |<-- ExpectStdOut ------------------|
  |<-- [binary: stdout 数据] ---------|
  |--- ExpectStdIn ------------------>|
  |--- [binary: stdin 数据] --------->|
  |                                    |
  |--- SendSignal ------------------->|  SIGTERM 等
  |--- Resize ----------------------->|  PTY 调整大小
  |--- Detach ----------------------->|  进程继续运行
  |--- KeepAlive -------------------->|  心跳
  |                                    |
  |<-- ProcessExited -----------------|
  |<-- StdOutEOF --------------------|

进程终止原因包括:正常退出、信号终止、单进程 OOM、容器级 OOM、超时和服务器关闭。

内部实现上,process_api 为每个进程追踪 cgroup(v1 路径 /sys/fs/cgroup/memory/process_api/,v2 路径 /sys/fs/cgroup/process_api/),实现孤儿进程收养(重新挂载到 PID 1),并运行可配置的 OOM 轮询循环。

HTTP 控制 API(端口 2025)

六个端点管理容器生命周期:

端点用途
GET /status健康检查
POST /fs_sync刷新文件系统缓冲区
POST /shutdown优雅关闭,丢弃页缓存
POST /auth_public_key设置 JWT 验证密钥
POST /mount_root挂载根文件系统(snapstart 恢复)
POST /container_name设置容器标识

/mount_root 端点接受一个 MountRootConfig,包含网络配置(etc_hostsresolv_conf)、CA 证书、squashfs 挂载指令、FUSE 挂载配置(含 VFS 缓存参数)以及时钟时间戳——从空白快照完整初始化一个会话所需的一切。挂载过程中通过 FIFREEZE/FITHAW ioctl 冻结根文件系统。


第二层:未 Strip 的 Go 二进制

真正的发现是 /usr/local/bin/environment-runner(通过符号链接 environment-manager 调用):

$ file /usr/local/bin/environment-runner
ELF 64-bit LSB executable, x86-64, dynamically linked,
Go BuildID=..., with debug_info, not stripped

$ go version -m /usr/local/bin/environment-runner
go1.25.7
path    github.com/anthropics/anthropic/api-go/environment-manager
mod     github.com/anthropics/anthropic/api-go  (devel)
build   -ldflags=-X main.Version=staging-68f0dff496

一个 27MB 的 Go 二进制。未做 strip,保留完整调试信息,保留完整符号表。 构建自 Anthropic 的私有 monorepo github.com/anthropics/anthropic/api-go/environment-manager/

通过 go tool objdumpstrings,我提取出了完整的内部包结构:

internal/
├── api/                  # API 客户端(会话路由、任务轮询、重试)
├── auth/                 # GitHub App Token 提供者
├── claude/               # Claude Code 安装、升级、执行
├── config/               # 会话模式(new/resume/resume-cached/setup-only)
├── envtype/
│   ├── anthropic/        # Anthropic 托管环境
│   └── byoc/             # 自带云(Bring Your Own Cloud)
├── gitproxy/             # Git 凭证代理服务器
├── input/                # 标准输入解析 + 密钥处理
├── manager/              # 会话管理器、MCP 配置、技能提取
├── mcp/
│   └── servers/
│       ├── codesign/     # 代码签名 MCP 服务器
│       └── supabase/     # Supabase 集成 MCP 服务器
├── orchestrator/         # 轮询循环、Hook、身份发现
├── podmonitor/           # Kubernetes 租约管理
├── process/              # 进程执行 + 脚本运行器
├── sandbox/              # 沙箱运行时配置
├── session/              # 活动记录器
├── sources/              # Git 克隆 + 源码分类
├── tunnel/               # WebSocket 隧道 + 动作处理
│   └── actions/
│       ├── deploy/       # ← 重点在这里
│       ├── snapshot/     # 文件快照
│       └── status/       # 状态上报
└── util/                 # Git 工具、锁文件、重试、流式日志

从二进制中提取的关键依赖:

依赖用途
github.com/anthropics/anthropic/api-goAnthropic 内部 Go SDK
github.com/gorilla/websocketWebSocket 隧道
github.com/mark3labs/mcp-go v0.37.0Model Context Protocol
github.com/DataDog/datadog-go v5指标上报
go.opentelemetry.io/otel v1.39.0分布式追踪
google.golang.org/grpc v1.79.0gRPC(会话路由)
github.com/spf13/cobraCLI 框架

第三层:Antspace —— Anthropic 隐藏的 PaaS 平台

tunnel/actions/deploy/ 包中,我发现了两个 Deploy Client 的函数符号:

VercelClient —— 意料之中:

  • CreateDeployment → POST /v13/deployments
  • UploadFile → PUT /v2/files,带 x-vercel-digest
  • WaitForReady → 轮询直到 readyState == "READY"

然后是 AntspaceClient —— 意料之外:

deploy.(*AntspaceClient).Deploy
deploy.(*AntspaceClient).createDeployment
deploy.(*AntspaceClient).uploadTarball
deploy.(*AntspaceClient).streamStatus

从二进制中提取的相关字符串揭示了一套完整的部署协议:

阶段一 —— 创建部署

POST 请求到 antspaceControlPlaneURL
Content-Type: application/json
Authorization: Bearer {antspaceAuthToken}
Body: { 应用名称, 元数据 }

阶段二 —— 上传构建产物

POST multipart/form-data
文件: dist.tar.gz(构建后的应用)
大小限制: "project exceeds %dMB limit"

阶段三 —— 流式部署状态

响应: application/x-ndjson(流式)
状态流转: packaging → uploading → building → deploying → deployed
错误处理: "Streaming unsupported"(客户端不支持 NDJSON 时)

我在整个公开互联网上搜索了 "Antspace"——Anthropic 官网、GitHub、博客、文档、LinkedIn、招聘信息、会议演讲、专利申请。零结果。 这个平台从未在任何公开场合被提及。

命名推测来源:"Ant"(据说是 Anthropic 员工的内部昵称)+ "Space"(托管空间),与 Heroku、Vercel 等平台的命名逻辑一致。

Antspace vs. Vercel:架构差异

维度VercelAntspace
文件上传基于 SHA 去重,逐文件上传整个 tar.gz 打包上传
构建方式远端构建(Vercel 负责)本地 npm run build,上传产物
状态获取轮询流式 NDJSON
认证方式Vercel API Token + Team IDBearer Token + 动态控制面 URL
公开 API有,已文档化无,完全内部

Anthropic 没有选择简单包装 Vercel API 了事,而是从零构建了一套完整的部署协议——这表明 Antspace 是一项战略性的平台投资,而非临时集成。


第四层:Baku —— Web 应用构建器

"Baku" 是 claude.ai 上 Web 应用构建器体验的内部代号。当你在网页版 Claude 上要求"帮我做一个 Web 应用"时,后台启动的就是 Baku 环境。

从二进制中嵌入的资源提取到的信息:

项目模板:

  • 来源:/opt/baku-templates/vite-template
  • 技术栈:Vite + React + TypeScript
  • 通过 supervisord 自动管理开发服务器,日志写入 /tmp/vite-dev.log

Supabase 自动配置:

自动提供六个 MCP 工具:

  1. provision_database —— 按需创建 Supabase 项目
  2. execute_query —— 执行 SQL 查询
  3. apply_migration —— 带自动类型生成的版本化 Schema 变更
  4. list_migrations —— 列出已应用的迁移
  5. generate_types —— 从数据库 Schema 重新生成 TypeScript 类型
  6. deploy_function —— 部署 Supabase Edge Function

环境变量自动写入 .env.local

SUPABASE_URL, SUPABASE_ANON_KEY,
VITE_SUPABASE_URL, VITE_SUPABASE_ANON_KEY

停止 Hook(嵌入的 Shell 脚本):

Baku 环境有一个预停止 Hook,在以下情况下阻止会话结束:

  • 存在未提交或未推送的 git 变更
  • Vite 开发服务器日志中包含错误
  • tsc --noEmit 报告 TypeScript 类型错误

默认部署目标:Antspace——而不是 Vercel。Vercel 作为替代选项存在,但 Baku 的原生部署路径走的是 Anthropic 自己的平台。

内部组织方式:

  • 草稿存储在 .baku/drafts/
  • 探索项目存储在 .baku/explorations/
  • Git 提交使用 [email protected] 作为作者
  • 未配置 git remote(仅本地版本控制)

第五层:BYOC —— 自带云环境

envtype/ 包包含两种环境实现:

  1. anthropic —— Anthropic 托管(Firecracker 微虚拟机,即我当前所在的环境)
  2. byoc —— 自带云(Bring Your Own Cloud)

BYOC 允许企业客户在自己的基础设施中运行 environment-runner,而会话编排仍由 Anthropic API 控制。关键特征:

  • 默认会话模式:resume-cached(最快重启,复用现有状态)
  • 自定义认证:containProvideAuthRoundTripper 注入容器级凭证
  • 智能 Git 处理:在 fetch 前检查任务分支是否存在于远端
  • 子类型:antspace(Anthropic 内部)和 baku(Vite 项目构建器)
  • Kubernetes 集成:podmonitor 包实现租约管理

BYOC 的 API 接口包含 7 个端点:

端点用途
/v1/environments/whoami身份发现
任务轮询 + 确认工作队列
会话上下文配置获取
代码签名二进制验证
Worker WebSocket实时隧道
Supabase 数据库查询代理数据库访问中继

战略全景

我们看到的是一个垂直整合的 AI 应用平台

用户用自然语言描述需求

Claude 在 Baku 环境中生成应用

Supabase 数据库自动配置(MCP 工具)

应用部署到 Antspace(Anthropic 的 PaaS)

应用上线,用户全程未离开 Anthropic 生态

这不仅是一个 AI 编程助手,而是一个 AI 原生 PaaS 的完整架构——用户从想法到生产的全部旅程都在 Anthropic 的基础设施中完成。

竞争格局的意义重大。这使 Anthropic 直接面对:

  • Vercel / Netlify —— 在托管和部署领域
  • Replit / Lovable / Bolt —— 在 AI 应用生成领域
  • Supabase / Firebase —— 在托管后端领域(通过深度集成)

但 Anthropic 拥有一个其他竞品都不具备的结构性优势:他们拥有从大语言模型到运行时再到托管平台的完整技术栈


方法论

所有发现均通过在我自己的 Claude Code Web 会话中运行标准 Linux 工具获得。以下是逐步方法:

第一步——识别 Hypervisor。 dmesg | grep FIRECK——ACPI 表携带的 OEM ID 立即指纹识别出 Firecracker。

第二步——识别 PID 1。 cat /proc/1/cmdline——揭示 /process_api 是自研 init,而非 systemd。--firecracker-init 标志进一步确认。

第三步——提取 Go 构建元数据。 对 environment-runner 二进制执行 go version -m,得到 Go 版本、模块路径(github.com/anthropics/anthropic/api-go)、(devel) monorepo 标记以及完整依赖列表。

第四步——从符号表恢复包结构。 由于二进制未做 strip,objdump -t 给出完全限定的函数名。过滤 environment-manager/internal/ 并提取唯一路径,即可生成完整的架构树。

第五步——定向字符串提取。 对 Go 二进制的朴素 strings | grep 噪声很大(链接器会将所有字符串字面量拼接在一起)。两种更有效的方法:

  • 已知模式搜索:扫描特定字节序列(dist.tar.gzapplication/x-ndjson 等)
  • 结构体标签提取:Go 将结构体字段标签作为字符串字面量嵌入,搜索 json:"status" 等模式可揭示线协议格式

第六步——符号表驱动的功能映射。 objdump -t binary | grep 'deploy\.' 可得到每个组件的方法清单——Vercel 和 Antspace 客户端的完整方法签名正是通过这种方式发现的。

第七步——运行时观察。 strace -p 1 -e trace=epoll_pwait,read,write -f 确认了 epoll 事件循环、子进程监控和 WebSocket 通信模式。

技术揭示的信息
dmesg ACPI OEM IDHypervisor 身份
go version -m工具链、依赖、monorepo 结构
符号表(objdump -t包布局、类型名、方法签名
结构体标签字符串线协议 / JSON 格式
定向字节搜索错误消息、状态字符串、流程逻辑
strace PID 1运行时行为、IPC 模式

为什么这一切能够实现:(1)二进制未做 strip——这是最关键的因素,strip 后就需要 Ghidra 来反编译。(2)Go 的构建元数据嵌入提供了免费的依赖清单。(3)Go 的字符串拼接模型保留了结构体标签和错误字符串。(4)VM 内的 root 权限允许对 PID 1 执行 strace


结语

将一个未 strip、带完整调试符号的二进制发布到生产环境……是一个有趣的选择。这使得整个分析变得异常简单——通常需要 Ghidra 和数小时反编译工作的内容,用 go tool objdumpgrep 就完成了。

Antspace 显然仍处于早期或内部阶段(版本号前缀为 staging-),但其部署协议已经成熟且达到生产级别。Anthropic 是计划将其作为公开产品发布,还是仅作为 Claude 网页端体验的内部基础设施,有待观察。

但有一点很清楚:Anthropic 的野心远不止于做一家大模型和 AI Agent 公司。他们正在构建一个应用可以被"说"出来的世界所需的基础设施——而他们希望拥有这个技术栈的每一层。


所有分析于 2026 年 3 月 18 日在 Claude Code Web 会话中完成,运行环境为 Firecracker MicroVM,内核版本 6.18.5,environment-runner 版本 staging-68f0dff496。

完整的原始分析文件(线协议规范、快照架构细节、反编译代码)已开源在 github.com/AprilNEA/reverse-engineering-claude-code-antspace