Aller au contenu principal

Exercice : ingenierie de prompts

Objectif

Ameliorer un generateur de descriptions produit en appliquant les 4 techniques d’ingenierie de prompts, une par une. A chaque etape, vous observez l’amelioration qualitative.

Les 3 produits de test

Vous testerez chaque version du prompt sur ces 3 produits :

products = [
    {
        "name": "SoundWave Pro X",
        "type": "Casque audio sans fil",
        "price": "179 EUR",
        "features": "Reduction de bruit active, 40h d'autonomie, Bluetooth 5.3, pliable, microphones integres, codec LDAC",
        "target": "Professionnels en teletravail et audiophiles",
        "brand_tone": "Premium mais accessible"
    },
    {
        "name": "BrewMaster 3000",
        "type": "Machine a cafe automatique",
        "price": "449 EUR",
        "features": "Broyeur ceramique, 15 boissons, ecran tactile, reservoir 1.8L, systeme lait integre, mode eco",
        "target": "Amateurs de cafe exigeants",
        "brand_tone": "Expert et passionnee"
    },
    {
        "name": "TrailBlazer 45L",
        "type": "Sac a dos de randonnee",
        "price": "129 EUR",
        "features": "45 litres, dos ventile, housse de pluie integree, poches laterales filet, sangles de compression, compatible poche a eau",
        "target": "Randonneurs reguliers (treks 2-5 jours)",
        "brand_tone": "Aventurier et fiable"
    }
]

Iteration 1 : Le prompt naif (baseline)

import anthropic

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

def generate_description(prompt: str, product: dict) -> str:
    """Genere une description produit avec le prompt donne."""
    formatted = prompt.format(**product)
    response = client.messages.create(
        model=MODEL,
        max_tokens=1024,
        messages=[{"role": "user", "content": formatted}]
    )
    return response.content[0].text

# V1 — Prompt naif
PROMPT_V1 = "Ecris une description produit pour {name}."

for p in products:
    print(f"\n--- {p['name']} ---")
    print(generate_description(PROMPT_V1, p))

Problemes attendus : descriptions generiques, longueur imprecise, pas de structure, ton aleatoire, les caracteristiques du produit ne sont pas exploitees.


Iteration 2 : Etre clair et direct

On reecrit la premiere ligne avec un verbe d’action precis et on indique l’objectif.

# V2 — Clair et direct
PROMPT_V2 = """Redige une description commerciale pour le produit {name} ({type}).
La description doit convaincre un client potentiel d'acheter ce produit a {price}.
Cible : {target}."""

for p in products:
    print(f"\n--- {p['name']} ---")
    print(generate_description(PROMPT_V2, p))

Ameliorations attendues : la description est orientee vers la vente, le prix et la cible sont pris en compte. Mais la longueur, la structure et le ton restent imprecis.


Iteration 3 : Etre specifique

On ajoute des consignes sur la sortie (longueur, structure, contenu obligatoire) et le ton editorial.

# V3 — Specifique
PROMPT_V3 = """Redige une description commerciale pour le produit {name} ({type}) au prix de {price}.

Consignes :
- Longueur : 150-200 mots
- Structure : accroche (1 phrase percutante) + 1 paragraphe sur les benefices + liste de 3-4 fonctionnalites cles + phrase de conclusion avec appel a l'action
- Ton : {brand_tone}
- Cible : {target}
- Mentionne au moins 3 fonctionnalites parmi : {features}
- Mets en avant les benefices pour l'utilisateur, pas juste les specs techniques
- Ne commence pas par "Decouvrez" ou "Presentant"
"""

for p in products:
    print(f"\n--- {p['name']} ---")
    print(generate_description(PROMPT_V3, p))

Ameliorations attendues : structure coherente, bonne longueur, ton adapte. La description est vendable. Mais le format peut encore varier.


Iteration 4 : Structurer avec des balises XML

On encadre les informations produit dans des balises XML pour separer clairement les donnees des instructions.

# V4 — Balises XML
PROMPT_V4 = """<instructions>
Redige une description commerciale pour le produit ci-dessous.
Longueur : 150-200 mots.
Structure : accroche (1 phrase percutante) + paragraphe benefices + liste de 3-4 fonctionnalites + appel a l'action.
Ne commence pas par "Decouvrez" ou "Presentant".
Mets en avant les benefices pour l'utilisateur, pas juste les specs.
</instructions>

<produit>
Nom : {name}
Type : {type}
Prix : {price}
Fonctionnalites : {features}
</produit>

<cible>
Public : {target}
Ton editorial : {brand_tone}
</cible>"""

for p in products:
    print(f"\n--- {p['name']} ---")
    print(generate_description(PROMPT_V4, p))

Ameliorations attendues : meilleure separation entre instructions et donnees. Claude distingue clairement ce qu’il doit faire de ce sur quoi il doit travailler.


Iteration 5 : Fournir un exemple

On ajoute un exemple de description ideale pour ancrer le format et le style.

# V5 — Avec exemple
PROMPT_V5 = """<instructions>
Redige une description commerciale pour le produit ci-dessous.
Longueur : 150-200 mots.
Structure : accroche (1 phrase percutante) + paragraphe benefices + liste de 3-4 fonctionnalites + appel a l'action.
Ne commence pas par "Decouvrez" ou "Presentant".
Mets en avant les benefices pour l'utilisateur, pas juste les specs.
</instructions>

<exemple>
  <sample_input>
  Nom : AeroLite Runner
  Type : Chaussure de running
  Prix : 139 EUR
  Fonctionnalites : Semelle carbone, 195g, mesh respirant, drop 6mm, amorti reactif
  Public : Coureurs reguliers (10-50 km/semaine)
  Ton : Dynamique et technique
  </sample_input>
  <ideal_output>
  Chaque kilometre compte. L'AeroLite Runner est concue pour les coureurs qui refusent de choisir entre performance et confort.

  Avec seulement 195 grammes au pied, vous oubliez vos chaussures pour ne penser qu'a votre foulee. La semelle carbone transforme chaque appui en propulsion, tandis que le mesh respirant garde vos pieds au sec meme apres une heure d'effort.

  - **Semelle carbone** : restitution d'energie maximale a chaque foulee
  - **195g seulement** : l'une des plus legeres de sa categorie
  - **Amorti reactif** : protection articulaire sans sacrifier la reactivite
  - **Drop 6mm** : equilibre naturel entre attaque talon et mediopied

  A 139 EUR, l'AeroLite Runner est votre prochain PR qui n'attend plus que vous.
  </ideal_output>
</exemple>

<produit>
Nom : {name}
Type : {type}
Prix : {price}
Fonctionnalites : {features}
</produit>

<cible>
Public : {target}
Ton editorial : {brand_tone}
</cible>"""

for p in products:
    print(f"\n--- {p['name']} ---")
    print(generate_description(PROMPT_V5, p))

Ameliorations attendues : le format, le style et la structure sont constants d’un produit a l’autre. L’accroche est percutante, les fonctionnalites sont orientees benefices, l’appel a l’action est naturel.


Solution complete

"""
Exercice d'ingenierie de prompts : generateur de descriptions produit.
Necessite : pip install anthropic
Variable d'environnement : ANTHROPIC_API_KEY
"""

import anthropic

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

products = [
    {
        "name": "SoundWave Pro X",
        "type": "Casque audio sans fil",
        "price": "179 EUR",
        "features": "Reduction de bruit active, 40h d'autonomie, Bluetooth 5.3, pliable, microphones integres, codec LDAC",
        "target": "Professionnels en teletravail et audiophiles",
        "brand_tone": "Premium mais accessible"
    },
    {
        "name": "BrewMaster 3000",
        "type": "Machine a cafe automatique",
        "price": "449 EUR",
        "features": "Broyeur ceramique, 15 boissons, ecran tactile, reservoir 1.8L, systeme lait integre, mode eco",
        "target": "Amateurs de cafe exigeants",
        "brand_tone": "Expert et passionnee"
    },
    {
        "name": "TrailBlazer 45L",
        "type": "Sac a dos de randonnee",
        "price": "129 EUR",
        "features": "45 litres, dos ventile, housse de pluie integree, poches laterales filet, sangles de compression, compatible poche a eau",
        "target": "Randonneurs reguliers (treks 2-5 jours)",
        "brand_tone": "Aventurier et fiable"
    }
]

def generate_description(prompt: str, product: dict) -> str:
    formatted = prompt.format(**product)
    response = client.messages.create(
        model=MODEL,
        max_tokens=1024,
        messages=[{"role": "user", "content": formatted}]
    )
    return response.content[0].text

# --- Les 5 versions du prompt ---

PROMPT_V1 = "Ecris une description produit pour {name}."

PROMPT_V2 = """Redige une description commerciale pour le produit {name} ({type}).
La description doit convaincre un client potentiel d'acheter ce produit a {price}.
Cible : {target}."""

PROMPT_V3 = """Redige une description commerciale pour le produit {name} ({type}) au prix de {price}.

Consignes :
- Longueur : 150-200 mots
- Structure : accroche + paragraphe benefices + liste 3-4 fonctionnalites + appel a l'action
- Ton : {brand_tone}
- Cible : {target}
- Mentionne au moins 3 fonctionnalites parmi : {features}
- Benefices utilisateur, pas juste specs techniques
- Ne commence pas par "Decouvrez"
"""

PROMPT_V4 = """<instructions>
Redige une description commerciale pour le produit ci-dessous.
Longueur : 150-200 mots.
Structure : accroche + paragraphe benefices + liste 3-4 fonctionnalites + appel a l'action.
Ne commence pas par "Decouvrez" ou "Presentant".
Mets en avant les benefices utilisateur.
</instructions>

<produit>
Nom : {name}
Type : {type}
Prix : {price}
Fonctionnalites : {features}
</produit>

<cible>
Public : {target}
Ton editorial : {brand_tone}
</cible>"""

PROMPT_V5 = """<instructions>
Redige une description commerciale pour le produit ci-dessous.
Longueur : 150-200 mots.
Structure : accroche + paragraphe benefices + liste 3-4 fonctionnalites + appel a l'action.
Ne commence pas par "Decouvrez" ou "Presentant".
Mets en avant les benefices utilisateur.
</instructions>

<exemple>
  <sample_input>
  Nom : AeroLite Runner | Type : Chaussure de running | Prix : 139 EUR
  Fonctionnalites : Semelle carbone, 195g, mesh respirant, drop 6mm, amorti reactif
  Public : Coureurs reguliers | Ton : Dynamique et technique
  </sample_input>
  <ideal_output>
  Chaque kilometre compte. L'AeroLite Runner est concue pour les coureurs qui refusent de choisir entre performance et confort.

  Avec seulement 195 grammes au pied, vous oubliez vos chaussures pour ne penser qu'a votre foulee. La semelle carbone transforme chaque appui en propulsion, tandis que le mesh respirant garde vos pieds au sec meme apres une heure d'effort.

  - **Semelle carbone** : restitution d'energie maximale a chaque foulee
  - **195g seulement** : l'une des plus legeres de sa categorie
  - **Amorti reactif** : protection articulaire sans sacrifier la reactivite
  - **Drop 6mm** : equilibre naturel entre attaque talon et mediopied

  A 139 EUR, l'AeroLite Runner est votre prochain PR qui n'attend plus que vous.
  </ideal_output>
</exemple>

<produit>
Nom : {name}
Type : {type}
Prix : {price}
Fonctionnalites : {features}
</produit>

<cible>
Public : {target}
Ton editorial : {brand_tone}
</cible>"""

# --- Execution ---
prompts = {
    "V1 (naif)": PROMPT_V1,
    "V2 (clair et direct)": PROMPT_V2,
    "V3 (specifique)": PROMPT_V3,
    "V4 (balises XML)": PROMPT_V4,
    "V5 (avec exemple)": PROMPT_V5,
}

for version, prompt in prompts.items():
    print(f"\n{'='*60}")
    print(f"  {version}")
    print(f"{'='*60}")
    for p in products:
        print(f"\n--- {p['name']} ---")
        print(generate_description(prompt, p))

Ce que vous apprenez

  • Chaque technique apporte une amelioration incrementale et mesurable
  • Clair et direct fixe l’intention generale
  • Specifique donne les contraintes concretes
  • XML structure les donnees quand le prompt grossit
  • Exemples ancrent le format et le style de maniere definitive
  • L’ordre d’application compte : partez toujours du general vers le specifique