Claude Media
Claude Agent SDKとLangGraphの違い — ループを任せるか、遷移を描くか

Claude Agent SDKとLangGraphの違い — ループを任せるか、遷移を描くか

Claude Agent SDKはClaude Codeのエージェントループごと組み込み、LangGraphはノードとエッジで状態遷移を自分で描きます。制御・永続化・中断の持ち方を並べ、選び方を示します。

違いは「ループを誰が持つか」にある

Claude Agent SDKとLangGraphは、どちらもエージェントをコードから動かす道具です。ただ、最初に手渡されるものが違います。

Claude Agent SDKは、Claude Codeが使っているエージェントループ・ビルトインツール・コンテキスト管理を、PythonとTypeScriptから呼べるようにしたライブラリです。ループはすでに動いていて、開発者は何を許可し、どこで止めるかを決めます。

LangGraphは、長時間動く状態付きエージェントのための低レベルなオーケストレーション基盤です。ノードとエッジで処理の流れを自分で描き、LLMに任せる箇所と決め打ちのコードで進める箇所を使い分けます。

比べる軸Claude Agent SDKLangGraph
位置づけClaude Agent SDKClaude Codeのエージェントを組み込むライブラリLangGraphオーケストレーション基盤(ランタイム)
次の一手を決める主体Claude Agent SDKClaudeがループの中で決めるLangGraphグラフのエッジと自分で書いた分岐
最初から持つものClaude Agent SDKファイル操作・コマンド実行・フック・サブエージェント・MCP・権限・セッションLangGraph状態・ノード・エッジ・永続化・中断
状態の保存Claude Agent SDKセッション(再開・フォーク)LangGraphチェックポインターとストア
人の承認Claude Agent SDK権限評価の流れとコールバックLangGraphinterrupt()で止めて再開

「どちらが高機能か」ではなく、「ループを任せたいのか、遷移を自分で設計したいのか」で選びます。以降は、この軸に沿って制御・状態・中断・分業を順に見ます。

Claude Agent SDKは、完成したループを渡してくる

SDKの概要ページは、これを「自分のプロセスで運用する、Claude Codeのエージェントの組み込み」と位置づけています。中身はClaude Codeのバイナリを動かすライブラリで、Claude Codeの機能がそのまま使えます。

ループの進み方は単純です。Claudeがツール呼び出しを要求し、SDKが実行し、結果をClaudeへ返す。この1往復が1ターンで、ツール呼び出しを含まない応答が出たところでループが終わります。途中でコードに制御が戻ることはありません。

import asyncio
from claude_agent_sdk import query, ClaudeAgentOptions, ResultMessage
 
 
async def main():
    options = ClaudeAgentOptions(
        allowed_tools=["Read", "Edit", "Bash", "Glob", "Grep"],
        max_turns=30,  # 暴走防止の上限
    )
    async for message in query(
        prompt="auth モジュールのテスト失敗の原因を直して",
        options=options,
    ):
        if isinstance(message, ResultMessage):
            print(message.result)
 
 
asyncio.run(main())

ここには「最初にテストを走らせる、次に読む、次に直す」という手順がありません。順序はClaudeがその場で決めます。開発者が書いたのは、使ってよいツールと、ターン数の上限だけです。

上限はmax_turns(TypeScriptではmaxTurns)とmax_budget_usd(同maxBudgetUsd)の2種類があります。max_turnsが数えるのはツール呼び出しを含むターンだけです。上限を置かないと、「コードベースを改善して」のような曖昧な依頼ではループが長く続きます。

ループ内部の挙動(メッセージの型、自動圧縮、並列ツール実行)はAgent SDKのエージェントループで詳しく扱っています。

LangGraphは、遷移を自分で描く

LangGraphには「エージェントのループ」が最初からあるわけではありません。状態の型を決め、ノード(処理)を足し、エッジ(次にどこへ進むか)でつなぎます。

from langgraph.graph import StateGraph, MessagesState, START, END
 
def mock_llm(state: MessagesState):
    return {"messages": [{"role": "ai", "content": "hello world"}]}
 
graph = StateGraph(MessagesState)
graph.add_node(mock_llm)
graph.add_edge(START, "mock_llm")
graph.add_edge("mock_llm", END)
graph = graph.compile()
 
graph.invoke({"messages": [{"role": "user", "content": "hi!"}]})

これは概要ページにあるhello worldです。LLMを呼ぶ処理は1ノードにすぎず、その前後に何をつなぐかは開発者が決めます。

分岐はエッジで表します。add_conditional_edgesにノード名と判定関数を渡すと、判定関数の戻り値で次のノードが変わります。状態更新と遷移先を1つの関数でまとめたいときはCommandを返します。

def route(state: MessagesState):
    last = state["messages"][-1]
    return "tools" if getattr(last, "tool_calls", None) else END
 
graph.add_conditional_edges("agent", route)

「LLMがツールを呼びたがったらツールノードへ、そうでなければ終了」というエッジを描けば、エージェントループが成立します。つまり、Claude Agent SDKが内蔵しているループを、LangGraphでは構成要素から組み立てる形です。

LangGraphのドキュメントは、ワークフローとエージェントを分けて説明しています。ワークフローは決まった順序のコードパスで進み、エージェントは自分で手順とツールの使い方を決めます。LangGraphの強みは、この2つを1つのグラフに混ぜられる点です。決定論的な箇所は予測可能で監査しやすく、モデルに任せる箇所だけが柔軟に動きます。

なお、LangGraphはプロンプトやアーキテクチャを抽象化しません。ツール呼び出しループのような定型の構成がほしいときは、LangChainのエージェント(LangGraphの上に作られた抽象化)を使う案内が概要ページにあります。LangGraph自体を使うのにLangChainは必須ではありません。

状態はどう持つか — セッションとチェックポイント

どちらも「中断しても続きから再開できる」点は共通です。ただ、再開の単位が違います。

観点Claude Agent SDKLangGraph
保存の単位Claude Agent SDK会話(セッション)LangGraphグラフ状態のスナップショット(チェックポイント)
再開の鍵Claude Agent SDKセッションID(または直近のセッション)LangGraphthread_id
過去に戻って試すClaude Agent SDKセッションをフォーク(元は変わらない)LangGraphタイムトラベル(チェックポインターの用途の1つ)
長期の記憶Claude Agent SDKCLAUDE.mdやメモリなどClaude Codeの仕組みLangGraphストア(スレッドをまたぐ値)
別ホストで続けるClaude Agent SDKセッションストアを渡すか、ファイルを移すLangGraph永続化に対応したチェックポインターを選ぶ

Claude Agent SDKの再開は、「前回の会話」を復元する動きです。読んだファイル、行った分析、実行した操作を含む全文脈が戻ります。フォークは元の履歴をコピーした新しいセッションを作り、元のセッションは変わりません。

セッションファイルは作成したマシンのローカルに置かれます。CIワーカーやサーバーレスのように別ホストで再開するなら、session_store(TypeScriptではsessionStore)のアダプターを渡してトランスクリプトを自前のバックエンドに複製します。再開に頼らず、必要な結果をアプリの状態として持ち、新しいセッションのプロンプトに渡す選択肢もあります。

LangGraphでは、グラフをcompile(checkpointer=...)でコンパイルし、実行のたびにthread_idを渡します。同じthread_idを使えば同じチェックポイントから続き、新しい値なら空の状態から始まります。チェックポインターは短期の(スレッドに閉じた)記憶、ストアは長期の(スレッドをまたぐ)記憶という役割分担です。

本番では永続化に対応したチェックポインターを使います。InMemorySaverとMemorySaverはRAMに保存するため、プロセスを再起動すると消えます。チェックポイントは会話が長くなるほど溜まるので、古いものを消す運用も要ります。

人の承認を挟むとき — 権限評価とinterrupt

自動で動くエージェントに「ここは人が確認する」を入れる方法は、両者で発想が逆です。

Claude Agent SDKでは、ツール呼び出しが権限評価の流れを通ります。順序はフック、拒否ルール、確認ルール、権限モード、許可ルール、canUseToolコールバックです。どこにも当たらなかった呼び出しが、最後にコールバックへ届きます。

注意点がひとつあります。許可ルールやacceptEdits・bypassPermissionsで自動承認された呼び出しは、canUseToolに届きません。コールバックに書いた確認が黙って素通りされることがあります。すべての呼び出しで必ず走らせたい検査は、PreToolUseフックに置きます。フックは他のどの段階より先に動き、フックの拒否はbypassPermissionsでも効きます。

LangGraphでは、ノードの中でinterrupt()を呼びます。グラフの状態が保存され、再開されるまで実行が止まります。

from langgraph.types import interrupt
 
def approval_node(state: State):
    approved = interrupt("この操作を実行してよいですか?")
    return {"approved": approved}

再開はCommand(resume=...)でグラフを呼び直します。渡した値が、ノード内のinterrupt()の戻り値になります。使うには、チェックポインターとthread_idが必須です。

ここにも設計上の落とし穴があります。LangGraphのドキュメントは、interruptをtry/exceptで包まないこと、ノード内でinterruptの呼び出し順を変えないこと、interruptの前に走る副作用は冪等にすることを挙げています。再開時にはノードが先頭から再実行されるためです。

まとめると、Claude Agent SDKは「ツール単位のゲート」、LangGraphは「処理の途中に置く任意の停止点」です。承認を挟む場所が「このツールを呼ぶ直前」なら前者が素直で、「3ステップ目の結果を人が編集してから4ステップ目へ」のように業務の区切りで止めたいなら後者が合います。

分業の考え方 — サブエージェントとグラフの分岐

複数の役割で仕事を分けたいときも、扱いが違います。

Claude Agent SDKのサブエージェントは、メインのエージェントが生成する別のエージェントインスタンスです。それぞれが自分の会話を持ち、途中のツール呼び出しや結果はサブエージェントの中に閉じ、親に返るのは最終メッセージだけです。コンテキストの隔離、並列実行、専門的な指示、ツールの制限が主な利点です。サブエージェントがさらにサブエージェントを生成することもでき、深さは環境変数で制限します。

LangGraphでは、分業はグラフの形そのものです。並列化、ルーティング、オーケストレーター・ワーカー、評価と改善の繰り返しといったパターンが、ノードとエッジの組み合わせで描かれます。誰に何を渡すかは、モデルの判断ではなく設計図に書かれます。

「誰に任せるかをモデルが決めてよい」ならサブエージェント、「この入力ならこのノード」を固定したいならグラフ、という整理になります。同じSDK系のOpenAI Agents SDKやGoogle ADKとの違いは、OpenAI Agents SDKとの比較とGoogle ADKとの比較にまとめています。

どちらを選ぶか — 状況から決める

こういう状況寄せる先理由
コードを読んで直す、調べてまとめるなど、手順を決めにくい作業寄せる先Claude Agent SDK理由ファイル操作・コマンド実行を含むループが最初からある
手順が決まっていて、一部だけLLMに任せたい寄せる先LangGraph理由決定論的なノードと、LLMのノードを1つのグラフに混ぜられる
業務の区切りごとに人が確認・編集する寄せる先LangGraph理由interrupt()で任意の位置に止められる
ツール単位で許可・拒否を細かく管理したい寄せる先Claude Agent SDK理由拒否・確認ルール、権限モード、フックで制御する
実行を永続化し、失敗後に続きから回したい寄せる先LangGraph理由チェックポインターが状態を保存する
自社のアプリに、コーディングエージェントの能力をそのまま載せたい寄せる先Claude Agent SDK理由Claude Codeの機能をそのまま呼べる

両者を排他と考える必要はありません。LangGraphのノードの中から、Claudeにコードを書かせる処理を呼ぶ構成も考えられます。概要ページにこの組み合わせの推奨は書かれていないため、設計は自分で検証する前提になります。LangGraph側の実装手順はClaude CodeでLangGraphエージェントを実装する手順にあります。

ホスト型のエージェントが選択肢に入るなら、状態遷移とイベントの扱いをManaged Agentsのworkflow runで確認できます。

導入前に確認する条件

Claude Agent SDKには、認証まわりの条件があります。承認を得ていない限り、サードパーティの開発者が自社製品でclaude.aiのログインやレート制限を提供することは認められません。クイックスタートに書かれているAPIキー認証を使います。

利用はAnthropicの商用利用規約に従います。自社のユーザーに提供する製品やサービスを動かす場合も同じです。

Claude Agent SDKの言語はPythonとTypeScriptです。ほかの言語から同じループを動かすなら、-pフラグと--output-format jsonを付けたCLIをサブプロセスとして起動する方法が案内されています。製品の中でClaudeを名乗るときのブランド表記にも制約があり、「Claude Code」や「Claude Code Agent」の名称は使えません。

LangGraph側で押さえる条件は、チェックポインターの選択です。開発中はメモリ上で足りても、本番ではPostgresのような永続化できる実装が必要になります。PostgresSaverを使うときは、thread_idが255文字を超えないようにします。

まとめ

Claude Agent SDKは「判断をモデルに任せ、周りに柵を立てる」道具、LangGraphは「判断の置き場所を自分で決める」道具です。判断の置き場所を選べることがLangGraphの自由度であり、同時に設計の手間でもあります。

迷ったときは、手順を事前に書けるかで切り分けます。書けないなら、ループごと渡してツールと権限で囲う。書けるなら、グラフに起こして、LLMの出番だけを限定する。後者でも、重い実行部分だけをClaude Agent SDKに任せる構成は成立します。

この記事を共有:XはてブLinkedIn