DSPy 3.3.0の実験機能「Flex」「ReActV2」──プロンプトでなくプログラムの構造そのものをGEPAに最適化させる
DSPy 3.3.0(2026-08-03公開)は、プログラムの実装構造自体をGEPAの探索対象にする実験的モジュール`dspy.Flex`と、ネイティブtool-callingに載せ替えた新しいReAct実装`dspy.ReActV2`を同時公開した。GitHub公式リリースノートはReActV2で「一部タスクで最大50%のコスト減を確認した」と書いている。

目次
3行まとめ
- DSPy(Stanford NLP発のLLMプログラミングフレームワーク)は2026-08-03公開のv3.3.0で、プログラムの「実装そのもの」をGEPAで最適化できる実験的モジュール
dspy.Flexを追加した。- 同じリリースで、ネイティブなtool-calling(
dspy.History/dspy.Tool/dspy.ToolCalls)を使う新しいReAct実装dspy.ReActV2も公開された。GitHub公式リリースノートは「一部タスクで内部テスト時に最大50%のコスト減を確認した」としている。- どちらも「experimental(実験的)」と明記された機能で、DSPyチーム自身が「Flex・ReActV2・型付きLMパスについて特にフィードバックを歓迎する」とリリースノートに書いている段階の機能。
dspy.Flex──プログラム構造そのものを探索対象にする
DSPyのこれまでのモジュール設計は、Predictなら1回の予測、ReActならツールループ、RLMならコードインタープリタのループというように、プログラムの「形」があらかじめ固定されていた。GEPAなどのオプティマイザはその形の中で指示文(instructions)を改善できても、形そのものは変えられなかった。
GitHub公式リリースノート(担当者@michaelisaac-dev)によれば、新しい実験的モジュールdspy.Flexはこの制約を外す。Predictと同じシグネチャを渡すと、まず「動く最小構成」(dspy.Predict1個、あるいはツールが与えられていればdspy.RLM1個)から始まり、コンパイル時にGEPAが完全なモジュール実装──predictorの構成、制御フロー、DSPyのプリミティブ、PythonコールとLMコールのバランス──をメトリクスに対して書き換えられるようになる。
program = dspy.Flex("question -> answer")
optimized = dspy.GEPA(metric=metric, reflection_lm=reflection_lm).compile(
program,
trainset=trainset,
valset=valset,
)
print(optimized.module_src)
リリースノートは、オプティマイザが生成したソースコードは常にCodeInterpreterサンドボックス内で実行される(デフォルトはdspy.PythonInterpreter)とし、predictorの構築とLM呼び出しはホスト側に橋渡しされ、壊れた候補はクラッシュではなく失敗スコアとして扱われる、max_predictor_callsが暴走した生成プログラムに対する歯止めになる、と説明している。最適化後のmodule_srcはプログラムのシリアライズされた状態の一部として保存されるため、保存・読み込みでGEPAが発見した実装がそのまま保たれる。Flexは実験的機能であり、プログラムがFlexモジュールを含まない限り通常のGEPAの挙動は変わらない、ともリリースノートは明記している。実装のPR #10047をGitHub APIで確認すると、33ファイル変更・追加4,487行/削除54行という、このリリースの中でも大規模な変更であることが分かる。ここで使われるCodeInterpreter(dspy.PythonInterpreter)は、v3.3.1のリリースでサンドボックスの分離が強化された、DSPyがLLM生成コードを動かす際の共通基盤でもある。
dspy.ReActV2──ネイティブtool-callingへの載せ替え
もう一つの目玉が、担当者@isaacbmillerによるdspy.ReActV2だ。従来のReAct実装は独自のnext_tool_argsとカスタムのtrajectory構文を使っていたが、ReActV2はこれをネイティブtool-calling向けのdspy.History・dspy.Tool・dspy.ToolCalls(オプションでdspy.ToolCallResultsも格納可能)に置き換えた。dspy.Historyを使うことで、メッセージが「1つの巨大なuserメッセージにtrajectoryを全部詰め込む」形式から、user/assistant/toolのグループに分かれた構造化メッセージに変わる。
リリースノートが挙げる具体的な変化点は次の3つ。
| 変化点 | 内容 |
|---|---|
parallel_tool_calls対応 |
DSPyがID単位で各call/resultペアを保持。ネイティブ・非ネイティブどちらのモードでも可能 |
| マルチターンのネイティブtool call対応 | 過去のtool callと結果を、プロンプトテキストに平坦化せず、assistant/toolメッセージとして再生できる |
| ターンごとの構造化履歴 | 各ターンが伸び続ける1本のtrajectory文字列でなくdspy.History内の構造化メッセージとして存在するため、プロンプトキャッシュ対応プロバイダが安定したプレフィックスを再利用しやすくなる。リリースノートは「一部タスクで内部テスト時に最大50%のコスト減を確認した」としている |
ReActV2はcallableをdspy.Toolに変換し、最終出力用の内部submitツールを追加し、未知のツール呼び出しやツール例外を処理し、シリアライズされた履歴の入力を受け付け、モデルがsubmitを呼ばなかった場合は最終submissionを強制する機能も持つ、とリリースノートは説明している。実装のPRは#9823・#9824・#9825・#9835。GitHub APIでPR #9823(「ReActV2の最小実装、全3本中の1本目」と明記)を確認すると、実際のマージ日は2026年5月26日で、v3.3.0のリリース(8月3日)より3ヶ月以上前だった。つまりReActV2は今回のリリースで急に作られた機能ではなく、5月から段階的に積み上げられてきた実装が、このリリースでまとめて「experimental」として公式にお披露目された、という経緯が読み取れる。
リリースの内訳
| 項目 | 内容 |
|---|---|
| リリース日 | 2026-08-03 |
| バージョン | DSPy 3.3.0 |
| Flex担当 | @michaelisaac-dev(PR #10047) |
| ReActV2担当 | @isaacbmiller(PR #9823/#9824/#9825/#9835) |
| ステータス | どちらも「experimental」明記 |
| 既存プログラムへの影響 | リリースノートは「ほとんどの既存DSPyプログラムは変更なしで動き続ける」と明記 |
ReActV2の4本のPRは、実は同じ日の数時間のうちにまとまってマージされていた
前段で「5月から段階的に積み上げられてきた実装」と書いたが、GitHub APIでReActV2関連の4本のPR(#9823・#9824・#9825・#9835)それぞれのマージ日時をあらためて確認すると、実態はやや違っていた。
| PR | タイトル | マージ日時(UTC) | 変更行数 |
|---|---|---|---|
| #9823 | feat(adapter): preserve tool call ids and add tool results | 2026-05-26 17:31 | +378 / -60 |
| #9824 | feat(adapter): replay native tool call history | 2026-05-26 18:05 | +845 / -39 |
| #9825 | feat(predict): add ReActV2 | 2026-05-26 20:47 | +578 / -0 |
| #9835 | fix(utils): render inspect history tool calls | 2026-05-26 21:21 | +78 / -6 |
(出典:GitHub API、各PRのメタデータ)
4本すべてが2026年5月26日17:31〜21:21 UTC、約4時間のうちに連続してマージされている。合計すると追加1,879行・削除105行で、「段階的に積み上げ」というより「1日で集中して書かれた」というのが実態に近い。そこからDSPy 3.3.0で「experimental」として公式にお披露目されるまで、約2ヶ月半寝かされていたことになる──コードの実装時期と、機能として公式に発表される時期の間には、こうしたギャップがあることがGitHub APIから確認できる。
Flexのメトリクス関数には「6番目の引数」がある
PR #10047の本文を確認すると、dspy.Flexにはこの記事で紹介した以外にもう1つの技術的な仕組みがある。GEPAに渡すメトリクス関数はオプションで6番目のパラメータを受け取れるようになっており、それを使うとスコアリング時に実行トレース全体(LM呼び出し回数を含む)を参照できる。PR本文は使用例として「LM呼び出し回数にペナルティを課すため」と説明している。つまりFlexは、正解率のようなタスクの成否だけでなく、コスト(呼び出し回数)を直接メトリクスに織り込んでGEPAに最適化させることも想定した設計になっている。PR自体は2026年7月14日に作成され、8月3日のリリース当日にマージされており、Flex単体の開発期間は約3週間だった。
コスト減の数字について確認できていないこと
「一部タスクで最大50%のコスト減」というのはDSPyチーム自身の「内部テストで見た」という記述であり、リリースノートにベンチマークの詳細(どのタスク・どのモデル・何回の試行か)は書かれていない。第三者による独立検証は、この記事のために探した範囲では見つけられなかった。筆者はdspy.Flex・dspy.ReActV2を手元で実行して数値を再現する検証はしておらず、GitHub Releases APIで取得したリリースノート本文の記述をそのまま紹介している。Zenn記事検索でも「DSPy」自体の記事はあるものの、v3.3.0のFlex・ReActV2に絞った日本語記事はこの記事作成時点で見当たらなかった。
関連記事
出典・参照資料
- 二次資料DSPy 3.3.0 Release Notes(GitHub公式リリース) ↗
- 二次資料dspy.Flex PR #10047 ↗
- 二次資料PR #10047 のメタデータ(GitHub API、変更行数) ↗
- 二次資料PR #9823: ReActV2実装の1本目(GitHub API) ↗
- 二次資料PR #9824: ReActV2実装の2本目、ネイティブtool call履歴の再生(GitHub API) ↗
- 二次資料PR #9825: ReActV2実装の3本目、ReActV2本体の追加(GitHub API) ↗
- 二次資料PR #9835: ReActV2実装の4本目、履歴表示の修正(GitHub API) ↗
AIニュースの解説を動画でも
YouTubeでは注目ニュースの背景を解説し、Xでは新着記事をお知らせしています。
コメント
まだコメントはありません。最初のコメントを書いてみませんか?
AIについて聞きたいことはありますか?
質問箱で無料で受け付けています。回答は公開され、他の方の参考にもなります。
質問箱を見る →新しい記事をメールで受け取る
AIの新しい発表を、出典付きで整理して届けます。