Prompt engineering vs fine-tuning : cas concrets en production

Prompt engineering vs fine-tuning : cas concrets en production

Vous avez un cas d'usage LLM en production. Deux options s'offrent à vous : peaufiner vos prompts ou fine-tuner un modèle. Le mauvais choix peut vous coûter des mois de travail et des milliers d'euros. Ce guide vous aide à décider avec des cas concrets issus de projets réels.

Tableau décisionnel rapide

Critère Prompt Engineering Fine-tuning
Temps de mise en place Heures à jours Semaines à mois
Coût initial Quasi nul $500 - $50,000
Coût par requête Plus élevé (prompts longs) Plus faible
Flexibilité Très haute Figée après entraînement
Données requises Exemples dans le prompt 100 - 100,000 exemples
Maintenance Facile à itérer Réentraînement nécessaire
Performance max Bonne à très bonne Excellente si bien fait

Cas 1 : Classification de tickets support

Le contexte

Une entreprise SaaS reçoit 500 tickets/jour. Objectif : classifier automatiquement en 12 catégories (bug, feature request, billing, etc.).

Approche prompt engineering

CLASSIFICATION_PROMPT = """Tu es un expert en classification de tickets support.

CATÉGORIES DISPONIBLES:
1. BUG_CRITICAL - Application inutilisable
2. BUG_MINOR - Fonctionnalité dégradée mais utilisable
3. FEATURE_REQUEST - Demande de nouvelle fonctionnalité
4. BILLING - Questions facturation/paiement
5. ACCOUNT - Gestion de compte
6. INTEGRATION - Problèmes API/webhooks
7. PERFORMANCE - Lenteurs, timeouts
8. SECURITY - Failles, accès non autorisés
9. DOCUMENTATION - Questions sur la doc
10. ONBOARDING - Aide à la prise en main
11. DATA - Export, import, migration
12. OTHER - Ne correspond à aucune catégorie

RÈGLES:
- Choisis UNE SEULE catégorie
- Réponds UNIQUEMENT avec le code de catégorie
- En cas de doute entre bug et feature, choisis BUG

TICKET:
{ticket_content}

CATÉGORIE:"""

def classify_ticket(ticket: str) -> str:
    response = llm.generate(
        CLASSIFICATION_PROMPT.format(ticket_content=ticket),
        max_tokens=20,
        temperature=0
    )
    return response.strip()

Résultats :

  • Précision : 87%
  • Coût : $0.002/ticket (GPT-4o-mini)
  • Temps de développement : 2 jours

Approche fine-tuning

training_data = [
    {
        "messages": [
            {"role": "system", "content": "Classify support tickets."},
            {"role": "user", "content": "L'app crash quand je clique sur export"},
            {"role": "assistant", "content": "BUG_CRITICAL"}
        ]
    },
    # ... 5000 exemples annotés
]

from openai import OpenAI
client = OpenAI()

file = client.files.create(file=open("training.jsonl"), purpose="fine-tune")
job = client.fine_tuning.jobs.create(
    training_file=file.id,
    model="gpt-4o-mini-2024-07-18"
)

Résultats :

  • Précision : 94%
  • Coût : $0.0004/ticket (modèle fine-tuné)
  • Temps de développement : 3 semaines (annotation + entraînement)
  • Coût fine-tuning : ~$200

Verdict cas 1

Métrique Prompt Fine-tuning Gagnant
Précision 87% 94% Fine-tuning
Coût/requête $0.002 $0.0004 Fine-tuning
Time-to-market 2 jours 3 semaines Prompt
ROI à 6 mois Positif Très positif Fine-tuning

Recommandation : Commencer par prompt engineering pour valider le use case, puis fine-tuner si le volume justifie l'investissement (>1000 tickets/jour).

Cas 2 : Génération de descriptions produits e-commerce

Le contexte

Un marketplace génère des descriptions pour 10,000 nouveaux produits/mois. Chaque description doit respecter un ton de marque spécifique et inclure des mots-clés SEO.

Approche prompt engineering

PRODUCT_PROMPT = """Tu es un copywriter expert pour {brand_name}.

TON DE LA MARQUE:
- Professionnel mais accessible
- Valorise la qualité et la durabilité
- Évite le jargon technique excessif
- Utilise des phrases courtes et percutantes

STRUCTURE OBLIGATOIRE:
1. Accroche (1 phrase)
2. Bénéfices clés (3 points)
3. Caractéristiques techniques
4. Call-to-action

MOTS-CLÉS À INCLURE: {keywords}

PRODUIT:
Nom: {product_name}
Catégorie: {category}
Spécifications: {specs}

DESCRIPTION (150-200 mots):"""

Résultats :

  • Qualité : 7/10 (jugement humain)
  • Cohérence ton : 70%
  • Coût : $0.01/description
  • Temps de développement : 1 semaine

Approche fine-tuning

training_examples = [
    {
        "messages": [
            {"role": "system", "content": "Generate product descriptions for BrandX."},
            {"role": "user", "content": "Product: Veste imperméable TrailPro\nCategory: Outdoor\nSpecs: Gore-Tex, 450g, 3 poches"},
            {"role": "assistant", "content": "Affrontez les éléments en toute confiance.\n\n✓ Protection Gore-Tex contre pluie et vent\n✓ Légèreté remarquable (450g) pour vos longues randonnées\n✓ Rangement optimisé avec 3 poches stratégiques\n\nConçue pour les aventuriers exigeants, la TrailPro combine technicité et confort. Sa membrane respirante évacue l'humidité tout en vous gardant au sec.\n\nPrêt pour votre prochaine aventure ?"}
        ]
    }
]

Résultats :

  • Qualité : 9/10
  • Cohérence ton : 95%
  • Coût : $0.003/description
  • Temps de développement : 4 semaines
  • Coût fine-tuning : ~$150

Verdict cas 2

Fine-tuning recommandé car :

  • Le ton de marque est difficile à capturer en prompt
  • Volume élevé (10K/mois) → économies significatives
  • La cohérence est critique pour l'image de marque

Cas 3 : Chatbot FAQ interne

Le contexte

Une entreprise de 500 employés veut un chatbot pour répondre aux questions RH (congés, remboursements, procédures).

Approche prompt engineering avec RAG

def answer_hr_question(question: str) -> str:
    # 1. Récupérer les documents pertinents
    docs = vector_store.search(question, top_k=3)

    # 2. Construire le prompt
    context = "\n\n".join([d.content for d in docs])

    prompt = f"""Tu es l'assistant RH de {company_name}.

DOCUMENTATION RH:
{context}

RÈGLES:
- Réponds UNIQUEMENT à partir de la documentation
- Si l'info n'est pas disponible, oriente vers hr@company.com
- Sois concis et pratique
- Cite la source (nom du document)

QUESTION: {question}

RÉPONSE:"""

    return llm.generate(prompt)

Résultats :

  • Précision : 92%
  • Satisfaction utilisateurs : 4.2/5
  • Coût : $0.005/question
  • Temps de développement : 2 semaines

Pourquoi NE PAS fine-tuner ici

  1. Données évolutives : Les politiques RH changent régulièrement
  2. Traçabilité : Le RAG permet de citer les sources
  3. Pas de style spécifique : Un ton professionnel standard suffit
  4. Volume faible : ~100 questions/jour

Le fine-tuning serait contre-productif : il faudrait réentraîner à chaque mise à jour de politique.

Cas 4 : Extraction d'informations structurées

Le contexte

Une entreprise juridique extrait des informations de contrats (parties, montants, dates, clauses clés) à partir de PDF.

Approche prompt engineering

EXTRACTION_PROMPT = """Extrais les informations suivantes du contrat.

FORMAT DE SORTIE (JSON strict):
{
  "parties": [{"name": "...", "role": "vendeur|acheteur|..."}],
  "montant_total": {"value": number, "currency": "EUR|USD|..."},
  "date_signature": "YYYY-MM-DD",
  "date_effet": "YYYY-MM-DD",
  "duree_mois": number,
  "clauses_importantes": ["...", "..."]
}

CONTRAT:
{contract_text}

JSON:"""

Résultats :

  • Précision extraction : 78%
  • Erreurs de format JSON : 15%
  • Coût : $0.05/contrat (documents longs)

Approche fine-tuning

training_data = [
    {
        "messages": [
            {"role": "system", "content": "Extract contract information as JSON."},
            {"role": "user", "content": "[Contract text...]"},
            {"role": "assistant", "content": '{"parties": [...], "montant_total": {...}}'}
        ]
    }
]

job = client.fine_tuning.jobs.create(
    training_file=file.id,
    model="gpt-4o-mini-2024-07-18",
    hyperparameters={"n_epochs": 3}
)

Résultats :

  • Précision extraction : 91%
  • Erreurs de format JSON : 2%
  • Coût : $0.015/contrat
  • Temps annotation : 2 mois (500 contrats complexes)

Verdict cas 4

Aspect Prompt Fine-tuning
Précision 78% 91%
Fiabilité format 85% 98%
Coût/contrat $0.05 $0.015
Investment initial Faible Élevé (annotation)

Recommandation : Fine-tuning si les erreurs ont un coût business élevé (contexte juridique). Sinon, prompt engineering avec validation.

Cas 5 : Code review automatisée

Le contexte

Une équipe de 50 développeurs veut automatiser les code reviews pour détecter les problèmes courants (security, performance, style).

Approche prompt engineering (gagnante)

CODE_REVIEW_PROMPT = """Tu es un senior developer effectuant une code review.

CHECKLIST:
□ Sécurité (injections, auth, secrets)
□ Performance (N+1, boucles inefficaces)
□ Lisibilité (nommage, complexité)
□ Tests (couverture, edge cases)
□ Architecture (SOLID, couplage)

CODE À REVIEWER:

{code}

CONTEXTE: {context}

Fournis une review structurée avec:
1. 🔴 Critiques (à corriger avant merge)
2. 🟡 Suggestions (améliorations recommandées)
3. 🟢 Points positifs
4. Score global: X/10

REVIEW:"""

Pourquoi prompt engineering gagne ici :

  1. Standards évolutifs : Les conventions de code changent
  2. Multi-langage : Un modèle fine-tuné serait spécifique
  3. Contexte variable : Chaque review nécessite un contexte différent
  4. Pas de ground truth : Difficile d'annoter "la bonne review"

Résultats :

  • Utilité perçue : 8/10
  • Faux positifs : 20% (acceptable pour suggestions)
  • Adoption équipe : 85%

Matrice de décision complète

Choisir prompt engineering si :

  • [ ] Time-to-market < 1 mois
  • [ ] Volume < 1000 requêtes/jour
  • [ ] Données/règles changent fréquemment
  • [ ] Pas de dataset d'entraînement disponible
  • [ ] Besoin de flexibilité (multi-cas d'usage)
  • [ ] Budget limité pour l'investissement initial

Choisir fine-tuning si :

  • [ ] Précision critique (>90% requis)
  • [ ] Volume > 10,000 requêtes/jour
  • [ ] Style/ton très spécifique à reproduire
  • [ ] Format de sortie strict et constant
  • [ ] Dataset de qualité disponible (>500 exemples)
  • [ ] Cas d'usage stable dans le temps
  • [ ] Réduction des coûts prioritaire

Approche hybride

Dans certains cas, combinez les deux :

fine_tuned_model = "ft:gpt-4o-mini:company:classifier:abc123"

def classify_with_fallback(text: str) -> str:
    # 1. Essayer le modèle fine-tuné
    result = fine_tuned_model.predict(text)

    # 2. Si confiance faible, fallback sur prompt détaillé
    if result.confidence < 0.7:
        result = detailed_prompt_classification(text)

    return result

Estimation des coûts

Prompt engineering

Poste Coût
Développement prompt 2-10 jours dev
Tests et itérations 1-5 jours
Coût API (10K req/jour) $300-1000/mois

Fine-tuning

Poste Coût
Annotation dataset $2K-20K (selon complexité)
Fine-tuning compute $50-500
Développement pipeline 5-15 jours dev
Maintenance/réentraînement $500-2K/an
Coût API (10K req/jour) $100-300/mois

Break-even analysis

Coût prompt/mois = Coût_API_prompt
Coût fine-tuning/mois = Coût_API_ft + (Investissement_initial / 12)

Si Coût_API_prompt - Coût_API_ft > Investissement_initial / 12
→ Fine-tuning rentable en < 12 mois

Exemple :

  • Prompt : $800/mois
  • Fine-tuning : $200/mois + $5000 initial
  • Économie mensuelle : $600
  • Break-even : 8.3 mois

Conclusion

Le choix entre prompt engineering et fine-tuning n'est pas binaire :

  1. Commencez TOUJOURS par prompt engineering pour valider le use case
  2. Fine-tunez quand le volume, la précision ou les coûts le justifient
  3. Réévaluez régulièrement : les modèles de base s'améliorent

Le prompt engineering est votre MVP. Le fine-tuning est votre optimisation. Ne sautez pas les étapes.


Pour approfondir les limites du fine-tuning : Quand le fine-tuning est une mauvaise idée

Pour une introduction au prompt engineering : Fine-tuning ou prompt engineering : quand investir dans chaque approche