Aller au contenu principal

Introduction a l'ingenierie de prompts

Le processus iteratif

L’ingenierie de prompts n’est pas de l’inspiration — c’est une methode. Le processus suit un cycle rigoureux :

  1. Definir l’objectif — Que doit faire le prompt, precisement ?
  2. Ecrire un premier prompt — Version naive, sans optimisation
  3. Evaluer — Mesurer les performances avec un pipeline d’evaluation
  4. Appliquer une technique — Une seule modification a la fois
  5. Re-evaluer — Mesurer l’impact de cette modification

Puis on repete les etapes 4 et 5 jusqu’a atteindre le score souhaite.

La regle d’or : un seul changement a la fois. Si vous modifiez trois choses en meme temps et que le score monte, vous ne saurez pas laquelle a eu l’effet positif.

Mise en place de l’evaluateur

Pour pratiquer de maniere reproductible, on met en place un evaluateur qui automatise le cycle.

import anthropic
import json

client = anthropic.Anthropic()
MODEL = "claude-sonnet-4-20250514"

def evaluate_prompt(prompt_template: str, test_cases: list, criteria: list) -> dict:
    """Evalue un prompt sur un jeu de donnees avec des criteres definis."""
    all_scores = []

    for case in test_cases:
        # Generer la reponse
        response = client.messages.create(
            model=MODEL,
            max_tokens=1024,
            messages=[{"role": "user", "content": prompt_template.format(**case["inputs"])}]
        )
        output = response.content[0].text

        # Noter la reponse
        scores = grade_response(output, case, criteria)
        all_scores.append(scores)

    # Calculer les moyennes
    avg = round(sum(s["moyenne"] for s in all_scores) / len(all_scores), 2)
    return {"detail": all_scores, "average": avg}

Generer des donnees de test

Plutot que d’ecrire manuellement chaque cas de test, on peut specifier le format attendu et laisser Claude generer les donnees :

prompt_inputs_spec = {
    "nom_athlete": "Nom d'un athlete fictif",
    "sport": "Un sport parmi : course, natation, cyclisme, musculation",
    "objectif": "Un objectif sportif precis (ex: marathon en moins de 3h30)",
    "restrictions": "Restrictions alimentaires eventuelles (vegetarien, sans gluten, etc.)"
}

def generate_test_data(spec: dict, n: int = 5) -> list:
    """Genere n cas de test a partir d'une specification."""
    prompt = f"""Genere {n} cas de test varies au format JSON.
Chaque cas doit avoir une cle "inputs" contenant les champs suivants :
{json.dumps(spec, indent=2, ensure_ascii=False)}

Reponds uniquement avec un tableau JSON."""

    response = client.messages.create(
        model=MODEL,
        max_tokens=2048,
        messages=[{"role": "user", "content": prompt}]
    )
    return json.loads(response.content[0].text)

Exemple concret : plan alimentaire pour athletes

Le prompt naif (baseline)

PROMPT_V1 = "Cree un plan alimentaire pour {nom_athlete} qui fait du {sport}."

Ce prompt va “fonctionner” — Claude va generer quelque chose. Mais sans contraintes, le resultat sera imprevisible : parfois trop long, parfois trop court, parfois sans macronutriments, parfois avec des aliments inappropries pour le sport en question.

Les criteres d’evaluation

criteria = [
    {
        "nom": "pertinence_sport",
        "description": "Le plan est-il adapte au sport et a l'objectif de l'athlete ?",
        "poids": 3
    },
    {
        "nom": "completude",
        "description": "Le plan couvre-t-il tous les repas de la journee avec des quantites ?",
        "poids": 2
    },
    {
        "nom": "precision_nutritionnelle",
        "description": "Les calories, macros et timing sont-ils precises ?",
        "poids": 3
    },
    {
        "nom": "respect_restrictions",
        "description": "Les restrictions alimentaires sont-elles respectees ?",
        "poids": 2
    }
]

Premier resultat

Avec le prompt naif, attendez-vous a un score faible — probablement entre 2 et 4 sur 10. C’est normal et c’est le point de depart. Ne soyez pas decourage par un mauvais score initial : il sert de reference pour mesurer les progres.

results_v1 = evaluate_prompt(PROMPT_V1, test_cases, criteria)
print(f"Score baseline : {results_v1['average']}/10")
# Score typique : ~3/10

La methode en pratique

A partir de cette baseline, on va appliquer les techniques des lecons suivantes, une par une :

EtapeTechniqueImpact attendu
1Etre clair et directScore passe de ~3 a ~4
2Etre specifiqueScore passe de ~4 a ~7-8
3Structurer avec XMLScore passe de ~7-8 a ~8-9
4Fournir des exemplesScore passe de ~8-9 a ~9+

Chaque technique a un impact mesurable. Les plus gros gains viennent des deux premieres (clarte et specificite). Les suivantes affinent les resultats.

Points cles

  • L’ingenierie de prompts est un processus iteratif mesurable, pas de l’intuition
  • Commencez toujours par un prompt naif pour etablir une baseline
  • Un seul changement a la fois pour isoler l’impact de chaque modification
  • Les scores bas au depart sont normaux — c’est le point de reference
  • Generez vos donnees de test avec Claude pour gagner du temps, mais verifiez-les
  • Definissez vos criteres d’evaluation avant de commencer a optimiser