OpenAICloudflare Developer Platform2026/05/01 0:00

Workflows, Workers - Run Workflows inside Dynamic Workers with the @cloudflare/dynamic-workflows library

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

元記事

Quick Digest

要約

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

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

@cloudflare/dynamic-workflowsでDynamic Worker内にWorkflowsを実行可能に

Key Points

  • Dynamic Worker内でWorkflowを耐久実行
  • テナントIDでワーカーを再ロードして復帰
  • 事前登録不要で動的コードを実行可能

Summary

Cloudflare の @cloudflare/dynamic-workflows ライブラリにより、ランタイムでロードされる Dynamic Worker の内部で Workflow を実行できるようになりました。Worker Loader がオンデマンドで Dynamic Worker をロードするため、ワークフローが数時間・数日スリープして再開するケースでも、該当する Dynamic Worker を再読み込みして耐久実行(persistence / retries)を維持します。ワークフロー本体のコードは変更不要で、テナントごとの動的コードや AI エージェントなどのユースケースで有効です。

Key Points

  • 動作の仕組み

    • 各 Workflow インスタンスにテナントID等のメタデータを付与し、復帰時にそのメタデータで対応する Dynamic Worker を Worker Loader 経由でロードして実行を継続する。
    • Dynamic Worker はオンデマンドで作成されるため、事前に全ワークフローを登録する必要がない。
  • 実装上の注目点(エンジニア向け)

    • エントリポイントは createDynamicWorkflowEntrypoint で定義し、async ({ env, metadata }) => { ... } 内で metadata.tenantId を使って Dynamic Worker を読み込む。
    • Dynamic Worker の env に WORKFLOWS: wrapWorkflowBinding({ tenantId }) を渡すことで、create() が自動的にタグ付けされる。
    • WorkerLoader の get(tenantId, async () => ({ compatibilityDate, mainModule, modules, env })) でテナントコードをオンデマンド返却するパターン。
    • ワークフローエンジンが永続化とリトライを担い、ワークフローコード自体にルーティング処理を組み込む必要はない。
  • 想定ユースケース

    • SaaS のテナント固有ワークフロー(オンボーディング、承認チェーン、請求リトライなど)
    • AI エージェントフレームワークでのランタイム生成・実行されるマルチステッププラン
    • マルチテナントジョブ処理システムでの顧客ごと処理ロジック

Practical tips

  • Wrangler の workflows binding の class_namecreateDynamicWorkflowEntrypoint のエントリ名を一致させる。
  • Dynamic Worker のマニフェストに compatibilityDate / mainModule / modules を含めて動的に返す。
  • メタデータ(例: tenantId)が正しく付与されていることを確認すると、ワークフロー復帰時に正しい Dynamic Worker がロードされる。

(詳細なハンズオンは公式の Dynamic Workflows ガイドを参照してください)

Full Translation

翻訳

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

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

Workflows、Workers — @cloudflare/dynamic-workflows ライブラリで Dynamic Workers 内で Workflows を実行する

公開日: 2026-05-01

Workflows、Workers — @cloudflare/dynamic-workflows ライブラリで Dynamic Workers 内で Workflows を実行する

@cloudflare/dynamic-workflows ↗ を使って、ランタイムでロードされるコードに対しても耐久性のある実行を保証しつつ、Dynamic Worker の内部で Workflow を実行できるようになりました。

Worker Loader は Dynamic Worker をオンデマンドでロードするため、これまでは耐久性の確保が困難でした。Dynamic Worker 内の Workflow はステップ間で数時間または数日間スリープする可能性があり、再開時には元の Dynamic Worker コードがメモリ上に存在しないことがあります。

このライブラリは、各 Workflow インスタンスにどの Dynamic Worker をロードするかを識別するメタデータ(例えば tenant ID)をタグ付けし、Workflow が再開するたびに Worker Loader を通して該当する Dynamic Worker を再ロードすることでこの問題を解決します。Dynamic Workers はオンデマンドで作成されるため、各 Workflow を事前に登録したり個別に管理したりする必要はありません。必要なときに Dynamic Worker 内で Workflow コードをロードし、Workflows エンジンが永続化やリトライを裏側で処理します。Workflow コード自体にルーティングのための変更は不要で、通常どおり動作します。

これにより、Workflow コード自体が動的であるパターンが可能になります。例えば次のようなユースケースで有用です:

  • SaaS プラットフォーム: 各テナントがオンボーディングシーケンス、承認チェーン、課金のリトライロジックなど独自のオートメーションを定義するケース。
  • AI エージェントフレームワーク: エージェントが実行時にマルチステップの計画を生成・実行し、ツール呼び出しの間に人間の承認を待つなど、再起動や待機をまたいで継続するケース。
  • マルチテナントのジョブシステム: 各顧客が独自の処理ロジックを提出し、各ステップが進捗を永続化して失敗時にリトライするケース。

使用例 (TypeScript)

以下は @cloudflare/dynamic-workflows を使って、テナントごとにコードをロードして Workflow を実行する例です。

import { createDynamicWorkflowEntrypoint, DynamicWorkflowBinding, wrapWorkflowBinding, type WorkflowRunner, } from "@cloudflare/dynamic-workflows";
export { DynamicWorkflowBinding };
interface Env { WORKFLOWS: Workflow; LOADER: WorkerLoader; }
function loadTenant(env: Env, tenantId: string) {
    return env.LOADER.get(tenantId, async () => ({
        compatibilityDate: "2026-01-01",
        mainModule: "index.js",
        modules: { "index.js": await fetchTenantCode(tenantId) },
        // The Dynamic Worker uses this exactly like a real Workflow binding;
        // every create() is tagged with { tenantId } automatically.
        env: { WORKFLOWS: wrapWorkflowBinding({ tenantId }) },
    }));
}
// The entrypoint name must match `class_name` in the workflows binding of your Wrangler config file.
export const DynamicWorkflow = createDynamicWorkflowEntrypoint<Env>(
    async ({ env, metadata }) => {
        const stub = loadTenant(env, metadata.tenantId as string);
        return stub.getEntrypoint("TenantWorkflow") as unknown as WorkflowRunner;
    },
);
export default {
    fetch(request: Request, env: Env) {
        const tenantId = request.headers.get("x-tenant-id")!;
        return loadTenant(env, tenantId).getEntrypoint().fetch(request);
    },
};

注: 上記の例では、Dynamic Worker の構成で Workflows バインディングの class_name とエントリポイント名が一致する必要があります。

詳細とリソース

詳細なウォークスルーについては Dynamic Workflows guide を参照してください。