【AIエージェントの解剖学:第7回】意思決定の地図を描く:State & Graph Routingの制御技術
【新連載:AIエージェントの解剖学】
※本連載は、何も話せない空っぽの「チャットボット」の前に立ち、彼に命を吹き込みながら、自分の意志で動く「AIエージェント」へとパーツごとに作り上げていく開発ドキュメンタリーです。
1. プロローグ:次のパーツ「複雑な経路を導く意思決定の地図」
前回、私たちはロボットのシステムに「Memory & RAG(長期・短期メモリ)」の記憶装置を取り付けました。
これにより、彼は過去の対話や行動の歴史を永遠に蓄積し、必要に応じて思い出して行動に生かすことができるようになりました。
しかし、今の彼はまだ一本道のレールの上を歩いているに過ぎません。
「Aを実行し、次にBを実行し、最後にCで回答する」という直線の処理(シーケンス)しかできないため、ステップBでエラーが起きた瞬間に立ち往生し、処理がクラッシュしてしまいます。
現実の実務では、「エラーが起きたら一歩戻ってやり直す」「もし情報が足りなければユーザーに質問するノードへ迂回する」といった柔軟な進路変更が必要です。
今回は、ロボットが現在の状況に応じて進むべき経路を自分で判断し、時に循環(ループ)し、時に分岐(ルーティング)するための脳内マップ、「State & Graph Routing(状態とグラフによる制御)」のコンソールチップを装着します。
知能の行動経路を、直線から「網の目(グラフ)」へと解放しましょう。
2. 直線的パイプラインが抱える限界
初期のシンプルなAIシステムは、以下のような直線の連鎖で設計されていました。
ユーザー入力 ➡ 検索実行 ➡ 回答生成
しかし、エージェントが「プログラムのデバッグ」のような複雑なタスクを行う場合、直線的な設計ではコードが破綻します。
「コードを生成し(A)、テストを実行し(B)、エラーが出たらコードを修正する(C)」というタスクを直線で書こうとすると、何回エラーが出るか事前にわからないため、ループのネストが深くなり、スパゲッティコード(解読不能なコード)と化してしまいます。
実務を安定してこなすエージェントには、「状態(State)を維持したまま、処理ステップ間を自由に行ったり来たりできる循環構造」が不可欠なのです。
3. グラフアーキテクチャの3大要素:Node, Edge, State
LangGraphなどの最先端エージェントフレームワークが採用しているのが、この「グラフアーキテクチャ(Graph Architecture)」です。

※図:ノード(実行ステップ)と条件分岐付きエッジが、グローバルな状態(State)を介して循環・遷移するグラフ構造(AI生成ダイアグラム)
-
状態(State):
すべての処理ステップで共有されるグローバルな情報ボード(共有メモリ)。現在の「コードの中身」「エラー文」「進捗フラグ」などの変数はすべてここに記録され、更新されていきます。 -
ノード(Node):
個別の具体的な処理を行うステップ(関数)。Stateを入力として受け取り、処理を行って、更新したStateを返します。 -
エッジ(Edge):
ノードとノードを繋ぐ経路の矢印。特に「条件付きエッジ(Conditional Edge)」は、現在のStateの値(例: 「errorが存在するか?」)を判断し、次に進むノードを動的に切り替えるルーティングの役割を果たします。
4. 【体験】30行の簡易グラフ状態遷移マシンを動かそう
外部の複雑なライブラリを使わずに、グローバルな「状態(State)」を更新しながら、エラー発生時に自動で「前の処理ノードへ逆戻り(ループ)」するグラフ型意思決定プロセスを再現したPythonコードです。
手元の環境で実行してみてください。
import time
# 1. 共有されるグローバルな状態(State)
agent_state = {
"code": "print('Hello')",
"test_passed": False,
"error_message": "",
"retry_count": 0
}
# 2. 各処理ステップ(Node)の定義
def node_execute_test(state: dict) -> dict:
print(f"🤖 Node: テストを実行します... [現在のコード: {state['code']}]")
time.sleep(1)
# 最初の1回目はエラーを模擬発生させ、2回目で成功させる
if state["retry_count"] == 0:
state["test_passed"] = False
state["error_message"] = "SyntaxError: invalid syntax"
state["retry_count"] += 1
else:
state["test_passed"] = True
state["error_message"] = ""
return state
def node_fix_code(state: dict) -> dict:
print(f"🤖 Node: エラーを検知したため、コードを修正します... [Error: {state['error_message']}]")
time.sleep(1)
state["code"] = "print('Hello World!')" # 修正コード
return state
# 3. グラフの条件付き分岐(Conditional Edge)のシミュレート
def run_agent_graph(state: dict):
# 初期ノード: テスト実行
state = node_execute_test(state)
# 条件判定ループ
while not state["test_passed"]:
if state["retry_count"] > 3:
print("\n🚨 限界到達: リトライ回数を超えたため強制終了します。")
return
# 条件付きエッジ: エラーがあるため「コード修正ノード」へルーティング
state = node_fix_code(state)
# 循環ループ: 修正後、再び「テスト実行ノード」へ戻る
state = node_execute_test(state)
print(f"\n✅ 成功: すべてのテストに合格しました! [最終コード: {state['code']}]")
# 実行
run_agent_graph(agent_state)
このコードを実行すると、プログラムが上から下へ流れるだけでなく、状態(agent_state)の書き換わりに応じて Execute ➡ Fix ➡ Execute とノード間を自律的にループし、問題解決へ進む流れがコンソールで確認できます。
5. エピローグ:迷路を征服したロボット

※画像:ロボットの目の前に広がる3Dホログラムの意思決定マップから、状況に合わせて次の最適なルートをタッチ選択するイメージ(AI生成画像)
これで、ロボットに「State & Graph Routing」の意思決定マップが組み込まれ、どんな複雑な条件分岐やバグの再処理も、状態を保ったまま循環・分岐して解き進む「自律制御」が実装されました。
しかし、1つの巨大な脳(LLM)に対して、すべてのタスク(プランニング、コーディング、テスト、修正)を1つの巨大なグラフマップ上で処理させようとすると、脳への負荷(コンテキストの混濁やプロンプトの競合)が高まり、精度が急激に低下し始めます。
高度なビジネスシステムを組む場合、1人の天才にすべてを任せるのには限界があります。
次回、第8回。
この知能の負荷を分散させ、複数の特化型エージェント(プランナー、コーダー、レビュアー)が互いにチャットを交わしてプロジェクトを完了させる組織設計、「Multi-Agent Collaboration(マルチエージェント協調)の設計」のチームモジュールを彼に装着します。
知能の形態が、個人の闘いから「チーム(社会)」へと進化する瞬間へと進みましょう。