
Apache Airflow & Apache Magpie Meetupでの発表を準備している間に、Airflow 3.4.0のリリースを知った。商品カタログの情報を補うパイプラインにLLMを組み込んでいるところだったので、繰り返し実行とモデル呼び出しの記録に関する変更がまず目に留まった。
今回のバージョンでは、ワークフローの書き方と運用の両方が変わった。タスクグループを条件に応じて繰り返すTask Loopsが加わり、Python以外にもTypeScript、Java、GoでDAG全体を書けるようになった。YAMLによるDAGの宣言やフォルダ単位の一覧表示も追加された一方で、Assetイベントの処理など、既存の実行に影響するデフォルト値も変わっている。公式発表とバージョン別のドキュメントをもとに、主な変更点を整理してみた。
#主な変更点の一覧
| 分野 | 3.4.0の変更 | 変わる作業 |
|---|---|---|
| 繰り返し実行 | Task Loops | 前回の結果を渡しながらタスクグループを繰り返し、反復ごとの実行履歴を確認する。 |
| DAG作成 | Dag ImporterとSDK | スケジュール、タスク、依存関係を含むDAG全体をTypeScript、Java、Goで書く。YAMLによる宣言にも対応する。 |
| 一覧と実行画面 | Foldersと反復別の画面 | バンドルのフォルダ構造からDAGを探し、ループの各反復を確認する。 |
| AIの実行記録 | AI Modelタブ | Common AI providerが記録したモデル名、トークン使用量、推定コストを確認する。 |
| イベント処理 | Assetイベント別の実行 | 単一のAssetとOR条件では、デフォルトでイベントごとにDAG実行を一つ作る。 |
| 実行の一時停止 | draining状態 | 新たな自動実行を止め、既存の実行が終わってから一時停止する。 |
表のAI実行記録は、Airflow本体とは別にリリースされるCommon AI providerに関わる機能だ。@task.llmやエージェントのツール呼び出し、人による承認はすでに提供されており、3.4ではTask Loopsと組み合わせて繰り返し処理を構成できる。providerが提供するAI Modelタブも3.4以降で利用できるため、モデルの呼び出し情報をUIで確認しやすくなった。
#Task Loopsで繰り返しを管理する
APIレスポンスに含まれる次のページのURLをたどったり、検証結果を反映して生成物を修正したりする場合、実行前に繰り返し回数を決めるのは難しい。Task Loopsを使うと、こうした処理を@task_groupにまとめ、.loop()で繰り返せる。上限回数のmax_iterationsは必須だが、until条件も指定すれば、上限に達する前でも条件が真になった時点で停止する。
生成とレビューを繰り返す処理なら、次の図のようになる。最初のレビュー結果を次の生成の入力に反映し、2回目のレビューで終了条件を満たす例だ。Airflowには反復ごとにタスクの状態とログが残るので、各段階で何が起きたのかを個別に確認できる。
ループ本体を実行してから終了条件を調べるため、処理は必ず1回以上実行される。2回目以降は、タスク内でloop.previousから前回の結果を読み、終了条件ではloop.resultで今回の結果を確認する。Airflowは、この判断で次の反復が必要になったときだけタスクインスタンスを作る。DAGの依存関係に循環を加えず、実行時に繰り返しを管理する仕組みだ。
条件で停止するループと回数だけを指定したループでは、上限に達したときの扱いも異なる。until条件を満たせなければ、最後の終了判定タスクは失敗する。回数だけを指定した場合は、その回数の実行を終えて正常に完了する。終了条件からLoopDecisionを返すと判断理由も記録でき、実行画面で継続や停止の理由を確認できる。
前回の結果を次の処理に反映する繰り返しは、リトライや動的タスクマッピングとは目的が異なる。必要な動作に応じて、次のように使い分けられる。
| 必要な動作 | 使用する機能 |
|---|---|
| 一時的に失敗したAPI呼び出しをやり直す。 | タスクのリトライ |
| すでに取得した商品リストの各項目を処理する。 | 動的タスクマッピング |
| レビュー結果を次の入力に反映して処理を続ける。 | Task Loops |
各反復は順番に進むが、一つの反復内にある独立したタスクは並列実行や動的マッピングができる。ただし、ループの入れ子、マッピングされたタスクグループ内のループ、ループ全体の動的マッピングには対応していない。たとえば、商品リストの各項目に生成とレビューのループを一つずつ割り当てる構成は、まだ作れない。
#TypeScript、Java、GoでDAG全体を書く
Airflow 3.3で導入されたJavaとGoのSDKは、Pythonで宣言したDAGの個々のタスクを別の言語で実装するためのものだった。3.4では対象がDAG全体に広がり、実行スケジュール、タスク定義、タスク間の依存関係をTypeScript、Java、Goで書けるようになった。この構成では、DAGを宣言するためのPythonファイルを別途書く必要がない。
たとえば、Javaでデータを読み込み、加工して保存するパイプラインなら、各処理の実装だけでなく、毎日いつ実行するか、どの順番でつなぐかもJavaコードで定義する。タスクグループや条件分岐もSDKで表現できる。既存のサービスとワークフローを同じ言語で管理したいチームには便利な変更だ。Airflow Beyond Pythonの発表でも、チームごとに異なる言語で書いたDAGを一つのAirflowで運用する構成が紹介されていた。
こうして書いたDAGをAirflowにつなぐ基盤がDag Importerだ。Pythonファイル以外の形式も読み込めるようにする拡張ポイントで、各言語のSDKやYAML importerがこの仕組みを使う。
デプロイ時には、各SDKで作った成果物をDAGバンドルに配置する。DAGプロセッサは成果物を実行してDAG定義を読み取り、スケジューラとUIはPythonのDAGと同様に管理する。配置するファイルと必要な実行環境は言語によって異なる。
| 言語 | DAGバンドルに配置するファイル | DAGプロセッサとワーカーに必要な環境 |
|---|---|---|
| TypeScript | 依存関係をまとめた.min.mjsファイル | Node.js 22以降 |
| Java | 依存関係を含むJARファイル | Javaランタイム |
| Go | 対象のOSとCPU向けにビルドした実行ファイル | 別途Goランタイムは不要 |
ファイルを配置した後は、言語ごとの実行を担当するコーディネータを登録し、DAGのタスクキューをそのコーディネータに関連付ける。この設定はDAGプロセッサとワーカーの両方に必要だ。記述言語が変わってもスケジュールや状態はAirflowが管理し、コードの読み込みとタスク実行に必要な環境は別途用意する構成になる。
コードの代わりに設定ファイルでDAGを宣言したい場合は、YAMLを選べる。スケジュールと依存関係をYAMLに書き、Pythonのオペレータを指定したり、コードタスクをつないだりする方式だ。YAML定義自体にビルドは不要だが、importerは別途登録する必要がある。Dag Importerと各言語のSDKは3.4.0のリリースノートで実験的機能とされているため、導入時にはAPIが変わる可能性も考慮したい。
#DAGの一覧と実行画面が変わる
DAGの記述方法が増えたのに合わせて、画面からもソースや実行の流れをたどりやすくなった。DAG一覧に加わったFoldersパネルは、バンドル内のディレクトリ構造を表示する。フォルダを選ぶと、そのパスにあるDAGだけに一覧が絞り込まれるため、DAGが多くてもフォルダをたどって探せる。

画面の出典: Apache Airflow 3.4.0公式発表。
個々のDAGを開くと、コード画面でその言語のソースを確認できる。Task Loopsには反復ごとの実行履歴とタスク履歴を見る画面が加わり、何回目の反復で失敗したのかを調べやすくなった。終了条件に判断理由を記録していれば、次の反復に進んだ理由も確認できる。
Common AI providerのLLMタスクとエージェントタスクには、AI Modelタブが用意されている。Airflow 3.4以降で使えるこのタブには、モデル名、トークン使用量、推定コストが表示される。値はXComに残っている直近の試行の使用量であり、すべてのリトライや反復のコストを合算したものではない。個々のモデル呼び出しやツール実行まで追跡したければ、providerのOpenTelemetry連携を使える。この計測機能は実験的機能だ。
進行中の処理を終えてからDAGを一時停止するdraining状態も追加された。この状態では、新たな定期実行やAssetを契機とする実行は作らず、すでにキューに入っている実行や実行中のDAGは処理を続ける。残りの実行が終わると自動的にpausedになるが、draining中もユーザーが明示的に要求した実行は許可される。
#Assetの処理とアップグレードへの影響
運用中のDAGをアップグレードするときは、まずAssetイベントの処理単位を確認したい。AssetはDAGが生成したり待ち受けたりするデータリソースを表し、その更新イベントを別のDAGの実行条件に使える。3.4では、単一のAssetやOR条件で蓄積したイベントをまとめて処理するデフォルト動作が、イベントごとにDAG実行を作る方式に変わった。一つのAssetにイベントが三つたまれば、デフォルトでは実行も三つ作られる。
従来どおりまとめて処理したい場合は、timetableまたはスケジューラの設定でbatch_asset_events=Trueを指定し、DAGを再パースする必要がある。複数のAssetをすべて待つAND条件などはバッチ処理のデフォルトを維持するため、使用中のスケジュール条件によって影響が異なる。
実行環境や保存方式にも変更があるので、アップグレード前に自分たちの構成と照合しておきたい。3.4.0のリリースノートから、主な互換性の変更を抜き出した。
| 項目 | 変更点 | アップグレード時に確認すること |
|---|---|---|
| Python | 3.10のサポート終了、3.11〜3.14に対応 | 実行環境と依存パッケージ |
| PostgreSQL | メタデータDBのデフォルトドライバをpsycopg3に変更 | 接続文字列とドライバ固有の設定 |
| コンテナ | Debian 13とDocker Hardened Imagesをベースに使用 | システムパッケージを追加したカスタムイメージ |
| タスクのクリア | 個々のタスクをclearすると、デフォルトでは状態ストアの記録も削除 | 状態を残すならkeep_task_state=Trueを指定する。自動リトライは従来どおり状態を保持する。 |
| XComバックエンド | ループの反復を区別する保存インターフェースを追加 | カスタムバックエンドのstore_value対応。common.ioのオブジェクトストレージバックエンドは1.11.0以降が必要。 |
| ダウングレード | 新しいXComはxcom_v2に保存 | 3.4より前に戻す際はデータのコピーが必要なため、復旧にかかる時間を検証する。 |
今回の更新で、準備中の商品カタログ補強の実験にも、追加で確認したい点が増えた。実験環境を3.4.0に上げて細かな動作を一つずつ確認し、発表で扱うパイプラインに影響する変更もテストするつもりだ。検証結果を次の反復に渡す部分はTask Loopsで構成し、現在の方式と実行記録がどう変わるかを比較したい。
Astronomerでも12月10日にWhat’s New in Apache Airflow 3.4のウェビナーが予定されている。実際に使って確かめた結果と、その後のウェビナーで得た内容は、別の記事にまとめるつもりだ。
#参考資料
- Apache Airflow 3.4.0公式発表、Rahul Vats、2026年11月6日。Task Loops、多言語DAG、運用画面の変更を例とともに紹介している。
- Airflow 3.4.0リリースノート。機能ごとの対応範囲と、既存の実行に影響する互換性の変更を説明している。
- Airflow Beyond Python、Jason LiuとWei Lee、2026年10月11日。3.4を前に、多言語でのDAG作成とデプロイ構成を説明した発表。
- Common AI providerの観測機能。AI Modelタブに表示する使用量と、OpenTelemetryによる追跡の範囲を説明している。
- Common IO 1.11.0の変更履歴。Task Loopsに対応するオブジェクトストレージXComバックエンドの変更を説明している。