DSPy ReActV2とは|ネイティブツール呼び出し前提の新ReActモジュール【2026年版】

DSPy ReActV2は、2026年5月28日公開のDSPy 3.3.0b1(beta)で追加された、ネイティブツール呼び出しを前提に作り直された新しいReActモジュールです。従来のdspy.ReActは履歴を一本の長いtrajectory文字列で持っていました。ReActV2はこれをdspy.Historyに置き換え、user・assistant・toolのメッセージに分けて扱います。この変更で、ツールの並列呼び出し、マルチターンのネイティブ呼び出し、プロンプトキャッシュによるコスト削減が可能になりました。本記事ではV1との設計差分、仕組み、3.3.0b1での導入手順、experimental指定の現状の扱い方までを、公式リリースノートと実装コードに基づいて解説します。

目次

DSPy ReActV2の要点と移行判断のまとめ

ReActV2は、ReAct(思考と行動を交互に回すエージェント手法)のDSPy実装を、LLM側のネイティブなツール呼び出しに合わせて再構築したモジュールです。コンストラクタはdspy.ReActV2(signature, tools, max_iters=20)。内部には最終出力専用のsubmitツールが自動で組み込まれます。履歴はdspy.Historyに構造化メッセージとして積まれ、プロンプトキャッシュが効きやすい構造です。社内検証では一部タスクでコストが最大50%下がったと公式が報告しています。

ただし注意点があります。ReActV2は@experimental指定で、収録先の3.3.0b1自体がbetaです。同時点の安定版は3.2.1で、ReActV2は安定版に入っていません。新規エージェントの試作や、ツール呼び出し中心の多ターン処理でコストを抑えたい場面なら、試す価値は十分あります。逆に可用性が最優先の本番では、安定版を待つか、バージョンを固定して破壊的変更を前提にテストする運用に限るのが現実的な線引きです。

DSPy ReActV2の定義と位置づけ|3.3.0b1で追加された実験的モジュール

ReActV2の概要|DSPy 3.3.0b1で追加された実験的な新ReActモジュール

DSPyはStanford NLP発のオープンソースPythonフレームワークで、LLMを「プロンプトを手で書く」のではなく「コードでプログラミングする」ことを狙います。ReActV2は、そのエージェント向けモジュールdspy.ReActを作り直した後継です。実装ファイルには@experimentalデコレータが付き、クラスはclass ReActV2(Module)として定義され、dspy.ReActV2で公開されています。関連PRは#9823・#9824・#9825・#9835で、作者はisaacbmiller氏。ライセンスはMIT、対応Pythonは3.10以上3.15未満です。

思考と行動を交互に進めるReActパターンとDSPyでのエージェント実装

ReActは「Reasoning and Acting」の略。モデルが状況を推論し、ツールを呼ぶか回答を確定するかを繰り返し判断する手法です。たとえば「検索が要ると判断→検索を実行→結果を踏まえて再考→追加検索」のように、外部ツールと対話しながら問題を解く形です。DSPyではこのパターンが、入出力の型を宣言するsignatureに対して汎用的に動くよう一般化されています。SignatureやModuleといったDSPyの基本要素そのものは、DSPyとは何かを解説した記事で前提を押さえると、本記事の変更点が読み解きやすくなります。

安定版3.2.1とbeta版3.3.0b1の違いと現在の提供状況

ReActV2を使うには、安定版ではなくbetaの3.3.0b1を明示的に入れます。両者は位置づけが別物です。混同して安定版にdspy.ReActV2を期待すると、importの段階で見つからず詰まります。

項目 DSPy 3.2.1(安定版) DSPy 3.3.0b1(beta)
公開日 2026年5月5日 2026年5月28日
位置づけ 最新の安定版(Latest) pre-release(beta)
ReActV2 未収録 収録(experimental)
インストール pip install dspy pip install “dspy==3.3.0b1”

betaはpip install dspyだけでは入りません。バージョンを固定して取得する——これが検証時の最初の分かれ目です。

dspy.ReAct(V1)からReActV2への設計変更点とdspy.History導入

従来のtrajectory文字列とnext_tool_args方式が抱えていた限界

V1のdspy.ReActは、思考とツール実行の記録をtrajectoryという一本の文字列にためていき、毎ターン長いuserメッセージとして渡していました。next_tool_argsという独自の引数表現も使います。この方式には弱点がありました。ターンが増えるほど一塊の文字列が膨らみ、LLM側のネイティブなツール呼び出しや、過去ターンをassistant・toolメッセージとして再生する仕組みと噛み合いません。プロンプト先頭が毎回変わるため、プロバイダのプロンプトキャッシュも効きにくい構造でした。

trajectory廃止とdspy.History・ToolCallsへの型の置き換え

ReActV2は、独自の文字列表現をやめ、DSPyの型に寄せました。コンストラクタに渡した関数(callable)は内部でdspy.Toolへ変換される点が基本です。履歴はdspy.History、モデルが要求するツール呼び出しはdspy.ToolCalls、その実行結果は任意でdspy.ToolCallResultsに保持されます。実装上、推論の内部シグネチャにはhistorydspy.History)、toolslist[dspy.Tool])、next_thoughtdspy.Reasoning)、tool_callsdspy.ToolCalls)が定義されています。

観点 dspy.ReAct(V1) dspy.ReActV2
履歴の持ち方 trajectory(単一文字列) dspy.History(構造化メッセージ)
ツール表現 next_tool_args等の独自記法 dspy.Tool / dspy.ToolCalls
実行結果の記録 文字列に追記 dspy.ToolCallResults(任意・ID付き)
メッセージ構成 一本の長いuserメッセージ user / assistant / tool に分割
最終出力 回答フィールドへ整形 内部submitツールで確定

user・assistant・toolメッセージ分割による実行モデルの変化

履歴がdspy.Historyになり、各ターンは一本の文字列ではなくuser・assistant・toolのメッセージ群として表現されます。過去のツール呼び出しと結果を、プロンプト本文に平坦化せず、assistantメッセージとtoolメッセージとしてそのまま再生できるわけです。ネイティブな関数呼び出しに対応したプロバイダなら、モデルが過去のツール対話を本来の形式で受け取れます。結果として、ツール選択の精度や挙動の一貫性で有利になります。

ネイティブツール呼び出しが実現する並列実行

parallel_tool_callsによる複数ツールの並列実行とID単位の保持

ReActV2では、アダプタがparallel_tool_callsで構成されていれば、プロバイダ側の並列ツール呼び出しを使えます。モデルが要求した各呼び出しと、それぞれの観測結果を呼び出しIDで対応付けて保持する仕組みです。複数ツールを一度に走らせても、結果の取り違えは起きません。これはネイティブモードでも非ネイティブモードでも利用できます。独立した複数の情報源を同時に引きたいエージェントなら、逐次呼び出しより往復回数を減らせます。

内部submitツールとsubmit未呼び出し時の強制送信の挙動

ReActV2は初期化時に、最終出力を確定するsubmitツールを内部で自動追加します。submitはsignatureの出力フィールドを引数に取り、欠けたフィールドがあればエラーで知らせる設計です。submitは予約名のため、ユーザーが同名ツールを渡すとValueErrorになる点に注意してください。モデルが上限ターンまでにsubmitを呼ばなかった場合は、tool_choicesubmitを強制し、最終出力を取り出します。この強制送信を経たときは、戻り値のtermination_reasonforced_submitとなり、通常の確定(submit)と区別できます。

未知ツール・例外処理とToolCallResultsによるエラー記録

モデルが存在しないツール名を呼んだ場合や、ツール実行中に例外が出た場合も、ReActV2は処理を止めずに扱います。実行結果はdspy.ToolCallResultsとして、呼び出しID・ツール名・戻り値・エラーフラグを伴って記録される仕組みです。失敗した呼び出しもエラーフラグ付きで履歴に残る設計です。だからモデルは次のターンで「そのツールは失敗した」と踏まえて方針を変えられます。エラーで即クラッシュさせず、ループ内で回復を試みられる——この堅牢性が実務上の差になります。

マルチターンのネイティブツール呼び出しとMCPサーバー連携の親和性

過去のツール呼び出しと結果をassistant・toolメッセージとして再生できるため、ReActV2はマルチターンのネイティブツール呼び出しと相性のよい構造です。外部ツールサーバーを標準化された方法でつなぐ仕組みにはMCP(Model Context Protocol)があり、ネイティブな関数呼び出しを前提に複数ツールを動的に扱う設計と方向性が一致します。ツールを「LLMが直接呼べる関数」として渡す思想が、ReActV2のdspy.Tool変換と無理なく重なります。

dspy.Historyがプロンプトキャッシュとコストに効く理由と削減幅

安定プレフィックスの再利用でプロンプトキャッシュが効く仕組み

多くのプロバイダのプロンプトキャッシュは、リクエスト先頭の同一部分(プレフィックス)が前回と一致しているほど効きます。V1のtrajectory方式では、ターンごとに履歴文字列が伸びてプロンプト構成が変わり、先頭の一致が崩れやすい設計でした。ReActV2は各ターンをdspy.Historyの独立したメッセージとして積みます。システム指示やツール定義など変わらない部分を安定したプレフィックスとして保ちやすく、キャッシュの再利用率を上げられるわけです。

社内検証で最大50%とされるコスト削減幅とその適用前提の整理

公式リリースノートは、この履歴構造への変更について、社内検証で一部タスクのコストが最大50%下がったと述べています。ここで押さえたいのは前提です。第一に「一部タスクで」「最大」の数値であり、すべての用途で半減する話ではありません。第二に、効果はプロンプトキャッシュ対応プロバイダで、ツール呼び出しを多くのターン繰り返すワークロードほど出やすい性質を持ちます。ターン数が少ない単発タスクや、キャッシュの効かない構成では削減幅は小さくなります。自分のワークロードでトークン使用量を計測してから効果を見積もってください。

ReActV2の導入と移行の手順|3.3.0b1インストールと変更点の確認

3.3.0b1のインストールとdspy.ReActV2を使う最小コード例

ReActV2を動かす最小の流れは次のとおりです。signatureには入出力の型を文字列で渡し、toolsには関数をそのまま渡せます(内部でdspy.Toolに変換)。max_itersの既定値は20です。

  1. betaを固定して導入する:pip install "dspy==3.3.0b1"
  2. 利用するLMを設定する:dspy.configure(lm=dspy.LM("openai/gpt-4o-mini"))
  3. ツールを通常の関数として定義する:def get_weather(city: str) -> str: ...
  4. エージェントを生成する:agent = dspy.ReActV2("question -> answer", tools=[get_weather])
  5. 実行して出力を受け取る:pred = agent(question="東京の天気は?") から pred.answer を取得

戻り値のPredictionには、出力フィールドのほかにhistorytermination_reasonが含まれます。termination_reasonを見れば、submitで正常終了したのか、上限ターンでforced_submitになったのかを判別できます。

dspy.ReActからの移行で確認すべき入出力とToolCalls周りの差異

V1からの移行でまず変わるのは、履歴とツール呼び出しの扱い方です。V1でtrajectorynext_tool_argsを前提に後処理を書いていたなら、その部分はdspy.Historydspy.ToolCallsdspy.ToolCallResults前提に組み直します。submitはReActV2の予約名なので、既存ツールに同名があれば改名が必要です。出力はsubmit経由でsignatureの出力フィールドに確定する流れに変わります。出力フィールドの定義が、実際に取り出したい項目と一致しているか確認しておきましょう。

numpy任意化・LMError統一など3.3.0b1の破壊的変更の確認

3.3.0b1はReActV2以外にも破壊的変更を含みます。多くの既存プログラムはそのまま動きますが、次に依存していた場合は影響を受けます。

  • numpyが任意化された:基本インストールから外れ、埋め込みやKNN、SIMBAなどNumPy依存の機能にはpip install "dspy[numpy]"が必要
  • LMエラーが正規化された:プロバイダ固有やLiteLLM固有の例外を直接catchしていたコードは、dspy.LMErrorかそのサブクラスを捕捉する形へ
  • GEPAの結果構造が変わった:gepa[dspy]==0.1.1対応に伴い、detailed_resultsを精査するコードは戻り値の形を要確認

betaである以上、これらの仕様は今後さらに変わり得ます。移行時はバージョンを固定し、変更点を1つずつ自分の環境で確認するのが安全です。

ReActV2を採用すべき場面と本番運用で見送るべき条件の整理

新規エージェント試作とコスト重視の多ターン用途での採用妥当性

ReActV2が向くのは次のような場面です。逆に、すでにV1で安定稼働している既存システムを、明確な理由なく急いで載せ替える必要はありません。

  • これから新規にツール使用エージェントを試作する:最初からネイティブツール呼び出し前提で組める
  • ツール呼び出しを多くのターン繰り返す処理でコストを抑えたい:キャッシュ再利用の恩恵が出やすい
  • 複数ツールの並列実行を使いたい:parallel_tool_callsでID単位に結果を保持できる
  • ツールの失敗を握りつぶさずループ内で回復させたい:例外とエラーフラグを履歴に残せる

experimental・beta前提で本番運用に3.3.0b1を見送るべき条件

可用性や後方互換が最優先の本番では、現時点の3.3.0b1の採用は見送る判断が妥当です。理由は二つ。ReActV2が@experimental指定であること、そして収録先の3.3.0b1がbetaで、同時点の安定版が3.2.1であることです。experimentalのAPIは予告なく変わり得るため、SLAを保証する基幹処理に組み込むのは時期尚早といえます。先行して使うなら、検証環境に閉じ、安定版でのReActV2提供を待ってから本番へ移す——この順序が堅実です。

ありがちな失敗|beta APIを本番固定し破壊的変更で詰まる事例

避けたい典型例があります。3.3.0b1を本番に入れたうえで、バージョン固定だけして放置するパターンです。betaは破壊的変更を前提にしており、3.3.0b1でもnumpy任意化、LMエラー正規化、GEPAの結果構造変更が入りました。固定して安心していると、後続betaや正式版へ上げた瞬間に、例外処理・結果パース・NumPy依存箇所がまとめて壊れます。先行導入するなら、変更履歴を追い続け、experimental部分はいつ作り直されてもよい疎結合な形で囲っておく。これが後で詰まらないための条件です。

ReActV2が活きるユースケース|ツール使用エージェントとエージェンティックRAG

Web検索・コード実行・API呼び出しを担うツール使用エージェント

ReActV2が最も自然に効くのは、外部ツールを呼びながら答えを組み立てるエージェントです。具体的には次のような処理が該当します。

  • Web検索やベクトルDB照会で根拠を集めてから回答するQA
  • 計算やデータ整形をコード実行ツールに任せる数値タスク
  • 社内システムのAPIを叩いて状態取得や更新を行う業務処理

いずれもツール呼び出しの往復が増えやすく、並列実行とキャッシュ再利用の効きが出やすい領域です。

エージェンティックRAGでの動的ツール利用とReActV2の相性

固定的な検索フローではなく、エージェントが状況に応じて検索ツールを動的に選び、複数ソースを横断する——これがエージェンティックRAGです。ReActV2は、検索ツールの呼び出しと結果を構造化メッセージとして積み、マルチターンで推論を続ける設計のため、この動的なツール利用と噛み合います。複数の検索結果をID単位で保持できるので、どの結果がどの呼び出しに対応するかを失わず、回答の根拠もたどりやすくなります。

GEPA・MIPROv2などオプティマイザと組み合わせたエージェント最適化

DSPyの強みは、組んだプログラムをオプティマイザで自動調整できる点にあります。GEPAやMIPROv2といったオプティマイザは、指示文や少数例の選び方を改善してタスク性能を引き上げる仕組みです。ReActV2で組んだエージェントも、評価指標と少量のデータを用意すれば、こうしたオプティマイザによる最適化の対象にできます。手書きのプロンプト調整に頼らず、ツール使用エージェントの挙動をデータ駆動で詰められる。これがDSPy上でReActV2を使う実利です。

DSPy ReActV2に関するよくある質問

ReActV2の採用可否や前提でつまずきやすい点を、実際の検索質問に沿って整理します。

ReActV2とdspy.ReActはどちらを使うべきですか?

すでに本番でV1のdspy.ReActが安定稼働しているなら、急いで載せ替える必要はありません。これから新規にツール使用エージェントを作る、ネイティブツール呼び出しや並列実行を使いたい、ツール多ターン処理のコストを下げたい、という場合はReActV2を試す価値があります。ただしReActV2はexperimentalで、収録先の3.3.0b1はbetaです。安定性を最優先するならV1の安定版、新機能とコスト効率を取るならReActV2が目安です。

ReActV2は本番環境で使っても問題ないですか?

可用性が最優先の基幹処理では、現時点での採用は慎重に判断してください。ReActV2は@experimental指定で、3.3.0b1はpre-release(beta)です。同時点の安定版は3.2.1で、APIは予告なく変わり得ます。先行検証は有効ですが、本番投入は安定版での提供を待つか、検証環境に閉じてバージョンを固定し、破壊的変更を前提にテストする運用に限るのが安全です。

ReActV2を使うにはどのバージョンのDSPyが必要ですか?

ReActV2は安定版の3.2.1には含まれず、beta版の3.3.0b1から提供されます。pip install dspyでは安定版が入るため、pip install "dspy==3.3.0b1"のようにbetaを明示して導入します。対応Pythonは3.10以上3.15未満、ライセンスはMITです。

ReActV2でツールの並列呼び出しはできますか?

できます。アダプタがparallel_tool_callsで構成されていれば、プロバイダ側の並列ツール呼び出しを利用できます。モデルが要求した各呼び出しと観測結果は呼び出しIDで対応付けて保持されるため、複数ツールを同時に走らせても結果が混ざりません。ネイティブモードでも非ネイティブモードでも利用できます。

ReActV2はどのLLMプロバイダーで利用できますか?

ReActV2はDSPyのLM抽象(dspy.LM)経由でモデルを呼ぶため、DSPyが対応するプロバイダで利用できます。ネイティブな関数呼び出しに対応したプロバイダではネイティブモードの恩恵(メッセージ分割やキャッシュ再利用)が出やすく、非対応でも非ネイティブモードで動作する点が利点です。

関連記事

資料請求

RELATED POSTS 関連記事