Strands AgentsのGraphで有向グラフベースのエージェント制御を試してみた

Strands AgentsのGraphで有向グラフベースのエージェント制御を試してみた

2026.01.31

こんにちは。サービス開発室の武田です。

前回の記事ではAgents as Toolsパターンについて紹介しました。今回は Graph パターンを試してみます。

Graphとは

Graphは、開発者が定義した有向グラフにしたがってエージェントを実行するパターン です。条件関数によるルーティングと、ループ(サイクル)に対応しています。

公式ドキュメントでは次のように説明されています。

The Directed Graph Multi-Agent Pattern provides a deterministic graph-based agent orchestration system where agents or MultiAgentBase instances (like Swarm or Graph) are nodes in a graph, executed according to edge dependencies, with output from one node passed as input to connected nodes.

決定論的なグラフベースのオーケストレーションシステムです。エージェントやMultiAgentBaseインスタンス(SwarmやGraph)がグラフのノードとなります。エッジの依存関係にしたがって実行され、あるノードの出力が接続されたノードへの入力として渡されます。

なぜこのパターンを使うのか

公式ドキュメントでは、Graphの主要な特徴として次の点が挙げられています。

特徴 説明
Deterministic execution order グラフ構造に基づいた予測可能な実行順序
Output propagation ノード間でのデータフロー管理
Conditional edges 条件関数によるダイナミックなルーティング
Cyclic graph support フィードバックループと反復的なワークフロー

「決定論的な実行順序」「出力伝播」「条件付きエッジ」「循環グラフ対応」という特徴があります。フローを明示的に制御したいときに適したパターンですね。

基本的なしくみ

このパターンの構造を図で示すとこうなります。
strands-agents-graph-directed-agent-control_1.png

ノードはエージェントやカスタムロジック、他のマルチエージェントシステム(SwarmやGraph)を表し、エッジはノード間の依存関係と情報フローを表します。エッジには条件関数を設定でき、条件に応じて異なるパスをたどることもできます。

GraphBuilderの役割

Strands Agentsでは、GraphBuilderを使ってグラフを構築します。主要なメソッドは次のとおりです。

メソッド 説明
add_node(agent, node_id) グラフにノードを追加
add_edge(from_node, to_node, condition=None) ノード間にエッジを追加(条件関数はオプション)
set_entry_point(node_id) グラフの開始ノードを設定
set_max_node_executions(n) ノードの最大実行回数を設定(無限ループ防止)
set_execution_timeout(seconds) 実行タイムアウトを設定
build() グラフをビルド

実装例1: シーケンシャル(直列実行)

まずはもっともシンプルな例から見ていきましょう。ノードが順番に実行される基本的なグラフです。

ユースケース

「アイデア発想 → 評価 → 実行計画」という3段階のプロセスを実装します。

グラフノードの定義

https://github.com/TAKEDA-Takashi/study-for-strands-agents/blob/main/02-graph/01_sequential_graph.py#L18-L40

3つのエージェントを作成しています。idea_generatorがアイデアを3つ提案し、idea_evaluatorがもっとも実現可能性の高いものを選び、action_plannerが具体的なアクションプランを作成します。

グラフの構築

https://github.com/TAKEDA-Takashi/study-for-strands-agents/blob/main/02-graph/01_sequential_graph.py#L43-L58

add_nodeでノードを追加し、add_edgeでノード間の依存関係を定義します。set_entry_pointで開始ノードを指定し、build()でグラフを構築して文字列を渡して実行します。

各ノードの結果が次のノードへ自動的に渡されるため、シンプルなコードで連鎖処理を実現できます。

実装例2: 条件分岐

次に、条件に応じて異なるパスをたどる例を見てみましょう。

ユースケース

質問を分類し、技術的な質問なら技術専門家へ、ビジネスの質問ならビジネス専門家へルーティングします。

strands-agents-graph-directed-agent-control_2.png

分類エージェントと専門家エージェント

https://github.com/TAKEDA-Takashi/study-for-strands-agents/blob/main/02-graph/02_conditional_graph.py#L17-L52

classifierが質問を「技術」か「ビジネス」に分類し、それぞれの専門家が回答します。最後にsummarizerが回答をまとめます。

条件関数の定義

https://github.com/TAKEDA-Takashi/study-for-strands-agents/blob/main/02-graph/02_conditional_graph.py#L55-L70

条件関数はGraphStateを引数に取ります。state.resultsで前のノードの結果にアクセスできます。ここでは分類結果に「技術」または「ビジネス」が含まれているかで判定しています。

条件付きエッジの追加

https://github.com/TAKEDA-Takashi/study-for-strands-agents/blob/main/02-graph/02_conditional_graph.py#L72-L93

add_edgeconditionパラメーターに条件関数を渡すことで、条件付きエッジを定義できます。複数のエッジに条件を設定し、条件に合致するパスのみが実行されます。

GraphStateの活用

GraphStateは、グラフ実行中の状態を管理するオブジェクトです。state.resultsで各ノードの実行結果を保持する辞書にアクセスでき、state.results.get("node_id").resultで特定ノードの出力を取得できます。

条件関数ではこれを使って、前のノードの結果に基づいたルーティングを実現します。

実装例3: ループ(サイクル)

最後に、Graphパターンの大きな特徴である ループ(サイクル) の例を紹介します。これはDAGであるWorkflowパターンでは実現できない機能です。

ユースケース

コードレビューで問題があれば修正し、再レビューするサイクルを実装します。

strands-agents-graph-directed-agent-control_3.png

コード生成エージェントとレビューエージェント

https://github.com/TAKEDA-Takashi/study-for-strands-agents/blob/main/02-graph/03_loop_graph.py#L19-L53

coderがコードを生成し、reviewerがレビューします。レビュー結果が「要修正」の場合は修正指示を出し、問題なければ「承認」します。

ループ条件関数

https://github.com/TAKEDA-Takashi/study-for-strands-agents/blob/main/02-graph/03_loop_graph.py#L56-L71

needs_revisionは「要修正」を含む場合にTrue、is_approvedは「承認」を含む場合にTrueを返します。

ループエッジの設定

https://github.com/TAKEDA-Takashi/study-for-strands-agents/blob/main/02-graph/03_loop_graph.py#L74-L94

add_edge("review", "code", condition=needs_revision)で、要修正の場合にcoderへループバックします。add_edge("review", "approve", condition=is_approved)で、承認の場合は最終承認へ進みます。

set_max_node_executions(3)は重要な安全機構です。ループが意図せず続いてしまうことを防いでくれます。

このパターンが向いているケース

条件分岐やループを含むワークフローが必要な場合、フローを明示的に制御して予測可能な動作を求める場合に向いています。コードレビュー→修正→再レビューのような反復処理や、質問分類→専門家ルーティングのような条件分岐がいい例ですね。

逆に、固定フローを再利用可能なツールとして定義したいならWorkflowが適しています。文脈に応じて柔軟にエージェントを切り替えたいならSwarm、単純な専門家への委譲だけならAgents as Toolsの方がいいでしょう。

Workflowとの比較

GraphとWorkflowはどちらも有向グラフでフローを定義しますが、用途が異なります。

観点 Graph Workflow
グラフ構造 有向グラフ(サイクル可) DAG(非循環)のみ
ループ ×
並列実行 ○(独立ブランチ) ○(DAG最適化)
ルーティング 条件関数 依存関係のみ
用途 フロー制御重視 タスク管理・再利用重視

公式ドキュメントでは、Workflowは「再利用可能なツールとしてカプセル化すべき、繰り返し可能で複雑な操作」に適していると説明されています。一方、Graphはループや条件分岐を含む動的なフロー制御に向いています。

Swarmとの比較

GraphとSwarmはどちらも複数のエージェントが協調するパターンですが、ルーティングの決定方法が根本的に異なります。

観点 Graph Swarm
ルーティング決定 条件関数(コード) LLM判断
予測可能性 高い 低い
柔軟性 低い 高い
デバッグ 容易 困難

公式ドキュメントでは、この違いを次のように説明しています。

The critical distinction is how execution paths are determined

「実行パスがどう決定されるか」が重要な違いです。Graphでは開発者がコードで条件を定義し、予測可能なルーティングを実現します。一方、Swarmではエージェント(LLM)が文脈を理解してルーティングを判断します。

どちらを選ぶか

条件が明確に定義できる場合はGraphが向いています。たとえばif "技術" in responseのように判定できるなら技術専門家へルーティングできます。

一方、文脈に応じた判断が必要ならSwarmの方がいいでしょう。「これは表面上は技術の質問だが、実は請求の問題だ」とLLMが理解して適切なエージェントへ振り分けるような場合です。

予測可能な動作とデバッグのしやすさを重視するならGraph、柔軟な対応を重視するならSwarmが適しています。

まとめ

Graphは、Strands Agentsで フローを明示的に制御する ためのパターンです。GraphBuilderで有向グラフを定義し、条件関数でルーティングを制御します。

グラフ構造に基づいた予測可能な流れで実行され、add_edgeconditionパラメーターで動的ルーティングができます。ループにも対応しているのがWorkflowとの大きな違いですね。set_max_node_executionsで無限ループを防止できるため安心です。

公式ドキュメントでは「決定論的有向グラフベースのエージェント編成」と説明されています。フローを明示的に制御し、予測可能な動作を求める場合に適したパターンです。

参考リンク

この記事をシェアする

FacebookHatena blogX

関連記事