Active Context Tasks
Active Context Tasks フレームワークの設計ドキュメント
概要
ActiveContext::Task は、ActiveContext システム内で長時間実行される非同期処理を管理するためのフレームワークです。複数の順次ステップや依存ステップを伴う可能性がある複雑なワークフローを定義、実行、追跡するための構造化された方法を提供します。
これは、埋め込みモデルの切り替え、埋め込みフィールドの作成とバックフィル、メタデータ同期のように、慎重なオーケストレーションとエラー処理を必要とする処理を扱うよう設計されています。
コンポーネント
Task ベースクラス(ActiveContext::Task[1.0])
すべてのタスク実装のための抽象基底クラスであり、すべてのサブクラスが従う必要があるインターフェースを定義します。
具象クラスの実装は、タスクの実際のロジックを定義します。
バッチタスク:
タスクは batched! としてマークでき、これによりバッチ単位で作業を実行し、完了までに複数回の実行が必要になる可能性があることを示します。バッチタスクでは、すべての作業が完了したタイミングを判断するために completed? を実装する必要があります。
Task クラス実装の例
Ai::ActiveContext::Tasks::BackfillEmbeddings: 新しい埋め込みモデルを使用して、既存ドキュメントの埋め込みを生成します。Ai::ActiveContext::Tasks::SyncFeatureSettings: 機能設定を埋め込みモデル設定と同期します。
Task モデル(Ai::ActiveContext::Task)
タスク情報を永続化する ActiveRecord モデルです。
データベーススキーマ:
connection_id- ベクターストア接続への外部キーdepends_on_id- 先行タスクへの外部キー(タスクチェーン用)name- タスククラス名status- 現在の実行ステータス(pending、in_progress、completed、failed)params- タスクに渡される JSON パラメータretries_left- 残りのリトライ試行回数(デフォルト: 3)started_at- 実行が開始された時刻completed_at- 実行が完了した時刻error_message- タスクが失敗した場合のエラー詳細
Task Dictionary(ActiveContext::Task::Dictionary)
定義済みタスククラスのレジストリです。これはグローバルアクセス用のシングルトンインスタンスを提供します。
# Find a task class by name
task_class = ActiveContext::Task::Dictionary.instance.find_by_name('Ai::ActiveContext::Tasks::BackfillEmbeddings')
# Or use the shorthand
task_class = ActiveContext::Task::Dictionary.find_by_name('Ai::ActiveContext::Tasks::BackfillEmbeddings')
# Returns an array of task class objects that have been loaded
ActiveContext::Task::Dictionary.instance.tasks
Task Service(Ai::ActiveContext::TaskService)
タスクチェーンを作成し、管理します。
create_task(task_class, params: {}, depends_on: nil)- 単一のタスクを作成するcreate_chain(*tasks_with_params)- 依存関係を持つ一連のタスクを作成する
使用例:
service = Ai::ActiveContext::TaskService.new
service.create_chain(
[Ai::ActiveContext::Tasks::AddEmbeddingsField, { collection: 'code', field: 'embeddings_v2', dimensions: 768 }],
[Ai::ActiveContext::Tasks::BackfillEmbeddings, { collection: 'code', field: 'embeddings_v2' }],
[Ai::ActiveContext::Tasks::UpdateCollectionMetadata, { collection: 'code', metadata: {...} }]
)
Task Worker(Ai::ActiveContext::TaskWorker)
作成されたタスクの実行を担う Sidekiq Worker です。
実行フロー:
- Worker が次に処理可能なタスクレコードを見つける
- タスクレコードの
nameから正しいタスクオブジェクトをインスタンス化する - タスクレコードを
in_progressとしてマークする - タスクオブジェクトの
execute!を呼び出す - 成功時: タスクレコードを
completedとしてマークする - 失敗時: 下記の「エラー処理」の詳細を参照
- タスクがバッチタスクで、まだ完了していない場合: Worker を再エンキューする
- 処理可能なタスクが残っていない場合: Worker は終了する
エラー処理:
- タスク実行中の例外を捕捉する
- 失敗した実行ごとにリトライ回数が減り、次のようになります。
- タスクはリトライが 1 つ少ない状態で
in_progressのままになり、cron Worker が次回実行時に取得する - リトライが残っていない場合、タスクは
failedとしてマークされ、依存タスクへカスケードする
- タスクはリトライが 1 つ少ない状態で
再エンキューのロジック:
- 完了していないバッチタスクでは、Worker が処理を継続するために自身を再エンキューする
- バッチではないタスクが成功した後、Worker は終了し、cron スケジュールされた呼び出しが次のタスクを取得する
タスクチェーン
タスクは depends_on リレーションを通じて他のタスクに依存できます。タスクが処理可能になるのは、次の場合だけです。
- ステータスが
pendingまたはin_progressであり、かつ - 依存関係がない、または依存先のステータスが
completedである
これにより、タスク実行の有向非巡回グラフ(DAG)が作成されます。
タスク実行フローの概要
- タスク作成 - サービスが
TaskServiceを使用して 1 つ以上のタスクを作成する - 依存関係の解決 - タスクは
depends_onリレーションを通じて連結される - 処理可能なタスクの選択 -
Ai::ActiveContext::Task.processableスコープが実行可能なタスクを見つける - Worker のポーリング -
TaskWorkerがAi::ActiveContext::Task.currentを通じて次に処理可能なタスクを見つける - 実行 -
TaskWorkerがタスクのexecute!メソッドを呼び出す - ステータス遷移 - タスクのステータスが pending →
in_progress→completed/failedに移行する - 依存タスクの実行 - タスクが完了すると、その依存タスクが処理可能になる
- Worker の再エンキュー - バッチタスクでは Worker が自身を再エンキューし、それ以外の場合は cron スケジュールされた呼び出しが次のタスクを取得する
- エラー処理 - 失敗したタスクはすべての依存タスクへ失敗をカスケードする
今後予定している機能強化
- タスクの優先順位付け - 優先度の高いタスクを他より先に実行できるようにする
- 並列実行 - 独立したタスクを並行して実行する
- タスクのキャンセル - pending または進行中のタスクをキャンセルできるようにする
- 条件付きタスク - 条件または以前の結果に基づいてタスクを実行する
最終更新 July 30, 2026: Merge pull request #483 from kyama0/translation/batch-2026-07-29-1 (
c955a93f)