Évaluation et sélection dans l’auto-amélioration
Apprenez à déterminer quels prompts générés sont les meilleurs et à sélectionner les gagnants.
Évaluation et sélection dans l’auto-amélioration est une leçon AI Prompt Engineering gratuite sur CoddyKit. Ceci est la leçon 4 sur 4. Tu peux lire la leçon complète ci-dessous gratuitement — puis la pratiquer en direct dans le navigateur avec un éditeur de code intégré et un tuteur IA 24/7. Elle fait partie du parcours d'apprentissage AI Prompt Engineering, et ta progression se synchronise sur le web et l'application CoddyKit. Le cours AI Prompt Engineering comprend 4 leçons au total.
Pourquoi l’évaluation est la partie la plus difficile
Générer des variantes d’instructions est facile. Évaluer quelle variante est réellement meilleure est la partie difficile de l’auto-amélioration. Sans évaluation rigoureuse, vous ne pouvez pas déterminer si une instruction réécrite est véritablement améliorée ou simplement différente. La qualité de l’évaluation détermine la qualité de toute la boucle d’amélioration.
Conception des critères de notation
Avant d’exécuter une boucle d’auto-amélioration, définissez ce que signifie « meilleure » pour votre tâche. Les critères de notation doivent être objectifs, mesurables et directement liés aux conditions de réussite de la tâche.
# Scoring criteria for different task types
SCORING_CRITERIA = {
'Classification': {
'primary_metric': 'Accuracy',
'formula': 'correct_predictions / total_predictions',
'secondary': ['Precision per class', 'F1 for rare classes'],
'target': 0.90
},
'Summarization': {
'primary_metric': 'LLM judge quality score',
'formula': 'average of judge scores on 1-5 scale, normalized to 0-1',
'secondary': ['ROUGE-L', 'Coverage of key facts', 'Hallucination rate'],
'target': 4.0 # on 1-5 scale
},
'Code generation': {
'primary_metric': 'Test pass rate',
'formula': 'tests_passing / total_tests',
'secondary': ['Syntax validity rate', 'Edge case coverage'],
'target': 0.85
},
'Information extraction': {
'primary_metric': 'F1 (precision + recall)',
'formula': '2 * precision * recall / (precision + recall)',
'secondary': ['Field-level accuracy', 'Format compliance rate'],
'target': 0.88
}
}
for task, criteria in SCORING_CRITERIA.items():
print(f'{task}: {criteria["primary_metric"]} (target: {criteria["target"]})')LLM évaluateur : notation multidimensionnelle
Pour les tâches ouvertes, un LLM évaluateur peut mesurer simultanément plusieurs dimensions de la qualité. Une notation multidimensionnelle fournit un signal plus riche qu’une note unique.
import anthropic, json
client = anthropic.Anthropic(api_key='YOUR_API_KEY')
MULTI_DIM_JUDGE_PROMPT = '''Evaluate this AI response across 5 dimensions. Return JSON only.
Task description: {task}
User input: {input}
AI response: {response}
Score each dimension 1-5:
- accuracy: Is the information correct and complete?
- relevance: Does it address exactly what was asked?
- clarity: Is it clear and easy to understand for the target audience?
- format: Does it follow the required output format?
- safety: Does it avoid harmful, misleading, or inappropriate content?
Return: {{"accuracy": N, "relevance": N, "clarity": N,
"format": N, "safety": N, "overall": avg, "rationale": "<1 sentence>"}}'''
def judge_response(task, input_text, response, weights=None):
weights = weights or {'accuracy': 0.30, 'relevance': 0.25,
'clarity': 0.20, 'format': 0.15, 'safety': 0.10}
judge_result = client.messages.create(
model='claude-opus-4-5', max_tokens=300,
messages=[{'role': 'user', 'content':
MULTI_DIM_JUDGE_PROMPT.format(
task=task, input=input_text, response=response
)}]
)
scores = json.loads(judge_result.content[0].text)
weighted_score = sum(scores[dim] * w for dim, w in weights.items() if dim in scores)
scores['weighted_total'] = round(weighted_score, 2)
return scoresAgrégation des notes sur les cas d’essai
La note globale d’une instruction est calculée sur l’ensemble de la suite d’essais. Les différentes stratégies d’agrégation révèlent différents aspects de la qualité de l’instruction.
import statistics
def aggregate_scores(case_scores):
'''
case_scores: list of dicts with dimension scores per test case
'''
dimensions = ['accuracy', 'relevance', 'clarity', 'format', 'safety']
aggregated = {}
for dim in dimensions:
values = [s[dim] for s in case_scores if dim in s]
if not values:
continue
aggregated[dim] = {
'mean': round(statistics.mean(values), 2),
'min': min(values),
'max': max(values),
'stdev': round(statistics.stdev(values), 2) if len(values) > 1 else 0
}
# Overall weighted mean
overall_scores = [s.get('weighted_total', 0) for s in case_scores]
aggregated['overall'] = {
'mean': round(statistics.mean(overall_scores), 2),
'p10': round(sorted(overall_scores)[int(len(overall_scores)*0.10)], 2),
'p90': round(sorted(overall_scores)[int(len(overall_scores)*0.90)], 2)
}
return aggregated
# Example
sample_scores = [
{'accuracy': 4, 'relevance': 5, 'clarity': 4, 'format': 3, 'safety': 5, 'weighted_total': 4.1},
{'accuracy': 3, 'relevance': 4, 'clarity': 5, 'format': 4, 'safety': 5, 'weighted_total': 3.9},
]
print(aggregate_scores(sample_scores))Critères de sélection : qualité, diversité, robustesse
La sélection de la meilleure instruction parmi les candidates doit prendre en compte trois dimensions : qualité (note moyenne), diversité (échoue-t-elle sur des cas différents de l’instruction actuelle ?) et robustesse (faible variance entre les cas).
def select_best_prompt(candidates, current_prompt_score):
'''
candidates: list of {prompt, scores, aggregated}
Returns the best candidate based on quality, diversity, robustness
'''
scored_candidates = []
for c in candidates:
agg = c['aggregated']['overall']
# Quality: mean score
quality = agg['mean']
# Robustness: inverse of P90-P10 spread (low spread = robust)
robustness = 1.0 - (agg['p90'] - agg['p10']) / 5.0
# Must beat current: reject if not better
if quality <= current_prompt_score:
continue
# Combined score
combined = 0.70 * quality + 0.30 * robustness
scored_candidates.append((combined, c))
if not scored_candidates:
print('No candidate beats current prompt. Keeping current.')
return None
scored_candidates.sort(reverse=True)
best = scored_candidates[0][1]
print(f'Selected candidate with combined score {scored_candidates[0][0]:.2f}')
return best['prompt']Suivi de l’instruction la plus performante
Tout au long de la boucle d’amélioration, suivez toujours l’instruction la plus performante observée jusqu’à présent. L’instruction de l’itération finale n’est pas nécessairement la meilleure : une réécriture peut améliorer certains cas tout en en faisant échouer d’autres.
class BestPromptTracker:
def __init__(self):
self.best_score = -1
self.best_prompt = None
self.best_iteration = -1
self.all_scores = []
def update(self, iteration, prompt, score):
self.all_scores.append({'iteration': iteration, 'score': score})
if score > self.best_score:
self.best_score = score
self.best_prompt = prompt
self.best_iteration = iteration
print(f'New best at iteration {iteration}: score={score:.2f}')
else:
print(f'Iteration {iteration}: score={score:.2f} '
f'(best is still {self.best_score:.2f} at iter {self.best_iteration})')
def get_best(self):
return self.best_prompt, self.best_score, self.best_iteration
def is_converged(self, patience=2, min_delta=0.01):
if len(self.all_scores) < patience + 1:
return False
recent = self.all_scores[-(patience+1):]
improvement = recent[-1]['score'] - recent[0]['score']
return improvement < min_delta
tracker = BestPromptTracker()
for i, score in enumerate([0.65, 0.72, 0.78, 0.77, 0.79]):
tracker.update(i, f'prompt_v{i}', score)
print('Best:', tracker.get_best())Critères d’arrêt
Savoir quand s’arrêter est aussi important que savoir quand continuer. De mauvais critères d’arrêt gaspillent le budget d’API ou mettent fin au processus trop tôt, avant d’atteindre les objectifs de qualité.
STOPPING_CONDITIONS = [
'Target score reached (e.g., >= 0.90)',
'No improvement over last N iterations (patience)',
'Maximum iteration budget exhausted',
'Score improvement delta below minimum threshold',
'All test cases pass (score = 1.0)',
'Cost budget exceeded'
]
def should_stop(tracker, config):
_, best_score, _ = tracker.get_best()
# Condition 1: Target reached
if best_score >= config['target_score']:
return True, f'Target score {config["target_score"]} reached'
# Condition 2: Patience exhausted
if tracker.is_converged(patience=config['patience'],
min_delta=config['min_delta']):
return True, f'No improvement over {config["patience"]} iterations'
# Condition 3: Max iterations
if len(tracker.all_scores) >= config['max_iterations']:
return True, f'Max iterations {config["max_iterations"]} reached'
return False, 'Continue'
config = {'target_score': 0.90, 'patience': 3,
'min_delta': 0.01, 'max_iterations': 10}
stop, reason = should_stop(tracker, config)
print(f'Stop: {stop} | Reason: {reason}')Conception de la suite d’essais pour l’auto-amélioration
La qualité de la boucle d’auto-amélioration dépend de la qualité de la suite d’essais. Une suite bien conçue couvre les cas typiques, limites et conçus pour mettre le système à l’épreuve, tout en restant stable (sans être mise à jour pendant la boucle).
def design_test_suite_for_improvement(task_description, target_size=50):
'''
Generate a balanced test suite for prompt self-improvement loops.
The suite is fixed and does not change during iterations.
'''
distribution = {
'typical': int(target_size * 0.50), # 50% typical cases
'edge_case': int(target_size * 0.25), # 25% edge cases
'adversarial': int(target_size * 0.15), # 15% adversarial
'off_topic': int(target_size * 0.10) # 10% off-topic (guardrails)
}
print('Test suite distribution:')
for category, count in distribution.items():
print(f' {category}: {count} cases')
# Key properties of a good evaluation test suite:
properties = [
'Fixed (never modified during improvement loop)',
'Balanced across difficulty levels',
'Has ground truth labels / expected outputs',
'Diverse in topic and phrasing within each category',
'Held-out: separate from any few-shot examples in the prompt'
]
for p in properties:
print(f' Property: {p}')
return distributionÉvaluation de la diversité entre les versions d’instruction
Deux instructions ayant la même note moyenne peuvent échouer sur des cas complètement différents. Comparer leurs ensembles d’échecs permet de déterminer si une nouvelle instruction est réellement complémentaire, ce qui est utile pour combiner plusieurs instructions.
def compare_failure_sets(prompt_a_results, prompt_b_results):
'''
Compare which cases each prompt fails on.
'''
fails_a = {r['case_id'] for r in prompt_a_results if not r['correct']}
fails_b = {r['case_id'] for r in prompt_b_results if not r['correct']}
both_fail = fails_a & fails_b
only_a_fails = fails_a - fails_b
only_b_fails = fails_b - fails_a
overlap = len(both_fail) / max(len(fails_a | fails_b), 1)
print(f'Prompt A failures: {len(fails_a)}')
print(f'Prompt B failures: {len(fails_b)}')
print(f'Both fail: {len(both_fail)} (overlap: {overlap:.0%})')
print(f'Only A fails: {len(only_a_fails)}')
print(f'Only B fails: {len(only_b_fails)}')
if overlap < 0.3:
print('LOW overlap — prompts are complementary. Consider ensembling.')
else:
print('HIGH overlap — B is a refinement of A, not a different approach.')
return {'overlap': overlap, 'only_a': only_a_fails, 'only_b': only_b_fails}Étalonnage : les notes de votre évaluateur sont-elles fiables ?
Les notes d’un LLM évaluateur ne sont utiles que si elles sont corrélées à la qualité réelle. L’étalonnage vérifie que les notes de l’évaluateur concordent avec les évaluations humaines sur un ensemble d’exemples de référence.
def calibrate_judge(judge_fn, gold_standard):
'''
gold_standard: list of {input, response, human_score} dicts
Returns correlation between judge scores and human scores.
'''
import statistics
judge_scores = []
human_scores = []
for example in gold_standard:
judge_score = judge_fn(
task='General response quality',
input_text=example['input'],
response=example['response']
)
judge_scores.append(judge_score)
human_scores.append(example['human_score'])
# Pearson correlation
n = len(judge_scores)
mean_j = statistics.mean(judge_scores)
mean_h = statistics.mean(human_scores)
cov = sum((j - mean_j) * (h - mean_h) for j, h in zip(judge_scores, human_scores))
std_j = statistics.stdev(judge_scores)
std_h = statistics.stdev(human_scores)
if std_j == 0 or std_h == 0:
return 0.0
correlation = cov / ((n - 1) * std_j * std_h)
print(f'Judge-Human correlation: {correlation:.3f}')
if correlation < 0.7:
print('WARNING: Low correlation. Judge may not reflect human quality judgment.')
return correlationApproche par combinaison : associer les meilleures instructions
Lorsque plusieurs variantes d’instructions échouent sur des cas différents, les combiner par vote majoritaire ou pondération selon la confiance produit une qualité supérieure à celle de toute instruction unique.
def ensemble_prompts(prompts, test_input, model='claude-haiku-4-5'):
'''
Run multiple prompts on the same input and take majority vote.
'''
outputs = []
for i, prompt in enumerate(prompts):
response = client.messages.create(
model=model, max_tokens=300,
messages=[{'role': 'user', 'content':
prompt + '\n\nInput: ' + test_input}]
)
outputs.append(response.content[0].text.strip())
# Majority vote for classification
from collections import Counter
vote_counts = Counter(outputs)
majority = vote_counts.most_common(1)[0][0]
confidence = vote_counts[majority] / len(outputs)
print(f'Ensemble ({len(prompts)} prompts): {majority} ({confidence:.0%} agreement)')
return majority, confidence
# When to use ensemble vs. single best prompt:
# - Ensemble: high-stakes classification, tolerate 3x API cost
# - Single best: cost-sensitive production, latency-critical
print('Ensemble is costlier but more robust for high-stakes outputs.')Vérification rapide
Deux variantes d’instructions obtiennent toutes deux une note de 0,82 sur la suite d’évaluation. Comment décider laquelle retenir ?
Résumé de l’évaluation et de la sélection
L’évaluation et la sélection sont les fondations de boucles d’auto-amélioration efficaces :
- Conception des critères : définir ce que signifie « meilleur » avant de commencer — exactitude, robustesse, respect du format
- Notation multidimensionnelle : les LLM évaluateurs notent séparément la qualité, la pertinence, la clarté, le format et la sécurité
- Agrégation : suivre la moyenne, P10 et P90 — pas uniquement la moyenne
- Sélection : équilibrer la qualité (note moyenne) et la robustesse (faible variance)
- Suivi de la meilleure instruction : toujours conserver la meilleure version historique, et pas seulement l’itération la plus récente
- Critères d’arrêt : note cible, patience, nombre maximal d’itérations, budget de coûts
- Diversité des ensembles d’échecs : repérer les instructions complémentaires à combiner
Questions Fréquemment Posées
La leçon « Évaluation et sélection dans l’auto-amélioration » est-elle gratuite ?
Oui — le texte complet de « Évaluation et sélection dans l’auto-amélioration » est gratuit à lire ici sur le web. Pour la pratiquer de manière interactive (un éditeur de code intégré et un tuteur IA 24/7) et déverrouiller le reste du cours AI Prompt Engineering, passe à CoddyKit PRO. Le cours AI Prompt Engineering comprend 4 leçons au total.
Qu'est-ce que j'apprendrai dans « Évaluation et sélection dans l’auto-amélioration » ?
Apprenez à déterminer quels prompts générés sont les meilleurs et à sélectionner les gagnants. Tu pratiques AI Prompt Engineering avec du code pratique que tu exécutes directement dans le navigateur, et un tuteur IA 24/7 répond à tes questions au fur et à mesure que tu avances dans la leçon.
Dois-je avoir de l'expérience pour commencer AI Prompt Engineering ?
Aucune expérience préalable n'est requise. AI Prompt Engineering sur CoddyKit est structuré pour les débutants jusqu'aux apprenants avancés, donc tu peux commencer ici ou depuis le début et avancer à ton rythme. Ceci est la leçon 4 sur 4.
Combien de temps prend la leçon « Évaluation et sélection dans l’auto-amélioration » ?
La plupart des leçons CoddyKit prennent environ 5–10 minutes. Chacune est courte et interactive, tu progresses régulièrement et tu repiques exactement où tu t'es arrêté sur le web et l'app.
Peux-tu écrire et exécuter du code dans cette leçon AI Prompt Engineering ?
Oui. Chaque leçon AI Prompt Engineering inclut un éditeur de code intégré, tu écris et exécutes du vrai code directement dans ton navigateur et tu reçois des retours IA instantanés — aucune configuration locale requise.
Toutes les leçons de ce cours
- Qu’est-ce que le méta-prompting ?
- Des prompts qui génèrent des prompts
- Systèmes de prompts qui s’améliorent eux-mêmes
- Évaluation et sélection dans l’auto-amélioration