LangChainとLangGraphは、同じLangChain社が出している2つのライブラリです(Python版とJavaScript/TypeScript版があり、本記事は主にPython版で説明します)。違いを一言でいえば、LangGraphはエージェントを動かす実行基盤(ランタイム)で、LangChainはその上に載る高レベルのフレームワークです。2024年ごろの解説には「LangGraphはLangChainの上に乗る拡張」と書かれていますが、2025年10月のv1.0で上下関係は逆になりました。本記事では2026年10月21日時点の最新版(langchain 1.4.6/langgraph 1.2.16)を実際にインストールし、依存関係とエージェントの中身を確かめた結果をもとに、両者の違い、使い分け、旧コードからの移行で詰まる点を整理します。
まとめ:LangChainとLangGraphの違いと選び方
- 関係:LangGraphがランタイム、LangChainがその上のフレームワーク。
create_agentの戻り値はLangGraphのCompiledStateGraphそのもの。 - 依存の向き:langchainはlanggraphに依存し、langgraphはlangchain本体に依存しない(LangChain側で必要なのは
langchain-coreだけ)。 - 選び方:まず
create_agentで作り、独自の分岐・検証工程・長時間の中断と再開が要る部分だけLangGraphで書く。 - 周辺製品:Deep AgentsはLangChainの上に載る「ハーネス」、LangSmithはトレース・評価・デプロイの基盤で、どちらも別の層を担う。
| 比較軸 | LangChain | LangGraph |
|---|---|---|
| 公式の分類 | エージェントフレームワーク | エージェントランタイム |
| 中心のAPI | create_agent・ミドルウェア |
StateGraph・Node・Edge |
| 制御フロー | モデル⇄ツールのループを内蔵 | 分岐・ループを自分で定義 |
| 永続化・承認待ち | checkpointer引数・承認はHITLミドルウェア |
checkpointer・interruptを直接使う |
| 依存 | langgraphに依存 | langchain本体には依存しない |
| 最新版(2026-10-21) | 1.4.6(10月14日UTC) | 1.2.16(10月16日UTC) |
LangChainとLangGraphの関係:v1.0で逆転した上下関係
2024年までの説明:LangGraphはLangChainの拡張
LangGraphが登場した2024年1月、公式ブログ(2024年1月17日)はLangGraphを「LangChainの上に構築されたモジュール」と紹介し、LCEL(LangChain Expression Language)で組んだ処理にサイクルを足すものとして説明していました。比較記事に「LangGraphはLangChainの上」と書かれていたら、v1.0以前の説明として読み替えてください。
v1.0以降:LangGraphがランタイム、LangChainがその上のフレームワーク
LangChain 1.0とLangGraph 1.0は2025年10月に公開されました。PyPIへの1.0.0の登録は両方とも10月17日(UTC)、公式の変更履歴が記すリリース日と、創業者Harrison Chaseがブログで「langchain 1.0, released today」と書いた日がともに10月20日、v1.0到達の告知記事は10月22日付です。告知記事には「LangChain agents are built on LangGraph, so you’re not locked in」とあり、LangChainの高レベルAPIから始めて、必要になったらLangGraphに降りる構成として説明されています。
現在の公式ドキュメントは、両者を役割で分けています。Runtimes, frameworks, and harnessesのページでは、LangChainを「エージェントフレームワーク」、LangGraphを「エージェントランタイム」に分類し、「LangChain 1.0 is built on top of LangGraph」と明記しています。一方でLangGraphの概要ページは「you don’t need to use LangChain to use LangGraph」と書いています。上に載るのはLangChainで、LangGraphは単独でも成り立つ、という非対称な関係です。
v1.0ではlangchainパッケージの中身も絞り込まれました。旧来のチェーン実装・Retriever・indexing API・hubモジュールはlangchain-classicへ移り、langchain名前空間はエージェントの構築に必要な部品だけになっています。v1.0で入れ替わったAPIの全体像はLangChain v1.0とは|create_agent・ミドルウェア・langchain-classicを実装例で解説で扱っています。
PyPIの宣言とインストール実測で見る依存の向き
依存の向きは、パッケージのメタデータを見るのが確実です。PyPI上の最新版が宣言している必須依存は次のとおりです(2026年10月21日取得)。
| パッケージ | 版 | 宣言している主な依存 |
|---|---|---|
| langchain | 1.4.6 | langgraph >=1.2.12,<1.3.0/langchain-core |
| langgraph | 1.2.16 | langchain-core/langgraph-checkpoint/langgraph-prebuilt |
| langchain-core | 1.6.12 | langsmith/pydantic など |
Python 3.12の空の仮想環境(uv venv)にuv pip install langgraphだけを実行すると、入るパッケージは38個で、langchain本体は含まれません(importlib.util.find_spec("langchain")はNone)。そこへlangchainを足しても増えるのはlangchainの1個だけで、LangGraph一式は既に揃っています。LangChainを使えば必ずLangGraphが入り、LangGraphを使ってもLangChainは入らない。この結果が、v1.0以降の上下関係をそのまま表しています。なお、langgraphは2024年1月の初版0.0.8からlangchain-coreにだけ依存しており、langchain本体に依存したことはありません。v1.0で変わったのは、langchainがlanggraphに依存するようになった点です。
LangChain・LangGraph・Deep Agents・LangSmithの位置関係
LangChain社はLangChain・LangGraphのほかにDeep AgentsとLangSmithも出しており、名前の近い製品の役割を取り違えやすくなっています。公式ドキュメントの分類に、観測基盤のLangSmithを加えて並べると次のようになります。
| 製品 | 層 | 足すもの | 向く場面 |
|---|---|---|---|
| LangGraph | ランタイム | 永続実行・ストリーミング・HITL | 細かい制御・長時間の処理 |
| LangChain | フレームワーク | モデル抽象・ツール・ミドルウェア | 早く作る・チームで書き方を揃える |
| Deep Agents | ハーネス | ファイル操作・サブエージェント・文脈圧縮 | 複雑で手順が読めないタスク |
| LangSmith | 観測・評価・デプロイ | トレース・評価・ホスティング | 本番運用と品質管理 |
Deep Agentsは、ファイルシステム、サブエージェントへの委譲、会話履歴の要約と大きな結果の退避を最初から持つSDKです(計画用のToDoリストはv0.7から任意で足す機能になりました)。公式ドキュメントは「Deep Agents are built on LangChain agents」と説明しており、PyPIのdeepagents 0.7.29もlangchain>=1.4.6を必須依存に宣言しています。LangChainのさらに上に載る層です。ハーネスという考え方自体はAIハーネスとは?LLMエージェントの制御基盤を構成する6部品とSDK別の実装で整理しています。
LangSmithは、LangChainやLangGraphで作ったエージェントの実行をトレースし、評価するための基盤です。LangChain/LangGraphのどちらを選んでも併用でき、OSSライブラリの代わりにはなりません。トレースの送り方と料金はLangSmithとは?トレース送信の設定・評価の実行・料金とリージョンの選び方で扱っています。LangGraphで作ったエージェントのホスティングは、2025年10月にLangGraph PlatformからLangSmith Deploymentへ改称されています。デプロイ手順はLangGraph Platform(旧 LangGraph Cloud)とは?デプロイ手順・Studio・料金を実践解説【2026年版】で扱っています。
処理構造の違い:エージェントループとState・Node・Edge
LangChain:create_agentがツール呼び出しのループを持つ
v1.0以前のLangChainの中心はチェーン、つまりプロンプト・モデル・出力パーサーを一方向につなぐ部品でした。v1.0以降の中心はcreate_agentです。モデルとツールを渡すと、「モデルを呼ぶ→ツール呼び出しが返ればツールを実行→結果を持ってモデルに戻る→最終回答で終わる」というループが組み上がります。挙動を変えたいときはグラフを書き換えるのではなく、ミドルウェアを差し込みます。なお、prompt | model | parserのように|でつなぐLCELの書き方はlangchain-coreに残っており、1回の呼び出しで終わる要約や分類には今も使えます。
LangGraph:State・Node・Edgeで分岐とループを定義する
LangGraphは処理をグラフとして定義します。構成要素は次の4つです。
| 要素 | 役割 |
|---|---|
| State | 全Nodeが共有する状態(各Nodeは差分を返す) |
| Node | 処理単位(モデル呼び出し・ツール実行・任意の関数) |
| Edge | 次のNodeへの経路(条件付きEdgeで分岐・ループ) |
| StateGraph | グラフ本体(compile()で実行可能になる) |
差が出るのは条件付きEdgeです。「ツール呼び出しが返ったらツールNodeへ、最終回答なら終了へ」「検証に3回落ちたら人の確認へ」といった判定を、グラフの経路として書けます。checkpointerを付ければStateがステップごとに保存されるので、サーバーを再起動しても途中から再開でき、人の承認待ちで何時間も止めておけます。ツール呼び出しの仕組みはLangGraphのTool Callingとは|仕組みとToolNodeでの実装・create_agentとの使い分けで詳しく扱っています。
同じエージェントの実装比較:create_agentとStateGraph
create_agentによる社内文書検索エージェント
社内文書を検索して答えるエージェントを、まずcreate_agentで書きます。ループはこの関数の中に組み込まれています。
from langchain.agents import create_agent
from langchain.tools import tool
@tool
def search_docs(query: str) -> str:
"""社内文書を検索して該当箇所を返す"""
docs = retriever.invoke(query) # retriever は別途用意したRetriever
return "\n\n".join(d.page_content for d in docs)
# 実行には langchain-openai も必要(pip install -U langchain langchain-openai)
# モデルIDは「プロバイダ名:モデル名」。利用するプロバイダの現行モデルに合わせる
agent = create_agent(
model="openai:gpt-6.1-sol",
tools=[search_docs],
system_prompt="あなたは社内文書を検索して回答するアシスタントです。",
)
result = agent.invoke({"messages": [{"role": "user", "content": "有給休暇の付与日は?"}]})
create_agentの戻り値はLangGraphのグラフ
このエージェントの正体を確かめるため、APIキーの要らない擬似モデル(langchain_coreのGenericFakeChatModelを継承し、ツール呼び出しと最終回答を順に返すもの)で同じcreate_agentを実行しました。戻り値の型とグラフの構造を出力した結果が次です(Mermaid出力はEdgeの行だけを抜粋)。
type: langgraph.graph.state CompiledStateGraph
nodes: ['__start__', 'model', 'tools', '__end__']
graph TD;
__start__ --> model;
model -.-> __end__;
model -.-> tools;
tools -.-> model;
create_agentが返すのはLangGraphのCompiledStateGraphで、modelとtoolsの2つのNodeが条件付きEdge(点線)で行き来するグラフになっています。invokeすると、HumanMessage → ツール呼び出しを含むAIMessage → ToolMessage → 最終回答のAIMessageの順にメッセージが積まれました。LangChainのエージェントは、LangGraphで組んだReActループの完成品です。
ミドルウェアを足すとどうなるかも確かめました。@before_modelで関数log_turnを登録すると、ノード一覧は['__start__', 'model', 'tools', 'log_turn.before_model', '__end__']に変わり、ミドルウェアがグラフのNodeとして差し込まれます。実行中は、モデルを呼ぶ前に毎回このNodeが通り、1回目はメッセージ1件、ツール実行後の2回目は3件の状態を受け取りました。ミドルウェアは「グラフを書かずにNodeを足す仕組み」と捉えると、LangGraphへ降りる境目が見えやすくなります。
StateGraphによる同じループの書き下ろし
同じループをLangGraphで直接書くと次のようになります。
from langchain.chat_models import init_chat_model
from langgraph.graph import StateGraph, START, END, MessagesState
from langgraph.prebuilt import ToolNode
from langgraph.checkpoint.memory import InMemorySaver
model = init_chat_model("openai:gpt-6.1-sol").bind_tools([search_docs])
tool_node = ToolNode([search_docs]) # search_docs は前のコード例で定義したツール
def call_model(state: MessagesState):
return {"messages": [model.invoke(state["messages"])]}
def should_continue(state: MessagesState):
last = state["messages"][-1]
return "tools" if getattr(last, "tool_calls", None) else END
builder = StateGraph(MessagesState)
builder.add_node("model", call_model)
builder.add_node("tools", tool_node)
builder.add_edge(START, "model")
builder.add_conditional_edges("model", should_continue)
builder.add_edge("tools", "model")
graph = builder.compile(checkpointer=InMemorySaver())
graph.invoke(
{"messages": [{"role": "user", "content": "有給休暇の付与日は?"}]},
{"configurable": {"thread_id": "user-42"}},
)
add_conditional_edgesで分岐を書き、toolsからmodelへEdgeを戻すとループが閉じます。モデルの初期化にlangchainのinit_chat_modelを使っていますが、LangGraph単体で使うならOpenAI SDKなどを直接呼ぶ関数をNodeにしても構いません。create_agentで足りる処理をこの形で書き直す必要はありません。ツール実行の前に独自の検証Nodeを挟む、失敗したら別の経路へ逃がす、といった制御が要るときにこちらへ降ります。状態管理から承認フローまでの一通りの実装はLangGraphでAIエージェントを実装する手順:状態管理から承認フローまでで追っています。
使い分けの判断基準:create_agentで足りる要件とLangGraphに降りる要件
LangChain(create_agent)で足りる要件
処理が「モデルを呼び、必要ならツールを呼んで答える」の繰り返しに収まるなら、create_agentで完結します。社内文書のQ&A、数個のAPIを呼ぶアシスタント、要約・分類のような単発処理が該当します。呼び出し回数の上限、モデルのフォールバック、個人情報のマスキング、会話履歴の要約、人の承認待ちといった定番の制御は、組み込みミドルウェアで足せます(後述)。ここでStateGraphを手書きすると、NodeとEdgeの保守が増えるだけです。検索と回答生成だけが主題なら、索引と検索に守備範囲を絞ったLlamaIndexとは?RAG構築の仕組み・LangChainとの違いと採用判断を実装者向けに解説も比較対象になります。
LangGraphに降りるべき要件
次のどれかに当てはまる部分は、グラフを自分で組む価値があります。
- 決まった手順(取得→検証→整形)とモデル任せの判断を、1つの処理の中で混ぜたい
- 複数のエージェントに役割を分け、Stateを共有しながら協調させたい(Agentic RAGとは?従来RAGとの違い・設計パターンとLangGraph実装の落とし穴で扱う多段検索もこの形)
- 途中で人の確認を挟み、数時間後に同じ地点から再開したい
- 失敗したNodeだけをリトライし、規定回数を超えたら別の経路へ逃がしたい
人の確認で止めて再開する動きは、LangGraph単体の環境で次のように確かめました。下書きを2回書き直したら承認Nodeでinterruptを呼ぶグラフです。
from typing import TypedDict
from langgraph.graph import StateGraph, START, END
from langgraph.checkpoint.memory import InMemorySaver
from langgraph.types import interrupt, Command
class S(TypedDict):
draft: str
retries: int
approved: bool
def write(s):
return {"draft": f"下書きv{s['retries'] + 1}", "retries": s["retries"] + 1}
def check(s):
return "approve" if s["retries"] >= 2 else "write"
def approve(s):
ok = interrupt({"draft": s["draft"], "question": "公開してよいですか"})
return {"approved": ok}
b = StateGraph(S)
b.add_node("write", write)
b.add_node("approve", approve)
b.add_edge(START, "write")
b.add_conditional_edges("write", check, ["write", "approve"])
b.add_edge("approve", END)
g = b.compile(checkpointer=InMemorySaver())
cfg = {"configurable": {"thread_id": "t1"}}
print(g.invoke({"draft": "", "retries": 0, "approved": False}, cfg))
print(g.get_state(cfg).next) # ('approve',)
print(g.invoke(Command(resume=True), cfg))
1回目のinvokeは'__interrupt__'キーに承認待ちの内容を入れて戻り、get_state(cfg).nextは('approve',)でした。Command(resume=True)で再開すると{'draft': '下書きv2', 'retries': 2, 'approved': True}が返り、保存されたチェックポイントは5件でした。InMemorySaverはプロセスが終わると消えるため、本番ではPostgreSQLなどの永続checkpointerに替えます。承認フローの設計そのものはヒューマンインザループ(HITL)とは?意味・HOTLとの違い・承認の実装と導入で解説しています。
LangGraph・Deep Agentsを採用すべきでない場面
「将来マルチエージェントにするかもしれないから、最初からLangGraphで書く」という設計は勧めません。前の章で見たとおりcreate_agentの中身はLangGraphのグラフなので、後から降りても実行基盤は変わらず、先回りして得られるものがありません。State設計と分岐が初期から増え、プロンプトやツールを直す速度が落ちるだけです。逆に、LangChainの高レベルAPIだけで頑張りすぎるのも失敗の形です。ミドルウェアのフックの中で状態を持ち回し、分岐をif文で積み上げ始めたら、それはグラフで書くべき処理です。
Deep Agentsも同じで、計画とサブエージェントが要らない定型処理に使うと、組み込みのプロンプトとツールが毎回のトークン消費を押し上げます。手順が事前に読めない調査・コーディング系のタスクに限って選ぶのが妥当です。フレームワークをLangChain系以外まで広げて比べたい場合はAIエージェントフレームワークとは?主要8種の比較・動作コード・選定基準【2026年9月版】を参照してください。LangChain/LangGraphでの業務エージェントの設計から実装までを外部に任せたい場合は、AIエージェント開発の支援サービスで相談を受け付けています。
旧コードからの移行とv1.x以降の変更点
create_react_agentの非推奨警告
2024〜2025年前半の記事に多いfrom langgraph.prebuilt import create_react_agentは、langgraph 1.2.16でも動きますが、呼び出すと次の警告が出ます(実測。読みやすさのため改行を入れています)。
LangGraphDeprecatedSinceV10: create_react_agent has been moved to `langchain.agents`.
Please update your import to `from langchain.agents import create_agent`.
Deprecated in LangGraph V1.0 to be removed in V2.0.
非推奨なのはcreate_react_agentだけで、langgraph.prebuiltモジュール自体は残っています。ToolNodeやtools_conditionは引き続きlanggraph.prebuiltから使えます。移行先のcreate_agentは引数も変わっています。langgraph 1.2.16とlangchain 1.4.6のシグネチャを比べると、promptはsystem_promptに、pre_model_hook/post_model_hookはmiddlewareに置き換わっています。置換は公式の移行ガイドと突き合わせて行ってください。
AgentExecutorとチェーンはlangchain-classicへ
v0系のAgentExecutor、RetrievalQAなどのチェーン、langchain.hubは、v1.0でlangchain-classicパッケージへ移りました。pip install langchain-classicを足し、importをfrom langchain_classic.chains import ...のように書き換えれば当面は動きます(langchain-classicの最新は1.0.8、2026年6月10日UTC)。ただし新機能が入るのはcreate_agent側だけです。動いているAgentExecutorを急いで書き直す必要はありませんが、手を入れる機会があればcreate_agentへ移し、その先で必要になった部分だけLangGraphに降りる順序なら無駄がありません。
ミドルウェアの6フックと組み込み15種
create_agentの挙動を変える入口はミドルウェアです。AgentMiddlewareが持つフックはbefore_agent・before_model・wrap_model_call・wrap_tool_call・after_model・after_agentの6つで、それぞれ非同期版もあります。langchain 1.4.6のlangchain.agents.middlewareが公開している組み込みは、名前がMiddlewareで終わる次の15種と、ツールの応答をモデルで模擬するテスト用のLLMToolEmulatorでした(実測)。公式の組み込みミドルウェア一覧にはサブエージェントやルーブリック評価なども含めて19項目が載っており、このモジュールに無いものもあります。
| 用途 | 組み込みミドルウェア |
|---|---|
| 人の承認 | HumanInTheLoopMiddleware |
| 文脈の圧縮 | SummarizationMiddleware/ContextEditingMiddleware |
| 回数の上限 | ModelCallLimitMiddleware/ToolCallLimitMiddleware |
| 失敗時の処理 | ModelRetryMiddleware/ModelFallbackMiddleware |
| ツールの失敗 | ToolRetryMiddleware/ToolErrorMiddleware |
| ツールの選択 | LLMToolSelectorMiddleware/ProviderToolSearchMiddleware |
| 個人情報 | PIIMiddleware |
| 計画 | TodoListMiddleware |
| 実行環境 | ShellToolMiddleware/FilesystemFileSearchMiddleware |
この一覧に必要な制御が揃っているなら、LangGraphへ降りる前にミドルウェアで済ませられます。
LangGraph 1.2で増えたNode単位のtimeoutとerror_handler
LangGraph側でも、Node単位で失敗を扱う機能が増えています。langgraph 1.2.16のStateGraph.add_nodeは、retry_policy・cache_policy・error_handler・timeoutを引数に取ります(シグネチャを実測)。error_handlerとtimeoutはLangGraph 1.2(PyPI公開は2026年5月12日UTC)で入った機能です。外部APIを呼ぶNodeに3回までのリトライと、失敗時の逃げ道を付けると次のようになります。
from typing import TypedDict
from langgraph.graph import StateGraph, START, END
from langgraph.errors import NodeError
from langgraph.types import Command, RetryPolicy
class S(TypedDict):
status: str
def call_api(s):
raise ValueError("外部APIが500")
def on_error(state: S, error: NodeError) -> Command:
return Command(update={"status": f"{error.node}で失敗: {error.error}"}, goto=END)
b = StateGraph(S)
b.add_node("call_api", call_api,
retry_policy=RetryPolicy(max_attempts=3, retry_on=ValueError),
error_handler=on_error)
b.add_edge(START, "call_api")
b.add_edge("call_api", END)
print(b.compile().invoke({"status": ""}))
実行するとcall_apiは3回呼ばれ、3回とも失敗したあとon_errorに制御が移り、{'status': 'call_apiで失敗: 外部APIが500'}が返りました。グラフには__error_handler__call_apiというNodeが自動で足されます。timeoutには注意が要ります。同期関数のNodeにtimeout=0.5を付けると、add_nodeは通りますが、compile()の時点で「Node timeouts are only supported for async nodes」というValueErrorになりました。非同期関数のNodeでは0.5秒でNodeTimeoutErrorが送出されます。外部APIの待ち時間で打ち切りたいNodeはasync defで書いてください。
よくある質問
LangGraphを使うならLangChainは不要ですか?
不要です。LangGraphの必須依存にlangchain本体は含まれず、LangChain系で入るのはlangchain-coreだけです。OpenAI SDKなどを直接呼ぶ関数をNodeにしても動きます。ただしinit_chat_modelやツール定義で各社モデルの差を吸収できるため、両方を入れる構成が一般的です。
LangGraphはLangChainを置き換えるものですか?
置き換えません。LangChainのエージェントはLangGraph上で動いており、両者は同じ処理系の上の層と下の層です。高レベルのAPIで書けるところはLangChain、細かい制御が要るところはLangGraph、と1つのアプリの中で併用するのが公式の想定です。
AgentExecutorで書いた既存コードはLangGraphへ移行すべきですか?
移行先はまずLangChainのcreate_agentです。langchain-classicを入れれば当面は動くので、手を入れるときに置き換え、ミドルウェアで足りない部分だけLangGraphで書きます。
LangChainとLangGraphはどちらから学ぶべきですか?
LangChainのcreate_agentからです。モデル・ツール・メッセージの扱いを先に覚えると、LangGraphのState・Node・Edgeが何を抽象化しているのかが分かりやすくなります。LangGraphの公式ドキュメントも、LangGraphに入る前にLangChainのモデルとツールの章を読むよう勧めています。
TypeScript/JavaScriptでも同じ構成ですか?
同じ構成です。npmの最新版(2026年10月21日取得)では、langchain 1.5.18が@langchain/langgraph ^1.4.18に依存し、@langchain/langgraph 1.5.1は@langchain/coreをpeer依存に持ち、langchainには依存していません。ただしLangGraph 1.2のNode単位のtimeoutとerror_handlerは公式の変更履歴でPython限定とされており、リトライポリシーは両言語で使えると明記されています。版番号はPython版と独立に進んでいるため、Python版の1.4系とJS版の1.5系を対応づけて読まないよう注意してください。LangChain.jsの導入と使い方はLangChain.jsとは|JavaScript/TypeScriptでLLM・エージェントを作る導入と使い方で扱っています。