0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

LangChainのAgentExecutorが消えた、create_agentと比較した

0
Posted at

はじめに

LangChainでエージェントを作るとき、これまでは AgentExecutor を使うのが定番でした。しかし LangChain 1.x 系をインストールした環境で from langchain.agents import AgentExecutor を実行すると、ImportError になります。対象読者は、LangChain でツール呼び出し型のエージェントを実装している開発者、および AgentExecutor ベースの既存コードを LangChain 1.x へ移行しようとしている開発者です。

この記事では、クラウド環境に実際に langchain 1.3.14 / langgraph 1.2.10 / langchain-classic 1.0.8 をインストールし、AgentExecutor(レガシー実装)と、後継の create_agent(LangGraph 実行エンジン採用)の両方を同一タスクで動かして比較した結果をまとめます。

比較表(同一タスクでの実測)

天気を返す 1 つのツール(get_weather)を呼び出すだけの単純なエージェントを、両方の実装で構築して比較しました。LLM 呼び出し部分は API キーを使わず、決まったレスポンスを返すスクリプト化モデル(後述)に差し替えています。

評価軸 AgentExecutor(langchain-classic create_agent(LangChain 1.x)
パッケージ langchain-classic 1.0.8 langchain 1.3.14(内部で langgraph 1.2.10 を利用)
インポート元 langchain.agents からは ImportErrorlangchain_classic.agents からのみ可能 langchain.agents から直接インポート可能
プロンプト設計 ReAct 形式のテキストプロンプトを PromptTemplate で手書きする必要がある 不要(モデルのネイティブ tool calling を前提にした設計)
実装コード行数(空行除く・同一タスク) 20 行 8 行(60% 減)
実行エンジン AgentExecutor 独自の実行ループ LangGraph の状態グラフ(Pregel ランタイム)
ツール呼び出しの仕組み LLM の出力テキストを Thought: / Action: / Action Input: でパースする モデル API のネイティブ tool calling(bind_tools)を使う
メンテナンス状況 由来元の LangChain 0.3 系が公式に 2026 年 12 月まで MAINTENANCE mode と明言 現行の推奨 API

出典: LangGraph v1 migration guidecreate_react_agent プリビルトの非推奨化と create_agent への移行を案内)、Is AgentExecutor Deprecated in LangChain?AgentExecutor を含む旧世代エージェント実装の概要)、Release policy - Docs by LangChain(LangChain 0.3 系が MAINTENANCE mode・2026 年 12 月までのサポートである旨を明記。langchain-classic はこの 0.3 系に由来する旧実装の切り出し先)

1. AgentExecutorが動かなくなった経緯を実機で確認する

まず、クラウド環境に主要パッケージをインストールしてバージョンを確認しました。

pip install -q langchain langgraph langchain-anthropic
langchain          1.3.14
langgraph          1.2.10
langchain-anthropic 1.5.3

この状態で AgentExecutor を素直にインポートすると、次のように失敗します。

from langchain.agents import AgentExecutor, create_react_agent
ImportError: cannot import name 'AgentExecutor' from 'langchain.agents'

Web上の移行ガイドには「create_react_agent プリビルトが非推奨になった」という記述はありますが、langchain.agents から AgentExecutor 自体が完全に取り除かれている点は、実際にインポートしてみるまで気づきにくい変化でした。原因を辿ると、AgentExecutor を含む旧世代のエージェント実装一式が langchain-classic という別パッケージに切り出されていました。

pip install -q langchain-classic
from langchain_classic.agents import AgentExecutor, create_react_agent

これは成功します。パッケージ構成としては、langchain 本体からレガシーコードを分離し、新規ユーザーが誤って古い実装を使わないようにする意図と読めます。

2. 同一タスクを両実装で動かす

天気を返すだけのツールを1つ用意し、同じ入力(「東京の天気は?」)に対して同じ出力(「東京は晴れです。」)を返すように、LLM 呼び出し部分を決め打ちの応答シーケンスに差し替えて実行しました。APIキーを使わずに実行フロー全体を検証するための構成です。

create_agent(新API)での実装

from langchain.agents import create_agent
from langchain_core.tools import tool

@tool
def get_weather(city: str) -> str:
    """指定した都市の天気を返す"""
    return f"{city}は晴れです"

def build_new_agent(model):
    return create_agent(model=model, tools=[get_weather])

ツールを渡す以外の設定はほぼありません。プロンプトの雛形はライブラリ側が持っており、モデルの bind_tools(ネイティブ tool calling)を前提にした設計になっています。この構成で agent.invoke({"messages": [{"role": "user", "content": "東京の天気は?"}]}) を実行すると、HumanMessage → AIMessage(tool_calls=...) → ToolMessage → AIMessage の順でメッセージ列が積み上がり、最終応答として「東京は晴れです。」を得られることを確認しました。

AgentExecutor(レガシー実装)での実装

from langchain_classic.agents import AgentExecutor, create_react_agent
from langchain_core.tools import tool
from langchain_core.prompts import PromptTemplate

@tool
def get_weather(city: str) -> str:
    """指定した都市の天気を返す"""
    return f"{city}は晴れです"

REACT_PROMPT = PromptTemplate.from_template(
    "Answer the following questions as best you can. You have access to the following tools:\n\n"
    "{tools}\n\nUse the following format:\n\nQuestion: the input question\n"
    "Thought: you should always think about what to do\n"
    "Action: the action to take, should be one of [{tool_names}]\n"
    "Action Input: the input to the action\nObservation: the result of the action\n"
    "... (this Thought/Action/Action Input/Observation can repeat N times)\n"
    "Thought: I now know the final answer\nFinal Answer: the final answer\n\n"
    "Begin!\n\nQuestion: {input}\nThought:{agent_scratchpad}"
)

def build_legacy_agent(llm):
    agent = create_react_agent(llm, [get_weather], REACT_PROMPT)
    return AgentExecutor(agent=agent, tools=[get_weather], verbose=False)

こちらは ReAct 形式のプロンプトを自前で用意する必要があります。LLM は Action: get_weather\nAction Input: 東京 のようなテキストを出力し、AgentExecutor がそのテキストをパースしてツールを呼び出します。同じ「東京の天気は?」を入力すると、{'input': '東京の天気は?', 'output': '東京は晴れです。'} という辞書が返り、最終的な回答は create_agent と一致しました。

空行を除いたコード行数で比較すると、create_agent 実装が 8 行、AgentExecutor 実装が 20 行でした。差分の大部分は ReAct プロンプトの手書き部分です。

3. 実行エンジンの違い

両者の最も大きな違いは、内部の実行エンジンです。create_agent は LangGraph の状態グラフ(Pregel ランタイム)の上に構築されており、エージェントのループはノードとエッジで表現されます。

一方 AgentExecutor は、while ループの中で「LLM呼び出し → テキストパース → ツール実行」を繰り返す、より手続き的な実装です。LangGraph 化されたことで、状態の永続化(チェックポイント)やストリーミング、複数エージェントの合成がしやすくなる一方、bind_tools を実装していないモデル(テキスト出力のみのモデル)は create_agent にそのまま渡せないという制約も実測で確認しました。テスト用に bind_tools 未実装の FakeMessagesListChatModel を渡すと NotImplementedError になり、ツール呼び出し(Function Calling)に対応したモデルであることが create_agent の前提条件になっています。

4. 移行を検討する際の所見

今回の実測を通じて分かったのは、「AgentExecutor が非推奨になった」という情報だけでは移行作業の全体像がつかめない、という点です。実際には次の2段階の変化が同時に起きていました。

  1. パッケージの切り出し: AgentExecutor を含む旧実装一式が langchain-classic という独立パッケージへ移動し、langchain 本体からは ImportError になる
  2. 実行モデルの変更: 新しい create_agent は ReAct テキストパースをやめ、モデルのネイティブ tool calling 前提の設計に変わっている

既存コードを LangChain 1.x に移行する場合、pip install langchain-classic を追加してインポート元を書き換えるだけで動かし続けることは可能です。ただし langchain-classic は maintenance-only(重大な不具合修正のみ)と案内されているため、恒久的な対応としては create_agent への書き換えが必要になります。移行コストは、ReAct プロンプトを自前で書いていた分をそのまま削除できるため、今回検証した単純なツール呼び出しエージェントでは大きくありませんでした。ただしカスタムの Observation フォーマットや独自の停止条件を AgentExecutor に実装していた場合は、LangGraph のノード・エッジ設計に置き換える作業が発生します。

まとめ

LangChain 1.x では AgentExecutorlangchain.agents から取り除かれ、langchain-classic パッケージに切り出されています。新しい create_agent は LangGraph の実行エンジン上で動作し、モデルのネイティブ tool calling を前提とした設計です。同一タスクで比較した結果、ReAct プロンプトの手書きが不要になった分、コード行数はおよそ 6 割減りました。一方で bind_tools に対応していないモデルは create_agent に渡せないため、移行前にモデル側の tool calling 対応状況を確認しておく必要があります。

関連記事

参考リンク

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?