DSPy搭載オプティマイザ一覧

概要
DSPy オプティマイザ 統合リファレンス
DSPyオプティマイザとは
DSPyにおけるオプティマイザ(旧称:Teleprompter)は、DSPyプログラムのパラメータを自動的に調整し、指定したメトリクスを最大化するアルゴリズムである。従来、LLMアプリケーションの品質向上はプロンプトの手動チューニングに依存していたが、オプティマイザはこのプロセスをデータ駆動で自動化する——いわばLLMプログラムのための「コンパイラ」に相当する。
最適化対象となる3種のパラメータ
DSPyプログラムが持つ最適化可能なパラメータは以下の3種類であり、それぞれを専門とするカテゴリのオプティマイザが存在する。
- Few-Shotデモ(デモンストレーション): プロンプトに挿入する「入力→出力」の具体例。どの例を何件挿入するかをオプティマイザが自動選択・生成する
- インストラクション(指示文): 各モジュールに与えるタスク指示テキスト。「どのように考えるか」「何に注目するか」といった指示をオプティマイザが自動生成・改善する
- LMの重み: ファインチューニングによりモデル自体を更新する。プロンプト最適化だけでは限界がある場合に用いる
最適化の仕組み
最適化の方向性はユーザが定義する metric関数 によって決まる。metric関数はプログラムの出力を受け取りスコアを返す関数であり、オプティマイザはこのスコアを最大化するよう trainset(訓練データ)を用いてパラメータを探索する。
metric関数は正解ラベルとの比較関数(精度・F1等)である必要はない。「出力が日本語か」「回答が100文字以内か」といったルールベースの判定や、LLM-as-Judgeも利用できる。また、一部のオプティマイザはmetricなし(None)でも動作する。詳細は補足を参照のこと。
公式ドキュメント(dspy.ai)に基づき、以下の 4カテゴリ・11種類 のオプティマイザが存在する。
1. Automatic Few-Shot Learning(自動Few-Shot学習)
プロンプトに最適化された例(デモンストレーション)を自動生成・挿入するオプティマイザ群である。
Few-Shotデモとはプロンプト内に含める「入力→出力」の具体例のことであり、適切な例を適切な数だけ与えることでLLMは目的タスクのパターンを文脈から把握し精度が向上する。このカテゴリのオプティマイザは「どの例を選ぶか」「どう生成するか」を自動化するが、インストラクション(指示文)そのものは変更しない。
表の読み方:「metric」列はmetric関数が必要かどうか、「ラベル(正解出力)」列は訓練データに正解出力が必要かどうかを示す。
| オプティマイザ | 概要 | 適したタスク/指示のタイプ | metric | ラベル(正解出力) | コード例(一文) |
|---|---|---|---|---|---|
LabeledFewShot | ラベル付きデータからランダムに k 個のデモを選んでプロンプトに挿入する最もシンプルな方法。ラベル付きデータからランダムにデモを選ぶだけなので、metricは使わない。ただしラベルは必須。 | 良質なラベル付きデータが少量あり、素早くベースラインを作りたい分類・QAタスク。 | 不要 | 必要 | dspy.LabeledFewShot(k=8).compile(program, trainset=trainset) |
BootstrapFewShot | teacherモジュールで各ステップの完全なデモを自動生成し、metricを通過した高品質デモのみ保持する。metricがNoneの場合、すべてのブートストラップされたデモが受け入れられる(フィルタなし)。入力のみでも動作可能。 | データが約10件程度と少なく、自動でデモを生成して品質を底上げしたいタスク全般。 | あると良い(None可) | あると良い | dspy.BootstrapFewShot(metric=my_metric, max_bootstrapped_demos=4, max_labeled_demos=16).compile(program, trainset=trainset) |
BootstrapFewShotWithRandomSearch | BootstrapFewShot を複数回ランダムサーチで実行し、最良の候補プログラムを選択する。num_candidate_programs で候補数を指定可能。最も一般的に使われるオプティマイザの一つ。 | 50件以上のデータがあり、Bootstrap単体より確実に良い結果を得たいタスク全般。 | 必要 | あると良い | dspy.BootstrapFewShotWithRandomSearch(metric=my_metric, max_bootstrapped_demos=4, max_labeled_demos=4, num_candidate_programs=10).compile(program, trainset=trainset) |
KNNFewShot | k-最近傍法で入力に最も類似した訓練例を動的に選び、それをBootstrapFewShotの訓練セットとして使用する。入力依存の動的なデモ選択が可能。 | 入力の多様性が高く、入力ごとに最も関連性の高いデモを選びたいタスク(例:多ドメインQA)。入力の類似度でデモを選ぶ。 | 内部のBootstrapFewShot依存 | あると良い | dspy.KNNFewShot(k=3, trainset=trainset, vectorizer=dspy.Embedder(encoder_fn)).compile(program) |
2. Automatic Instruction Optimization(自動インストラクション最適化)
プロンプトのインストラクション(指示文)そのものを最適化するオプティマイザ群である。
インストラクションとは「あなたは優秀なアシスタントです。次の質問をステップバイステップで考えてください」のような、LLMへの振る舞い指示テキストのことである。Few-Shot学習がデモ(具体例)を最適化するのに対し、このカテゴリはテキストとしての指示そのものをデータから自動生成・改善する。なお MIPROv2 はインストラクションとFew-Shotデモの両方を同時に最適化する点で両カテゴリにまたがる存在である。
| オプティマイザ | 概要 | 適したタスク/指示のタイプ | metric | ラベル(正解出力) | コード例(一文) |
|---|---|---|---|---|---|
COPRO | 各ステップに対して新しいインストラクションを生成・改善し、座標上昇法(Coordinate Ascent)で最適化する。depth パラメータで改善イテレーション回数を制御。インストラクションの良し悪しをmetricで評価する必要あり。 | プロンプトの指示文(instruction)自体を磨き上げたい、比較的シンプルなパイプライン。 | 必要 | 入力のみでも可 | dspy.COPRO(metric=my_metric, depth=3, breadth=6).compile(program, trainset=trainset, eval_kwargs={}) |
MIPROv2 | インストラクション と Few-Shotデモの両方を同時に最適化。データ・デモ認識型の指示生成を行い、ベイズ最適化で探索空間を効率的に探索する。auto="light"/"medium"/"heavy" モードあり。最も強力な汎用オプティマイザの一つ。ベイズ最適化でインストラクション+デモを探索するためmetric必須。0-shot設定(max_bootstrapped_demos=0, max_labeled_demos=0)ならインストラクションだけ最適化でき、ラベル不要。 | 200件以上のデータで長時間最適化が可能な、複雑なマルチステップパイプラインやRAG。0-shot設定でインストラクションのみの最適化も可能。 | 必要 | 入力のみでも可 | dspy.MIPROv2(metric=my_metric, auto="light", num_threads=24).compile(program, trainset=trainset) |
SIMBA | Stochastic Introspective Mini-Batch Ascent。確率的ミニバッチサンプリングで出力のばらつきが大きい困難な例を特定し、LMの自己内省(Introspection)で失敗を分析、自己改善ルールやデモを生成する。失敗分析にmetricが必要。 | 大規模データセットでの系統的な改善や、出力品質のばらつきが大きいタスク。 | 必要 | 入力のみでも可 | dspy.SIMBA(metric=my_metric, bsize=8, max_steps=4, num_candidates=4).compile(program, trainset=trainset) |
GEPA | LMを使ってプログラムのトラジェクトリ(実行軌跡)を振り返り、何がうまくいき何がうまくいかなかったかを特定し、ギャップを埋めるプロンプトを提案する進化的オプティマイザ。ドメイン固有のテキストフィードバックも活用可能。トラジェクトリの振り返りにmetricが必要。論文: GEPA: Reflective Prompt Engineering | 複雑な推論タスクやドメイン特化の最適化で、ドメイン知識をフィードバックとして組み込みたい場合。 | 必要 | 入力のみでも可 | dspy.GEPA(metric=my_metric, auto="medium", reflection_lm=dspy.LM("openai/gpt-4o")).compile(program, trainset=trainset) |
3. Automatic Finetuning(自動ファインチューニング)
LMの重み自体を更新するオプティマイザである。
カテゴリ1・2のオプティマイザがプロンプトのみを変化させるのに対し、このカテゴリはモデルの重みを直接更新する。典型的な用途は「大規模LMで最適化したプログラムの振る舞いを小規模LMに蒸留し、推論コストとレイテンシを削減する」というものである。重みの更新が伴うため、利用可能なモデルはファインチューニングAPIに対応したものに限られる。
| オプティマイザ | 概要 | 適したタスク/指示のタイプ | metric | ラベル(正解出力) | コード例(一文) |
|---|---|---|---|---|---|
BootstrapFinetune | プロンプトベースのDSPyプログラムをLMの重み更新に蒸留。各ステップがファインチューニング済みモデルで実行されるプログラムを生成する。metricがあるとトレーニングデータのフィルタリングに使われる。 | 大規模LMで最適化した後、小規模LMに蒸留してコスト・レイテンシを下げたい場合。 | あると良い(None可) | あると良い | dspy.BootstrapFinetune(metric=my_metric, num_threads=24).compile(program, trainset=trainset) |
4. Program Transformations(プログラム変換)
複数のプログラムを組み合わせる変換オプティマイザである。
このカテゴリは単一プログラムを最適化するのではなく、すでに最適化された複数のプログラムを束ねて推論精度を向上させる。他のオプティマイザが生成した候補プログラム群を入力として受け取り、アンサンブルとして統合するため、単体では使わず他カテゴリと組み合わせて使用するのが一般的である。
| オプティマイザ | 概要 | 適したタスク/指示のタイプ | metric | ラベル(正解出力) | コード例(一文) |
|---|---|---|---|---|---|
Ensemble | 複数のDSPyプログラムをアンサンブルし、全セットまたはランダムサブセットを1つのプログラムに統合する。 | 複数のオプティマイザで生成した候補プログラムを多数決等で束ねて推論精度を上げたい場合。 | 不要 | 不要 | dspy.Ensemble(reduce_fn=dspy.majority, size=5).compile(list_of_programs) |
5. 複合オプティマイザ
プロンプト最適化とファインチューニングを交互に実行し、両者の相乗効果を狙うオプティマイザである。単独カテゴリのオプティマイザより高い性能が期待できるが、その分計算コストも増大する。
| オプティマイザ | 概要 | 適したタスク/指示のタイプ | metric | ラベル(正解出力) | コード例(一文) |
|---|---|---|---|---|---|
BetterTogether | プロンプト最適化(MIPROv2等)とファインチューニング(BootstrapFinetune)を交互に実行し、両者の相乗効果で最適化する。内部でMIPROv2+BootstrapFinetuneを交互に回すのでmetric必須。論文: Fine-Tuning and Prompt Optimization: Two Great Steps that Work Better Together | プロンプト最適化だけでは不十分で、重み更新も組み合わせて最大限の性能を引き出したい場合。 | 必要 | あると良い | dspy.BetterTogether(metric=my_metric, num_threads=24).compile(program, trainset=trainset) |
補足
- metricについて: 「必要」と記載したオプティマイザでも、metricは必ずしも正解ラベルとの比較関数である必要はない。LLM-as-Judgeや、出力フォーマットチェックなど、ラベル不要のmetric関数でも動作する。例えば「出力が日本語であるか」「回答が100文字以内か」「フォーマットが正しいか」といった、正解データに依存しないmetricも有効である。
- ラベル(正解出力)について:
LabeledFewShot以外は、原則として入力のみ(ラベルなし)のデータでも動作可能である。ラベルがあればmetricの品質が上がるので最適化の精度も上がるが、必須ではない。 - 「入力のみでも可」について: trainsetに
dspy.Example(question="...").with_inputs("question")のように入力フィールドだけを持つデータを渡しても最適化が実行できる。ラベル付きデータがあるほど最適化精度は向上するが、必須ではない。
選び方ガイド(公式推奨)
| 条件 | 推奨オプティマイザ |
|---|---|
| 例がごく少数(約10件) | BootstrapFewShot |
| 50件以上のデータがある | BootstrapFewShotWithRandomSearch |
| 0-shotでインストラクションのみ最適化したい | MIPROv2(0-shot設定) |
| 十分な推論コスト・データ(200件以上)で長時間最適化 | MIPROv2 |
| 大規模LMで最適化後、小規模LMに蒸留したい | BootstrapFinetune |
| 複雑な推論タスク・ドメイン特化 | GEPA |
| 大規模データセットでの系統的改善 | SIMBA |
オプティマイザは組み合わせ可能である。例えば MIPROv2 の出力を再度 MIPROv2 に入れたり、BootstrapFinetune に渡したりできる。また、複数の候補プログラムを Ensemble で統合することも可能である。
