注意: この記事は、AIがLangChainとLangGraphのドキュメントおよびソースコードを解析して作成されています。情報の正確性については、必ず公式ドキュメントを併せてご確認ください。
はじめに
AIエージェントを構築する際、ReAct(Reasoning and Acting)パターンは非常に有効な手法です。この記事では、LangChainとLangGraphが提供するcreate_react_agent
関数を比較し、それぞれの特徴、使いどころ、違いについて詳しく解説します。
ReActパターンとは
ReActは「Reasoning and Acting」の略で、大言語モデル(LLM)が思考(Thought)→行動(Action)→観察(Observation)のサイクルを繰り返すことで、複雑なタスクを段階的に解決するパターンです。このパターンは2022年の論文「ReAct: Synergizing Reasoning and Acting in Language Models」で提案されました。
Question: 質問
Thought: 何をすべきか考える
Action: 実行するアクション
Action Input: アクションへの入力
Observation: アクションの結果
... (必要に応じて繰り返し)
Final Answer: 最終回答
LangChainのcreate_react_agent
特徴
LangChainのcreate_react_agent
は、2022年の論文「ReAct: Synergizing Reasoning and Acting in Language Models」に基づいたテキストベースの実装です。
アーキテクチャ
実装例
from langchain.agents import create_react_agent
from langchain_core.tools import tool
from langchain_openai import ChatOpenAI
@tool
def calculator(expression: str) -> str:
"""数式を計算します"""
return str(eval(expression))
llm = ChatOpenAI(model="gpt-4")
tools = [calculator]
agent = create_react_agent(
llm=llm,
tools=tools,
prompt=default_prompt # テキストベースのプロンプト
)
メリット・デメリット
メリット:
- シンプルで理解しやすい
- 任意のLLMで動作(Function Call対応不要)
- 軽量な実装
デメリット:
- テキスト解析によるエラーが発生しやすい
- プロンプトエンジニアリングが重要
- Function Callを使用しないため、構造化が困難
LangGraphのcreate_react_agent
特徴
LangGraphのcreate_react_agent
は、ステートフルなグラフベースの実装で、より現代的で柔軟性の高いアプローチを採用しています。
アーキテクチャ
実装例
from langgraph.prebuilt import create_react_agent
from langchain_core.tools import tool
@tool
def calculator(expression: str) -> float:
"""数式を計算します"""
return eval(expression)
@tool
def get_weather(city: str) -> str:
"""天気情報を取得します"""
return f"{city}は晴れです"
agent = create_react_agent(
model="anthropic:claude-3-7-sonnet-latest",
tools=[calculator, get_weather],
prompt="あなたは役立つアシスタントです"
)
# ステートフルな実行
result = agent.invoke({
"messages": [{"role": "user", "content": "東京の天気と2+3の計算をして"}]
})
メリット・デメリット
メリット:
- ステートフルな状態管理
- グラフベースで複雑なワークフローに対応
- 豊富な設定オプション(hooks、interrupts等)
- Function Callネイティブサポート
- チェックポイント機能
- 構造化レスポンス対応
デメリット:
- 学習コストが高い
- より重い実装
- LangGraphの理解が必要
詳細比較
1. 技術的な違い
項目 | LangChain | LangGraph |
---|---|---|
実装方式 | テキストベース | グラフベース |
状態管理 | 各実行で独立 | ステートフル |
ツール表現 | テキスト形式の説明 | Function Call + JSON Schema |
パーサー | ReActSingleInputOutputParser |
構造化パーサー |
エラー処理 | テキスト解析エラーが発生しやすい | 堅牢な構造化処理 |
実行制御 | 限定的 | フック、割り込み、チェックポイント |
2. 機能比較
LangChain create_react_agent
# 基本的な関数シグネチャ
create_react_agent(
llm: BaseLanguageModel,
tools: Sequence[BaseTool],
prompt: BasePromptTemplate,
output_parser: Optional[AgentOutputParser] = None,
tools_renderer: ToolsRenderer = render_text_description,
stop_sequence: Union[bool, List[str]] = True,
)
LangGraph create_react_agent
# より豊富なオプション
create_react_agent(
model: Union[str, LanguageModelLike],
tools: Union[Sequence[Union[BaseTool, Callable, dict]], ToolNode],
prompt: Optional[Prompt] = None,
response_format: Optional[StructuredResponseSchema] = None,
pre_model_hook: Optional[RunnableLike] = None,
post_model_hook: Optional[RunnableLike] = None,
state_schema: Optional[StateSchemaType] = None,
checkpointer: Optional[Checkpointer] = None,
interrupt_before: Optional[list[str]] = None,
interrupt_after: Optional[list[str]] = None,
# その他多数のオプション...
)
3. 使用場面の違い
LangChainがおすすめの場面
- シンプルなReActエージェントが必要
- Function Call非対応のLLMを使用
- 学習コストを抑えたい
- 軽量な実装が求められる
LangGraphがおすすめの場面
- 複雑なワークフローが必要
- ステートフルな処理が重要
- Human-in-the-loopが必要
- 高度な実行制御が求められる
- チェックポイント機能が必要
- 構造化レスポンスが必要
実際のコード例での比較
LangChain版
from langchain.agents import create_react_agent, AgentExecutor
from langchain_core.tools import tool
from langchain_openai import ChatOpenAI
from langchain import hub
@tool
def calculator(expression: str) -> str:
"""数式を計算します"""
return str(eval(expression))
# プロンプトを取得
prompt = hub.pull("hwchase17/react")
# エージェント作成
llm = ChatOpenAI(model="gpt-4")
agent = create_react_agent(llm, [calculator], prompt)
# エグゼキューター作成
agent_executor = AgentExecutor(agent=agent, tools=[calculator])
# 実行
result = agent_executor.invoke({"input": "2 + 3 × 4を計算して"})
LangGraph版
from langgraph.prebuilt import create_react_agent
from langchain_core.tools import tool
@tool
def calculator(expression: str) -> float:
"""数式を計算します"""
return eval(expression)
# エージェント作成(より簡潔)
agent = create_react_agent(
model="gpt-4",
tools=[calculator],
prompt="あなたは数学の専門家です"
)
# 実行
result = agent.invoke({
"messages": [{"role": "user", "content": "2 + 3 × 4を計算して"}]
})
パフォーマンスと運用面
LangChain
- 起動速度: 高速
- メモリ使用量: 少ない
- デバッグ: プロンプトベースなのでログが読みやすい
- 運用監視: 基本的な機能のみ
LangGraph
- 起動速度: やや低速(グラフ構築のため)
- メモリ使用量: 多め(状態管理のため)
- デバッグ: グラフの可視化、ステップごとの詳細ログ
- 運用監視: 豊富な監視・制御機能
まとめ
両者は同じReActパターンを実装していますが、アプローチが大きく異なります:
- LangChain: シンプル、軽量、テキストベース
- LangGraph: 高機能、ステートフル、グラフベース
選択の指針:
- プロトタイプや学習目的 → LangChain
- 本格的なプロダクション → LangGraph
- Function Call非対応LLM → LangChain
- 複雑なワークフロー → LangGraph
- Human-in-the-loop → LangGraph
どちらも優れたツールですが、用途や要件に応じて適切に選択することが重要です。LangGraphは学習コストが高い分、より柔軟で堅牢なエージェントを構築できます。