Artifacts:Gitに対応するバージョン付きストレージ
PublishedAt: 2026-04-16T13:01:00.000Z
Agentsは、ソースコントロール、ファイルシステム、状態の永続化に対する考え方を変えました。開発者とAgentsはこれまで以上に多くのコードを生成しており——今後5年間で過去の全プログラミング史を超えるコードが書かれるだろうと言われています——これに対応するためのシステム規模は桁違いの拡大を求められています。ソースコントロールプラットフォームは特に苦戦しています。人間のニーズに合わせて作られており、常に稼働し、複数の課題を同時に扱い疲れないAgentsによる10倍の増加に対応していないためです。
そこで我々は、新しいプリミティブが必要だと考えました:Agentsを第一に設計した、分散型でバージョン管理されたファイルシステムで、今日構築されているアプリケーションに応えられるもの。これを「Artifacts」と名付けました:Gitを話すバージョン付きファイルシステムです。リポジトリをプログラム的に作成して、Agents、サンドボックス、Workers、あるいは任意のコンピュートパラダイムに紐づけ、通常のGitクライアントから接続できます。
- すべてのAgentセッションにリポジトリを与えたい?Artifactsで可能です。
- すべてのサンドボックスインスタンスに?それもArtifactsです。
- 既知の良好な出発点から10,000個のフォークを作りたい?はい、Artifactsです。
Artifactsは、リポジトリの作成、資格情報の生成、Gitクライアントが適さない環境(たとえばサーバーレス関数)向けにコミットを行うためのREST APIとネイティブWorkers APIを公開します。Artifactsはプライベートベータで利用可能で、パブリックベータを5月上旬までに公開することを目指しています。
例:
const repo = await env.AGENT_REPOS.create(name)
return { repo.remote, repo.token }
クローンして通常のgitリモートのように使えます。
$ 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) {
const { remote, token } = await env.ARTIFACTS.import({
source: {
url: "https://github.com/cloudflare/workers-sdk",
branch: "main",
},
target: {
name: "workers-sdk",
},
})
const repo = await env.ARTIFACTS.get("workers-sdk")
const fork = await repo.fork("workers-sdk-review", { readOnly: true })
return Response.json({ remote: fork.remote, token: fork.token })
},
}
開始方法についてはドキュメントを参照してください。Artifactsの活用方法、内部構成、仕組みを理解したい方は以下を読み進めてください。
なぜGitなのか?バージョン付きファイルシステムとは?
AgentsはGitを理解しています。Gitは多くのモデルのトレーニングデータに深く含まれており、通常のパスやエッジケースをAgentsがよく把握しています。コードに最適化されたモデル(およびハーネス)は特にgitの操作に長けています。さらに、Gitのデータモデルはソースコントロールだけでなく、状態の追跡、タイムトラベル、少量のデータを大量に永続化する用途にも適しています。
コード、設定、セッションプロンプト、Agentの履歴:これらはすべて小さなチャンク(“コミット”)で保存したいオブジェクトであり、履歴として戻せる(ロールバック可能)必要があります。全く新しい専用プロトコルを発明することもできましたが、ブートストラップ問題があります。AIモデルはそれを知らないため、スキルやCLI、ドキュメントへの依存を配布しなければならず、フリクションが生じます。
Agentsに認証済み・安全なHTTPS GitリモートURLを渡して、Gitリポジトリとして動作させれば事足りるなら、それが非常にうまく機能します。Gitを話さないクライアント(Cloudflare Worker、Lambda関数、Node.jsアプリなど)向けには、REST APIと(まもなく)言語固有のSDKを提供しています。これらのクライアントはisomorphic-gitを使うこともできますが、多くの場合はよりシンプルなTypeScript APIでAPI面を抑えられます。
単なるソースコントロールではない
ArtifactsのGit APIはソースコントロール向けに見えるかもしれませんが、GitのAPIとデータモデルはフォーク、タイムトラベル、差分比較などのセマンティクスを提供することで、あらゆるデータの状態を永続化する強力な手段になります。
Cloudflare社内では、内部Agentsに対してArtifactsを利用しています:各セッションごとのArtifactsリポジトリにファイルシステムの現在状態とセッション履歴を自動的に永続化しています。これにより:
- ブロックストレージをプロビジョニング(かつ維持)せずにサンドボックス状態を永続化できる。
- セッションを他者と共有し、セッション(プロンプト)状態とファイル状態の両方を、実際のリポジトリへのコミットの有無にかかわらずタイムトラベルできる。
- 任意の時点からセッションをフォークし、別の同僚に引き継いでもらうことができる。(デバッグで別の目が欲しいときはURLを送ってフォークしてもらえばよい。)
また、Gitプロトコル自体が必須ではなく、Gitのセマンティクス(戻す、クローン、差分)だけが必要なケースでもTeamsからの要望を受けています。製品の一部として顧客別設定を保存し、ロールバック機能が欲しい場合にもArtifactsは有用です。
アンダーザフード
ArtifactsはDurable Objectsの上に構築されています。状態を持つ分離された多数のインスタンスを何百万単位で作成できる能力はDurable Objectsの特性であり、これが名前空間あたり何百万のGitリポジトリをサポートするために必要でした。Major League Baseball(ライブゲームのファンアウト)、Confluence Whiteboards、Agents SDKなど、既に大規模でDurable Objectsを活用しているプロダクトの実績があるため、実稼働で成熟したプリミティブの上に構築しています。
必要だったのは、Cloudflare Workers上で動くGitサーバ実装です。小さく、できるだけ完全で、拡張可能(notes、LFSなど)かつ効率的である必要がありました。そこで我々はZigで実装し、Wasmにコンパイルしました。
なぜZigか?理由は3つあります:
- gitプロトコルエンジン全体を純粋なZigで実装(libcなし)し、~100KBのWASMバイナリにコンパイル(さらなる最適化余地あり)。SHA-1、zlib inflate/deflate、デルタエンコーディング/デコーディング、パック解析、git smart HTTPプロトコルのフル実装を外部依存なしで実装している。
- ZigはDurable Objectsのような制約のある環境で重要なメモリ割り当てを手動で制御できる。
- Zig Build Systemにより、WASMランタイム(本番)とネイティブビルド(libgit2を使った正当性検証用)間でコードを簡単に共有できる。
WASMモジュールはJSホストと薄いコールバックインターフェースで通信します:ストレージ操作用の11個のホストインポート関数(host_get_object, host_put_object など)と、ストリーミング出力用の1つの関数(host_emit_bytes)です。WASM側は単体でテスト可能です。
内部的には、Artifactsはスナップショット用にR2、認証トークン追跡用にKVを使用しています。
仕組み(Workers、Durable Objects、WebAssembly)
Workerはフロントエンドとして機能し、認証・認可、主要指標(エラー、レイテンシ)を扱い、各Artifactsリポジトリ(Durable Object)をオンザフライでルックアップします。具体的には:
- ファイルは基盤となるDurable ObjectのSQLiteデータベースに保存されます。
- Durable Objectのストレージは2MBの最大行サイズがあるため、大きなGitオブジェクトはチャンクに分割され複数行に格納されます。
- 同期KV API(state.storage.kv)を利用しており、内部的にはSQLiteで裏打ちされています。
- DOには約128MBのメモリ制限があるため、大量に(何千万単位で)起動可能で高速・軽量ですが、その制約内で動作します。
- fetch/push経路の両方でストリーミングを多用し、生のWASM出力チャンクから構築した
ReadableStream<Uint8Array>を直接返します。
- Gitデルタの再計算は避け、代わりに生のデルタとベースハッシュを解決済みオブジェクトと並べて永続化します。fetch時にクライアントが既にベースオブジェクトを持っていれば、Zigはフルオブジェクトの代わりにデルタを出力し、帯域とメモリを節約します。
- gitプロトコルのv1およびv2の両方をサポートします。ls-refs、shallow clones(deepen, deepen-since, deepen-relative)、have/want交渉による増分fetchなどの機能をサポートしています。
- gitクライアントに対する適合性テストスイートや、プロトコルサポートを検証するためのlibgit2サーバとの検証テストを備えています。
- さらに、git-notesをネイティブサポートしています。ArtifactsはAgentファーストに設計されており、notesによりエージェントはGitオブジェクトに対してメタデータ(プロンプト、Agentの帰属情報、その他のメタ情報)をオブジェクト自体を改変せずに読み書きできます。
大きなリポジトリ、大きな問題?ArtifactFSの登場
ほとんどのリポジトリはそれほど大きくなく、Gitはストレージ効率に優れています:ほとんどのリポジトリはクローンに数秒しかかからず、その時間はネットワークセットアップ、認証、チェックサム計算が支配します。多くのAgentやサンドボックスのシナリオでは、サンドボックス開始時にリポジトリをクローンして作業を始めることで問題ありません。
しかし、マルチGBのリポジトリやオブジェクトが数百万単位のリポジトリではどうでしょうか?エージェントが数分待たされることなく素早く作業を開始するにはどうすればよいでしょうか。例えばある人気Webフレームワーク(2.4GBで長い履歴あり)はクローンにほぼ2分かかります。shallow cloneは速くなりますが、数十秒を一桁秒にまで削るには不十分で、履歴を省略したくない場合もあります。
答えは「いくつかのトリックで可能」です。Artifactsのローンチに合わせて、我々はArtifactFSをオープンソース化しています。ArtifactFSは大きなGitリポジトリをできるだけ早くマウントするために設計されたファイルシステムドライバで、初回クローンでファイル内容をすべて取得するのではなくオンデマンドで内容をハイドレートします。これは、起動時間が重要なAgents、サンドボックス、コンテナ等に最適です。
- ArtifactFSは“非同期のgit clone”と考えられます:ファイルツリーとrefsは取得するが、ファイル内容(blobs)は取得しない「blobless clone」を実行します。
- サンドボックス起動中にこれを行い、Agentハーネスはすぐに作業を開始できます。
- 背景で軽量デーモンが並行してファイル内容をハイドレート(ダウンロード)します。
- package.json, go.modなどのパッケージマニフェストや設定ファイル、コードなど、Agentsが通常先に操作するファイルを優先してハイドレートし、画像や実行ファイルなどのバイナリは優先度を下げます。
- ファイルが完全にハイドレートされていないときにAgentがそれを読み込もうとすると、読み込みは完了までブロックされます。
- ファイルシステムはファイルをリモートリポジトリに“同期”しようとしません:何千〜何百万のオブジェクトでは通常非常に遅く、gitを使うという前提なら必要ありません。Agentは通常どおりコミットしてプッシュすれば良いだけです(新しいAPIを学ぶ必要はありません)。
- 重要な点として、ArtifactFSは自社のArtifactsに限らず、任意のGitリモートで動作します。GitHub、GitLab、セルフホストのGitインフラから大きなリポジトリをクローンする場合でもArtifactFSを使えます。
(原文はここで途切れていますが、要点は以上です。)
ドキュメントを参照して始めてください。ArtifactsとArtifactFSはAgentファーストのワークフロー、低レイテンシなサンドボックス起動、そして既存のGitエコシステムとの互換性を提供します。