OpenAICloudflare2026/04/17 13:00

Introducing Flagship: feature flags built for the age of AI

要点だけを先に読めるように短く再構成したセクションです。

元記事

Quick Digest

要約

要点だけを先に読めるように短く再構成したセクションです。

openaijamodel: gpt-5-mini-2025-08-07

Flagship を発表: AI時代に最適化された機能フラグ

Key Points

  • Workersでエッジ評価
  • OpenFeature準拠
  • Durable Objects→KV同期

Summary

Cloudflare は Flagship を発表しました。Flagship は OpenFeature 準拠のネイティブ機能フラグサービスで、Workers・Durable Objects・KV を使ってエッジでローカルにフラグ評価を行います。外部 HTTP 呼び出しを排し、Workers バインディング経由で低レイテンシかつ一貫した評価を実現。クローズドベータで提供中です。

Key Points

  • エッジ評価アーキテクチャ
    • フラグ定義は Durable Object に原子書き込みされ、数秒以内に Workers KV に同期される
    • 評価はリクエスト処理中に同一リージョンの KV から行われ、外部ネットワーク往復が不要
  • Workers バインディングと OpenFeature
    • wrangler.jsonc にバインディングを追加するだけで getBooleanValue / getStringDetails 等の型付き API を利用可能
    • OpenFeature プロバイダ経由で既存の評価コードをほぼ変更せずに Flagship に切替え可能(binding を渡すだけ)
  • 安全なローリングとターゲティング
    • 条件式はネストされた AND/OR をサポート(最大5階層)
    • 一貫性のあるハッシュによるパーセンテージロールアウトでユーザがロール間を行き来しない
  • 運用・監査性
    • フラグの変更はフィールド単位の差分と監査ログが残る
    • 評価エラー時はデフォルトを返却、型不一致は例外(コードのバグとして扱う)
  • クライアントとブラウザ
    • ブラウザ向けは事前フェッチ+TTL キャッシュで同期評価を提供

Practical notes for engineers

  • Worker への導入は wrangler.jsonc に binding を追加し、Worker 内で env.FLAGS.getBooleanValue(...) 等を呼ぶだけ。OpenFeature を使う場合は OpenFeature.setProviderAndWait(new FlagshipServerProvider({ binding: env.FLAGS })) を初期化する。
  • 外部フラグサービスへの毎リクエスト HTTP をやめ、KV 経由のローカル評価に移行することでレイテンシと可用性を改善できる。
  • AI/エージェントによる自動デプロイ時は、フラグでブレークアウト半径を制御し、段階的ロールアウトと即時ロールバックで安全性を確保する。

Availability

  • Flagship は現在クローズドベータ。Workers 上で最も高速に動作し、他ランタイム(Node.js, Deno, Bun, ブラウザ)でも OpenFeature 経由で利用可能。

Full Translation

翻訳

原文の流れを保ったまま読める翻訳セクションです。

openaijamodel: gpt-5-mini-2025-08-07

Flagshipの紹介:AI時代のために作られたフィーチャーフラグ

Flagshipの紹介:AI時代のために作られたフィーチャーフラグ

AIはこれまでにない速度でコードを書いています。AI支援の寄与はプラットフォーム上で新しいコードの急速に増える割合を占め、Agent的なコーディングツール(OpenCodeやClaude Codeのような)は数分で機能全体を出荷しています。AI生成コードが本番に入る流れはさらに加速しますが、より大きな変化は速度だけでなく自律性です。今日ではAIエージェントがコードを書き、人間がレビュー、マージ、デプロイします。明日にはそのエージェント自身がすべてを実行するでしょう。では、すべての安全網を取り払わずにエージェントを本番に出荷させるにはどうすればよいでしょうか。

フィーチャーフラグが答えです。エージェントは新しいコードパスをフラグの背後に書いてデプロイします — フラグはオフのままなのでユーザーへの挙動は変わりません。エージェントは自分自身や小さなテストコホートにフラグを有効にし、本番で機能を実行して結果を観察します。メトリクスが良ければロールアウトを段階的に拡大し、何かが壊れればフラグを無効にします。人間がすべてのステップに介入する必要はなく、境界を設定し、フラグがブラスト半径(影響範囲)を制御します。これはフィーチャーフラグが常に目指してきたワークフローであり、デプロイとリリースを切り離すだけでなく、出荷プロセスのあらゆる段階から人間の注意を切り離します。フラグがあるからエージェントは速く動いても安全に動けるのです。

本日、Flagshipを発表します — Cloudflareのネイティブなフィーチャーフラグサービスで、CNCFのフィーチャーフラグ評価のオープン標準である OpenFeature 上に構築されています。Workers、Node.js、Bun、Deno、ブラウザなどどこでも動作しますが、Workers上では最速です。Workers上ではフラグが Cloudflare ネットワーク内で評価されます。Flagship binding と OpenFeature を使った統合は次のようになります:

await OpenFeature.setProviderAndWait(
  new FlagshipServerProvider({ binding: env.FLAGS })
);

Flagshipはクローズドベータで利用可能です。

Workers上のフィーチャーフラグにまつわる問題

多くのCloudflare開発者は実用的な回避策として、フラグロジックをWorkersに直接ハードコードすることに頼ってきました。最初はそれで十分に機能します。Workersは数秒でデプロイされるため、コード内のブール値を切り替えて本番にプッシュするのは多くの場合十分速いです。しかし、それは長続きしません。1つのハードコードされたフラグが10になり、10が50になり、異なるチームが所有するようになります。中央のビューが存在せず、監査トレイルもないため、問題発生時には誰が何を切り替えたかを git blame で探さなければならなくなります。

外部サービスへのネットワークコール

Workersでよく見られる別のパターンは、外部サービスへHTTPリクエストを行うことです。例:

const response = await fetch("https://flags.example-service.com/v1/evaluate", {
  ...
  body: JSON.stringify({
    flagKey: "new-checkout-flow",
    context: { ... },
  }),
});
const { value } = await response.json();
if (value === true) {
  return handleNewCheckout(request);
}
return handleLegacyCheckout(request);

そのアウトバウンドリクエストはすべてのユーザーリクエストのクリティカルパス上に乗り、ユーザーがフラグサービスのリージョンからどれだけ離れているかによっては大きなレイテンシを追加します。アプリケーションはエッジ、つまりユーザーに非常に近い場所で動作しているにもかかわらず、フラグチェックのためにインターネット越しに別APIへ往復しなければならないのは奇妙な状況です。

ローカル評価が解決にならない理由

一部のフィーチャーフラグサービスは「ローカル評価」SDKを提供し、各リクエストでリモートAPIを呼ぶ代わりにフラグルール全体をメモリにダウンロードしてローカルで評価します。評価ごとのアウトバウンドはなくなりますが、Workersではこの前提が崩れます。長時間生き続けるプロセスはなく、Workerのアイソレートは作成されリクエストに応答した後にエビクトされる可能性があります。新しい呼び出しはSDKを最初から初期化することを意味するかもしれません。サーバーレス環境では、すでにエッジに存在し、キャッシュが管理され、読み取りがローカルで、状態を最新に保つための永続接続を必要としない分配プリミティブが必要です。Cloudflare KV はこの用途に非常に適しています。

Flagshipの仕組み

FlagshipはCloudflareのインフラ(Workers、Durable Objects、KV)上に完全に構築されています。評価パスに外部データベースやサードパーティサービス、中央のオリジンサーバーは存在しません。フラグを作成または更新すると、コントロールプレーンは変更をDurable Objectに原子的に書き込みます。Durable ObjectはSQLiteをバックエンドに持つグローバルにユニークなインスタンスで、そのアプリのフラグ設定と変更ログの単一の信頼できるソースになります。数秒以内に更新はWorkers KV(Cloudflareのグローバル分散型キー・バリュー・ストア)に同期され、ネットワーク全体にレプリケートされます。

リクエストがフラグを評価すると、Flagshipはリクエストを処理しているのと同じエッジのKVからフラグ設定を直接読み取ります。評価エンジンはそのアイソレート内で実行され、リクエストコンテキストをターゲティングルールと照合し、ロールアウトのパーセンテージを解決して、バリエーションを返します。データもロジックもエッジ上に存在し、評価のために他所へ送られることはありません。

Flagshipの使用方法:Workerバインディング

Cloudflare Workersを実行するチーム向けに、FlagshipはWorkerランタイム内でフラグを評価する直接バインディングを提供します。HTTPラウンドトリップもSDKのオーバーヘッドも不要です。wrangler.jsonc にバインディングを追加するとWorkerがFlagshipに接続されます:

{
  "flagship": [
    {
      "binding": "FLAGS",
      "app_id": "<APP_ID>"
    }
  ]
}

アカウントIDはCloudflareアカウントから推測され、app_idはバインディングを特定のFlagshipアプリに紐付けます。Worker内では単にフラグ値を要求します:

export default {
  async fetch(request: Request, env: Env) {
    // Simple boolean check
    const showNewUI = await env.FLAGS.getBooleanValue('new-ui', false, {
      userId: 'user-42',
      plan: 'enterprise',
    });
    // Full evaluation details when you need them
    const details = await env.FLAGS.getStringDetails('checkout-flow', 'v1', {
      userId: 'user-42',
    });
    // details.value = "v2", details.variant = "new", details.reason = "TARGETING_MATCH"
  },
};

バインディングはすべてのバリエーション型に対する型付きアクセサ(getBooleanValue(), getStringValue(), getNumberValue(), getObjectValue())をサポートし、解決された値と一致したバリアントおよび選択理由を返す *Details() 変種も提供します。評価エラー時はデフォルト値が優雅に返され、型の不一致があるとバインディングは例外を投げます — それは一時的な失敗ではなくコードのバグです。

SDK:OpenFeatureネイティブ

ほとんどのフィーチャーフラグSDKは独自のインターフェースと評価パターンを持ち、時間とともにコードベースに深く埋め込まれて、プロバイダを切り替えるにはすべての呼び出し箇所を書き換える必要が出ます。私たちはそれを繰り返したくありませんでした。FlagshipはOpenFeature上に構築されています。OpenFeatureは言語とプロバイダを横断するフラグ評価の共通インターフェースを定義するCNCFのオープン標準であり、OpenTelemetryが観測性に対して果たす役割に相当します。一度標準に対して評価コードを書けば、設定の1行を変えるだけでプロバイダを差し替えられます。

import { OpenFeature } from '@openfeature/server-sdk';
import { FlagshipServerProvider } from '@cloudflare/flagship/server';
await OpenFeature.setProviderAndWait(
  new FlagshipServerProvider({
    appId: 'your-app-id',
    accountId: 'your-account-id',
    authToken: 'your-cloudflare-api-token',
  })
);
const client = OpenFeature.getClient();
const showNewCheckout = await client.getBooleanValue(
  'new-checkout-flow',
  false,
  { targetingKey: 'user-42', plan: 'enterprise', country: 'US' }
);

Workers上でFlagshipバインディングを使っている場合は、それをOpenFeatureプロバイダに直接渡せます。バインディングは既にアカウントコンテキストを含んでいるため、追加設定は不要で認証は暗黙的に行われます:

import { OpenFeature } from '@openfeature/server-sdk';
import { FlagshipProvider } from '@cloudflare/flagship/server';
let initialized = false;
export default {
  async fetch(request: Request, env: Env) {
    if (!initialized) {
      await OpenFeature.setProviderAndWait(
        new FlagshipServerProvider({ binding: env.FLAGS })
      );
      initialized = true;
    }
    const client = OpenFeature.getClient();
    const showNewCheckout = await client.getBooleanValue('new-checkout-flow', false, {
      targetingKey: 'user-42',
      plan: 'enterprise',
    });
  },
};

評価コードは変わりません — OpenFeatureのインターフェースは同一です。しかし内部ではFlagshipはHTTPではなくバインディングを通してフラグを評価します。標準の移植性とバインディングの性能を両立できます。ブラウザ用のクライアントサイドプロバイダもあり、指定したフラグを事前取得し、設定可能なTTLでキャッシュして、そのキャッシュから同期的に評価を返します。

Flagshipでできること

Flagshipは一般に期待されるパターンと、AI生成コードが本番に頻繁に入る状況で重要になるパターンの両方をサポートします。フラグ値はboolean、string、number、または完全なJSONオブジェクトにでき、構成ブロックやUIテーマ定義、別々のコードパスを維持せずに異なるAPIバージョンへルーティングするなどに有用です。

  • ターゲティングルール

    • 各フラグは優先順位順に評価される複数のルールを持てます。最初に一致したルールが勝ちます。
    • ルールは次の要素で構成されます:
      • そのコンテキストにルールが適用されるかを決める条件
      • ルールが一致したときに返すフラグバリエーション
      • 任意のパーセンテージロールアウト
      • 複数ルールがある場合の評価順を決める優先度(数値が小さいほど高優先)
  • ネストされた論理条件

    • 条件はAND/ORで構成でき、最大5レベルまでネスト可能です。単一ルールで例えば次のように表現できます:

      (plan == "enterprise" AND region == "us") OR (user.email.endsWith("@cloudflare.com")) = serve ("premium")

    • ルールのトップレベルでは複数の条件が暗黙のANDで結合され、すべての条件が満たされればルールが一致します。各条件内ではAND/ORグループをネストして複雑な論理を表現できます。

  • パーセンテージによるロールアウト

    • 段階的デプロイ(異なるアップロード済みWorkerバージョン間でトラフィックを分割する手法)とは異なり、フィーチャーフラグは単一バージョンで100%トラフィックを処理しているまま、パーセンテージ単位で振る舞いをロールアウトできます。任意のルールにパーセンテージロールアウトを含められ、条件に一致するすべてのユーザーではなくその一部にバリエーションを提供できます。ロールアウトは指定したコンテキスト属性に基づく一貫したハッシュを用います。同じ属性値(例:userId)は常に同じバケットにハッシュされるため、リクエスト間でバリエーションが切り替わることはありません。5%→10%→50%→100%と段階的に増やしても、既にロールアウトに含まれているユーザーはそのまま維持されます。

次に来るものに向けて構築

AI生成コードの本番投入はさらに加速し、エージェント的ワークフローがそれを推し進めます。エージェントが自律的に本番でデプロイ、テスト、反復する未来において成功するチームは、単に最速で出荷するチームではありません。速く出荷しつつ、ユーザーに見せるものを制御し、問題時に秒でロールバックでき、新しいコードパスを段階的に自信をもって公開できるチームです。これがFlagshipの目標です。

  • 地域全体での評価:KVでグローバルにキャッシュ
  • 完全な監査トレイル:すべてのフラグ変更はフィールドレベルの差分で記録され、誰がいつ何を変更したかが分かる
  • ダッシュボード統合:誰でもフラグの状態と変更履歴を確認できる