Artifacts は、作業を分離し、アクセス範囲を狭く保ち、メタデータを分けておき、ストレージを意図的に分割すると、最もうまく使えます。
エージェント、自動化、共有システム向けにリポジトリを構成するときは、次のパターンを使います。
自律的な作業の単位ごとに、リポジトリを 1 つ作ります。エージェントが 10,000 あるなら、リポジトリも 10,000 作ります。
こうすると、各エージェントの変更、失敗、クリーンアップのライフサイクルが分かれます。共有リポジトリ 1 つが、競合、大きな差分、誤上書きの集中箇所になることも避けられます。
次のような場合に、このパターンを使います。
- あるエージェントの作業を、別のエージェントの作業から分離する
- リポジトリを 1 つのセッションまたはユーザーアプリケーションに渡す
- 作業を独立してレビュー、マージ、アーカイブ、削除する
共同作業者が同じライフサイクルを共有し、同じリポジトリで作業する必要がある場合にだけ、ブランチを使います。多数の自律エージェントのキューとして、共有リポジトリ 1 つを使わないでください。
リポジトリ名は、名前空間内で一意です。複数のエージェントが 1 つの名前空間で同じベースラインリポジトリの分離コピーを必要とする場合は、docs-site のような短い共有名を再利用しないでください。
リポジトリ名には、エージェント名、セッション ID、ユーザー ID、ワークフロー ID など、安定した識別子を含めます。${agentName}-${sessionId}-${repoName} のような名前は、${repoName} より安全です。衝突を避けられ、クリーンアップも簡単になります。
次の例では、リポジトリを作る前に一意なリポジトリ名を組み立てます。
async function createRepoCopy(env, agentName, sessionId, repoName) {
const uniqueRepoName = `${agentName}-${sessionId}-${repoName}`;
return env.ARTIFACTS.create(uniqueRepoName);
}interface Env {
ARTIFACTS: Artifacts;
}
async function createRepoCopy(
env: Env,
agentName: string,
sessionId: string,
repoName: string,
) {
const uniqueRepoName = `${agentName}-${sessionId}-${repoName}`;
return env.ARTIFACTS.create(uniqueRepoName);
}エージェントが同じスターターファイル、プロンプト、アプリケーション構成を必要とするときは、信頼できるベースラインから新しいリポジトリを始めます。レビュー済みリポジトリからのフォークは、新しいリポジトリごとにファイルを手でコピーするより安全です。
開始点が揃い、下流の差分もレビューしやすくなります。取り込みたい結果だけをマージバックすることもできます。
次の例では、レビュー済みのベースラインリポジトリを、セッション固有のリポジトリへフォークします。
async function forkFromBaseline(env, sessionId) {
const baseline = await env.ARTIFACTS.get("starter-repo");
const forked = await baseline.fork(`starter-repo-${sessionId}`, {
description: `Fork for session ${sessionId}`,
defaultBranchOnly: true,
readOnly: false,
});
return {
name: forked.name,
remote: forked.remote,
};
}interface Env {
ARTIFACTS: Artifacts;
}
async function forkFromBaseline(env: Env, sessionId: string) {
const baseline = await env.ARTIFACTS.get("starter-repo");
const forked = await baseline.fork(`starter-repo-${sessionId}`, {
description: `Fork for session ${sessionId}`,
defaultBranchOnly: true,
readOnly: false,
});
return {
name: forked.name,
remote: forked.remote,
};
}Artifacts のトークンはリポジトリ単位です。クローン、インデックス、レビュー、取得には read トークンを優先します。
write トークンは、変更をプッシュする必要があるエージェントまたはシステムにだけ使います。トークンの有効期間は短くし、エージェントセッションごとに新しいトークンを再発行します。
次の例では、Workers バインディング を使い、リポジトリ向けの短命な read トークンを発行します。
このルートがトークンを返す前に、呼び出し元はすでに認証・認可済みであるとします。
export default {
async fetch(request, env) {
const url = new URL(request.url);
const repoName = url.searchParams.get("repo") ?? "starter-repo";
const repo = await env.ARTIFACTS.get(repoName);
const token = await repo.createToken("read", 900);
return Response.json({
repo: repoName,
scope: token.scope,
expiresAt: token.expiresAt,
token: token.plaintext,
});
},
};interface Env {
ARTIFACTS: Artifacts;
}
export default {
async fetch(request: Request, env: Env): Promise<Response> {
const url = new URL(request.url);
const repoName = url.searchParams.get("repo") ?? "starter-repo";
const repo = await env.ARTIFACTS.get(repoName);
const token = await repo.createToken("read", 900);
return Response.json({
repo: repoName,
scope: token.scope,
expiresAt: token.expiresAt,
token: token.plaintext,
});
},
} satisfies ExportedHandler<Env>;変更をプッシュする必要があるセッションを Worker が認可したあとでのみ、同じパターンで write トークンを使います。
長寿命の write トークンをすべてのエージェントに発行しないでください。発行するトークンは、できる限り狭い権限で、できる限り短い期間にします。
git notes ↗ を使い、コミットオブジェクトや作業ツリーを変えずに、プロンプト、モデル出力、実行 ID、その他のハーネスメタデータをコミットに付けます。
こうすると、Artifacts をエージェント作業のバージョン管理されたファイルシステムと、エージェントハーネスの信頼できる情報源の両方として使えます。ファイルは成果物に集中し、実行の文脈はコミットの notes に残します。
次の例では、現在のコミットにユーザープロンプトとアシスタントの要約を保存し、その note を読み戻します。
git notes add -m 'user: Add a best-practices section for unique repo names.' HEAD
git notes append -m 'assistant: Added naming guidance and a code example.' HEAD
git notes show HEADシステム間でリポジトリを同期する場合、notes は別の ref に置かれる点に注意してください。そのメタデータをリポジトリと一緒に運ぶときは、ほかのリポジトリデータとあわせて refs/notes/* を push / fetch します。
運用上の境界を分けるために、名前空間を使います。リポジトリの分離は作業単位を分け、名前空間の分離は所有権、環境、トラフィックパターンを分けます。
利用が増えたら、すべてのリポジトリを 1 つのデフォルト名前空間に置かないでください。所有権を明確にしたい場合や、名前空間ごとの リクエストレート制限 の中でスケールする余地が必要な場合は、名前空間を分割します。
| 用途 | 名前空間の例 | 理由 |
|---|---|---|
| 環境 | staging, prod |
テストトラフィックと本番トラフィックを分けます。 |
| チームの境界 | sales, finance, devtools |
所有権、アクセス、クリーンアップ方針を分けます。 |
| トラフィックの分離 | agents-batch, agents-realtime |
あるワークロードが、別のワークロードの制限を消費しないようにします。 |
1 つの名前空間が過熱したら、共有名前空間をさらに大きくするのではなく、新しいリポジトリを追加の名前空間に分散します。