Back

LangGraph vs CrewAI vs AutoGen:2026年版マルチエージェントAI完全ガイド

2025年は単体のAIエージェントを作っていましたね。2026年は、複数のエージェントを同時に動かす時代になりました。

なんでもかんでも一人でやろうとして破綻する万能エージェントの代わりに、今は役割ごとに専門エージェントを分けてチームのように協力させるのがトレンドです。でも問題が一つ。フレームワークが3つもあるんですよね—LangGraphCrewAIAutoGen。それぞれ思想が全然違うので、選び方を間違えると後で作り直すハメになるかもしれません。

この記事では、各フレームワークの違いと使いどころをしっかり整理していきます。コードも一緒に見ていきましょう。


なぜ単体エージェントじゃダメなのか

フレームワークの話の前に、そもそもなぜマルチエージェントが必要なのか確認しておきましょう。

万能エージェントの限界

カスタマーサポート用のAIを作るとして、このエージェントがやるべきことは:

  1. お客さんが何を求めているか把握
  2. 関連情報をDBから検索
  3. 顧客のアカウント情報を確認
  4. 適切な返答を生成
  5. 必要に応じて人間にエスカレ

これを一つのエージェントで全部やろうとすると:

# いわゆる「神エージェント」アンチパターン class CustomerServiceAgent: def handle_request(self, message: str) -> str: intent = self.classify_intent(message) context = self.search_knowledge_base(intent) account_info = self.get_account_info() response = self.generate_response(context, account_info) if self.should_escalate(response): return self.escalate_to_human() return response

何が問題かというと:

  • トークンすぐ溢れる:あれこれプロンプトに詰め込むとコンテキストウィンドウ即死
  • LLMが混乱する:分類したり返答作ったり忙しすぎ
  • 遅い:並列でできることも直列で回す羽目に
  • デバッグ地獄:エラー出たら2000行のプロンプトを漁ることに

マルチエージェントで解決

役割ごとにエージェントを分けるとこうなります:

┌─────────────────────────────────────────────────────────────┐
│                    オーケストレーター                         │
│               (リクエストを適切なエージェントに振り分け)        │
└─────────────────┬──────────────────────────────┬───────────┘
                  │                              │
    ┌─────────────▼─────────────┐  ┌─────────────▼─────────────┐
    │   分類エージェント          │  │   検索エージェント          │
    │  (意図把握専門)           │  │  (RAG専門)               │
    └─────────────┬─────────────┘  └─────────────┬─────────────┘
                  │                              │
    ┌─────────────▼─────────────┐  ┌─────────────▼─────────────┐
    │   アカウントエージェント     │  │   返答エージェント          │
    │  (CRM照会専門)           │  │  (文章作成専門)           │
    └───────────────────────────┘  └───────────────────────────┘

こうするメリット:

  • 各エージェントが自分の仕事だけやるからプロンプトがシンプル
  • 独立したエージェントは同時に動かせる
  • 一つがコケても全体は死なない
  • テストもエージェント単位でできる

さて、各フレームワークがこれをどう実現しているか見ていきましょう。


LangGraph:グラフでフローを設計する

LangGraphはLangChainチームが作りました。核となるコンセプトはエージェントシステムをグラフで表現すること。ノードが関数で、エッジがフローです。全部可視化できるので「今何やってるんだっけ?」がすぐわかります。

基本的な考え方

  • ノード = 関数(エージェントでもツールでもただのロジックでも)
  • エッジ = 次に何するか
  • ステート = ノード間でやり取りするデータ

コード見れば一発で理解できると思います:

from typing import Annotated, TypedDict from langgraph.graph import StateGraph, START, END from langgraph.graph.message import add_messages from langchain_openai import ChatOpenAI # エージェント間で共有するステート定義 class AgentState(TypedDict): messages: Annotated[list, add_messages] current_intent: str knowledge_context: str account_info: dict should_escalate: bool # 各エージェントを関数で定義 def classify_intent(state: AgentState) -> AgentState: """意図分類エージェント""" llm = ChatOpenAI(model="gpt-4o") response = llm.invoke([ {"role": "system", "content": "ユーザーの意図をbilling, technical, general, complaintのどれかに分類して"}, {"role": "user", "content": state["messages"][-1].content} ]) return {"current_intent": response.content.strip().lower()} def retrieve_knowledge(state: AgentState) -> AgentState: """ナレッジ検索エージェント""" intent = state["current_intent"] # 本番ではベクトルDBクエリ knowledge_map = { "billing": "請求ポリシー:30日以内なら返金可能...", "technical": "技術問題:まず再起動してみてください...", "general": "会社概要:SaaSプラットフォームです...", "complaint": "クレーム対応:真摯に対応します..." } return {"knowledge_context": knowledge_map.get(intent, "")} def lookup_account(state: AgentState) -> AgentState: """アカウント照会エージェント""" # 本番ではCRM APIコール return { "account_info": { "tier": "premium", "tenure_months": 24, "open_tickets": 2 } } def generate_response(state: AgentState) -> AgentState: """返答生成エージェント""" llm = ChatOpenAI(model="gpt-4o") prompt = f"""以下の情報をもとに丁寧に返答して: 意図:{state['current_intent']} 参考情報:{state['knowledge_context']} 顧客ランク:{state['account_info']} お客様のメッセージ:{state['messages'][-1].content}""" response = llm.invoke([{"role": "user", "content": prompt}]) return {"messages": [response]} def check_escalation(state: AgentState) -> AgentState: """オペレーター接続が必要かチェック""" should_escalate = ( state["current_intent"] == "complaint" and state["account_info"].get("tier") == "premium" ) return {"should_escalate": should_escalate} def route_after_check(state: AgentState) -> str: if state["should_escalate"]: return "escalate" return "respond" def escalate_to_human(state: AgentState) -> AgentState: return { "messages": [ {"role": "assistant", "content": "専門スタッフにおつなぎします。"} ] } # グラフ組み立て def build_graph(): workflow = StateGraph(AgentState) workflow.add_node("classify", classify_intent) workflow.add_node("retrieve", retrieve_knowledge) workflow.add_node("lookup", lookup_account) workflow.add_node("check_escalation", check_escalation) workflow.add_node("respond", generate_response) workflow.add_node("escalate", escalate_to_human) workflow.add_edge(START, "classify") workflow.add_edge("classify", "retrieve") workflow.add_edge("retrieve", "lookup") workflow.add_edge("lookup", "check_escalation") workflow.add_conditional_edges( "check_escalation", route_after_check, {"respond": "respond", "escalate": "escalate"} ) workflow.add_edge("respond", END) workflow.add_edge("escalate", END) return workflow.compile() # 実行 graph = build_graph() result = graph.invoke({ "messages": [{"role": "user", "content": "請求書がおかしいです!"}], "current_intent": "", "knowledge_context": "", "account_info": {}, "should_escalate": False })

LangGraphのいいところ

1. 可視化できる

from IPython.display import Image, display display(Image(graph.get_graph().draw_mermaid_png()))

グラフを図として出力できます。複雑なフローも一目瞭然。

2. 途中で止めて再開できる

from langgraph.checkpoint.memory import MemorySaver memory = MemorySaver() graph = build_graph().compile(checkpointer=memory) config = {"configurable": {"thread_id": "user-123"}} result = graph.invoke({"messages": [...]}, config) # 後で同じ会話を続ける result = graph.invoke({"messages": [new_message]}, config)

3. 人間の承認を入れるのも簡単

from langgraph.types import interrupt def human_approval_node(state: AgentState) -> AgentState: if state["requires_approval"]: approval = interrupt("5万円以上の返金なのでマネージャー承認待ち") return {"approved": approval} return state

LangGraphを使うべき場面

おすすめ:

  • フローを細かくコントロールしたい
  • 監査ログやコンプライアンスが重要
  • 複雑な分岐がたくさんある
  • セッション維持が必要
  • すでにLangChain使ってる

向いてない:

  • とにかく早くプロトタイプ作りたい(学習コストあり)
  • シンプルなフローなのにわざわざ?

CrewAI:チームみたいに役割分担

CrewAIは発想が違います。グラフとかないです。代わりにチームメンバーに役割を与えて仕事させる感じ。実際のチーム運営みたいに。

基本的な考え方

  • Agent = メンバー(役割、ゴール、性格まで設定可能)
  • Task = やること
  • Crew = チーム

コードを見るとすぐ雰囲気わかると思います:

from crewai import Agent, Task, Crew, Process from crewai_tools import SerperDevTool # メンバー定義 classifier_agent = Agent( role="カスタマー意図アナリスト", goal="お客さんが何を求めているか正確に把握して分類する", backstory="""カスタマーサポート歴が長くて、 請求の問題なのか技術の問題なのかクレームなのか すぐ見分けられるプロ。""", verbose=True, allow_delegation=False ) researcher_agent = Agent( role="情報検索スペシャリスト", goal="問題解決に必要な情報を見つけてくる", backstory="""会社のポリシーや手順を熟知していて、 どんな質問にも関連情報を正確に探し出せる。""", tools=[SerperDevTool()], verbose=True ) response_agent = Agent( role="カスタマー対応エキスパート", goal="お客さんが満足する返答を作成", backstory="""怒ってるお客さんも落ち着かせる達人。 プロフェッショナルだけど温かみのある対応で お客さんに大切にされてると感じてもらう。""", verbose=True ) # タスク定義 classification_task = Task( description="""お客さんのメッセージを分析して: メッセージ:{customer_message} billing, technical, general, complaintのどれかに分類して 緊急度(low/medium/high)も教えて。""", expected_output="意図の分類と緊急度", agent=classifier_agent ) research_task = Task( description="""分類結果を見て関連情報を探して: {classification} 解決に必要なポリシーや手順をまとめて。""", expected_output="関連ポリシー情報と解決策", agent=researcher_agent, context=[classification_task] ) response_task = Task( description="""調査結果をもとに返答を作成: 元のメッセージ:{customer_message} 分類:{classification} 調査結果:{research} 丁寧でプロフェッショナルな返答をお願い。""", expected_output="お客さんに送る返答", agent=response_agent, context=[classification_task, research_task] ) # チーム編成 customer_service_crew = Crew( agents=[classifier_agent, researcher_agent, response_agent], tasks=[classification_task, research_task, response_task], process=Process.sequential, verbose=True ) # 実行 result = customer_service_crew.kickoff( inputs={"customer_message": "請求書がおかしいです!"} ) print(result)

CrewAIのいいところ

1. マネージャーエージェントも作れる

crew = Crew( agents=[classifier_agent, researcher_agent, response_agent], tasks=[...], process=Process.hierarchical, manager_llm=ChatOpenAI(model="gpt-4o"), verbose=True )

マネージャーが自動で誰に何をやらせるか判断してくれます。

2. メモリ機能

crew = Crew( agents=[...], tasks=[...], memory=True, embedder={ "provider": "openai", "config": {"model": "text-embedding-3-small"} } )

過去の会話を覚えて、どんどん賢くなります。

3. ツールが充実

from crewai_tools import ( SerperDevTool, # Web検索 ScrapeWebsiteTool, # クローリング FileReadTool, # ファイル読み込み CodeInterpreterTool # コード実行 )

CrewAIを使うべき場面

おすすめ:

  • 素早くプロトタイプ作りたい
  • 役割ベースで考えるのが楽
  • 非エンジニアにも理解してもらう必要がある
  • メモリ/学習機能が欲しい

向いてない:

  • フローを細かく制御したい
  • 毎回100%同じ結果が欲しい
  • 厳密な監査ログが必要

AutoGen:チャットで問題を解く

Microsoftが作ったAutoGenはアプローチがまた違います。エージェントたちが会話しながら問題を解いていくんです。Slackで複数人が議論するような感じ。

基本的な考え方

  • エージェント同士がメッセージをやり取り
  • 終了条件になるまで会話が続く
  • 人間も参加者の一人として入れる
from autogen import AssistantAgent, UserProxyAgent, GroupChat, GroupChatManager import os config_list = [{"model": "gpt-4o", "api_key": os.environ["OPENAI_API_KEY"]}] llm_config = {"config_list": config_list} # エージェント作成 classifier = AssistantAgent( name="Classifier", system_message="""意図分類担当だよ。 メッセージ見てbilling/technical/general/complaintのどれか、 緊急度はどうか簡潔に教えて。""", llm_config=llm_config ) researcher = AssistantAgent( name="Researcher", system_message="""情報調査担当だよ。 意図がわかったら関連ポリシーや解決策を探してまとめて。""", llm_config=llm_config ) responder = AssistantAgent( name="Responder", system_message="""返答作成担当だよ。 調査内容をもとに丁寧に返答を書いて。 完了したら'TERMINATE'で終わらせて。""", llm_config=llm_config ) human_proxy = UserProxyAgent( name="Customer", human_input_mode="NEVER", max_consecutive_auto_reply=0, code_execution_config=False ) # グループチャット設定 group_chat = GroupChat( agents=[human_proxy, classifier, researcher, responder], messages=[], max_round=10, speaker_selection_method="round_robin" ) manager = GroupChatManager(groupchat=group_chat, llm_config=llm_config) # 会話開始 human_proxy.initiate_chat(manager, message="請求書がおかしいです!")

AutoGenのいいところ

1. コード書いて実行もできる

coder = AssistantAgent( name="Coder", system_message="Pythonエキスパートだよ。コードで問題解決して。", llm_config=llm_config ) executor = UserProxyAgent( name="Executor", human_input_mode="NEVER", code_execution_config={ "work_dir": "workspace", "use_docker": True } ) executor.initiate_chat(coder, message="複利計算の関数作って")

コード書いて、実行して、結果見て修正して...開発自動化にぴったり!

2. ディベートさせるのに向いてる

optimist = AssistantAgent(name="Optimist", system_message="いい面を探して...") critic = AssistantAgent(name="Critic", system_message="問題点を探して...") synthesizer = AssistantAgent(name="Synthesizer", system_message="意見をまとめて...") group_chat = GroupChat(agents=[optimist, critic, synthesizer], ...)

AutoGenを使うべき場面

おすすめ:

  • コード書いて実行する必要がある
  • 繰り返しブラッシュアップが必要
  • 議論を通じて答えを出したい
  • 開発自動化ツールを作る

向いてない:

  • 毎回同じ動作が必要
  • トークン代が心配(会話が長くなりがち)
  • フローをきっちり制御したい

3行まとめ比較

基準LangGraphCrewAIAutoGen
一言でグラフで設計チームで役割分担チャットで協力
学習コストちょっとある低い普通
トークン効率良い普通多め
デバッグ可視化◎ログでちょい難
本番運用すぐいける成長中研究寄り

いつ何を使う?

シーンおすすめ
カスタマーサポートbotLangGraph(フロー制御+監査ログ)
コンテンツ制作パイプラインCrewAI(役割分担が直感的)
コード生成・実行AutoGen(コード実行特化)
リサーチ自動化LangGraph(複雑な分岐処理)
素早くMVPCrewAI(覚えやすい)

実践Tips

落とし穴1:エージェント作りすぎない

3つで済むのに20個作ったら管理地獄です。

# ❌ やめて # ✅ 2-3個でスタート simple_crew = Crew( agents=[classifier, responder], tasks=[classification_task, response_task] )

落とし穴2:無限ループ注意

エージェント同士でずっと投げ合うと永遠に終わらない。

# 終了条件を必ず入れる graph.invoke(state, config={"recursion_limit": 25}) group_chat = GroupChat(max_round=10, ...)

落とし穴3:コンテキスト爆発

会話全体を渡し続けるとトークン死。途中で要約しましょう。

def summarize_context(state): summary_llm = ChatOpenAI(model="gpt-4o-mini") summary = summary_llm.invoke([ {"role": "user", "content": f"100字で要約して:{state['context']}"} ]) return {"context": summary.content}

まとめ:何を選ぶ?

LangGraph = フロー制御が大事で、本番レベルが必要なとき

CrewAI = 素早く作りたくて、役割ベースが楽なとき

AutoGen = コード実行が必要、または議論型の問題解決が必要なとき

どれを選んでも原則は同じ:

  • 2-3個でスタートして必要に応じて増やす
  • エージェントごとに役割を明確に
  • エラー処理は必須
  • モニタリングも必須

エージェントは準備OK、フレームワークも成熟してます。さあ、作り始めましょう!

AILangGraphCrewAIAutoGenMulti-AgentLLMPythonAI Engineering