ai-switching-models について
DSPy プログラムで AI モデルやプロバイダーを切り替える開発者向けのスキルです。タスクのシグネチャとモジュールを保ちながら、基準評価、モデル別のプロンプト再最適化、体系的な比較を案内します。
主な機能
- 01現在のモデルのベンチマーク
- 02別プロバイダーの設定
- 03モデルごとのプロンプト再最適化
- 04評価による候補モデルの比較
- 05モジュールごとのモデル割り当て
- 06モデル別の最適化済みプログラム保存
活用シーン
- 01低コストモデルの候補評価
- 02プロバイダー間での処理移行
- 03プライバシー要件に向けたローカルモデルの検証
- 04モデル更新による性能低下の評価
インストール
コマンドをコピーしてターミナルで実行します。
npx skills add https:/ / github.com/ lebsral/ dspy-programming-not-prompting-lms-skills --skill ai-switching-modelsインストール後、Claude Code で/ai-switching-modelsを入力して読み込まれたか確認します。
同梱ファイル
SKILL.md と一緒にインストールされる参考資料やスクリプト。
audit.yamlexamples.mdreference.mdevals/evals.json詳細
問題を起こさずにモデルを切り替える
AI モデルやプロバイダーを安全に切り替えられるよう、ユーザーを案内します。重要なポイントは、最適化されたプロンプトはモデル間で引き継げないことです(arxiv 2402.10949v2 — 「The Unreasonable Effectiveness of Eccentric Automatic Prompts」)。DSPy は、タスクの定義(シグネチャ+モジュール)とモデル固有のプロンプト(オプティマイザーでコンパイル)を分離することで、この問題を解決します。
モデルの切り替えで問題が起きる理由
手作業で調整したプロンプトはモデル固有です。GPT-4o 向けに設計されたプロンプトは、Claude、Llama、さらには GPT-4o-mini でも異なる結果になります。あるモデル向けに最適化されたプロンプトは、別のモデルの性能を実際に低下させる場合があることが、研究で示されています。
DSPy を使えば、次の理由から安全に切り替えられます。
- シグネチャはタスクの内容(入力、出力、型)を定義します。モデルに依存しません。
- モジュールはタスクの解決方法(Chain of Thought、ReAct など)を定義します。モデルに依存しません。
- コンパイル済みプロンプト(少数ショットの例、指示)はモデル固有ですが、オプティマイザーで自動的に再生成されます。
**ワークフロー:**プログラムはそのままに、モデルを切り替えて再最適化します。これで完了です。
ステップ 1:状況を把握する
ユーザーに次の質問をします。
- 現在使用しているモデルと、切り替え先のモデルを教えてください。(例:GPT-4o から Claude へ、クラウドからローカルへ)
- 切り替える理由は何ですか?(コスト、ベンダーの分散、性能の低下、プライバシー)
- 評価指標とテストデータはありますか?(切り替えがうまくいったか測定するために必要です。ない場合は、まず
/ai-improving-accuracyを使ってください)
よくあるシナリオ:
- コスト削減 — 「GPT-4o は高すぎます。もっと安価なモデルを使えますか?」
- ベンダーの分散 — 「1 つのプロバイダーだけに依存することはできません」
- 性能の低下 — 「プロバイダーがモデルを更新して、出力の品質が落ちました」
- データのプライバシー/コンプライアンス — 「自社のインフラストラクチャでモデルを実行する必要があります」
ステップ 2:任意のプロバイダーを設定する
DSPy は内部で LiteLLM を使用しているため、対応しているプロバイダーであれば、シンプルな文字列を指定して利用できます。
import dspy
# OpenAI
lm = dspy.LM("openai/gpt-4o")
lm = dspy.LM("openai/gpt-4o-mini")
# Anthropic
lm = dspy.LM("anthropic/claude-sonnet-4-5-20250929")
lm = dspy.LM("anthropic/claude-haiku-4-5-20251001")
# Azure OpenAI
lm = dspy.LM("azure/my-gpt4-deployment")
# Google
lm = dspy.LM("gemini/gemini-2.0-flash")
# Together AI (open-source models)
lm = dspy.LM("together_ai/meta-llama/Llama-3-70b-chat-hf")
# Local models (via Ollama)
lm = dspy.LM("ollama_chat/llama3.1", api_base="http://localhost:11434")
# Any OpenAI-compatible server (vLLM, TGI, etc.)
lm = dspy.LM("openai/my-model", api_base="http://localhost:8000/v1", api_key="none")
dspy.configure(lm=lm)
環境変数
API キーは環境変数として設定し、コードに直接記述しないでください。
# .env file
OPENAI_API_KEY=sk-...
ANTHROPIC_API_KEY=sk-ant-...
TOGETHER_API_KEY=...
AZURE_API_KEY=...
AZURE_API_BASE=https://your-resource.openai.azure.com/
対応プロバイダーの全一覧(100 以上)については、LiteLLM プロバイダーのドキュメントを参照してください。
ステップ 3:現在のモデルをベンチマークする
変更を加える前に、ベースラインを測定します。評価指標とテストデータが必要です。
from dspy.evaluate import Evaluate
# Your existing program and metric
program = MyProgram()
program.load("current_optimized.json") # load your production prompts
evaluator = Evaluate(
devset=devset,
metric=metric,
num_threads=4,
display_progress=True,
display_table=5,
)
# Benchmark with your current model
current_lm = dspy.LM("openai/gpt-4o")
dspy.configure(lm=current_lm)
baseline_score = evaluator(program)
print(f"Current model baseline: {baseline_score:.1f}%")
評価指標やテストデータがまだない場合は、まず /ai-improving-accuracy を使って準備してください。
ステップ 4:新しいモデルを試す(簡易テスト)
モデルを切り替え、再最適化せずに評価を実行します。これにより、古いプロンプトを引き継げないという問題を確認できます。
# Try the new model with your OLD optimized prompts
new_lm = dspy.LM("anthropic/claude-sonnet-4-5-20250929")
dspy.configure(lm=new_lm)
naive_score = evaluator(program)
print(f"Old model (optimized): {baseline_score:.1f}%")
print(f"New model (old prompts): {naive_score:.1f}%")
print(f"Drop: {baseline_score - naive_score:.1f}%")
通常は品質の低下が見られますが、これは想定どおりです。最適化済みのプロンプトは、以前のモデル向けに調整されているためです。
ステップ 5:新しいモデル向けに再最適化する
次に、新しいモデル向けにプログラムを再最適化します。同じシグネチャとモジュールを使用し、変更するのはコンパイル済みプロンプトだけです。
# Configure the new model
new_lm = dspy.LM("anthropic/claude-sonnet-4-5-20250929")
dspy.configure(lm=new_lm)
# Start from a fresh (unoptimized) program
fresh_program = MyProgram()
# Re-optimize for the new model
optimizer = dspy.MIPROv2(metric=metric, auto="medium")
optimized_for_new = optimizer.compile(fresh_program, trainset=trainset)
# Evaluate
reoptimized_score = evaluator(optimized_for_new)
print(f"Old model (optimized): {baseline_score:.1f}%")
print(f"New model (old prompts): {naive_score:.1f}%")
print(f"New model (re-optimized): {reoptimized_score:.1f}%")
再最適化後のスコアは、品質の大部分、またはすべてを取り戻せるはずです。そうならない場合は、次のいずれかを試してください。
- 新しいモデルでは、このタスクを同じ品質で処理できない可能性があります
- より重い最適化(
auto="heavy")を試します - まず BootstrapFewShot を試し、簡単な動作確認を行います
再最適化に適したオプティマイザーの選択
| オプティマイザー | 速度 | 品質の上限 | 使用する場面 |
|---|---|---|---|
BootstrapFewShot | 高速(数分) | 良好 | 簡単な動作確認、厳しい予算、初期の反復 |
MIPROv2(auto="light") | 中程度 | より良好 | ほとんどの切り替えでのデフォルトの再最適化 |
MIPROv2(auto="medium") | 低速(30~60 分) | 最高 | ローカル/小規模モデル、品質が重要な場合 |
MIPROv2(auto="heavy") | 非常に低速 | 最高 | medium でも性能が不足する場合の最終手段 |
簡易な再最適化(高速テスト)
本格的な MIPROv2 の実行に進む前に、手早く確認するには次の方法を使います。
optimizer = dspy.BootstrapFewShot(
metric=metric,
max_bootstrapped_demos=4,
max_labeled_demos=4,
)
quick_optimized = optimizer.compile(fresh_program, trainset=trainset)
quick_score = evaluator(quick_optimized)
ステップ 6:モデルを体系的に比較する
候補モデルを順に試し、それぞれを最適化して比較表を作成します。
candidates = [
("openai/gpt-4o", "GPT-4o"),
("openai/gpt-4o-mini", "GPT-4o-mini"),
("anthropic/claude-sonnet-4-5-20250929", "Claude Sonnet"),
("together_ai/meta-llama/Llama-3-70b-chat-hf", "Llama 3 70B"),
]
results = []
for model_id, label in candidates:
lm = dspy.LM(model_id)
dspy.configure(lm=lm)
# Optimize for this model
fresh = MyProgram()
optimizer = dspy.BootstrapFewShot(metric=metric, max_bootstrapped_demos=4)
optimized = optimizer.compile(fresh, trainset=trainset)
# Evaluate
score = evaluator(optimized)
# Save the optimized program
optimized.save(f"optimized_{label.lower().replace(' ', '_')}.json")
results.append({"model": label, "score": score})
print(f"{label}: {score:.1f}%")
# Print comparison table
print("\n--- Model Comparison ---")
print(f"{'Model':<25} {'Score':>8}")
print("-" * 35)
for r in sorted(results, key=lambda x: x["score"], reverse=True):
print(f"{r['model']:<25} {r['score']:>7.1f}%")
MIPROv2 を使用し、コストとレイテンシを追跡してさらに詳細に比較するには、examples.md を参照してください。
ステップ 7:1 つのパイプラインでモデルを使い分ける
すべての処理に同じモデルを使う必要はありません。各ステップに異なるモデルを割り当てます。単純なタスクには低コストのモデルを、難しいタスクには高コストのモデルを使います。
dspy.context を使用する(一時的、呼び出しごと)
cheap_lm = dspy.LM("openai/gpt-4o-mini")
expensive_lm = dspy.LM("openai/gpt-4o")
dspy.configure(lm=expensive_lm) # default
class MyPipeline(dspy.Module):
def __init__(self):
self.classify = dspy.Predict(ClassifySignature)
self.generate = dspy.ChainOfThought(GenerateSignature)
def forward(self, text):
# Cheap model for simple classification
with dspy.context(lm=cheap_lm):
category = self.classify(text=text)
# Expensive model for complex generation
return self.generate(text=text, category=category.label)
set_lm を使用する(永続的、モジュールごと)
pipeline = MyPipeline()
pipeline.classify.set_lm(cheap_lm)
pipeline.generate.set_lm(expensive_lm)
モジュールごとの LM 割り当てによるコスト最適化のパターンについては、/ai-cutting-costs を参照してください。
ステップ 8:保存してデプロイする
本番環境で使用する可能性のあるモデルごとに、最適化済みのプログラムを個別に保存します。
# Save per-model optimized programs
optimized_gpt4o.save("optimized_gpt4o.json")
optimized_claude.save("optimized_claude.json")
optimized_llama.save("optimized_llama.json")
# In production — load the right one
import os
model_name = os.environ.get("AI_MODEL", "openai/gpt-4o")
lm = dspy.LM(model_name)
dspy.configure(lm=lm)
program = MyProgram()
program.load(f"optimized_{model_name.split('/')[-1]}.json")
よくあるシナリオ
GPT-4o から GPT-4o-mini への移行(コスト削減)
- GPT-4o のベースラインをベンチマークします(ステップ 2)
- 以前のプロンプトで GPT-4o-mini を試し、性能の低下を確認します(ステップ 3)
- MIPROv2 を使用して GPT-4o-mini 向けに再最適化します(ステップ 4)
- スコアを比較し、品質が許容範囲内であれば移行します
OpenAI から Anthropic への移行(ベンダーの多様化)
- 環境に Anthropic の API キーを設定します
- モデル文字列を
"openai/gpt-4o"から"anthropic/claude-sonnet-4-5-20250929"に変更します - 再最適化します。モデルが異なれば、必要なプロンプトも異なります
- 最適化済みのプログラムを両方保持し、環境変数で切り替えます
クラウドからローカルへの移行(データプライバシー)
- ローカルモデルサーバー(Ollama、vLLM、TGI など)をセットアップします
- DSPy の接続先を指定します:
dspy.LM("ollama_chat/llama3.1", api_base="http://localhost:11434") - 再最適化します。特にローカルモデルでは再最適化が必要です
- 大規模なクラウドモデルと比べて品質が多少低下することを想定し、より強力な最適化を使用します
モデルのバージョン更新で問題が発生した場合
プロバイダーがモデルを更新したとき(例:GPT-4o のバージョン更新)は、次の手順を実行します:
- 評価を実行して、性能の低下を確認します
- 更新後のモデルを対象に再最適化します
- 新しい最適化済みプログラムを保存します
- ワークフローに評価と最適化を組み込むことが重要なのはこのためです。バージョン更新は緊急事態ではなく、定常的な作業になります
モデルを切り替えないほうがよい場合
- 評価をまだセットアップしていない場合。 指標とテストセットがなければ、新しいモデルのほうが良いか悪いか判断できません。まず
/ai-improving-accuracyを参照して評価をセットアップしてください。 - モデルではなく、プロンプトの品質をデバッグしている場合。 現在のモデルで出力の品質が低い場合、モデルを切り替えても、適切に定義されていないシグネチャーや不足している例は改善されません。まず現在の設定を最適化してください。
- 必要なのが別のモデルではなく、応答の高速化だけの場合。 レイテンシが問題なら、性能の低いモデルに切り替える前に、キャッシュ(
dspy.cache)、短いシグネチャー、またはdspy.ChainOfThoughtの代わりにdspy.Predictを使うことを検討してください。 - どのモデルでも対応できるほど単純なタスクの場合。 ゼロショットの
dspy.Predictですでに 95% 以上のスコアが出ているなら、モデルの選択はほとんど重要ではありません。別の点に注力してください。
注意点
- 再最適化せずに、最適化済みのプロンプトを複数のモデルで使い回すこと。 Claude はデフォルトで保存済みのプログラムを読み込み、LM の設定だけを切り替えます。コンパイル済みの少数例デモと指示は元のモデルに合わせて調整されているため、別のモデルでは通常、性能が低下します。モデルを切り替えたら、必ず新しい(未コンパイルの)プログラムから再最適化してください。
- 最適化されていないプロンプトや単一モデル向けのプロンプトでモデルを比較すること。 ゼロショットプロンプトや、あるモデル向けに最適化されたプロンプトで候補を実行すると、誤解を招く順位になります。比較スコアがプロンプトとの適合度ではなくモデルの能力を測るよう、各候補を個別に最適化してから比較してください。
- モデルを競わせる際に、評価モデルを固定し忘れること。 LLM を評価者として使うメトリクスでは、評価者を分離せずに
dspy.configure(lm=candidate_lm)を呼び出すと、評価モデルも変わります。すべての候補で評価者を一定に保つには、メトリクス関数内でdspy.context(lm=judge_lm)を使用してください。 set_lmが必要な場面でdspy.contextを使うこと(またはその逆)。dspy.context(lm=...)は一時的で、withブロックのスコープ内に限定されます。呼び出しごとの上書きに適しています。module.set_lm(lm)は永続的で、最適化中も設定が維持されます。モジュールで常に特定のモデルを使う場合に使用してください。取り違えると、気づきにくい評価バグが発生します。- より大規模な最適化を行わずに、ローカルモデルがクラウドモデルと同等の品質になると期待すること。 小規模なローカルモデル(7B~13B)は、クラウドモデルの品質に近づけるには、通常、より多くのブートストラップデモと大規模な最適化(
auto="heavy")が必要です。まずBootstrapFewShotでmax_bootstrapped_demos=8を設定し、それでもスコアが低い場合はMIPROv2に移行してください。
関連項目
任意のスキルをインストール:
npx skills add lebsral/DSPy-Programming-not-prompting-LMs-skills --skill <name>
- 切り替え前にメトリクスと評価を設定する方法については、
/ai-improving-accuracyを参照してください - コスト最適化のためのモジュール単位のモデル割り当てについては、
/ai-cutting-costsを参照してください - 複数のモデルを組み合わせたマルチステップパイプラインについては、
/ai-building-pipelinesを参照してください - 高価なモデルから安価なモデルへの蒸留については、
/ai-fine-tuningを参照してください - 再最適化に使用する DSPy オプティマイザーについては、
/dspy-optimizersを参照してください /ai-doがない場合はインストールしてください — あらゆる AI の問題を適切なスキルに振り分け、最も効率よく作業できます:npx skills add lebsral/DSPy-Programming-not-prompting-LMs-skills --skill ai-do
追加リソース
- 実例(コスト移行、ベンダー切り替え、モデルの比較)については、examples.md を参照してください
- API リファレンス(dspy.LM コンストラクター、dspy.configure、dspy.context、オプティマイザーのパラメーター)については、reference.md を参照してください