こちらの記事の続きとなります。ここでは LangGraph を構成する State・Nodes・Edges・Graph のうち、State・Nodes・Edges の3つを作りました。
この記事では、これらを組み立てて Graph を完成させ、実際にエージェントを動かします。
おさらい
前編で作成したものは以下の3つです。
-
State: メッセージの履歴を保持する状態 -
call_model/tool_node: LLMが次のアクションを判断する Agent ノードと、検索を実行する Tool ノード -
should_continue: ツールを呼ぶか終了するかを判定する条件付きエッジ
4. グラフの組み立てとコンパイル
1つのワークフロー(グラフ)に組み立てます。
from langgraph.graph import StateGraph, START
# 1. グラフの初期化(Stateを渡す)
workflow = StateGraph(State)
# 2. ノードの登録 (名前, 対応する関数)
workflow.add_node("agent", call_model)
workflow.add_node("tools", tool_node)
# 3. エントリポイント(スタート地点)の設定
workflow.add_edge(START, "agent")
# 4. 条件付きエッジの設定
# agentの処理が終わったら、should_continue関数の結果に応じて、
# "tools" に行くか END に行くかを決める(分岐先を明示的にマッピングしておく)
workflow.add_conditional_edges(
"agent",
should_continue,
{"tools": "tools", END: END},
)
# 5. tools(検索)が終わったら、必ず再度 agent に戻る
workflow.add_edge("tools", "agent")
# 6. 最後にコンパイルして実行可能なオブジェクトにする
app = workflow.compile()
上記「5」の部分でループとなります。
# 5. tools(検索)が終わったら、必ず再度 agent に戻る
workflow.add_edge("tools", "agent")
視覚的に確認してみよう
コンパイルしたグラフは、Mermaid形式の画像として出力し、正しくループ構造が作れているか確認できます。
from IPython.display import Image, display
try:
display(Image(app.get_graph().draw_mermaid_png()))
except Exception:
print(app.get_graph().draw_mermaid())
draw_mermaid_png() はGraphvizなどのローカルライブラリではなく、mermaid.inkのオンラインAPIを呼び出して画像を生成するため、インターネット接続が必要です
実際に生成される画像はこちらです。START → agent の後、agent から __end__(直接回答)と tools(検索実行)への分岐が点線で、tools → agent のループが実線で描かれているのが分かります。
5. エージェントを動かしてみる
完成したエージェントを動かしてみましょう。
ディレクトリ構成はこのようになっています。
langgraph-search-agent/
├── requirements.txt
├── .env.example
├── main.py
└── src/
├── __init__.py
├── state.py # ステップ1: State
├── nodes.py # ステップ2: Agentノード・Toolノード
├── edges.py # ステップ3: 条件付きエッジ
└── graph.py # ステップ4: グラフの組み立て・コンパイル・可視化
stream() メソッドを使うと、どのノードがどういうデータを出力したのかがリアルタイムに追えます。
ケース1:ツールが必要ない質問(雑談など)
inputs = {"messages": [("user", "こんにちは!体調はどうですか?")]}
for output in app.stream(inputs):
for key, value in output.items():
print(f"--- Node: {key} ---")
print(value["messages"][-1].content)
実際の出力:
============================================================
ケース1: 雑談
User: こんにちは!体調はどうですか?
============================================================
--- Node: agent ---
こんにちは!私はAIなので、体調はありませんが、あなたの質問にお答えする準備はできています。何かお手伝いできることがありますか?
ちゃんとagentノードのみが実行され、検索ツール(tools)を挟まずに直接 AI から挨拶が返ってきて終了しました。
ケース2:最新情報の検索が必要な質問
inputs = {"messages": [("user", "今年の最新のAI技術トレンドを教えて")]}
for output in app.stream(inputs):
for key, value in output.items():
print(f"--- Node: {key} ---")
# 思考プロセスを覗き見る
last_msg = value["messages"][-1]
if hasattr(last_msg, 'content') and last_msg.content:
print(last_msg.content)
else:
print(f"[{key}が実行されました(詳細省略)]")
実際の出力(一部抜粋):
============================================================
ケース2: 検索が必要な質問
User: 今年の最新のAI技術トレンドを教えて
============================================================
--- Node: agent ---
[agent が実行されました(詳細省略)]
--- Node: tools ---
{"query": "latest AI technology trends 2026", "follow_up_questions":...
--- Node: agent ---
2026年の最新のAI技術トレンドについて、以下の2つのリソースからの情報をまとめました。
1. **Capgeminiの「Top Tech Trends 2026」**:
- **AIの真実の年**: AIは実験段階を超え、信頼性と企業全体での採用に焦点を当てるようになります。
- **AIがソフトウェアを食べる**: 従来のコーディングから意図駆動型開発や自律的なメンテナンスへと移行し、ソフトウェアライフサイクルを再定義します。
- **Cloud 3.0**: ハイブリッド、マルチクラウド、主権アーキテクチャの多様なエコシステムがAIのスケーラビリティとレジリエンスを支えます。
- **インテリジェントオペレーションの台頭**: AIエージェントによって駆動される適応型エンジンとして企業システムが進化します。
- **テクノロジー主権の国境を越えた逆説**: 組織がレジリエントな相互依存を構築するための戦略的優先事項として浮上します。
詳細は[こちら](https://www.capgemini.com/insights/research-library/top-tech-trends-of-2026)から。
...
期待通り、以下の流れで動作しました。
-
START → agentが動き、LLMが「検索ツールを呼ぶ」と判断 -
should_continueを通り、toolsノードへ遷移。Web検索が実行される -
tools → agentへ戻り、LLM が検索結果を踏まえて最終回答を生成 -
ENDへ
ストリーミングの出力を見ることで、AIが「自分で判断してツールを使い、その結果を読んでから答えている」という自律的な動き(エージェント性)を視覚的に実感できます。
4. まとめ
条件付きループが、StateGraph を使うことで見通しの良いコードで実装できることが体験できました。
さらにできること
このエージェントをさらに実用的にするためには、以下のような機能拡張が待っています。
- Checkpointer(永続性): 会話の履歴をデータベースに保存し、チャットボットのように過去の文脈を記憶させる
- Human-in-the-loop: ツールを実行する前に「本当に実行していいですか」と人間に承認を求めるステップを挟む
`
