技術 約13分で読めます

CloudflareのAIエージェント向けGit互換ストレージ「Artifacts」

いけさん目次

Cloudflareが2026年4月16日にAgents Week最終日の追加発表として「Artifacts」をプライベートベータで公開した。
AIエージェント向けに設計したGit互換のバージョン管理ストレージで、現在のGitHub等は人間向けに作られているという前提から出発した新しいプリミティブだ。

エージェントにとって既存のGitが合わない理由

GitHubやGitLabは、人間がPRをレビューし、コードを読んで、ブランチを管理するという前提で設計されている。
AIエージェントの文脈では話が違う。
数百から数千のエージェントが同時にコードを生成・編集・フォークし、セッション履歴、コンフィグ、ツール出力といった大量の小規模データを扱う。

人間向けGitの問題点は主に3つある。

  • スケール: GitHubのAPIレート制限はエージェントが大量にAPIを叩くことを想定していない
  • プログラム操作性: Web UIやCLI中心の設計で、Workers等のサーバーレスランタイムから直接リポジトリを作成・操作するAPIが整備されていない
  • エージェント固有のメタデータ: 実行ログ、プロンプト、出力をコミット履歴に紐づけて保存する仕組みがない

Cloudflareはこれをプラットフォームのプリミティブとして解決することにした。

アーキテクチャ

Durable Objects上に構築されたGitサーバー

ArtifactsはDurable Objectsを基盤とする。
各リポジトリが独立したDurable Objectインスタンスとして動き、グローバルに一意なIDを持つ。

ファイルオブジェクトはDurable ObjectのローカルSQLiteデータベースに保存される。
Durable ObjectのSQLiteはオブジェクトが動いているマシン上にローカルで存在するため、ネットワーク越しのストレージアクセスが発生しない。
2MBの行サイズ制限を超える大容量オブジェクトは分割して格納される。
スナップショット管理にはR2、認証トークンの追跡にはKVを使う構成だ。

Zig製の軽量Gitサーバー

GitプロトコルのエンジンはZig言語で実装されており、約100KBのWebAssemblyバイナリとしてDurable Object上で動作する。
SHA-1、zlib、デルタエンコーディング、packファイル解析に対応している。

Git v1とv2の両プロトコルをサポートし、浅いクローン(shallow clone)、インクリメンタルフェッチ、have/want ネゴシエーションが使える。
標準のGitクライアントがそのまま動く設計だ。

flowchart TD
    A[エージェント / Worker] --> B{アクセス方法}
    B --> C[Workers Binding]
    B --> D[REST API]
    B --> E[Git Protocol]
    C --> F[Durable Object<br/>Gitサーバー WASM]
    D --> F
    E --> F
    F --> G[SQLite<br/>ファイルオブジェクト]
    F --> H[R2<br/>スナップショット]
    F --> I[KV<br/>トークン管理]

3つのアクセス方法

Workers Binding

wrangler.jsonc に設定を追加するだけで、Workers から直接リポジトリを操作できる。

// wrangler.jsonc
{
  "artifacts": [
    {
      "binding": "ARTIFACTS",
      "namespace": "default"
    }
  ]
}

名前空間レベルの操作(creategetlistimportdelete)と、リポジトリハンドルの操作(createTokenlistTokensrevokeTokenfork)が使える。

// リポジトリ作成とトークン発行
const repo = await env.ARTIFACTS.create("agent-session-47")
const token = await repo.createToken({ scope: "write", ttl: 3600 })

return { remote: repo.remote, token: token.secret }

生成されるリモートURLは https://{accountId}.artifacts.cloudflare.net/git/{namespace}/{repo}.git の形式で、標準のGitクライアントに渡せる。

git clone https://x:${TOKEN}@123def456abc.artifacts.cloudflare.net/git/agent-session-47.git

REST API

Workers Bindingsを使わずにREST APIから直接操作することもできる。

POST /accounts/$ACCOUNT_ID/artifacts/namespaces/$NAMESPACE/repos
GET  /accounts/$ACCOUNT_ID/artifacts/namespaces/$NAMESPACE/repos
POST /accounts/$ACCOUNT_ID/artifacts/namespaces/$NAMESPACE/repos/:name/fork
POST /accounts/$ACCOUNT_ID/artifacts/namespaces/$NAMESPACE/repos/:name/import
POST /accounts/$ACCOUNT_ID/artifacts/namespaces/$NAMESPACE/tokens

import エンドポイントはHTTPS経由で公開Gitリポジトリを取り込む。depth オプションでシャロークローンの深さも指定できる。

Git Protocol経由

既存のGitワークフローは変更不要で動く。認証はBearerトークン(http.extraHeader)か、URLのパスワード部分にトークンを埋め込む方法の2通りに対応している。

# Bearer token方式
git -c http.extraHeader="Authorization: Bearer $TOKEN" clone $REMOTE

# URL埋め込み方式
git clone https://x:$TOKEN@123def456abc.artifacts.cloudflare.net/git/default/repo.git

ArtifactFS

Artifactsの補助機能として、大規模リポジトリを高速にマウントするFUSEドライバー「ArtifactFS」が提供される。

通常の git clone では全ファイルをダウンロードしてから作業を開始する。
2.4GBのリポジトリなら約2分かかる。
ArtifactFSはbloblessクローン(コミット・ツリー・refのみ取得)でリポジトリをFUSEマウントし、ファイルの中身は実際に読まれたタイミングでオンデマンド取得する。
同じリポジトリが10〜15秒でマウントできる。

Go言語で実装されたFUSEデーモンで、バックグラウンドで並行ダウンロードも走る。
package.json や設定ファイルなど優先度の高いファイルから先にダウンロードする仕組みも持っている。

ArtifactFS はCloudflareのArtifactsだけでなく、GitHubやGitLab、セルフホストのGitリモートにも使える。

flowchart LR
    A[ArtifactFS<br/>FUSEデーモン] --> B[Bloblessクローン<br/>コミット/ツリー/ref]
    A --> C[FUSEマウント<br/>ファイルツリーを即時公開]
    C --> D[ファイル読み取り要求]
    D --> E{キャッシュあり?}
    E -- No --> F[オンデマンド取得<br/>Blob本体をダウンロード]
    E -- Yes --> G[キャッシュから返却]
    F --> G

git-notesによるメタデータ管理

ArtifactsはGitのgit-notes機能をネイティブサポートする。
git-notesはコミットオブジェクト自体を変更せずに任意のメタデータを付加できる仕組みで、コミットハッシュは変わらないまま注釈を書き込める。

エージェントの実行ログ、使用したプロンプト、ツール出力を refs/notes/ 以下に書き込めば、コミット履歴とメタデータが一体で管理できる。
エージェントが生成したコードの「なぜその変更をしたか」という文脈をGitの外に切り出さずに済む。

# コミットにメタデータを付加
git notes --ref=refs/notes/agent add -m '{"prompt":"...", "model":"claude-opus-4-7"}' HEAD

# 読み出し
git notes --ref=refs/notes/agent show HEAD

ユースケース

1エージェント1リポジトリのパターン

セッションIDや安定した識別子をリポジトリ名に使い、エージェントごとに独立したリポジトリを作るのが推奨パターンだ。

export default {
  async fetch(request: Request, env: Env) {
    const sessionId = request.headers.get("x-session-id") ?? crypto.randomUUID()

    // セッションに紐づいたリポジトリを取得または作成
    const repo = await env.ARTIFACTS.create(`session-${sessionId}`)
    const token = await repo.createToken({ scope: "write", ttl: 1800 })

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

書き込み用トークンは短命(TTL付き)、読み取り専用トークンは必要な場合のみ発行という最小権限の設計が推奨されている。

Sandboxesとの組み合わせ

Sandboxes GA で取り上げたSandboxesとArtifactsは組み合わせて使うことが想定されている。
Sandboxesがエージェントに隔離実行環境を提供し、その実行結果をArtifactsにコミット・バージョン管理するパターンだ。

セッション間の「時間旅行」(任意のコミットに戻る)や、セッションのフォーク(同一状態から複数エージェントが独立して作業する)もGitの操作として表現できる。

名前空間によるテナント分離

名前空間はチーム・環境・プロジェクト単位で分けることが推奨される。

// 開発・本番を名前空間で分離する例
{
  "artifacts": [
    { "binding": "DEV_ARTIFACTS",  "namespace": "dev" },
    { "binding": "PROD_ARTIFACTS", "namespace": "prod" }
  ]
}

料金

項目無料枠超過単価
操作数月10,000操作$0.15/1,000操作
ストレージ月1GB$0.50/GB-月

「大きくアクティブなリポジトリはより多く、小さくほぼ使われないリポジトリはより少なく費用がかかる」という設計で、大量の小規模リポジトリを作るエージェントのユースケースではコストが抑えられる。

今後のロードマップ

2026年5月初旬にパブリックベータへ移行予定で、以下の機能が予告されている。

  • Event Subscriptions: プッシュ・プル・クローン・フォーク時にイベントを発火する仕組み
  • TypeScript / Go / Python SDK
  • リポジトリレベルの検索機能
  • 操作数・ストレージ使用量のメトリクス強化

Agents Weekの一連の発表(Sandboxes、Durable Object Facets、Project Think、Agent Memory等)と合わせると、Artifactsは「実行→状態保存→バージョン管理→メモリ検索」のうちバージョン管理レイヤーを埋める位置にある。

Agents Week 2026 で追ってきた他の発表

本記事ではArtifactsにフォーカスしたが、同じ週に連日出てきた関連発表を並べておく。

Sandboxes / Facetsで実行環境、Mesh / MCPでネットワーク、Project Think / Workflowsでオーケストレーション、Email / Memoryでチャネルと記憶、そしてArtifactsでバージョン管理、という並びになる。

文脈として読んでおきたい過去記事

Artifactsは単独の新プロダクトではなく、ここ数週間〜数カ月で並行して進んでいた隔離実行・エンタープライズ統制・並列エージェント・プロンプトインジェクション対策の延長線上にある。

jj(Jujutsu)というGit互換VCSから見たArtifacts

Artifactsは標準のGitクライアントがそのまま動く設計なので、Git互換のフロントエンドなら同じリモートに繋がる。
最近エージェント周りで名前を聞くようになった jj(Jujutsu) もその対象だ。
このブログで過去にjjを扱った記事はないので、ここで軽く整理しつつArtifactsとの噛み合いを見ておく。

jjとGitの操作モデルの違い

jjは「Gitと互換性を保ちつつクライアント側のCLIを作り直したVCS」と言っていい。
ストレージにGitバックエンドを使うモードがあり、そこで作られるコミットは普通のGitコミットとして読める。
そのためリモートはGitHubでもGitLabでもArtifactsでも同じように使える。
違いが出るのはクライアント側の操作モデルで、主な差は6点ある。

項目Gitjj
変更の単位コミット(内容を書き換えるとハッシュも変わる)チェンジセット(内容を書き換えてもIDが保たれる)
ステージングgit add でインデックスに積むインデックスなし、作業ツリーを自動でコミット化
ブランチデフォルトで明示的ブランチに紐づく匿名ブランチ、グラフの葉として管理
コンフリクト発生したら操作が止まるコミットにコンフリクトを格納、後で解消できる
履歴の巻き戻しreflog(ref単位)operation log(全refの原子的スナップショット)、jj undo で一発
作業ツリーコミットとは別の状態作業ツリー自体が1つのコミット扱い

特にエージェント運用と噛み合うのがoperation logの存在だ。
jj コマンドを打つたびに作業ツリーが自動スナップショットされるため、エージェントが未コミットのファイルを破壊しても jj obslog から復旧できる。
「Claude Codeにコンテキストを圧縮されて作業状態が飛ぶ」「書き途中のファイルを別プロセスに上書きされる」といった、Gitだと取り返しのつかない事故が、ロールバック可能な事故に降格する。

Artifactsリモートをjjからつつくとどう見えるか

ArtifactsはGitプロトコル v1 / v2 を話すので、jjのGitバックエンドから見れば普通のGitリモートでしかない。
Artifactsが払い出すクローンURLをそのまま jj git clone に渡せば初期化できる。

# Artifactsリモートをjjでクローン、同じディレクトリで git / jj 両方を使える状態にする
jj git clone --colocate \
  https://x:$TOKEN@123def456abc.artifacts.cloudflare.net/git/default/agent-session.git

--colocate を付けると、同じディレクトリで gitjj の両方を操作できる状態になる。
エージェント側の実装が git clone / git commit / git push を叩くだけのままでも、横でjjが作業ツリーをスナップショットし続けてくれる。
リモートにpushされるのはあくまで普通のGitコミットなので、Artifacts側から見ればjjクライアントもただのGitクライアントの1つだ。

役割を分けて並べると整理しやすい。

  • Artifacts: サーバー側のバージョン管理ストレージを用意する。Durable Objects上のGitサーバー、短命トークン、名前空間でのテナント分離。
  • jj: クライアント側に「エージェントが壊してもロールバックできる」操作モデルを被せる。未コミット変更の自動スナップショット、jj undo、匿名ブランチ。

Artifactsの「1エージェント1リポジトリ」パターンに、jjの「operation logで作業ツリーごと時系列で追える」挙動を重ねると、事故復旧の粒度がエージェントの1ステップ単位まで細かくなる。

現状の注意点

  • Artifactsは refs/notes/ 以下のgit-notesでメタデータを付加する設計だが、jj自体にはまだgit-notes専用のサブコマンドがない。コロケート状態でGit側のCLIから git notes を叩く運用になる。
  • jjのチェンジセットIDはjj側ローカルの概念で、Artifactsに流れる時点では普通のGitコミットに戻る。他のエージェントがArtifacts越しに受け取った場合、IDの安定性はjjを使っている側にしか効かない。
  • Agents Week でCloudflareが推しているのはあくまでGit互換のワークフローで、jjはローカルでエージェントを操る側の操作性を補う位置づけで乗せる運用になる。