#A1 LangGraph × ChatGPT で「調査 → 批判 → 要約」を自動化する

――Colab 完全動作スクリプトと実戦ノウハウを徹底解説

  • 公開日:2025‑04‑19
  • 想定読者
    1. ChatGPT を使い倒しているが「同じ手順を繰り返すのが面倒」な方
    2. RAG やエージェント分業を小規模でも実践したい個人開発者
    3. ブログ/YouTube/社内報告で AI リサーチ結果を量産したいクリエイター

00. 記事のゴール

  • 1 台本で 3 役(Researcher → Critic → Summarizer)の マルチエージェントパイプライン
    LangGraph で構築し、Google Colab で即実行できる形に落とし込む。
  • 実例を通して
    • ループ制御
    • エラー対策
    • Prompt エンジニアリング
      を解説し、**「品質を担保しながら自動生成」**する考え方を共有する。
  • 最後に ChatGPT 単発質問との比較や運用コスト、拡張アイデアも提案。

01. なぜ LangGraph なのか?

1‑1. “if 文地獄” からの脱却

LangChain を使っていると、複数ツール&分岐が増えるにつれ

#python
if poor_answer:
do_retry()
elif good:
summarize()

のネストが深くなる。
LangGraph はそのロジックを “グラフ” として宣言的に定義できる。

  • ノード = 関数
  • エッジ = 遷移条件
  • グラフ = ワークフロー

1‑2. 「途中結果を見たい」「ツールを差し替えたい」に強い

中間ステップごとに state を保持できるので、

  • RAG で取ってきた引用
  • LLM の中間ドラフト
    をログ保存・可視化しやすい。
    後から「ここだけ Gemini に変える」「Critic を二段構えにする」も簡単。

02. 全体アーキテクチャ


scssコピーする編集する(User Topic)


┌────────┐
│Research│ ← LLM ① 下調べ
└────────┘


┌────────┐
│ Critic │ ← LLM ② 品質判定
└────────┘
│yes no│
┌──┴───────────────────┘
│(tries≧MAX_TRIES?)│
└──┬───────────────────┘
│ │
▼ ▼
Summarize Research ← ループ


(Answer)
  • Researcher:指示されたテーマを 1 ~ 2 ページ程度で調査メモ化
  • Criticyesno の 1 語で評価。no が続くと再調査ループ
  • Summarizer:箇条書き+100 字要約でアウトプット
  • tries カウンタ:無限ループ対策、MAX_TRIES=3 で打ち止め
  • 全ノードが 同じ GPT‑4o‑mini を呼ぶが、将来はモデル別に切替可。

03. Colab で動かす完全スクリプト

依存langgraph>=0.0.27, langchain>=0.1.7, openai>=1.24
(本文末尾の requirements.txt 参照)

#python
!pip install -q langchain langgraph openai typing_extensions

from typing import TypedDict
from google.colab import userdata
from langchain.chat_models import ChatOpenAI
from langchain.prompts import ChatPromptTemplate
from langgraph.graph import StateGraph, END

### 1. LLM 準備 ###########################################################
llm = ChatOpenAI(
model="gpt-4o-mini",
temperature=0.7,
openai_api_key=userdata.get("OPENAI_API_KEY"), # Colab Secrets 推奨
)

### 2. State スキーマ ######################################################
class GraphState(TypedDict, total=False):
topic: str
draft: str
critic_verdict: str
summary: str
tries: int # ループカウンタ

### 3. ノード定義 ##########################################################
def research_node(state: GraphState) -> GraphState:
prompt = ChatPromptTemplate.from_messages([
("system", "You are a diligent researcher. Answer in Japanese."),
("human", f"「{state['topic']}」について 1~2 ページ程度で調査メモを作成してください。")
])
state["draft"] = llm.invoke(prompt.format_messages()).content
return state

def critic_node(state: GraphState) -> GraphState:
prompt = ChatPromptTemplate.from_messages([
("system", "You are a critical reviewer. Answer ONLY 'yes' or 'no'."),
("human", f"この調査メモは十分に詳しいですか?不足なら no。\n\n{state['draft']}")
])
state["critic_verdict"] = llm.invoke(prompt.format_messages()).content.strip().lower()
state["tries"] = state.get("tries", 0) + 1
return state

def summarize_node(state: GraphState) -> GraphState:
prompt = ChatPromptTemplate.from_messages([
("system", "You are a concise summarizer. Answer in Japanese."),
("human", f"以下の調査メモを (1) 箇条書き 5 点 (2) 100 字要約 にまとめてください。\n\n{state['draft']}")
])
state["summary"] = llm.invoke(prompt.format_messages()).content
return state

### 4. グラフ構築 ##########################################################
graph = StateGraph(state_schema=GraphState)

graph.add_node("research", research_node)
graph.add_node("critic", critic_node)
graph.add_node("summarize", summarize_node)

graph.set_entry_point("research")
graph.add_edge("research", "critic")

MAX_TRIES = 3
def route(edge_state: GraphState) -> str:
if edge_state["critic_verdict"].startswith("yes"):
return "summarize"
if edge_state.get("tries", 0) >= MAX_TRIES:
return "summarize"
return "research"

graph.add_conditional_edges("critic", route)
graph.add_edge("summarize", END)

assistant = graph.compile()

### 5. 実行 ###############################################################
topic = input("調査したいテーマを入力してください: ")
out = assistant.invoke({"topic": topic})
print("\n===== 要約結果 =====\n")
print(out["summary"])

04. コード解説:ポイントは 3 つだけ

4‑1. TypedDict で State を型安全に

TypedDict を使うと IDE が補完を効かせてくれ、
「キー名タイプミス → KeyError」事故が激減。

4‑2. LLM 呼び出しは invoke()

llm(prompt)langchain-core 0.1.7 で deprecate。
invoke() へ置き換えると将来の 1.0 リリースでも安心。

4‑3. ループ上限は ビジネスルール

自動化=無限ループ対策が命

  • コストを読める(MAX_TRIES×API 料金)
  • レイテンシを制御
    ビジネス要件に合わせて 2~5 回程度に設定すると良い。

05. 実行結果サンプル

テーマ:「量子コンピュータの勉強法」

===== 要約結果 =====

● 量子力学の基礎(重ね合わせ・エンタングルメント)を3週間で習得
● Python 製 SDK(Qiskit / Cirq)でハンズオンしながら計算基礎を体得
● アルゴリズム(Grover, Shor)を小規模 QPU シミュレータで実装
● NISQ 限界とエラー耐性の最新研究を arXiv ウォッチで追跡
● ビジネス応用(暗号・最適化)の国内外事例をケーススタディで整理

100 文字要約:
量子計算の基礎理論→SDK 実装→代表アルゴリズム→NISQ 課題→応用事例という 5 ステップ学習を 3 か月ロードマップで回すのが効率的。

Critic が no を返した例(1 回目)もログに残しておくと、
「何が不足と判定されたか?」が可視化でき、プロンプトの改善材料になる。


06. ChatGPT 単発質問との比較

項目本パイプライン直接 ChatGPT
品質チェックCritic が自動判定人が都度確認
再現性tries, prompt, model を固定テンション次第で揺れる
コストGPT‑4o‑mini ×(1+α) 呼び出し1 回だけで済む
拡張性ノード追加/外部 API 呼出し容易プロンプト拡張しかない

“楽をしたい瞬間” は ChatGPT、
“量産・自動化” は LangGraph――と 棲み分け するのが実践的。


07. 運用コスト試算

  • GPT‑4o‑mini(執筆時)
    • 入力 1 K tokens ≒ 0.5¢
    • 出力 1 K tokens ≒ 0.75¢
  • Research, Critic, Summarize 各 1 K tokens と仮定すると
    • 1 ループ~2.25¢
    • 3 ループ上限でも ≒ ~6.75¢
      ブログ 10 本書いても数百円=コーヒー 1 杯より安い。

08. より高度な拡張アイデア

アイデア実装ヒント
Web RAG 連携Researcher で ArxivSearchTool → ベクトル化 → コンテキスト注入
Dify / Flowise UI 化FastAPI エンドポイントに assistant.invoke() を包む
PDF / Markdown 自動生成Summarizer を DocxTool + MarkdownTool に切替
並列マルチトピックfork サブグラフで topic list を同時処理
評価ログの可視化Critic 出力 + verdict を Weights & Biases に送信

09. つまずきポイント FAQ

  1. GraphRecursionError が出た
    → MAX_TRIES を設定 or Critic プロンプトを緩める
  2. RateLimitError が出る
    sleep 挿入 or gpt-4o-minigpt-3.5-turbo に落とす
  3. OpenAI_API_KEY が None
    → Colab の左サイドバー > 🔑 Secrets に OPENAI_API_KEY を登録

10. まとめ & 次の一手

  • LangGraph は「LLM フロー型自動化」を超少コードで実現できる強力ツール
  • 3 ノード構成でも チェック付きアウトプット が得られ、
    ブログ/レポート量産に向いた再現性と品質を両立
  • 拡張余地が大きく、RAGマルチモーダルGUI への発展も容易

次回予告:このパイプラインに Neo4j を接続し、
「生成したメモを即座に知識グラフ化 → クエリで再活用」する究極ワークフローを構築します。
お楽しみに!


付録:requirements.txt

makefileコピーする編集するlangchain==0.1.7
langgraph==0.0.27
openai==1.24.0
typing_extensions>=4.10

ライセンス・引用ポリシー

  • コード部分:Apache‑2.0(OpenAI / LangChain のライセンスに準拠)
  • 記事本文:CC‑BY 4.0。引用の際は本記事へのリンクを明記してください。

[補足]Langgraphプログラムとchatgptとの比較

1. 基本コンセプトのちがい

項目 LangGraph プログラム ChatGPT に単発で質問
構造 Researcher → Critic → Summarizer の 3 エージェントをグラフで連結し、必要ならループで再調査 1 回のプロンプトに LLM が直接応答
プロセス 調査 → 批判 → 要約 の 明示的ステップ 単一ステップ(内部で推論・要約を同時実施)
出力の再現性 同じ seed/ステップ数でほぼ再現可(途中状態も保持可能) temperature 等を固定しても確率的ゆらぎが残る
拡張性 ノード増減・ツール呼び出しを自由に追加できる プロンプトを書き換える以外の拡張は難しい

2. 得られる “質” の違い

観点 LangGraph 直接 ChatGPT
網羅性 Critic が“情報不足”を検知すると自動リトライ → 抜け漏れが減る ユーザが不足に気付かなければそのまま終わる
要約粒度 100 字要約+箇条書き 5 点など フォーマット固定 指示どおり出るが、一貫性はユーザ操作に依存
客観チェック Critic ノードが「yes / no + 理由」で品質判定 追加プロンプトが必要
透明性 各段階のドラフトをログ保存すれば思考過程を追跡可 中間思考は見えない(CoT 非公開)

3. 実運用で感じるメリット・デメリット

  LangGraph パイプライン 単発 ChatGPT
メリット
  • 再利用・自動化・CI/CD との接続が簡単
  • 複数エージェントの役割分担で精度向上
  • 途中で RAG / DB 書込みなどの外部連携を挿し込み可
  • とにかく速い・安い・簡単
  • コードや設定が不要(UI から即質問)
デメリット
  • API 呼び出し回数が増え コスト↑ / レイテンシ↑
  • グラフ設計・バグ取りの手間
  • モデル更新時に各ノードの再調整が必要
  • 出力品質が一発勝負でブレやすい
  • 体系化・再現性に欠ける

4. 使い分けガイド

状況 おすすめ
ブログ用リサーチを大量に自動生成したい LangGraph でバッチ処理。Critic で品質担保しつつ 50 テーマ一気に回す
アイデア出し・ブレスト 単発 ChatGPT。思いつきをサクッと壁打ち
研究ノートや企業レポートで “証跡” が必要 LangGraph。途中ドラフトを保存→監査ログ化
デバッグ中の簡単な質問 ChatGPT。環境を切り替えず最速フィードバック

5. まとめ

LangGraph パイプライン は「ワークフローをコードに固定して、何度回しても均質な成果物を得たい」「途中工程を監視・改変したい」――そんな プロダクション用途 に最適です。

単発 ChatGPT は「とりあえず答えを聞きたい」「軽く壁打ちしたい」――といった インタラクティブ用途 に向いています。

🔑 鍵は “繰り返し同じ型で動かすか”

「1 回きり」なら ChatGPT
「10 回以上同じ流れ」なら LangGraph が効率的——これが実務現場の体感です。

最新情報をチェックしよう!