AIニュース最前線
最新ニュースAI日報Hacker日報週報動画AIツールトレンド企業

AIニュース最前線

世界中のAI最新情報を日本語で毎時更新

最新ニュース日報トレンド企業プレミアムRSS
© 2026 ainew.jp特定商取引法に基づく表記
ニュース一覧元記事を開く
MarkTechPost·2026年6月8日 02:05·約10分で読める

GEPA を用いた反射的プロンプト最適化:多要素プロンプト、構造化フィードバック、検証手法の構築

#Prompt Optimization#LLM Reasoning#GEPA#GPT-4.1#Structured Evaluation
TL;DR

GEPA フレームワークを用いた反射型プロンプト最適化手法が、多要素プロンプトと構造化フィードバックを通じて算数問題解決の精度を向上させる実証的なアプローチを示している。

AI深層分析2026年6月9日 14:12
4
重要/ 5段階
深度40%
5
関連度30%
4
実用性20%
4
革新性10%
3

キーポイント

1

反射型進化フレームワークの導入

GEPA(Generative Prompt Evolution with Action)を用いて、弱めのシードプロンプトから開始し、評価モデルによる構造化フィードバックを通じてプロンプトを反復的に改善する手法を採用している。

2

多コンポーネントプロンプトの同時最適化

指示(instruction)フィールドと出力フォーマット規則(output-format rules)という複数のプロンプト構成要素を同時に進化させることで、モデルの動作制御をより細かく行えるようにしている。

3

決定論的ベンチマークと検証セット

割引、移動距離、財布の中身などの算数問題からなる小規模な決定論的データセットを作成し、最適化プロセスを評価するためにホールドアウト検証セットを用いて比較検証を行っている。

4

タスクモデルと反射モデルの役割分担

GPT-4o-mini を問題解決用(タスク)モデルとして、より高性能な GPT-4.1 をプロンプト改善の判断を行う反射(リフレクション)モデルとして使い分ける構成を提案している。

5

多様な算数問題の自動生成

割引計算、移動距離、財布の残高計算、連鎖演算など4つの異なるカテゴリを含む決定論的なデータセットをプログラムで生成し、正解を厳密に定義しています。

6

検証可能なベンチマーク設計

各問題に対してコードベースで正解(gold answer)を算出することで評価の信頼性を高め、データセットをシャッフルして学習用と検証用に分割します。

7

構造化されたフィードバックルールの実装

正解・不正解・フォーマット違反のケースを明確に区別し、モデルが修正すべき具体的な指示(例:計算順序の見直しや最終行の形式強制)を含む詳細なフィードバックを生成する。

影響分析・編集コメントを表示

影響分析

この記事は、LLM のプロンプトエンジニアリングを「職人の勘」から「体系的な最適化プロセス」へと進化させる重要な一歩を示しています。特に、反射型アプローチと多コンポーネントの同時最適化を実装可能なコードとして提示している点は、実務における推論精度向上のための具体的な指針となり得ます。

編集コメント

プロンプトエンジニアリングの自動化において、単なるパラメータ調整ではなく「なぜ失敗したか」を分析する反射型アプローチの有効性を示しており、実務レベルでの推論精度向上を目指す開発者にとって非常に参考になる技術記事です。

本チュートリアルでは、GEPA を反射型プロンプト進化フレームワークとして使用し、言語モデルが算術文章問題を解決する方法を改善します。まず、弱いシードプロンプトから始め、小さな決定論的ベンチマークを作成し、構造化された評価者を定義して、候補となるプロンプトがなぜ失敗するのかを理解できるよう GEPA に実行可能なフィードバックを提供します。また、指示フィールドと出力フォーマット規則の両方が同時に進化するように、マルチコンポーネントプロンプト設定も使用します。最後に、保持された検証セット上でベースラインプロンプトと最適化済みプロンプトを比較し、進化プロセスがどのようにパフォーマンスを向上させるかを調査します。

GEPA と LiteLLM のインストールおよびタスク・反射モデルの設定

コードをコピーしました(別のブラウザを使用)

!pip install -q gepa litellm

import os, re, json, random, getpass, textwrap

import litellm

import gepa.optimize_anything as oa

from gepa.optimize_anything import (

optimize_anything, GEPAConfig, EngineConfig, ReflectionConfig,

)

litellm.suppress_debug_info = True

if not os.environ.get("OPENAI_API_KEY"):

os.environ["OPENAI_API_KEY"] = getpass.getpass("Enter your OpenAI API key: ")

TASK_LM = "openai/gpt-4o-mini"

REFLECTION_LM = "openai/gpt-4.1"

MAX_METRIC_CALLS = 100

GEPA と LiteLLM をインストールし、プロンプト最適化およびモデル呼び出しに必要なライブラリをインポートします。OpenAI API キーを安全に設定し、2 つのモデルを定義します。1 つは問題を解決するタスク用モデル、もう 1 つはプロンプトを改善するための反射用モデルです。また、最適化プロセスが制御範囲内となるよう、最大メトリック呼び出し予算を設定します。

決定論的算数ベンチマークデータセットの構築

コードをコピーしました(別のブラウザを使用してください)

必ず JSON 形式で返してください。translation フィールドのみ。他のフィールド (technical_terms 等) は一切追加しないこと — 余計なフィールドを書こうとして本文翻訳がトークン上限で打ち切られる事故を防ぐため:

{"translation": "翻訳全文"}

def make_problems(n, seed=0):

rng = random.Random(seed)

out = []

for _ in range(n):

t = rng.choice(["discount", "travel", "wallet", "chain"])

if t == "discount":

unit = rng.choice([40, 60, 80, 120])

qty = rng.choice([5, 6, 8, 10])

disc = rng.choice([10, 20, 25, 50])

total = unit * qty

gold = total - total * disc // 100

q = (f"A shop sells notebooks at {unit} rupees each. You buy {qty} "

f"notebooks and get a {disc}% discount on the total bill. "

f"How many rupees do you pay in total?")

elif t == "travel":

s1, h1 = rng.choice([40, 50, 60]), rng.choice([2, 3])

s2, h2 = rng.choice([30, 45, 70]), rng.choice([1, 2, 3])

gold = s1 * h1 + s2 * h2

q = (f"A car drives at {s1} km/h for {h1} hours, then at {s2} km/h "

f"for {h2} hours. What is the total distance travelled, in km?")

elif t == "wallet":

tens = rng.choice([3, 5, 7, 9])

fifties= rng.choice([2, 4, 6])

spent = rng.choice([50, 80, 110, 150])

gold = tens * 10 + fifties * 50 - spent

q = (f"You have {tens} ten-rupee notes and {fifties} fifty-rupee "

f"notes. You spend {spent} rupees. How many rupees are left?")

else:

x = rng.choice([6, 9, 12, 15]); y = rng.choice([4, 7, 10]); z = rng.choice([3, 8, 11])

gold = x * 2 - y + z

q = (f"Start with the number {x}. Double it, then subtract {y}, "

f"then add {z}. What number do you end with?")

out.append({"question": q, "answer": gold})

return out

all_problems = make_problems(18, seed=42)

random.Random(1).shuffle(all_problems)

trainset = all_problems[:12]

valset = all_problems[12:]

print(f"Dataset: {len(trainset)} train / {len(valset)} val problems\n")

割引、移動距離、財布の計算、連鎖演算を扱う算数文章問題からなる小規模な決定論的データセットを作成します。各問題に対する正解はプログラムによって生成されるため、ベンチマークの信頼性が保たれ、評価が容易になります。その後、例をシャッフルし、最適化用のトレーニングセットと一般化能力を検証するための検証セットに分割します。

GEPA における評価者の定義と構造化フィードバック

コピーコード コピー済み ブラウザを変更してください

必ず JSON 形式で返してください。translation フィールドのみ。他のフィールド (technical_terms 等) は一切追加しないこと — 余計なフィールドを書こうとして本文翻訳がトークン上限で打ち切られる事故を防ぐため:

{"translation": "翻訳全文"}

def build_system_prompt(candidate: dict) -> str:

return (f"{candidate['instructions']}\n\n"

f"OUTPUT FORMAT RULES:\n{candidate['format_rules']}")

def call_task_lm(system_prompt: str, question: str) -> str:

for attempt in range(3):

try:

r = litellm.completion(

model=TASK_LM,

messages=[{"role": "system", "content": system_prompt},

{"role": "user", "content": question}],

temperature=0, max_tokens=600, timeout=60,

)

return r["choices"][0]["message"]["content"] or ""

except Exception as e:

if attempt == 2:

return f"[LM_ERROR] {e}"

return ""

def parse_answers(text: str):

formatted = re.search(r"####\s*(-?\d+)", text)

all_nums = re.findall(r"-?\d+", text)

fmt_val = int(formatted.group(1)) if formatted else None

last_val = int(all_nums[-1]) if all_nums else None

return fmt_val, last_val

def evaluate(candidate: dict, example: dict):

system = build_system_prompt(candidate)

raw = call_task_lm(system, example["question"])

gold = example["answer"]

fmt_val, last_val = parse_answers(raw)

if fmt_val is not None and fmt_val == gold:

score, fb = 1.0, "Correct and correctly formatted."

elif fmt_val is not None and fmt_val != gold:

score, fb = 0.0, (f"WRONG ANSWER. You output '#### {fmt_val}' but the "

f"correct answer is {gold}. Re-check the arithmetic and "

f"the order of the steps.")

elif last_val == gold:

score, fb = 0.5, (f"Right number ({gold}) but FORMAT VIOLATION: the final "

f"line was not exactly '#### {gold}'. Always end with a "

f"line of the form '#### ' and nothing else.")

else:

score, fb = 0.0, (f"WRONG. Correct answer is {gold}. The model's final "

f"number was {last_val}. Likely a multi-step reasoning "

f"slip; show each step and verify before answering.")

oa.log(f"score={score} gold={gold} parsed_fmt={fmt_val} parsed_last={last_val}")

side_info = {

"feedback": fb,

"problem": example["question"],

"gold_answer": gold,

"model_output": raw[:500],

}

return score, side_info

def eval_set(candidate, dataset, label=""):

scores, exact, formatted = [], 0, 0

for ex in dataset:

s, info = evaluate(candidate, ex)

scores.append(s)

if s == 1.0: exact += 1; formatted += 1

elif s == 0.5: formatted += 0

acc = exact / len(dataset)

avg = sum(scores) / len(dataset)

print(f" [{label}] avg_score={avg:.3f} exact_correct+formatted={exact}/{len(dataset)}")

return avg, acc

候補プロンプトがシステムプロンプトに変換される方法と、タスクモデルが各質問を受け取る仕組みを定義します。また、モデルの出力を解析し、最終回答が必須の #### フォーマットに従っているかを確認してスコアを付与する評価者も作成します。GEPA が問題が推論の誤りなのか、フォーマットの不良なのか、あるいはその両方であるかを判断できるように、構造化されたフィードバックを実行可能なサイド情報として返します。

GEPA の設定とプロンプト最適化の実行

コードをコピーしました

別のブラウザを使用してください

seed_candidate = {

"instructions": "Solve the math problem.",

"format_rules": "Give the answer.",

}

print("=== BASELINE (seed prompt) ===")

print("Train:"); base_train = eval_set(seed_candidate, trainset, "train")

print("Val: "); base_val = eval_set(seed_candidate, valset, "val")

print()

objective = (

"Evolve a system prompt (the 'instructions' and 'format_rules' fields) so a "

"small LLM reliably solves multi-step arithmetic word problems AND always "

"ends with a line of exactly the form '#### '. Maximize the score."

)

background = (

"Scoring: 1.0 = correct number in the exact '#### ' format; 0.5 = correct "

"number but wrong/missing format; 0.0 = wrong number. Common failures are (a) not "

"emitting the '####' line, and (b) order-of-operations or multi-step slips. The "

"winning prompt should force explicit step-by-step work, a verification step, and "

"a strict final-answer line."

)

config = GEPAConfig(

engine=EngineConfig(

max_metric_calls=MAX_METRIC_CALLS,

max_workers=4,

parallel=True,

display_progress_bar=True,

seed=0,

),

reflection=ReflectionConfig(

reflection_lm=REFLECTION_LM,

),

)

print("=== RUNNING GEPA (this calls the LLMs; ~1-4 min) ===")

result = optimize_anything(

seed_candidate=seed_candidate,

evaluator=evaluate,

dataset=trainset,

valset=valset,

objective=objective,

background=background,

config=config,

)

まず、弱いシードプロンプトから始め、トレーニングセットとバリデーションセットの両方におけるそのベースライン性能を評価します。次に、最適化目標、背景スコアリングルール、および並列評価や反射モデルを含む GEPA 設定を定義します。最後に optimize_anything を実行して、GEPA が評価フィードバックを用いて指示とフォーマルールフィールドを進化させます。

バリデーションセットにおけるベースラインと GEPA 最適化プロンプトの比較

コピーコード コピー済み

異なるブラウザを使用してください

best = result.best_candidate

print("\n" + "=" * 78)

print("OPTIMIZED CANDIDATE")

print("=" * 78)

print("\n--- instructions ---\n" + textwrap.fill(best["instructions"], 96))

print("\n--- format_rules ---\n" + textwrap.fill(best["format_rules"], 96))

print("\n" + "=" * 78)

print("BEFORE vs AFTER (held-out validation set)")

print("=" * 78)

print("Seed prompt:"); _ = eval_set(seed_candidate, valset, "val-seed")

print("GEPA prompt:"); _ = eval_set(best, valset, "val-gepa")

print(f"\nBaseline val avg_score : {base_val[0]:.3f}")

print("\n" + "=" * 78)

print("EVOLUTION HISTORY (candidate index -> val score, parents)")

print("=" * 78)

cands = getattr(result, "candidates", [])

vscores = getattr(result, "val_aggregate_scores", [])

parents = getattr(result, "parents", [None] * len(cands))

for i, sc in enumerate(vscores):

par = parents[i] if i < len(parents) else None

tag = " <-- BEST" if cands and cands[i] == best else ""

print(f" cand {i:2d}: val_score={sc:.3f} parents={par}{tag}")

print(f"\nTotal metric calls used : {getattr(result, 'total_metric_calls', 'n/a')}")

print(f"Full validation evals : {getattr(result, 'num_full_val_evals', 'n/a')}")

print("\nDone. Try raising MAX_METRIC_CALLS or swapping REFLECTION_LM for a stronger model.")

GEPA によって見出された最良のプロンプトを抽出し、その最適化された指示とフォーマットルールコンポーネントを表示します。シードプロンプトと GEPA 最適化プロンプトを保持された検証セットで比較し、改善が未見の例にも転移するかを確認します。また、プロンプトが最適化の過程でどのように改善したかを理解するために、進化履歴、検証スコア、親関係、および総メトリック呼び出し回数を調査します。

結論として、GEPA を用いてプロンプト最適化が手動の試行錯誤を超えて進化する様子を示しました。タスクモデルが例を解き、評価者が出力にスコアをつけ、反射モデルが詳細なフィードバックを用いてより良いプロンプトを提案するという完全なワークフローを作成しました。また、最適化されたプロンプトを未見の検証問題でテストし、改善が単なる訓練セットへの過学習ではなく一般化しているかを評価できる仕組みを整えました。さらに、構造化されたフィードバック、厳格な評価、反復的な改良が連携してより強力で信頼性の高いプロンプトを生み出す、反射的プロンプト進化の実用的な例も構築しました。

ノートブック付きの完全コードをチェックしてください。また、Twitter でフォローすることもお気軽にどうぞ。15 万人以上の ML サブレッドに参加し、ニュースレターを購読することを忘れないでください。待ってください!Telegram をご利用ですか?今なら Telegram でも私たちに参加できます。

GitHub リポジトリや Hugging Face ページ、製品リリース、ウェビナーなどのプロモーションのためにパートナーシップをご希望ですか?ぜひご連絡ください。

GEPA を用いた反射的プロンプト最適化の構築:多コンポーネント・プロンプト、構造化フィードバック、およびホールドアウト検証に関する記事は、MarkTechPost で最初に公開されました。

原文を表示

In this tutorial, we use GEPA as a reflective prompt-evolution framework to improve the way a language model solves arithmetic word problems. We begin with a weak seed prompt, create a small deterministic benchmark, define a structured evaluator, and pass actionable feedback to GEPA so it can understand why a candidate prompt fails. We also use a multi-component prompt setup in which both the instruction field and the output-format rules evolve together. By the end, we compare the baseline prompt with the optimized prompt on a held-out validation set and inspect how the evolutionary process improves performance.

Installing GEPA and LiteLLM and Configuring the Task and Reflection Models

Copy CodeCopiedUse a different Browser

!pip install -q gepa litellm

import os, re, json, random, getpass, textwrap

import litellm

import gepa.optimize_anything as oa

from gepa.optimize_anything import (

optimize_anything, GEPAConfig, EngineConfig, ReflectionConfig,

)

litellm.suppress_debug_info = True

if not os.environ.get("OPENAI_API_KEY"):

os.environ["OPENAI_API_KEY"] = getpass.getpass("Enter your OpenAI API key: ")

TASK_LM = "openai/gpt-4o-mini"

REFLECTION_LM = "openai/gpt-4.1"

MAX_METRIC_CALLS = 100

We install GEPA and LiteLLM, then import the required libraries for prompt optimization and model calls. We securely set up the OpenAI API key and define two models: a task model that solves the problem and a reflection model that improves the prompt. We also set the maximum metric-call budget to keep the optimization process under control.

Building a Deterministic Arithmetic Benchmark Dataset

Copy CodeCopiedUse a different Browser

def make_problems(n, seed=0):

rng = random.Random(seed)

out = []

for _ in range(n):

t = rng.choice(["discount", "travel", "wallet", "chain"])

if t == "discount":

unit = rng.choice([40, 60, 80, 120])

qty = rng.choice([5, 6, 8, 10])

disc = rng.choice([10, 20, 25, 50])

total = unit * qty

gold = total - total * disc // 100

q = (f"A shop sells notebooks at {unit} rupees each. You buy {qty} "

f"notebooks and get a {disc}% discount on the total bill. "

f"How many rupees do you pay in total?")

elif t == "travel":

s1, h1 = rng.choice([40, 50, 60]), rng.choice([2, 3])

s2, h2 = rng.choice([30, 45, 70]), rng.choice([1, 2, 3])

gold = s1 * h1 + s2 * h2

q = (f"A car drives at {s1} km/h for {h1} hours, then at {s2} km/h "

f"for {h2} hours. What is the total distance travelled, in km?")

elif t == "wallet":

tens = rng.choice([3, 5, 7, 9])

fifties= rng.choice([2, 4, 6])

spent = rng.choice([50, 80, 110, 150])

gold = tens * 10 + fifties * 50 - spent

q = (f"You have {tens} ten-rupee notes and {fifties} fifty-rupee "

f"notes. You spend {spent} rupees. How many rupees are left?")

else:

x = rng.choice([6, 9, 12, 15]); y = rng.choice([4, 7, 10]); z = rng.choice([3, 8, 11])

gold = x * 2 - y + z

q = (f"Start with the number {x}. Double it, then subtract {y}, "

f"then add {z}. What number do you end with?")

out.append({"question": q, "answer": gold})

return out

all_problems = make_problems(18, seed=42)

random.Random(1).shuffle(all_problems)

trainset = all_problems[:12]

valset = all_problems[12:]

print(f"Dataset: {len(trainset)} train / {len(valset)} val problems\n")

We create a small deterministic dataset of arithmetic word problems covering discounts, travel distance, wallet calculations, and chained operations. We generate the correct answer for each problem programmatically, which keeps the benchmark reliable and easy to evaluate. We then shuffle the examples and split them into a training set for optimization and a validation set for testing generalization.

Defining the Evaluator and Structured Feedback for GEPA

Copy CodeCopiedUse a different Browser

def build_system_prompt(candidate: dict) -> str:

return (f"{candidate['instructions']}\n\n"

f"OUTPUT FORMAT RULES:\n{candidate['format_rules']}")

def call_task_lm(system_prompt: str, question: str) -> str:

for attempt in range(3):

try:

r = litellm.completion(

model=TASK_LM,

messages=[{"role": "system", "content": system_prompt},

{"role": "user", "content": question}],

temperature=0, max_tokens=600, timeout=60,

)

return r["choices"][0]["message"]["content"] or ""

except Exception as e:

if attempt == 2:

return f"[LM_ERROR] {e}"

return ""

def parse_answers(text: str):

formatted = re.search(r"####\s*(-?\d+)", text)

all_nums = re.findall(r"-?\d+", text)

fmt_val = int(formatted.group(1)) if formatted else None

last_val = int(all_nums[-1]) if all_nums else None

return fmt_val, last_val

def evaluate(candidate: dict, example: dict):

system = build_system_prompt(candidate)

raw = call_task_lm(system, example["question"])

gold = example["answer"]

fmt_val, last_val = parse_answers(raw)

if fmt_val is not None and fmt_val == gold:

score, fb = 1.0, "Correct and correctly formatted."

elif fmt_val is not None and fmt_val != gold:

score, fb = 0.0, (f"WRONG ANSWER. You output '#### {fmt_val}' but the "

f"correct answer is {gold}. Re-check the arithmetic and "

f"the order of the steps.")

elif last_val == gold:

score, fb = 0.5, (f"Right number ({gold}) but FORMAT VIOLATION: the final "

f"line was not exactly '#### {gold}'. Always end with a "

f"line of the form '#### <integer>' and nothing else.")

else:

score, fb = 0.0, (f"WRONG. Correct answer is {gold}. The model's final "

f"number was {last_val}. Likely a multi-step reasoning "

f"slip; show each step and verify before answering.")

oa.log(f"score={score} gold={gold} parsed_fmt={fmt_val} parsed_last={last_val}")

side_info = {

"feedback": fb,

"problem": example["question"],

"gold_answer": gold,

"model_output": raw[:500],

}

return score, side_info

def eval_set(candidate, dataset, label=""):

scores, exact, formatted = [], 0, 0

for ex in dataset:

s, info = evaluate(candidate, ex)

scores.append(s)

if s == 1.0: exact += 1; formatted += 1

elif s == 0.5: formatted += 0

acc = exact / len(dataset)

avg = sum(scores) / len(dataset)

print(f" [{label}] avg_score={avg:.3f} exact_correct+formatted={exact}/{len(dataset)}")

return avg, acc

We define how the candidate prompt is converted into a system prompt and how the task model receives each question. We also create the evaluator that parses the model output, checks whether the final answer follows the required #### <integer> format, and assigns a score. We return structured feedback as actionable side information so that GEPA can determine whether the issue is incorrect reasoning, poor formatting, or both.

Configuring GEPA and Running the Prompt Optimization

Copy CodeCopiedUse a different Browser

seed_candidate = {

"instructions": "Solve the math problem.",

"format_rules": "Give the answer.",

}

print("=== BASELINE (seed prompt) ===")

print("Train:"); base_train = eval_set(seed_candidate, trainset, "train")

print("Val: "); base_val = eval_set(seed_candidate, valset, "val")

print()

objective = (

"Evolve a system prompt (the 'instructions' and 'format_rules' fields) so a "

"small LLM reliably solves multi-step arithmetic word problems AND always "

"ends with a line of exactly the form '#### <integer>'. Maximize the score."

)

background = (

"Scoring: 1.0 = correct number in the exact '#### <int>' format; 0.5 = correct "

"number but wrong/missing format; 0.0 = wrong number. Common failures are (a) not "

"emitting the '####' line, and (b) order-of-operations or multi-step slips. The "

"winning prompt should force explicit step-by-step work, a verification step, and "

"a strict final-answer line."

)

config = GEPAConfig(

engine=EngineConfig(

max_metric_calls=MAX_METRIC_CALLS,

max_workers=4,

parallel=True,

display_progress_bar=True,

seed=0,

),

reflection=ReflectionConfig(

reflection_lm=REFLECTION_LM,

),

)

print("=== RUNNING GEPA (this calls the LLMs; ~1-4 min) ===")

result = optimize_anything(

seed_candidate=seed_candidate,

evaluator=evaluate,

dataset=trainset,

valset=valset,

objective=objective,

background=background,

config=config,

)

We start with a weak seed prompt and evaluate its baseline performance on both the training and validation sets. We then define the optimization objective, background scoring rules, and GEPA configuration, including parallel evaluation and the reflection model. Finally, we run optimize_anything so GEPA can evolve the instruction and format-rule fields using the evaluator feedback.

Comparing the Baseline and GEPA-Optimized Prompts on the Validation Set

Copy CodeCopiedUse a different Browser

best = result.best_candidate

print("\n" + "=" * 78)

print("OPTIMIZED CANDIDATE")

print("=" * 78)

print("\n--- instructions ---\n" + textwrap.fill(best["instructions"], 96))

print("\n--- format_rules ---\n" + textwrap.fill(best["format_rules"], 96))

print("\n" + "=" * 78)

print("BEFORE vs AFTER (held-out validation set)")

print("=" * 78)

print("Seed prompt:"); _ = eval_set(seed_candidate, valset, "val-seed")

print("GEPA prompt:"); _ = eval_set(best, valset, "val-gepa")

print(f"\nBaseline val avg_score : {base_val[0]:.3f}")

print("\n" + "=" * 78)

print("EVOLUTION HISTORY (candidate index -> val score, parents)")

print("=" * 78)

cands = getattr(result, "candidates", [])

vscores = getattr(result, "val_aggregate_scores", [])

parents = getattr(result, "parents", [None] * len(cands))

for i, sc in enumerate(vscores):

par = parents[i] if i < len(parents) else None

tag = " <-- BEST" if cands and cands[i] == best else ""

print(f" cand {i:2d}: val_score={sc:.3f} parents={par}{tag}")

print(f"\nTotal metric calls used : {getattr(result, 'total_metric_calls', 'n/a')}")

print(f"Full validation evals : {getattr(result, 'num_full_val_evals', 'n/a')}")

print("\nDone. Try raising MAX_METRIC_CALLS or swapping REFLECTION_LM for a stronger model.")

We extract the best prompt found by GEPA and print its optimized instruction and format-rule components. We compare the seed prompt and the GEPA-optimized prompt on the held-out validation set to check whether the improvement transfers to unseen examples. We also inspect the evolution history, validation scores, parent relationships, and total metric calls to understand how the prompt improved over the course of optimization.

In conclusion, we used GEPA to show how prompt optimization can move beyond manual trial and error. We created a complete workflow where a task model solves examples, an evaluator scores the outputs, and a reflection model uses detailed feedback to propose better prompts. We also tested the optimized prompt on unseen validation problems, which helps us assess whether the improvement generalizes rather than merely fitting the training set. Also, we built a practical example of reflective prompt evolution in which structured feedback, strict evaluation, and iterative refinement work together to produce a stronger, more reliable prompt.

Check out the Full Codes with Notebook. Also, feel free to follow us on Twitter and don’t forget to join our 150k+ ML SubReddit and Subscribe to our Newsletter. Wait! are you on telegram? now you can join us on telegram as well.

Need to partner with us for promoting your GitHub Repo OR Hugging Face Page OR Product Release OR Webinar etc.? Connect with us

The post Building Reflective Prompt Optimization with GEPA: Multi-Component Prompts, Structured Feedback, and Held-Out Validation appeared first on MarkTechPost.

この記事をシェア

関連記事

TLDR AI★42026年6月8日 09:00

AI エージェントに専用コンピューターを提供(7 分読了)

LangSmith は、信頼できないコードの実行リスクに対処するため、ハードウェア仮想化されたマイクロ VM を提供する「サンドボックス」を導入しました。これにより AI エージェントは、生産インフラを損なうことなく動的タスクを実行し、永続状態を管理できます。

Latent Space★52026年5月8日 16:11

OpenAI が新 SOTA リアルタイム音声 API「GPT-Realtime-2」などを発表

OpenAI は、音声認識・翻訳・リアルタイム通話性能を大幅に向上させた新モデル「GPT-Realtime-2」および関連 API を公開し、ベンチマークで前作より 15.2% 改善したと発表した。

Smol AI News★52026年5月7日 14:44

GPT-Realtime-2、-Translate、-Whisper:新SOTAリアルタイム音声APIの登場

AIニュース発信元が、OpenAI が発表した新しい SOTA(最新技術)リアルタイム音声 API「GPT-Realtime-2」「-Translate」「-Whisper」について報じた。これらは音声処理の速度と精度を大幅に向上させる新機能である。

今日のまとめ

AI日報で今日の重要ニュースをまとめ読み

ニュース一覧に戻る元記事を読む