← 返回 关于

Artifacts:会说 Git 的版本化存储

2026-04-20 · 原文链接

2026-04-16

9 分钟阅读

Agent 改变了我们看待源码控制、文件系统和状态持久化的方式。开发者和 agent 正在生成前所未有的代码量——未来 5 年写出的代码,会超过编程历史上此前所有代码的总和——这推动了承载需求所需系统规模发生了一个数量级的变化。源码控制平台尤其吃力:它们原本是为人类需求设计的,不是为那些 24 小时不停工、能同时处理多个问题、永远不知疲倦的 agent 带来的 10 倍量级变化而设计的。

我们认为,现在需要一种新的基础原语:一个首先为 agent 而生的分布式、版本化文件系统,并且它能够服务今天正在构建的这类应用。

我们把它叫做 Artifacts:一个会说 Git 的版本化文件系统。你可以通过程序创建仓库,把它和 agent、sandbox、Workers 或任何其他计算范式并排使用,同时也能从任意常规 Git 客户端连接进去。

想给每个 agent session 都配一个 repo?Artifacts 可以。每个 sandbox 实例都来一个?也可以。想从一个已验证可用的起点派生出 10,000 个 fork?没错,还是 Artifacts。Artifacts 提供了 REST API 和原生 Workers API,用于创建仓库、生成凭证、提交 commit,适合那些 Git 客户端并不合适的环境(例如任意 serverless function)。

Artifacts 目前处于私有测试阶段,我们计划在 5 月上旬开放公测。

// Create a repo
const repo = await env.AGENT_REPOS.create(name)
// Pass back the token & remote to your agent
return { repo.remote, repo.token }
# Clone it and use it like any regular git remote
$ git clone https://x:${TOKEN}@123def456abc.artifacts.cloudflare.net/git/repo-13194.git

就是这样。一个裸仓库,随建随用,任意 Git 客户端都可以像操作普通远端一样操作它。

如果你想把一个已有 Git 仓库引导进 Artifacts,让 agent 能独立处理并推送独立改动,也可以通过 .import() 完成:

interface Env {
  ARTIFACTS: Artifacts
}

export default {
  async fetch(request: Request, env: Env) {
    // Import from GitHub
    const { remote, token } = await env.ARTIFACTS.import({
      source: {
        url: "https://github.com/cloudflare/workers-sdk",
        branch: "main",
      },
      target: {
        name: "workers-sdk",
      },
    })

    // Get a handle to the imported repo
    const repo = await env.ARTIFACTS.get("workers-sdk")

    // Fork to an isolated, read-only copy
    const fork = await repo.fork("workers-sdk-review", {
      readOnly: true,
    })

    return Response.json({ remote: fork.remote, token: fork.token })
  },
}

看看文档开始上手;如果你想了解 Artifacts 是如何被使用、如何构建,以及底层是怎么工作的,那就继续往下读。

为什么是 Git?什么叫版本化文件系统?

Agent 懂 Git。Git 深深存在于大多数模型的训练数据中。无论是 happy path,还是各种边界情况,agent 都很熟悉;而面向代码优化的模型(和/或 harness)尤其擅长使用 Git。

更进一步,Git 的数据模型不仅适合源码控制,也适合任何你需要追踪状态、回到过去、并持久化大量小数据的场景。代码、配置、session prompt 和 agent 历史:这些都是你常常希望按小块(“commit”)保存、并且可以回滚到(“history”)的东西(“object”)。

我们当然也可以重新发明一种全新的专有协议……但那会遇到冷启动问题。AI 模型不懂它,于是你就得分发 skill、CLI,或者希望用户已经接上了你的 docs MCP……这些都会增加摩擦。如果我们只是给 agent 一个带认证、受保护的 HTTPS Git remote URL,让它像面对普通 Git 仓库那样操作,会怎样?事实证明,这样效果很好。而对那些不说 Git 的客户端——例如 Cloudflare Worker、Lambda function 或 Node.js 应用——我们则提供了 REST API,以及即将推出的特定语言 SDK。这些客户端当然也能用 isomorphic-git,但很多时候,一个更简单的 TypeScript API 能显著缩小所需 API 面。

不只是源码控制

Artifacts 的 Git API 可能会让你以为它只是做源码控制的,但实际上,Git API 和它背后的数据模型,是一种非常强大的状态持久化方式:它让任何数据都能被 fork、time-travel 和 diff。

在 Cloudflare 内部,我们已经把 Artifacts 用在内部 agent 上:自动把当前文件系统状态以及 session 历史持久化到每个 session 各自的 Artifacts repo 中。这样我们就能:

我们也和一些团队聊过,他们想在并不要求 Git 协议本身的场景里使用 Artifacts,但他们很需要 Git 的那些语义:回滚、克隆、diff。比如把每个客户的配置作为产品的一部分存起来,并希望可以回退,Artifacts 就会是个不错的表示方式。

我们很期待看到大家不仅把 Artifacts 用在 Git 场景里,也去探索那些非 Git 的用法。

底层实现

Artifacts 构建在 Durable Objects 之上。如今 Durable Objects 天生就具备创建数百万、甚至数千万个有状态、彼此隔离的计算实例的能力,而这也正是我们支持每个命名空间下数百万 Git repo 所需要的能力。

Major League Baseball(实时比赛分发)、Confluence Whiteboards,以及我们自己的 Agents SDK 都已经在相当大的规模下使用 Durable Objects,所以我们是在一个已经生产验证过一段时间的原语之上继续搭建。

不过,我们确实还需要一个能跑在 Cloudflare Workers 上的 Git 服务器实现。它必须足够小、尽可能完整、可扩展(notesLFS),还要高效。所以我们用 Zig 写了一个,并把它编译成了 Wasm。

为什么选 Zig?有三个原因:

  1. 整个 Git 协议引擎都用纯 Zig 编写(不依赖 libc),编译后是一个大约 100KB 的 WASM 二进制(而且还有进一步优化空间)。它从零实现了 SHA-1、zlib inflate/deflate、delta 编码/解码、pack 解析,以及完整的 git smart HTTP 协议,除标准库外零外部依赖。

  2. Zig 让我们能手动控制内存分配,这在 Durable Objects 这种受限环境里很重要。Zig Build System 也让我们能轻松在 WASM 运行时(生产)和原生构建(测试时对照 libgit2 做正确性验证)之间共享代码。

  3. WASM 模块通过一层很薄的回调接口与 JS host 通信:11 个由 host 导入的函数用于存储操作(host_get_objecthost_put_object 等),再加上一个用于流式输出的函数(host_emit_bytes)。WASM 这一侧可以完全脱离宿主环境独立测试。

除此之外,Artifacts 还使用了 R2(做快照)和 KV(跟踪认证 token):

BLOG-3269 2

*Artifacts 的工作方式(Workers、Durable Objects 与 WebAssembly)*

一个 Worker 充当前端,负责认证与授权、关键指标(错误、延迟)处理,并在请求到来时动态定位每个 Artifacts 仓库(也就是 Durable Object)。

具体来说:

在此基础上,我们还原生支持 git-notes。Artifacts 是为 agent 优先设计的,而 notes 正好允许 agent 给 Git object 附加注释(元数据),包括 prompt、agent 归属信息以及其他可以在不修改 object 本身的前提下读写的元数据。

大仓库,大麻烦?来认识 ArtifactFS

大多数仓库其实并不大,而 Git 在存储效率上本来就非常高:绝大多数仓库最多只需要几秒就能 clone 完,时间主要花在网络建立、认证以及校验上。在许多 agent 或 sandbox 场景里,这完全可以接受:sandbox 启动时直接 clone 仓库,然后开始工作。

但如果是一个多 GB 的仓库,或者一个包含数百万对象的仓库呢?怎样才能快速 clone,而不让 agent 为此卡上几分钟、同时吞掉大量算力?

一个流行的 Web 框架(2.4GB,而且历史很长)clone 下来接近 2 分钟。浅克隆会更快,但还不足以降到个位数秒,而且我们也不总想省略历史(agent 往往会从历史中获益)。

那能不能把大仓库的启动时间压到大约 10 到 15 秒,让 agent 尽快开始干活?可以,用一些技巧就行。

伴随 Artifacts 一起发布的,还有我们开源的 ArtifactFS:一个文件系统驱动,目标是在尽可能短的时间内挂载大型 Git 仓库,并在后台逐步 hydrate 文件内容,而不是在初始 clone 阶段全部阻塞住。它非常适合 agent、sandbox、容器以及任何启动时间很关键的场景。如果你能为每个大型仓库 sandbox 启动节省约 90 到 100 秒,而你每个月会运行 10,000 次这样的 sandbox 任务,那就是 2,778 小时的 sandbox 时间节省。

你可以把 ArtifactFS 理解成“异步版 Git clone”:

这个文件系统并不会尝试把文件“同步”回远端仓库:对于成千上万甚至数百万对象的场景,这通常非常慢;而且既然我们说的是 Git,本来也不需要这么做。你的 agent 只需要像对待普通仓库一样 commit 和 push。没有新的 API 要学。

更重要的是,ArtifactFS 可以配合任意 Git remote 使用,而不只是我们的 Artifacts。如果你是从 GitHub、GitLab,或者自建 Git 基础设施克隆大型仓库,一样可以用 ArtifactFS。

接下来会有什么?

今天发布的还只是 beta,我们已经在推进接下来几周会落地的一批功能:

我们也计划为 Workers Builds 提供 API,让你能在任意 agent 驱动的工作流上运行 CI/CD 任务。

这会花我多少钱?

Artifacts 还处在早期阶段,但我们希望它的定价能适应 agent 规模:拥有数百万个 repo 也要足够划算,闲置或很少使用的 repo 不该成为负担,而定价应当贴合 agent 这种高度单租户化的使用方式。

你也不该总担心一个 repo 会不会被使用、它是热的还是冷的、某个 agent 会不会把它唤醒。我们会按照你实际消耗的存储,以及针对每个 repo 发生的操作(例如 clone、fork、push 和 pull)收费。

单价

包含额度

操作

每 1,000 次操作 $0.15

每月前 10k 次免费

存储

$0.50 / GB-月

前 1GB 免费。

无论你有 1,000、100,000,还是 1,000 万个 repo,体积更大、使用更频繁的仓库,成本都会高于体积更小、访问更少的仓库。

随着 beta 推进,我们也会把 Artifacts 带到 Workers Free 计划(会附带一些合理限制),如果定价发生变化,我们会在 beta 期间持续同步,并在开始计费前提前说明。

我该从哪里开始?

BLOG-3269 3

Artifacts 以私有 beta 形式发布,我们预计在 5 月上旬准备好公测(明确一下,是 2026 年)。未来几周我们会逐步放量,你现在就可以登记私有 beta 意向

在此之前,你可以这样进一步了解 Artifacts:

关注changelog,追踪 beta 的后续进展。

在 Cloudflare TV 上观看

Cloudflare 的 connectivity cloud 能保护整个企业网络,帮助客户高效构建互联网级应用,加速任意网站或互联网应用抵御 DDoS 攻击阻挡黑客,并帮助你走上 Zero Trust 之路。

访问任意设备上的 1.1.1.1,即可开始使用我们的免费应用,让你的网络更快、更安全。

如果你想了解更多关于我们“帮助构建更好互联网”的使命,可以从这里开始。如果你正在寻找新的职业方向,也可以看看我们的招聘岗位

Agents WeekAgentsGitHubCloudflare WorkersStorageDeveloper PlatformDevelopers