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

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

2026.01.31

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

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

Graphとは

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

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

A Graph is a deterministic directed graph based agent orchestration system where agents, custom nodes, or other multi-agent systems (like Swarm or nested Graphs) are nodes in a graph.

決定論的なグラフベースのオーケストレーションシステムです。エージェントや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 most difference you should consider among those patterns is how the path of execution is 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

関連記事