前回の記事、DSPyのプロンプト自動最適化機能であるOptimizerを試してみるその1 ~基礎編~では DSPy の Optimizer を試しました。与えられた以下の trainset から最適な出力方式を自己学習し出力を変更しています。
trainset = [
dspy.Example(question="日本で一番高い山は?", answer="富士山"),
dspy.Example(question="日本の首都は?", answer="東京"),
dspy.Example(question="太陽系で一番大きい惑星は?", answer="木星"),
dspy.Example(question="水の化学式は?", answer="H2O"),
dspy.Example(question="光の速さはおよそ秒速何キロメートル?", answer="約30万km"),
dspy.Example(question="地球の衛星の名前は?", answer="月"),
dspy.Example(question="日本で一番長い川は?", answer="信濃川"),
]この文体を学習することにより以下の様に出力が「ですます口調」から単語だけをシンプルに回答する形式に調整されています。
============================================================
【最適化前】
============================================================
Q: 人体で一番大きい臓器は?
A: 皮膚
Q: 世界で一番深い海溝は?
A: マリアナ海溝
Q: 日本の国花は?
A: 日本の国花は桜です。
============================================================
【最適化後】
============================================================
Q: 人体で一番大きい臓器は?
A: 皮膚
Q: 世界で一番深い海溝は?
A: マリアナ海溝
Q: 日本の国花は?
A: 桜
============================================================
【Optimizerが選んだお手本(demos)】
============================================================
お手本の数: 3
Demo 1: Q=日本で一番高い山は? -> A=富士山
Demo 2: Q=日本の首都は? -> A=東京
Demo 3: Q=太陽系で一番大きい惑星は? -> A=木星調整結果の再利用
この調整結果はjson形式で保存されており、2回目以降の推論実行ではそのjsonを指定することで、再度最適化プロセスを実行しなくても、最適化後の結果が出力されます。以下のスクリプトファイルを作成し実行してみます。
import dspy
# LM設定
lm = dspy.LM("openai/gpt-4o-mini")
dspy.configure(lm=lm)
# モジュールを作り直して、最適化結果を読み込む
qa = dspy.ChainOfThought("question -> answer")
qa.load("optimized_qa.json")
# あとは普通に使うだけ
result = qa(question="世界で一番高い山は?")
print("推論:", result.reasoning)
print("回答:", result.answer)python afteroptimized.py
推論: 世界で一番高い山はエベレスト山です。エベレストの標高は8,848メートルで、ネパールと中国の国境に位置しています。
回答: エベレスト山シンプルに単語だけを回答する形式で出力されていることがわかります。
Optimizerの様々なオプション
前回の記事で作成した最適化を実行したスクリプトから、Optimizer部分を抜き出したのが以下です。
optimizer = dspy.BootstrapFewShot(
metric=metric,
max_bootstrapped_demos=3, # LMに解かせて自動生成するお手本の数
max_labeled_demos=2, # trainsetからそのまま使うお手本の数
)BootstrapFewShot とは、DSPyで最も基本的なOptimizerです。学習データの質問をLLMに解かせて、正解できたケースの推論過程をまるごと記録し、それをfew-shotのお手本としてプロンプトに自動挿入します。人間がお手本を考える必要がなく、「LLMが自分でうまく解けた問題の解き方を、次の問題のお手本に使い回す」という仕組みです。データが少量(数件〜数十件)でもすぐに試せるため、DSPy Optimizerの入門として最適です。
それに対して、BootstrapFewShotWithRandomSearch は BootstrapFewShot を複数回繰り返して、最も性能の良い組み合わせを選ぶOptimizerです。BootstrapFewShot が1回だけお手本を生成して終わりなのに対し、こちらは num_candidate_programs で指定した回数だけ異なるお手本の組み合わせを生成し、それぞれの精度を評価して最良のものを採用します。お手本の「当たり外れ」を吸収できるため、trainsetに含まれるデータが50件以上あり、質がそろっていない可能性があるならこちらを使うほうが安定した結果が得られます。
実行結果は以下の様になります。
python optimizer.py
============================================================
【最適化前】
============================================================
Q: 人体で一番大きい臓器は?
A: 皮膚
Q: 世界で一番深い海溝は?
A: マリアナ海溝
Q: 日本の国花は?
A: 日本の国花は桜です。
============================================================
【最適化中...】
============================================================
Going to sample between 1 and 3 traces per predictor.
Will attempt to bootstrap 5 candidate sets.
Average Metric: 5.00 / 7 (71.4%): 100%|███████████████████████████████████████████████████| 7/7 [00:03<00:00, 1.86it/s]
2026/02/11 15:08:32 INFO dspy.evaluate.evaluate: Average Metric: 5 / 7 (71.4%)
New best score: 71.43 for seed -3
Scores so far: [71.43]
Best score so far: 71.43
Average Metric: 6.00 / 7 (85.7%): 100%|███████████████████████████████████████████████████| 7/7 [00:02<00:00, 2.78it/s]
2026/02/11 15:08:35 INFO dspy.evaluate.evaluate: Average Metric: 6 / 7 (85.7%)
New best score: 85.71 for seed -2
Scores so far: [71.43, 85.71]
Best score so far: 85.71
43%|████████████████████████████████████ | 3/7 [00:00<00:00, 362.32it/s]
Bootstrapped 3 full traces after 3 examples for up to 1 rounds, amounting to 3 attempts.
Average Metric: 6.00 / 7 (85.7%): 100%|███████████████████████████████████████████████████| 7/7 [00:02<00:00, 2.97it/s]
2026/02/11 15:08:37 INFO dspy.evaluate.evaluate: Average Metric: 6 / 7 (85.7%)
Scores so far: [71.43, 85.71, 85.71]
Best score so far: 85.71
43%|████████████████████████████████████▍ | 3/7 [00:07<00:09, 2.39s/it]
Bootstrapped 2 full traces after 3 examples for up to 1 rounds, amounting to 3 attempts.
Average Metric: 6.00 / 7 (85.7%): 100%|███████████████████████████████████████████████████| 7/7 [00:05<00:00, 1.33it/s]
2026/02/11 15:08:50 INFO dspy.evaluate.evaluate: Average Metric: 6 / 7 (85.7%)
Scores so far: [71.43, 85.71, 85.71, 85.71]
Best score so far: 85.71
29%|████████████████████████▎ | 2/7 [00:03<00:07, 1.52s/it]
Bootstrapped 1 full traces after 2 examples for up to 1 rounds, amounting to 2 attempts.
Average Metric: 6.00 / 7 (85.7%): 100%|███████████████████████████████████████████████████| 7/7 [00:05<00:00, 1.33it/s]
2026/02/11 15:08:58 INFO dspy.evaluate.evaluate: Average Metric: 6 / 7 (85.7%)
Scores so far: [71.43, 85.71, 85.71, 85.71, 85.71]
Best score so far: 85.71
14%|████████████▏ | 1/7 [00:01<00:10, 1.67s/it]
Bootstrapped 1 full traces after 1 examples for up to 1 rounds, amounting to 1 attempts.
Average Metric: 6.00 / 7 (85.7%): 100%|███████████████████████████████████████████████████| 7/7 [00:03<00:00, 2.31it/s]
2026/02/11 15:09:03 INFO dspy.evaluate.evaluate: Average Metric: 6 / 7 (85.7%)
Scores so far: [71.43, 85.71, 85.71, 85.71, 85.71, 85.71]
Best score so far: 85.71
14%|████████████▏ | 1/7 [00:01<00:07, 1.29s/it]
Bootstrapped 1 full traces after 1 examples for up to 1 rounds, amounting to 1 attempts.
Average Metric: 6.00 / 7 (85.7%): 100%|███████████████████████████████████████████████████| 7/7 [00:02<00:00, 3.40it/s]
2026/02/11 15:09:06 INFO dspy.evaluate.evaluate: Average Metric: 6 / 7 (85.7%)
Scores so far: [71.43, 85.71, 85.71, 85.71, 85.71, 85.71, 85.71]
Best score so far: 85.71
14%|████████████▏ | 1/7 [00:01<00:08, 1.43s/it]
Bootstrapped 1 full traces after 1 examples for up to 1 rounds, amounting to 1 attempts.
Average Metric: 6.00 / 7 (85.7%): 100%|███████████████████████████████████████████████████| 7/7 [00:02<00:00, 2.87it/s]
2026/02/11 15:09:10 INFO dspy.evaluate.evaluate: Average Metric: 6 / 7 (85.7%)
Scores so far: [71.43, 85.71, 85.71, 85.71, 85.71, 85.71, 85.71, 85.71]
Best score so far: 85.71
8 candidate programs found.
最適化完了!
============================================================
【最適化後】
============================================================
Q: 人体で一番大きい臓器は?
A: 皮膚
Q: 世界で一番深い海溝は?
A: マリアナ海溝
Q: 日本の国花は?
A: 桜
============================================================
【Optimizerが選んだお手本(demos)】
============================================================
お手本の数: 2
Demo 1: Q=日本で一番長い川は? -> A=信濃川
Demo 2: Q=水の化学式は? -> A=H2O
これらのお手本がプロンプトにfew-shotとして自動挿入され、
LLMの回答精度が向上します。
最適化結果を optimized_qa.json に保存しました。
次回は以下で読み込めます:
qa = dspy.ChainOfThought("question -> answer")
qa.load("optimized_qa.json")BootstrapFewShot 系はLLMへ与えるプロンプトと得られる回答を最適化します。
"demos": [
{
"question": "日本で一番長い川は?",
"answer": "信濃川"
},
{
"question": "水の化学式は?",
"answer": "H2O"
}この部分をLLMへ与えることで認識させ回答を同じ文体にそろえる役割を果たしています。
与えられるプロンプトの構成としては以下です。
システムメッセージ (role: system)
├── 指示文(instructions)
│ "Given the fields question, produce the fields answer."
├── お手本(demos)
│ Q: 日本の首都は? → A: 東京
│ Q: 太陽系で一番大きい惑星は? → A: 木星
└── 本題の質問
Q: 世界で一番深い海溝は?
ユーザーメッセージ (role: user)
└── (応答を促すメッセージ)MIPROv2という最適化アルゴリズムは`指示文(instructions)`も一緒に最適化してしまうことで、より明示的に期待するレスポンスを得るようにするものであり、BootStrapFewShot より強力とされています。
miprov2.py というファイルを作成します。
"""
DSPy Optimizer デモ: MIPROv2 による指示文+お手本の同時最適化
前提:
source ~/dspy-env/bin/activate
pip install dspy-ai openai
export OPENAI_API_KEY="sk-your-key-here"
実行:
python dspy_miprov2_demo.py
"""
import dspy
# ============================================================
# 1. LMの設定
# ============================================================
# OpenAI を使用
lm = dspy.LM("openai/gpt-4o-mini")
# Anthropic を使う場合はこちらに差し替え
# lm = dspy.LM("anthropic/claude-sonnet-4-20250514")
dspy.configure(lm=lm)
# ============================================================
# 2. 学習データ(正解ペア)を用意する
# DSPy の Optimizer は、この少量データから
# 「良いお手本」を自動選別してプロンプトに組み込む
# ============================================================
trainset = [
dspy.Example(question="日本で一番高い山は?", answer="富士山"),
dspy.Example(question="日本の首都は?", answer="東京"),
dspy.Example(question="太陽系で一番大きい惑星は?", answer="木星"),
dspy.Example(question="水の化学式は?", answer="H2O"),
dspy.Example(question="光の速さはおよそ秒速何キロメートル?", answer="約30万km"),
dspy.Example(question="地球の衛星の名前は?", answer="月"),
dspy.Example(question="日本で一番長い川は?", answer="信濃川"),
]
# with_inputs() で「入力はquestionだけ、answerは正解ラベル」と明示
trainset = [ex.with_inputs("question") for ex in trainset]
# ============================================================
# 3. モジュールを定義する(最適化「前」のベースライン)
# ============================================================
qa = dspy.ChainOfThought("question -> answer")
# ============================================================
# 4. 評価関数を定義する
# Optimizer はこの関数を使って「良い回答かどうか」を判定する
# ============================================================
def metric(example, pred, trace=None):
"""正解が予測に含まれていればTrue"""
return example.answer.lower() in pred.answer.lower()
# ============================================================
# 5. 最適化前の動作を確認
# ============================================================
print("=" * 60)
print("【最適化前】")
print("=" * 60)
test_questions = [
"人体で一番大きい臓器は?",
"世界で一番深い海溝は?",
"日本の国花は?",
]
for q in test_questions:
result = qa(question=q)
print(f" Q: {q}")
print(f" A: {result.answer}")
print()
# ============================================================
# 6. MIPROv2 で最適化する
# BootstrapFewShot との違い:
# - お手本(demos)だけでなく指示文(instructions)も同時に最適化
# - ベイズ最適化で最良の組み合わせを探索
# ============================================================
print("=" * 60)
print("【MIPROv2 で最適化中...】")
print("=" * 60)
optimizer = dspy.MIPROv2(
metric=metric,
auto="light", # light / medium / heavy から選択
)
optimized_qa = optimizer.compile(
qa,
trainset=trainset,
max_bootstrapped_demos=3,
max_labeled_demos=2,
)
print("最適化完了!\n")
# ============================================================
# 7. 最適化後の動作を確認
# ============================================================
print("=" * 60)
print("【最適化後】")
print("=" * 60)
for q in test_questions:
result = optimized_qa(question=q)
print(f" Q: {q}")
print(f" A: {result.answer}")
print()
# ============================================================
# 8. 最適化で何が起きたかを確認する
# ============================================================
print("=" * 60)
print("【Optimizerが選んだお手本(demos)】")
print("=" * 60)
demos = optimized_qa.predict.demos
print(f" お手本の数: {len(demos)}")
for i, demo in enumerate(demos):
print(f" Demo {i+1}: Q={demo.question} -> A={demo.answer}")
print()
print("=" * 60)
print("【MIPROv2が最適化した指示文(instructions)】")
print("=" * 60)
print(f" 最適化前: Given the fields `question`, produce the fields `answer`.")
print(f" 最適化後: {optimized_qa.predict.signature.instructions}")
print()
print("お手本+指示文の両方が最適化され、プロンプトに自動挿入されます。")
# ============================================================
# 9. 最適化済みモジュールを保存・読み込み(再利用)
# ============================================================
optimized_qa.save("optimized_miprov2.json")
print("\n最適化結果を optimized_miprov2.json に保存しました。")
print("次回は以下で読み込めます:")
print(' qa = dspy.ChainOfThought("question -> answer")')
print(' qa.load("optimized_miprov2.json")')実行すると以下が出力されます。
python miprov2.py
============================================================
【最適化前】
============================================================
Q: 人体で一番大きい臓器は?
A: 皮膚
Q: 世界で一番深い海溝は?
A: マリアナ海溝
Q: 日本の国花は?
A: 日本の国花は桜です。
============================================================
【MIPROv2 で最適化中...】
============================================================
2026/02/11 15:29:05 INFO dspy.teleprompt.mipro_optimizer_v2:
RUNNING WITH THE FOLLOWING LIGHT AUTO RUN SETTINGS:
num_trials: 10
minibatch: False
num_fewshot_candidates: 6
num_instruct_candidates: 3
valset size: 5
2026/02/11 15:29:05 INFO dspy.teleprompt.mipro_optimizer_v2:
==> STEP 1: BOOTSTRAP FEWSHOT EXAMPLES <==
2026/02/11 15:29:05 INFO dspy.teleprompt.mipro_optimizer_v2: These will be used as few-shot example candidates for our program and for creating instructions.
2026/02/11 15:29:05 INFO dspy.teleprompt.mipro_optimizer_v2: Bootstrapping N=6 sets of demonstrations...
Bootstrapping set 1/6
Bootstrapping set 2/6
Bootstrapping set 3/6
100%|█████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████| 2/2 [00:06<00:00, 3.17s/it]
Bootstrapped 2 full traces after 1 examples for up to 1 rounds, amounting to 2 attempts.
Bootstrapping set 4/6
100%|████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████| 2/2 [00:00<00:00, 550.07it/s]
Bootstrapped 2 full traces after 1 examples for up to 1 rounds, amounting to 2 attempts.
Bootstrapping set 5/6
100%|████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████| 2/2 [00:00<00:00, 741.31it/s]
Bootstrapped 2 full traces after 1 examples for up to 1 rounds, amounting to 2 attempts.
Bootstrapping set 6/6
100%|████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████| 2/2 [00:00<00:00, 634.06it/s]
Bootstrapped 2 full traces after 1 examples for up to 1 rounds, amounting to 2 attempts.
2026/02/11 15:29:11 INFO dspy.teleprompt.mipro_optimizer_v2:
==> STEP 2: PROPOSE INSTRUCTION CANDIDATES <==
2026/02/11 15:29:11 INFO dspy.teleprompt.mipro_optimizer_v2: We will use the few-shot examples from the previous step, a generated dataset summary, a summary of the program code, and a randomly selected prompting tip to propose instructions.
2026/02/11 15:29:16 INFO dspy.teleprompt.mipro_optimizer_v2:
Proposing N=3 instructions...
2026/02/11 15:29:38 INFO dspy.teleprompt.mipro_optimizer_v2: Proposed Instructions for Predictor 0:
2026/02/11 15:29:38 INFO dspy.teleprompt.mipro_optimizer_v2: 0: Given the fields `question`, produce the fields `answer`.
2026/02/11 15:29:38 INFO dspy.teleprompt.mipro_optimizer_v2: 1: You are a knowledgeable guide on Japanese geography and cultural landmarks. Given the field `question`, provide a detailed thought process in the `reasoning` field to explain your answer step by step, and then conclude with the final `answer`.
2026/02/11 15:29:38 INFO dspy.teleprompt.mipro_optimizer_v2: 2: You are a knowledgeable guide on Japanese geography and culture. Given the user's input question about Japan, produce a detailed reasoning that leads to the final answer. Make sure your reasoning is structured and clear, so that the user can easily follow your thought process and understand the answer.
2026/02/11 15:29:38 INFO dspy.teleprompt.mipro_optimizer_v2:
2026/02/11 15:29:39 INFO dspy.teleprompt.mipro_optimizer_v2: ==> STEP 3: FINDING OPTIMAL PROMPT PARAMETERS <==
2026/02/11 15:29:39 INFO dspy.teleprompt.mipro_optimizer_v2: We will evaluate the program over a series of trials with different combinations of instructions and few-shot examples to find the optimal combination using Bayesian Optimization.
2026/02/11 15:29:39 INFO dspy.teleprompt.mipro_optimizer_v2: == Trial 1 / 10 - Full Evaluation of Default Program ==
Average Metric: 3.00 / 5 (60.0%): 100%|██████████████████████████████████████████████████████████████████████████████████████| 5/5 [00:00<00:00, 177.53it/s]
2026/02/11 15:29:39 INFO dspy.evaluate.evaluate: Average Metric: 3 / 5 (60.0%)
2026/02/11 15:29:39 INFO dspy.teleprompt.mipro_optimizer_v2: Default program score: 60.0
/home/h-kameda/dspy-env/lib/python3.12/site-packages/dspy/teleprompt/mipro_optimizer_v2.py:646: ExperimentalWarning: Argument ``multivariate`` is an experimental feature. The interface can change in the future.
sampler = optuna.samplers.TPESampler(seed=seed, multivariate=True)
2026/02/11 15:29:39 INFO dspy.teleprompt.mipro_optimizer_v2: ===== Trial 2 / 10 =====
Average Metric: 4.00 / 5 (80.0%): 100%|███████████████████████████████████████████████████████████████████████████████████████| 5/5 [00:05<00:00, 1.19s/it]
2026/02/11 15:29:45 INFO dspy.evaluate.evaluate: Average Metric: 4 / 5 (80.0%)
2026/02/11 15:29:45 INFO dspy.teleprompt.mipro_optimizer_v2: Best full score so far! Score: 80.0
2026/02/11 15:29:45 INFO dspy.teleprompt.mipro_optimizer_v2: Score: 80.0 with parameters ['Predictor 0: Instruction 1', 'Predictor 0: Few-Shot Set 3'].
2026/02/11 15:29:45 INFO dspy.teleprompt.mipro_optimizer_v2: Scores so far: [60.0, 80.0]
2026/02/11 15:29:45 INFO dspy.teleprompt.mipro_optimizer_v2: Best score so far: 80.0
2026/02/11 15:29:45 INFO dspy.teleprompt.mipro_optimizer_v2: ========================
2026/02/11 15:29:45 INFO dspy.teleprompt.mipro_optimizer_v2: ===== Trial 3 / 10 =====
Average Metric: 3.00 / 5 (60.0%): 100%|███████████████████████████████████████████████████████████████████████████████████████| 5/5 [00:04<00:00, 1.21it/s]
2026/02/11 15:29:49 INFO dspy.evaluate.evaluate: Average Metric: 3 / 5 (60.0%)
2026/02/11 15:29:49 INFO dspy.teleprompt.mipro_optimizer_v2: Score: 60.0 with parameters ['Predictor 0: Instruction 2', 'Predictor 0: Few-Shot Set 0'].
2026/02/11 15:29:49 INFO dspy.teleprompt.mipro_optimizer_v2: Scores so far: [60.0, 80.0, 60.0]
2026/02/11 15:29:49 INFO dspy.teleprompt.mipro_optimizer_v2: Best score so far: 80.0
2026/02/11 15:29:49 INFO dspy.teleprompt.mipro_optimizer_v2: ========================
2026/02/11 15:29:49 INFO dspy.teleprompt.mipro_optimizer_v2: ===== Trial 4 / 10 =====
Average Metric: 4.00 / 5 (80.0%): 100%|█████████████████████████████████████████████████████████████████████████████████████| 5/5 [00:00<00:00, 1943.61it/s]
2026/02/11 15:29:49 INFO dspy.evaluate.evaluate: Average Metric: 4 / 5 (80.0%)
2026/02/11 15:29:49 INFO dspy.teleprompt.mipro_optimizer_v2: Score: 80.0 with parameters ['Predictor 0: Instruction 1', 'Predictor 0: Few-Shot Set 5'].
2026/02/11 15:29:49 INFO dspy.teleprompt.mipro_optimizer_v2: Scores so far: [60.0, 80.0, 60.0, 80.0]
2026/02/11 15:29:49 INFO dspy.teleprompt.mipro_optimizer_v2: Best score so far: 80.0
2026/02/11 15:29:49 INFO dspy.teleprompt.mipro_optimizer_v2: ========================
2026/02/11 15:29:49 INFO dspy.teleprompt.mipro_optimizer_v2: ===== Trial 5 / 10 =====
Average Metric: 3.00 / 5 (60.0%): 100%|███████████████████████████████████████████████████████████████████████████████████████| 5/5 [00:03<00:00, 1.50it/s]
2026/02/11 15:29:52 INFO dspy.evaluate.evaluate: Average Metric: 3 / 5 (60.0%)
2026/02/11 15:29:52 INFO dspy.teleprompt.mipro_optimizer_v2: Score: 60.0 with parameters ['Predictor 0: Instruction 2', 'Predictor 0: Few-Shot Set 2'].
2026/02/11 15:29:52 INFO dspy.teleprompt.mipro_optimizer_v2: Scores so far: [60.0, 80.0, 60.0, 80.0, 60.0]
2026/02/11 15:29:52 INFO dspy.teleprompt.mipro_optimizer_v2: Best score so far: 80.0
2026/02/11 15:29:52 INFO dspy.teleprompt.mipro_optimizer_v2: ========================
2026/02/11 15:29:52 INFO dspy.teleprompt.mipro_optimizer_v2: ===== Trial 6 / 10 =====
Average Metric: 3.00 / 5 (60.0%): 100%|███████████████████████████████████████████████████████████████████████████████████████| 5/5 [00:02<00:00, 2.26it/s]
2026/02/11 15:29:54 INFO dspy.evaluate.evaluate: Average Metric: 3 / 5 (60.0%)
2026/02/11 15:29:54 INFO dspy.teleprompt.mipro_optimizer_v2: Score: 60.0 with parameters ['Predictor 0: Instruction 0', 'Predictor 0: Few-Shot Set 5'].
2026/02/11 15:29:54 INFO dspy.teleprompt.mipro_optimizer_v2: Scores so far: [60.0, 80.0, 60.0, 80.0, 60.0, 60.0]
2026/02/11 15:29:54 INFO dspy.teleprompt.mipro_optimizer_v2: Best score so far: 80.0
2026/02/11 15:29:54 INFO dspy.teleprompt.mipro_optimizer_v2: ========================
2026/02/11 15:29:54 INFO dspy.teleprompt.mipro_optimizer_v2: ===== Trial 7 / 10 =====
Average Metric: 3.00 / 5 (60.0%): 100%|█████████████████████████████████████████████████████████████████████████████████████| 5/5 [00:00<00:00, 8487.06it/s]
2026/02/11 15:29:54 INFO dspy.evaluate.evaluate: Average Metric: 3 / 5 (60.0%)
2026/02/11 15:29:54 INFO dspy.teleprompt.mipro_optimizer_v2: Score: 60.0 with parameters ['Predictor 0: Instruction 2', 'Predictor 0: Few-Shot Set 0'].
2026/02/11 15:29:54 INFO dspy.teleprompt.mipro_optimizer_v2: Scores so far: [60.0, 80.0, 60.0, 80.0, 60.0, 60.0, 60.0]
2026/02/11 15:29:54 INFO dspy.teleprompt.mipro_optimizer_v2: Best score so far: 80.0
2026/02/11 15:29:54 INFO dspy.teleprompt.mipro_optimizer_v2: ========================
2026/02/11 15:29:54 INFO dspy.teleprompt.mipro_optimizer_v2: ===== Trial 8 / 10 =====
Average Metric: 3.00 / 5 (60.0%): 100%|███████████████████████████████████████████████████████████████████████████████████████| 5/5 [00:02<00:00, 2.10it/s]
2026/02/11 15:29:57 INFO dspy.evaluate.evaluate: Average Metric: 3 / 5 (60.0%)
2026/02/11 15:29:57 INFO dspy.teleprompt.mipro_optimizer_v2: Score: 60.0 with parameters ['Predictor 0: Instruction 2', 'Predictor 0: Few-Shot Set 5'].
2026/02/11 15:29:57 INFO dspy.teleprompt.mipro_optimizer_v2: Scores so far: [60.0, 80.0, 60.0, 80.0, 60.0, 60.0, 60.0, 60.0]
2026/02/11 15:29:57 INFO dspy.teleprompt.mipro_optimizer_v2: Best score so far: 80.0
2026/02/11 15:29:57 INFO dspy.teleprompt.mipro_optimizer_v2: ========================
2026/02/11 15:29:57 INFO dspy.teleprompt.mipro_optimizer_v2: ===== Trial 9 / 10 =====
Average Metric: 3.00 / 5 (60.0%): 100%|███████████████████████████████████████████████████████████████████████████████████████| 5/5 [00:02<00:00, 1.97it/s]
2026/02/11 15:29:59 INFO dspy.evaluate.evaluate: Average Metric: 3 / 5 (60.0%)
2026/02/11 15:29:59 INFO dspy.teleprompt.mipro_optimizer_v2: Score: 60.0 with parameters ['Predictor 0: Instruction 1', 'Predictor 0: Few-Shot Set 4'].
2026/02/11 15:29:59 INFO dspy.teleprompt.mipro_optimizer_v2: Scores so far: [60.0, 80.0, 60.0, 80.0, 60.0, 60.0, 60.0, 60.0, 60.0]
2026/02/11 15:29:59 INFO dspy.teleprompt.mipro_optimizer_v2: Best score so far: 80.0
2026/02/11 15:29:59 INFO dspy.teleprompt.mipro_optimizer_v2: ========================
2026/02/11 15:29:59 INFO dspy.teleprompt.mipro_optimizer_v2: ===== Trial 10 / 10 =====
Average Metric: 3.00 / 5 (60.0%): 100%|█████████████████████████████████████████████████████████████████████████████████████| 5/5 [00:00<00:00, 1659.53it/s]
2026/02/11 15:29:59 INFO dspy.evaluate.evaluate: Average Metric: 3 / 5 (60.0%)
2026/02/11 15:29:59 INFO dspy.teleprompt.mipro_optimizer_v2: Score: 60.0 with parameters ['Predictor 0: Instruction 2', 'Predictor 0: Few-Shot Set 5'].
2026/02/11 15:29:59 INFO dspy.teleprompt.mipro_optimizer_v2: Scores so far: [60.0, 80.0, 60.0, 80.0, 60.0, 60.0, 60.0, 60.0, 60.0, 60.0]
2026/02/11 15:29:59 INFO dspy.teleprompt.mipro_optimizer_v2: Best score so far: 80.0
2026/02/11 15:29:59 INFO dspy.teleprompt.mipro_optimizer_v2: =========================
2026/02/11 15:29:59 INFO dspy.teleprompt.mipro_optimizer_v2: ===== Trial 11 / 10 =====
Average Metric: 4.00 / 5 (80.0%): 100%|█████████████████████████████████████████████████████████████████████████████████████| 5/5 [00:00<00:00, 9718.04it/s]
2026/02/11 15:29:59 INFO dspy.evaluate.evaluate: Average Metric: 4 / 5 (80.0%)
2026/02/11 15:29:59 INFO dspy.teleprompt.mipro_optimizer_v2: Score: 80.0 with parameters ['Predictor 0: Instruction 1', 'Predictor 0: Few-Shot Set 3'].
2026/02/11 15:29:59 INFO dspy.teleprompt.mipro_optimizer_v2: Scores so far: [60.0, 80.0, 60.0, 80.0, 60.0, 60.0, 60.0, 60.0, 60.0, 60.0, 80.0]
2026/02/11 15:29:59 INFO dspy.teleprompt.mipro_optimizer_v2: Best score so far: 80.0
2026/02/11 15:29:59 INFO dspy.teleprompt.mipro_optimizer_v2: =========================
2026/02/11 15:29:59 INFO dspy.teleprompt.mipro_optimizer_v2: Returning best identified program with score 80.0!
最適化完了!
============================================================
【最適化後】
============================================================
Q: 人体で一番大きい臓器は?
A: 皮膚
Q: 世界で一番深い海溝は?
A: マリアナ海溝
Q: 日本の国花は?
A: 桜
============================================================
【Optimizerが選んだお手本(demos)】
============================================================
お手本の数: 2
Demo 1: Q=日本の首都は? -> A=東京
Demo 2: Q=日本で一番高い山は? -> A=富士山
============================================================
【MIPROv2が最適化した指示文(instructions)】
============================================================
最適化前: Given the fields `question`, produce the fields `answer`.
最適化後: You are a knowledgeable guide on Japanese geography and cultural landmarks. Given the field `question`, provide a detailed thought process in the `reasoning` field to explain your answer step by step, and then conclude with the final `answer`.
お手本+指示文の両方が最適化され、プロンプトに自動挿入されます。
最適化結果を optimized_miprov2.json に保存しました。
次回は以下で読み込めます:
qa = dspy.ChainOfThought("question -> answer")
qa.load("optimized_miprov2.json")ポイントは以下の部分です。LLMへ与えられれている指示がより明示的に期待する形式でのレスポンスを要求しています。
============================================================
【MIPROv2が最適化した指示文(instructions)】
============================================================
最適化前: Given the fields `question`, produce the fields `answer`.
最適化後: You are a knowledgeable guide on Japanese geography and cultural landmarks. Given the field `question`, provide a detailed thought process in the `reasoning` field to explain your answer step by step, and then conclude with the final `answer`.
