タスクとセッション
ワークフローの各タスクがなぜ新しいエージェントセッションで実行されるのか、そしてそれがタスクの分割、結果の受け渡し、アクセスレベルの設定にどう関わるのか。
ワークフローのタスクは、どれも新しい Claude Code または Codex のセッションが担当します。セッションが長くなるほど、コンテキストには目の前の作業と関係のない情報が増え、エージェントの判断が当てにならなくなるからです。新しいセッションが知っているのは、タスクのプロンプトと、自分でワークスペースから読んだファイルだけです。上流のタスクでの会話や推論は引き継がれず、引き継がれるのはリポジトリ内のファイルだけです。そのため、タスクは 1 つのセッションで確実にやり遂げられる大きさまで分割し、プロンプトは事情を何も知らないセッションでも単独でやり遂げられるように書き、下流に渡したい結論はファイルに書いておく必要があります。
タスク
タスクを分割する理由と、分割の目安
普段 Claude Code や Codex と対話しているとき、エージェントの判断が最も正確なのは、セッションが始まった直後です。この時点のコンテキストには、依頼した内容しか入っていません。会話が長くなると、読んだファイル、試して捨てた案、とうに古くなった途中の結論がコンテキストに残り続けます。目の前の作業と関係のない情報が溜まるほど、エージェントは制約を見落としたり、前後で矛盾したことをしたりしやすくなります。コンテキストを圧縮すれば空きは作れますが、重要な制約まで抜け落ちるおそれがあります。そのため、モデルがどれほど優秀でも、目標がある程度以上に大きくなれば、1 つのセッションでうまくやり遂げることは期待できません。いくつかのタスクに分割し、どのタスクも 1 つのセッションで確実にやり遂げられるようにする必要があります。
どこまで分割すればよいかには、実用的な目安があります。あるタスクをエージェントに任せて 1 つのセッションでやり遂げさせたとき、人が一切手を加えなくても満足できる結果が返ってくると、十分に確信できるかどうかです。確信できるなら、それ以上分割する必要はありません。確信できないなら、さらに小さく分割します。この確信が、自分の許容できる水準を下回るところが、分割の境界になります。
この境界は、モデルの進歩とともに上がっていきます。それでも、境界をはるかに超える大きさの目標はいつでも立てられるので、タスクの分割が要らなくなることはありません。
分割したタスクをどう組み立てるか
分割したタスクを組み立てる方法としてよくあるのは、メインエージェントが作業を進めながら、サブエージェントに仕事を割り振っていくやり方です。この場合、サブエージェントのコンテキストはそれぞれまっさらですが、メインセッションはすべての報告を受け取り、計画全体も覚えておかなければなりません。タスクが増えれば、メインセッション自身のコンテキストも同じように膨らんでいきます。また、サブエージェントをいくつ起動し、何をどれに任せるかも、その場で決まります。計画はメインセッションの中にしかないため、あとから見ても何が計画されていたのかがわかりにくく、同じ内容をそのままもう一度実行することもできません。
CodeDAG のやり方は、これとは異なります。分割したタスクとその間の依存関係をあらかじめワークフローに書いておき、実行時には CodeDAG が依存関係に従って、タスクごとにまっさらなセッションを起動します。
CodeDAG におけるタスクとは
CodeDAG におけるタスクとは、ワークフローの中のひとまとまりの作業です。タスクには明確な目標とエージェントへの指示があり、ほかのタスクに依存することもできます。ワークフローファイルでは、tasks リストの 1 項目として書きます。title は人が読むための名前、prompt はエージェントへの指示で、dependencies には完了を待つ上流のタスクを並べます。実行の順番が来ると、CodeDAG はそのタスクのために新しい Claude Code または Codex のセッションを起動します。prompt は、このセッションが最初に受け取るメッセージになります。
目標をタスクに分割する方法とプロンプトの書き方は、タスクの分割とプロンプトの書き方を参照してください。
依存関係
CodeDAG における依存関係とは
ビルドシステムやデータパイプラインのように、依存関係に従って処理を実行するシステムでは、依存関係はたいていデータフロー(dataflow)を表します。上流が結果を出力し、下流がそれを入力として受け取るという関係です。CodeDAG のタスクには、このように下流へ個別に渡す出力がありません。タスクがするのはリポジトリを変更することであり、そのため依存関係の意味も異なります。
CodeDAG における依存関係は、下流が上流のリポジトリの状態を引き継ぐことを表します。上流の結果が承認されると、下流は上流が変更し終えたコードを出発点にして、その上に変更を重ねていきます。Git で、あるコミットが親コミットの後に続くのと同じです。デフォルトの分離ブランチモードでは、CodeDAG は下流を起動する前に、承認済みの上流の結果を下流のタスクブランチにマージします。このとき、間接的に依存している上流の結果も一緒に入ってきます。
上流が複数ある場合、下流が引き継ぐのは、それぞれ別々に変更された複数のリポジトリの状態です。これらはまず 1 つにマージしなければならず、コンフリクトがあれば先に解決する必要があります。データフローでは、複数の入力は並んでいるだけのデータなので、この手順はありません。マージとコンフリクトの扱いは、合流ノードでのマージとコンフリクトを参照してください。
つまり、分離ブランチモードでは、ブランチのマージのトポロジーは、依存関係のトポロジーとほぼ同じになります。主な違いは、ブランチのマージではさらに、リーフノード、つまり下流のないタスクが、最後に 1 本の統合ブランチにマージされる点です。
逆に、依存関係のない 2 つのタスクは、それぞれ別のブランチにあります。一方がとうに完了していても、もう一方からその変更は見えません。そのため、別のタスクの結果を使うには、依存関係を宣言しなければなりません。
下流に渡せるもの
タスクはどれも独立したセッションなので、下流に渡せるのはリポジトリ内のファイルだけです。つまり、上流が変更したコードと、書き残したドキュメントです。上流のセッションでの会話、推論の過程、書き残さなかった結論は、どれも下流には渡りません。そのため、上流は結論をファイルに書き、下流のプロンプトではそのファイルを名指しして読ませる必要があります。このファイルパスが、2 つのタスクの間のインターフェースになります。方法は結論を下流に渡すを参照してください。
タスクエージェントから見える範囲と権限
タスクエージェントは、リポジトリのワークスペースで起動される、ごく普通の Claude Code または Codex のセッションです。
タスクエージェントに見えるもの
タスクエージェントから見える範囲は、prompt と、自分で読んだファイルだけです。CodeDAG がタスクエージェントに渡すのは prompt だけです。ワークフローに書かれた title や description、ほかのタスクの内容は送られず、ユーザーとオーケストレーションエージェントとの会話がコンテキストに持ち込まれることもありません。
ファイルは、主にタスクエージェントがいるワークスペースのものです。デフォルトの分離ブランチモードでは、ワークスペースにはそのタスクのタスクブランチがチェックアウトされています。内容は、ワークフローのベースとなるコミットに、承認済みの上流の結果を加えたものです。共有ワークスペースモードでは、すべてのタスクが同じワークスペースでそのまま実行されるため、見えるのは、その時点でそのディレクトリにある内容です。
そのため、プロンプトは、事情を何も知らない新しいセッションでも単独でやり遂げられるように書く必要があります。プロンプトで名指しして読ませる資料は、ワークフローの開始前にコミットしてあるか、上流のタスクが作成するかのどちらかでなければなりません。
タスクエージェントにできること
タスクエージェントの権限は、タスクの mode で決まります。mode は、そのエージェント自身の権限設定にそのまま対応します。mode を書かない場合、CodeDAG が代わりに決めることはなく、エージェントは自身の設定に従って動作します。
ファイルの変更やコマンドの実行の前に同意を求める権限モードでは、エージェントはセッションの中で止まって人の応答を待ち、タスクもそこで止まります。このときは、タスクのネイティブセッションに入って許可する必要があります。タスクを無人実行で最後まで走らせたい場合は、操作のたびに確認を求めないモードを指定し、そのアクセスレベルに伴うリスクを受け入れることになります。2 つのエージェントでそれぞれ指定できる値と、無人実行と有人実行のトレードオフは、エージェント、モデル、権限モードを選ぶを参照してください。
タスクはサブエージェントではない
タスクはサブエージェントではありません。タスクの完了を待っているメインセッションはなく、タスクが結果を誰かに返すこともありません。
サブエージェントはメインセッションから起動され、作業を終えると結果をメインセッションに報告します。次に何をするかを決めるのは、メインセッションです。タスクには、このようなメインセッションがありません。ユーザーに代わってワークフローを書き、投入するオーケストレーションエージェントも、タスクのメインセッションではありません。タスクは CodeDAG が依存関係に従って起動し、完了した結果はリポジトリにだけ残ります。下流のタスクは、その結果をリポジトリから読み取ります。
一方で、タスクエージェントは、自分のセッションの中で普段と同じようにサブエージェントを起動できます。これはタスクをやり遂げるための手段であり、タスクの内部のことです。起動したサブエージェントがすべて終わるまで、そのタスクは完了とは見なされません。
最終更新