14 of 432

Artifacts:会说 Git 的版本化存储

C
Cloudflare
2026-04-16
https://blog.cloudflare.com

Artifacts:会说 Git 的版本化存储

随着 AI Agent 生成的代码量呈现指数级增长,传统的源代码管理平台正面临根本性的挑战——它们为人类设计,却要应对不知疲倦、能同时并行处理多个任务的 Agent 所带来的十倍容量冲击。Cloudflare 的这篇技术文章提出了一个大胆的答案:Artifacts,一个"会说 Git 语言"的版本化文件系统。它并非简单地在现有 Git 之上加一层封装,而是从底层为 Agent 时代重新设计——你可以通过编程方式即时创建仓库、在任意 serverless 函数中执行提交、从已知起点一键创建上万个分支。文章深入剖析了为什么 Git 的数据模型不仅适用于代码管理,更是追踪状态、时间旅行和持久化任意小片段数据的理想范式,并分享了 Cloudflare 内部如何将其用于 Agent 会话持久化的实践。无论你是关注 AI 基础设施演进,还是对版本控制系统的未来形态感兴趣,这篇文章都值得一读。


这篇文章也提供 DeutschEspañol 版本。

Agent 已经改变了我们对源代码管理、文件系统和状态持久化的思考方式。开发者和 Agent 生成的代码比以往任何时候都多——未来 5 年内编写的代码将超过整个编程史上的总和——这驱动了满足这一需求所需系统的规模发生了数量级的变化。源代码管理平台尤其吃力:它们是为满足人类需求而构建的,而非为应对从不休息、能同时处理多个问题、永不疲倦的 Agent 所驱动的 10 倍容量变化。

我们认为需要一种新的原语:一个分布式的、带版本控制的文件系统,它首先为 Agent 构建,同时也能服务于当今正在构建的各种应用类型。

我们称之为 Artifacts:一个说 Git 语言的版本化文件系统。你可以以编程方式创建仓库,与你的 Agent、沙箱、Workers 或其他任何计算范式并存,并从任何常规 Git 客户端连接到它。

想让每个 Agent 会话都有一个仓库?Artifacts 可以做到。每个沙箱实例?Artifacts 也可以。想从一个已知良好的起点创建 10,000 个 fork?你猜对了:还是 Artifacts。Artifacts 提供了 REST API 和原生 Workers API,用于在不适合 Git 客户端的环境(即在任何 serverless 函数中)创建仓库、生成凭证和执行提交。

Artifacts 目前处于 private beta 阶段,我们计划在 5 月初开放为 public beta。

// 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 仓库引导(bootstrap)一个 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。它深嵌在大多数模型的训练数据中。正常路径和边缘情况 Agent 都非常熟悉,而代码优化模型(或 harness)尤其擅长使用 git。

此外,Git 的数据模型不仅适用于源代码管理,也适用于任何需要追踪状态、时间旅行和持久化大量小数据的场景。代码、配置、会话提示词和 Agent 历史记录:所有这些都是你通常希望以小片段("提交")存储,并且能够回退或回滚("历史")的东西。

我们本可以发明一种全新的、特制的协议……但那样就会遇到引导(bootstrap)问题。AI 模型不认识它,所以你不得不分发技能(skills)或 CLI,或者希望用户接入了你的文档 MCP……所有这些都增加了摩擦。但如果我们只需给 Agent 一个经过认证的安全 HTTPS Git 远程 URL,让它们像操作 Git 仓库一样操作它呢?事实证明这非常有效。而对于不说 Git 语言的客户端——比如 Cloudflare Worker、Lambda 函数或 Node.js 应用——我们提供了 REST API,并且即将提供语言特定的 SDK。这些客户端也可以使用 isomorphic-git,但在许多情况下,更简洁的 TypeScript API 可以减少所需的 API 面。

不仅限于源代码管理

Artifacts 的 Git API 可能会让你觉得它只适用于源代码管理,但事实证明,Git API 和数据模型是一种强大的状态持久化方式,它允许你对任何数据进行 fork、时间旅行和状态差异比较。

在 Cloudflare 内部,我们正在将 Artifacts 用于我们的内部 Agent:在每个会话的 Artifacts 仓库中自动持久化文件系统的当前状态和会话历史记录。这使我们能够:

  • 持久化沙箱状态,而无需预配(并保留)块存储。
  • 与他人共享会话,允许他们回溯会话(提示词)状态和文件状态,无论是否对"实际"仓库(源代码管理)有过提交。
  • 最棒的是:从任意时刻 fork 一个会话,让我们的团队成员可以共享会话并从中接手。调试某问题时想要多一双眼睛?发送一个 URL,fork 它。想即兴创作一个 API?让同事 fork 它,然后从你停下的地方继续。

我们也与一些团队交流过,他们希望在根本不需要 Git 协议的情况下使用 Artifacts,但其语义(回退、克隆、差异比较)确实需要。将每个客户配置作为产品的一部分存储,并希望具备回滚能力?Artifacts 可以很好地实现这一点。

我们很高兴看到团队探索 Artifacts 的非 Git 用例,就像探索其 Git 相关用例一样。


底层实现

Artifacts 构建于 Durable Objects 之上。创建数百万(乃至数千万以上)个有状态、隔离的计算实例的能力,是 Durable Objects 当前工作方式的内在特性,而这正是我们在每个命名空间中支持数百万 Git 仓库所需要的。

美国职业棒球大联盟(用于实时比赛 fan-out)、Confluence Whiteboards,以及我们自己的 Agents SDK 都在大规模地使用 Durable Objects,因此我们构建在这样一个已经投产一段时间的原语之上。

然而,我们确实需要的是一个能在 Cloudflare Workers 上运行的 Git 服务器实现。它需要体积小、尽可能完整、可扩展(notesLFS)且高效。于是我们用 Zig 构建了一个,并将其编译为 Wasm。

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

  1. 整个 Git 协议引擎完全用纯 Zig 编写(无 libc),编译成约 100KB 的 WASM 二进制文件(还有优化空间!)。它从头实现了 SHA-1、zlib 压缩/解压缩、delta 编码/解码、pack 解析以及完整的 Git 智能 HTTP 协议——全部自主实现,除标准库外零外部依赖。
  2. Zig 让我们能够手动控制内存分配,这在 Durable Objects 这样的受限环境中非常重要。Zig 构建系统使我们能够轻松在 WASM 运行时(生产环境)和原生构建(针对 libgit2 进行正确性验证测试)之间共享代码。
  3. WASM 模块通过一个精简的回调接口与 JS 宿主通信:11 个宿主导入的存储操作函数(host_get_object、host_put_object 等)和一个用于流式输出的函数(host_emit_bytes)。WASM 端可以完全独立测试。

在底层,Artifacts 还使用了 R2(用于快照)和 KV(用于跟踪认证令牌):

BLOG-3269 2

BLOG-3269 2

Artifacts 的工作原理(Workers、Durable Objects 与 WebAssembly)

Worker 作为前端,负责处理身份认证与授权、关键指标(错误、延迟),并动态查找每个 Artifacts 仓库(Durable Object)。

具体来说:

  • 文件存储在下层 Durable Object 的 SQLite 数据库中。
    • Durable Object 存储的行大小上限为 2MB,因此大型 Git 对象会被分块存储在多个行中。
      • 我们使用了同步 KV API(state.storage.kv),其在底层由 SQLite 支持。
  • DO 约有 128MB 的内存限制:这意味着我们可以生成数千万个 DO(它们快速且轻量),但必须在此限制内工作。
    • 我们在 fetch 和 push 路径中都大量使用流式处理,直接返回由原始 WASM 输出块构建的 ReadableStream<Uint8Array>
      • 我们避免自行计算 Git delta,而是将原始 delta 和基础哈希值与解析后的对象一起持久化。在 fetch 时,如果请求的客户端已经拥有基础对象,Zig 会发送 delta 而非完整对象,从而节省带宽内存。
  • 支持 Git 协议的 v1 和 v2 版本。
    • 我们支持的能力包括 ls-refs、浅克隆(deepen、deepen-since、deepen-relative)以及通过 have/want 协商的增量 fetch。
      • 我们拥有广泛的测试套件,包括针对 Git 客户端的符合性测试以及针对 libgit2 服务器的验证测试,以确保协议支持的正确性。

在此之上,我们原生支持 git-notes。Artifacts 被设计为 Agent 优先,notes 使 Agent 能够向 Git 对象添加注释(元数据)。这包括提示词(prompts)、Agent 归属以及其他元数据,可以从仓库中读取/写入,而无需改变对象本身。

大型仓库,大问题?认识 ArtifactFS。

大多数仓库并不大,Git 在存储方面设计得极为高效:大多数仓库克隆最多只需几秒钟,耗时主要在网络建立、身份认证和校验和计算上。在大多数 Agent 或沙箱场景中,这是可行的:只需在沙箱启动时克隆仓库即可开始工作。

但对于数 GB 的仓库和/或拥有数百万个对象的仓库呢?如何快速克隆此类仓库,而不让 Agent 等待数分钟才能开始工作、同时消耗大量计算资源?

一个流行的 Web 框架(2.4GB,且历史悠久!)克隆需要将近 2 分钟。浅克隆会快一些,但还不足以缩短到个位数秒,而且我们并不总是想省略历史记录(Agent 发现历史记录很有用)。

我们能否将大型仓库的克隆时间缩短到约 10-15 秒,让 Agent 能够快速开始工作?嗯,可以:通过一些技巧。

作为 Artifacts 发布的一部分,我们正在开源 ArtifactFS,这是一个文件系统驱动程序,旨在尽可能快速地挂载大型 Git 仓库,动态按需填充文件内容,而不是阻塞在初始克隆上。它非常适合 Agent、沙箱、容器以及其他启动时间至关重要的场景。如果你能为每个大型仓库节省约 90-100 秒的沙箱启动时间,并且每月运行 10,000 个这样的沙箱任务——那就节省了 2,778 个沙箱小时。

你可以把 ArtifactFS 理解为"异步 Git 克隆":

  • ArtifactFS 执行 Git 仓库的 blobless 克隆:它获取文件树和引用(refs),但不获取文件内容。它可以在沙箱启动期间完成这一操作,从而使你的 Agent harness 能够立即开始工作。
  • 在后台,它通过一个轻量级守护进程并发地开始填充(下载)文件内容。
  • 它优先处理 Agent 通常首先需要操作的文件:包清单(package.jsongo.mod)、配置文件以及代码,尽可能降低二进制 blob(图像、可执行文件和其他非文本文件)的优先级,以便 Agent 能够在文件本身被填充的同时扫描文件树。
  • 如果 Agent 尝试读取时文件尚未完全填充,读取操作将阻塞直到完成。

该文件系统不会尝试将文件"同步"回远程仓库:对于成千上万个对象,这通常非常慢,而且由于我们使用的是 Git 协议,也无需如此。你的 Agent 只需要像使用任何仓库一样进行提交和推送即可。无需学习新的 API。

重要的是,ArtifactFS 适用于任何 Git 远程仓库,而不仅仅是我们自己的 Artifacts。如果你从 GitHub、GitLab 或自托管的 Git 基础设施克隆大型仓库——你仍然可以使用 ArtifactFS。

未来规划

今天的发布只是 beta 版本,我们已经在开发一系列功能,将在未来几周内陆续推出:

  • 扩展我们暴露的可用指标。今天我们已经发布了每个命名空间的操作计数、每个仓库的仓库和存储字节数等关键指标,以便管理数百万个 Artifacts 不会变得繁琐。
  • 支持仓库级别事件的事件订阅(Event Subscriptions),以便我们能够在命名空间内的任何仓库发生推送、拉取、克隆和 fork 时发出事件。这也将允许你消费事件、编写 webhook,并利用这些事件通知最终用户、驱动产品内的生命周期事件和/或运行推送后任务(如 CI/CD)。
  • 用于与 Artifacts API 交互的原生 TypeScript、Go 和 Python 客户端 SDK
  • 仓库级别的搜索 API 和跨命名空间的搜索 API,例如"查找所有包含 package.json 文件的仓库"。

我们还计划为 Workers Builds 提供 API,允许你在任何 Agent 驱动的工作流上运行 CI/CD 任务。

费用如何?

Artifacts 仍处于早期阶段,但我们希望定价能够适应 Agent 规模:拥有数百万个仓库需要具有成本效益,未使用(或很少使用)的仓库不应成为负担,并且我们的定价应与 Agent 的大规模单租户特性相匹配。

你也不应该去考虑某个仓库是否会被使用、是热数据还是冷数据、或者 Agent 是否会唤醒它。我们将根据你消耗的存储空间和针对每个仓库的操作(例如克隆、fork、推送和拉取)来收费。

$/单位 包含额度
操作 每 1,000 次操作 $0.15 每月前 10,000 次免费
存储 $0.50/GB-月 前 1GB 免费

大型、繁忙的仓库会比小型、不常使用的仓库费用更高,无论你有 1,000 个、100,000 个还是 1,000 万个仓库。

在 beta 进行过程中,我们还将把 Artifacts 引入 Workers Free 计划(带有一些合理限制),如果此定价发生变化,以及在实际计费之前,我们将在整个 beta 期间提供更新。


如何开始?

BLOG-3269 3

BLOG-3269 3

Artifacts 正在以私有 beta 形式推出,我们预计公开 beta 将在(2026 年)5 月初准备就绪。接下来的几周我们将逐步允许客户加入,你可以直接注册私有 beta 的意向

与此同时,你可以通过以下方式了解更多关于 Artifacts 的信息:

关注更新日志以跟踪 beta 的进展。

在 Cloudflare TV 上观看

Cloudflare 的连接云保护整个企业网络,帮助客户高效构建互联网规模的应用,加速任何网站或互联网应用抵御 DDoS 攻击阻挡黑客入侵,并能在你迈向 Zero Trust 的旅程中提供帮助。

从任何设备访问 1.1.1.1,即可开始使用我们的免费应用,让你的互联网更快更安全。

要了解更多关于我们帮助构建更好互联网的使命,请从这里开始。如果你正在寻找新的职业方向,请查看我们的空缺职位

Agents Week Agents GitHub Cloudflare Workers Storage Developer Platform Developers

术语表

原文 中文
agent Agent
Artifacts Artifacts
blobless clone blobless 克隆
bootstrap 引导
Durable Objects Durable Objects
Event Subscriptions 事件订阅(Event Subscriptions)
fork fork
harness harness
private beta 私有 beta
public beta 公开 beta
remote 远程(URL)
sandbox 沙箱
skills 技能(skills)

此文章由 AI 翻译