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
- Données évolutives : Les politiques RH changent régulièrement
- Traçabilité : Le RAG permet de citer les sources
- Pas de style spécifique : Un ton professionnel standard suffit
- 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 :
- Standards évolutifs : Les conventions de code changent
- Multi-langage : Un modèle fine-tuné serait spécifique
- Contexte variable : Chaque review nécessite un contexte différent
- 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 resultEstimation 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 moisExemple :
- 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 :
- Commencez TOUJOURS par prompt engineering pour valider le use case
- Fine-tunez quand le volume, la précision ou les coûts le justifient
- 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