LangChain Prompts, AIPRM, Humanloop : Écosystème Outils 2025
Écrire des prompts manuellement dans ChatGPT, c’est comme coder dans Notepad : ça fonctionne pour débuter, mais pas scalable pour la production.
Cet article présente l’écosystème professionnel du prompt engineering en 2025 : outils pour gérer, versionner, tester et optimiser vos prompts à l’échelle.

Pourquoi des Outils Dédiés ?
Problèmes du Prompt Engineering “Artisanal”
| Problème | Impact | Solution Outillée |
|---|---|---|
| Copier-coller manuel | Erreurs, perte de temps | Templates réutilisables (LangChain) |
| Pas de versioning | Impossible de revenir en arrière | Git + platforms (Humanloop) |
| Qualité incertaine | Outputs incohérents | Testing automatisé + métriques |
| Optimisation manuelle | Des heures d’itérations | A/B testing + auto-optimization |
| Coûts invisibles | Dépassements budgets | Monitoring intégré (tokens, latence) |
| Collaboration difficile | Silos, duplication | Hubs partagés, review process |
Évolution : Artisanat → Industrialisation
Phase 1 : Artisanat (2022-2023)
└─ Prompts manuels dans ChatGPT/Claude
└─ OK pour prototypes, pas scalable
Phase 2 : Semi-automatisé (2024)
└─ Templates réutilisables (LangChain)
└─ Versioning basique (Git)
└─ Testing manuel
Phase 3 : Industriel (2025) ← Nous sommes ici
└─ Platforms dédiées (Humanloop, PromptLayer)
└─ CI/CD pour prompts
└─ A/B testing automatisé
└─ Optimisation via ML (DSPy)
LangChain : Gérer Prompts Programmatiquement
LangChain pour la scalabilité : Hard-coder vos prompts = dette technique. LangChain permet de gérer 100+ prompts avec versioning, tests et réutilisabilité. Une équipe Airbnb a réduit son temps de maintenance de 70% en migrant vers LangChain.
Installation
pip install langchain langchain-openai langchain-anthropic
Template de Base
Problème artisanal :
# ❌ Mauvaise approche : prompt en dur
prompt = f"Tu es un {role}. Tâche : {task}. Contexte : {context}."
❌ Problèmes :
- Pas réutilisable
- Difficile à modifier
- Pas de validation
Solution LangChain :
from langchain.prompts import PromptTemplate
# ✅ Template réutilisable
template = """Tu es un {role} avec {experience} ans d'expérience.
Tâche : {task}
Contexte :
{context}
Contraintes :
- {constraint1}
- {constraint2}
Format de réponse : {format}
"""
prompt = PromptTemplate(
input_variables=["role", "task", "context", "constraint1", "constraint2", "format", "experience"],
template=template
)
# Utilisation
final_prompt = prompt.format(
role="expert marketing digital",
experience=10,
task="Rédiger une accroche publicitaire",
context="SaaS de gestion de projet pour startups tech",
constraint1="Max 100 caractères",
constraint2="Ton aspirationnel, pas corporate",
format="Titre + sous-titre"
)
print(final_prompt)
Output :
Tu es un expert marketing digital avec 10 ans d'expérience.
Tâche : Rédiger une accroche publicitaire
Contexte :
SaaS de gestion de projet pour startups tech
Contraintes :
- Max 100 caractères
- Ton aspirationnel, pas corporate
Format de réponse : Titre + sous-titre
Chat Prompt Template
Pour les modèles de chat (GPT-4, Claude, Gemini) :
from langchain.prompts import ChatPromptTemplate
chat_template = ChatPromptTemplate.from_messages([
("system", "Tu es un {role}. {instructions}"),
("human", "Voici le code à analyser :\n\n{code}"),
("ai", "J'ai analysé le code. Voici mes observations :"),
("human", "Maintenant {task}")
])
messages = chat_template.format_messages(
role="senior developer Python",
instructions="Tu fais des code reviews constructives et pédagogiques.",
code="def calculate(x, y):\n return x + y",
task="suggère des améliorations (type hints, docstrings, tests)"
)
# Envoi à l'API
from langchain_openai import ChatOpenAI
llm = ChatOpenAI(model="gpt-4", temperature=0)
response = llm(messages)
print(response.content)
Few-Shot Prompts (Exemples Dynamiques)
from langchain.prompts.few_shot import FewShotPromptTemplate
from langchain.prompts import PromptTemplate
# Base d'exemples
examples = [
{"input": "heureux", "output": "joyeux, content, ravi, enchanté"},
{"input": "triste", "output": "malheureux, mélancolique, affligé, morose"},
{"input": "rapide", "output": "véloce, prompt, agile, leste"},
{"input": "intelligent", "output": "brillant, perspicace, sagace, érudit"}
]
# Template pour chaque exemple
example_template = """
Mot : {input}
Synonymes : {output}
"""
example_prompt = PromptTemplate(
input_variables=["input", "output"],
template=example_template
)
# Combiner dans un few-shot prompt
few_shot_prompt = FewShotPromptTemplate(
examples=examples,
example_prompt=example_prompt,
prefix="Tu es un expert linguiste. Trouve 4 synonymes précis pour chaque mot.",
suffix="\nMot : {input}\nSynonymes :",
input_variables=["input"],
)
# Utilisation
print(few_shot_prompt.format(input="courageux"))
Output :
Tu es un expert linguiste. Trouve 4 synonymes précis pour chaque mot.
Mot : heureux
Synonymes : joyeux, content, ravi, enchanté
Mot : triste
Synonymes : malheureux, mélancolique, affligé, morose
Mot : rapide
Synonymes : véloce, prompt, agile, leste
Mot : intelligent
Synonymes : brillant, perspicace, sagace, érudit
Mot : courageux
Synonymes :
Conditional Logic (Prompts Dynamiques)
from langchain.prompts import PromptTemplate
def create_prompt(task_type: str, include_examples: bool = True):
"""Génère un prompt selon le type de tâche"""
base = "Tu es un assistant IA expert.\n\n"
if task_type == "code":
base += "Spécialité : Génération et review de code.\n"
constraints = "- Inclure type hints\n- Gestion erreurs\n- Tests unitaires"
elif task_type == "marketing":
base += "Spécialité : Copywriting et stratégie marketing.\n"
constraints = "- Accrocheur\n- Call-to-action clair\n- Preuve sociale"
else:
constraints = "- Clair et concis"
if include_examples:
base += "\nExemples de sorties attendues :\n{examples}\n"
base += f"\nContraintes :\n{constraints}\n\nTâche : {{task}}"
variables = ["task"]
if include_examples:
variables.append("examples")
return PromptTemplate(input_variables=variables, template=base)
# Utilisation
code_prompt = create_prompt("code", include_examples=False)
marketing_prompt = create_prompt("marketing", include_examples=True)
print(marketing_prompt.format(
task="Créer un slogan pour app de méditation",
examples="- Nike : Just Do It\n- Apple : Think Different"
))
Prompt Hubs et Marketplaces
LangChain Hub (Gratuit)
Repository communautaire de prompts versionnés.
URL : smith.langchain.com/hub
from langchain import hub
# Charger un prompt depuis le Hub
rag_prompt = hub.pull("rlm/rag-prompt")
# Voir le contenu
print(rag_prompt.template)
# Utiliser
response = rag_prompt.format(context="...", question="...")
Prompts populaires :
rlm/rag-prompt: RAG (Retrieval-Augmented Generation)jacob/chain-of-thought: CoT optimiséhwchase17/react-agent: Agent ReAct
Publier vos prompts :
from langchain import hub
# Pousser votre prompt
hub.push("username/my-awesome-prompt", my_prompt)
PromptBase (Marketplace Premium)
URL : promptbase.com
Concept : Marketplace de prompts payants créés par experts.
Catégories :
- Marketing (Facebook Ads, SEO, emails) : 2-5$
- Code (debugging, génération, review) : 3-7$
- Art (Midjourney, DALL-E, Stable Diffusion) : 2-10$
- Business (business plans, pitchs, analyses) : 5-10$
Avantages :
- ✅ Prompts testés et optimisés
- ✅ Ratings/reviews
- ✅ Support du créateur
Inconvénients :
- ❌ Payant (vs gratuit communautaire)
- ❌ Qualité variable
- ❌ Pas toujours à jour avec nouveaux modèles
Exemple : Prompt “Email Cold Outreach B2B” à 4.99$ avec 4.8★ (127 reviews)
FlowGPT (Gratuit)
URL : flowgpt.com
Concept : Reddit des prompts - communautaire, gratuit, voting system.
Catégories populaires :
- Productivity (15k+ prompts)
- Coding (12k+)
- Writing (18k+)
- Marketing (8k+)
Exemple : “Ultimate Code Reviewer” (8.2k upvotes)
Tu es un senior developer avec 15 ans d'expérience faisant une code review.
[... prompt détaillé de 500 mots ...]
Code à reviewer :
{CODE}
Avantages :
- ✅ Gratuit
- ✅ Grande diversité
- ✅ Système de voting (meilleurs prompts en top)
Inconvénients :
- ❌ Qualité très variable
- ❌ Pas de versioning
- ❌ Parfois obsolètes
AIPRM (Extension Chrome)
URL : aiprm.com
Concept : Extension Chrome avec 4000+ prompts pré-faits s’intégrant directement dans ChatGPT.
Installation :
- Installer extension Chrome
- Ouvrir ChatGPT
- Accéder bibliothèque AIPRM (menu déroulant)
Catégories :
- SEO (meta descriptions, articles, mots-clés)
- Marketing (ads, social media, emails)
- Copywriting (landing pages, sales pages)
- Productivité (résumés, traductions, reformulations)
Modèle : Freemium
- Gratuit : 20 prompts publics/mois
- Pro (9$/mois) : Illimité + prompts privés + custom lists
Exemple : Prompt “Human-Written Article | 100% Unique” → 1 clic, remplir champs (mot-clé, ton, longueur) → article généré
Avantages :
- ✅ Intégration native ChatGPT (UX fluide)
- ✅ Filtres avancés (topic, activity, tone)
- ✅ Mis à jour régulièrement
Inconvénients :
- ❌ Seulement ChatGPT (pas Claude, Gemini)
- ❌ Prompts anglais majoritairement
Versioning et Gestion de Prompts
Fichiers YAML/JSON (Approche Simple)
Structure : prompts.yaml
# prompts.yaml
marketing_facebook_ad:
version: "2.1"
description: "Generate Facebook ad copy (PAS framework)"
model: "gpt-4"
temperature: 0.7
template: |
Tu es un copywriter expert en publicités Facebook.
Produit : {{product}}
Audience : {{audience}}
Objectif : {{objective}}
Crée 3 variantes de publicité suivant le framework PAS (Problem-Agitate-Solve).
Format :
**Variante 1**
Titre : [...]
Corps : [...]
CTA : [...]
variables:
- product
- audience
- objective
metadata:
author: "Marie Dupont"
created: "2024-11-15"
last_updated: "2025-01-10"
tested: true
avg_performance: 0.87 # CTR moyen
cost_per_run: 0.024 # USD
code_review:
version: "1.5"
description: "Python code review with security focus"
model: "gpt-4"
temperature: 0.2
template: |
Tu es un senior developer Python faisant une code review.
[... template ...]
variables:
- code
- language
metadata:
author: "Jean Martin"
created: "2024-09-20"
tested: true
Charger en Python :
import yaml
from langchain.prompts import PromptTemplate
# Charger prompts
with open("prompts.yaml", "r") as f:
prompts = yaml.safe_load(f)
# Utiliser
ad_config = prompts["marketing_facebook_ad"]
ad_prompt = PromptTemplate(
input_variables=ad_config["variables"],
template=ad_config["template"]
)
# Formatter
final = ad_prompt.format(
product="App de méditation",
audience="Femmes 30-45 ans, stress professionnel",
objective="Installations app (7j gratuits)"
)
Git pour Prompts (Approche Pro)
Structure de repository :
prompts-repo/
├── README.md
├── prompts/
│ ├── marketing/
│ │ ├── facebook_ad_v1.txt
│ │ ├── facebook_ad_v2.txt
│ │ ├── facebook_ad_v3.txt ← Version actuelle
│ │ ├── email_cold_b2b_v1.txt
│ │ └── seo_meta_v2.txt
│ ├── code/
│ │ ├── code_review_v1.txt
│ │ ├── code_review_v2.txt
│ │ ├── debugging_v1.txt
│ │ └── generation_python_v1.txt
│ └── data/
│ ├── sql_query_v1.txt
│ └── pandas_eda_v1.txt
├── tests/
│ ├── test_marketing.py
│ └── test_code.py
├── benchmarks/
│ └── results.json
└── CHANGELOG.md
Workflow Git :
# Créer nouvelle version
cp prompts/marketing/facebook_ad_v2.txt prompts/marketing/facebook_ad_v3.txt
# Modifier v3
# Committer
git add prompts/marketing/facebook_ad_v3.txt
git commit -m "Improve facebook_ad prompt: +15% CTR (A/B test 500 samples)"
# Tagger version
git tag marketing/facebook_ad/v3.0
git push origin marketing/facebook_ad/v3.0
# Revenir à version précédente si problème
git checkout marketing/facebook_ad/v2.0 prompts/marketing/facebook_ad_v2.txt
CHANGELOG.md :
# Changelog
## [3.0] - 2025-01-15 {#30---2025-01-15}
### Marketing / Facebook Ad
- **Changed** : Ajout framework PAS explicite
- **Improved** : CTR +15% vs v2.0 (A/B test, n=500)
- **Fixed** : Génération CTA trop générique
## [2.0] - 2024-12-10 {#20---2024-12-10}
### Marketing / Facebook Ad
- **Added** : Support multi-langues (FR, EN, ES)
- **Improved** : Ton ajustable (urgent/aspirationnel/éducatif)
Platforms de Gestion (Humanloop, PromptLayer)
Humanloop
URL : humanloop.com
Fonctionnalités :
- ✅ Versioning automatique : Chaque modification = nouvelle version trackée
- ✅ A/B testing intégré : Split traffic entre versions, analytics temps réel
- ✅ Monitoring : Coûts (tokens), latence, taux erreurs
- ✅ Collaboration : Review process, commentaires, approval workflow
- ✅ Rollback 1-click : Revenir à version précédente instantanément
- ✅ Intégrations : OpenAI, Anthropic, Cohere, custom models
Exemple d’utilisation :
from humanloop import Humanloop
hl = Humanloop(api_key="your_api_key")
# Créer/updater un prompt
hl.prompts.upsert(
name="marketing-facebook-ad",
version="3.0",
template="Tu es un copywriter...",
model="gpt-4",
temperature=0.7,
metadata={
"category": "marketing",
"tested": True,
"performance": 0.87
}
)
# Appeler le prompt
response = hl.chat(
prompt_name="marketing-facebook-ad",
inputs={
"product": "App de méditation",
"audience": "Femmes 30-45 ans"
}
)
print(response.output)
# Dashboard : voir analytics (coût, latence, outputs)
Tarifs :
- Free : 1k calls/mois
- Pro : 50$/mois (50k calls)
- Enterprise : Custom
PromptLayer
URL : promptlayer.com
Concept : Logging + versioning de tous vos appels LLM.
Installation :
pip install promptlayer
Usage :
import promptlayer
from openai import OpenAI
# Wrapper OpenAI avec logging
promptlayer.api_key = "pl_xxxxx"
OpenAI = promptlayer.openai.OpenAI
client = OpenAI()
# Tous les appels sont automatiquement loggés
response = client.chat.completions.create(
model="gpt-4",
messages=[
{"role": "system", "content": "Tu es un expert marketing."},
{"role": "user", "content": "Crée une accroche pour app méditation."}
],
pl_tags=["marketing", "facebook-ad", "v3.0"] # Tags custom
)
print(response.choices[0].message.content)
# Dashboard PromptLayer : voir tous les logs, filtrer par tag, replayer
Fonctionnalités :
- ✅ Logging automatique : Input, output, metadata (modèle, tokens, latence, coût)
- ✅ Replay : Re-exécuter un appel passé
- ✅ Search : Filtrer par tag, date, modèle, coût
- ✅ Analytics : Graphiques coûts, latence, volume
- ✅ Templates : Créer templates depuis logs réussis
Tarifs : Gratuit jusqu’à 1k requests/mois, puis 29$/mois.
Testing et Évaluation de Prompts
Framework de Testing (Python)
import openai
from typing import List, Dict, Callable
from dataclasses import dataclass
@dataclass
class TestCase:
"""Un cas de test"""
input: Dict[str, str]
expected_criteria: Dict[str, bool] # Critères à vérifier
description: str
def test_prompt(
prompt_template: str,
test_cases: List[TestCase],
evaluator: Callable,
model: str = "gpt-4"
) -> Dict:
"""
Teste un prompt sur plusieurs cas.
Args:
prompt_template: Template avec {variables}
test_cases: Liste de TestCase
evaluator: Fonction qui évalue la réponse
model: Modèle LLM
Returns:
Résultats agrégés avec scores
"""
results = []
total_tokens = 0
total_cost = 0
for i, case in enumerate(test_cases):
print(f"\n🧪 Test {i+1}/{len(test_cases)}: {case.description}")
# Formatter prompt
prompt = prompt_template.format(**case.input)
# Appel API
response = openai.chat.completions.create(
model=model,
messages=[{"role": "user", "content": prompt}]
)
output = response.choices[0].message.content
tokens = response.usage.total_tokens
cost = calculate_cost(tokens, model)
# Évaluation
evaluation = evaluator(output, case.expected_criteria)
# Stocker résultat
results.append({
'test_id': i + 1,
'description': case.description,
'input': case.input,
'output': output,
'expected_criteria': case.expected_criteria,
'evaluation': evaluation,
'passed': all(evaluation.values()),
'tokens': tokens,
'cost': cost
})
total_tokens += tokens
total_cost += cost
# Affichage
status = "✅ PASS" if results[-1]['passed'] else "❌ FAIL"
print(f"{status} | Tokens: {tokens} | Cost: ${cost:.4f}")
if not results[-1]['passed']:
print(f" Critères non respectés : {[k for k, v in evaluation.items() if not v]}")
# Agrégation
pass_rate = sum(r['passed'] for r in results) / len(results)
summary = {
'total_tests': len(test_cases),
'passed': sum(r['passed'] for r in results),
'failed': len(test_cases) - sum(r['passed'] for r in results),
'pass_rate': pass_rate,
'total_tokens': total_tokens,
'total_cost': total_cost,
'avg_cost_per_test': total_cost / len(test_cases),
'results': results
}
return summary
def calculate_cost(tokens: int, model: str) -> float:
"""Calcule coût en USD"""
pricing = {
"gpt-4": {"input": 0.03/1000, "output": 0.06/1000},
"gpt-3.5-turbo": {"input": 0.0005/1000, "output": 0.0015/1000}
}
# Simplification : assume 50/50 input/output
return tokens * ((pricing[model]["input"] + pricing[model]["output"]) / 2)
# Evaluator example : Facebook Ad
def evaluate_facebook_ad(output: str, criteria: Dict[str, bool]) -> Dict[str, bool]:
"""Évalue si output respecte critères"""
evaluation = {}
# Critère : Contient CTA
evaluation['has_cta'] = any(word in output.lower() for word in ['télécharger', 'essayer', 'découvrir', 'profiter', 'commencer'])
# Critère : Longueur appropriée (corps < 125 car)
lines = output.split('\n')
corps_lines = [l for l in lines if l.startswith('Corps :')]
if corps_lines:
corps = corps_lines[0].replace('Corps :', '').strip()
evaluation['length_ok'] = len(corps) <= 125
else:
evaluation['length_ok'] = False
# Critère : Contient chiffre/stat (preuve sociale)
evaluation['has_social_proof'] = any(char.isdigit() for char in output)
# Critère : 3 variantes
evaluation['three_variants'] = output.count('Variante') >= 3
return evaluation
# Utilisation
test_cases = [
TestCase(
input={
"product": "App de méditation",
"audience": "Femmes 30-45 ans, stress",
"objective": "Installations"
},
expected_criteria={
"has_cta": True,
"length_ok": True,
"has_social_proof": True,
"three_variants": True
},
description="Cas nominal : app méditation"
),
TestCase(
input={
"product": "SaaS CRM B2B",
"audience": "Sales managers PME",
"objective": "Démo gratuite"
},
expected_criteria={
"has_cta": True,
"length_ok": True,
"has_social_proof": True,
"three_variants": True
},
description="Cas B2B : CRM"
)
]
prompt_template = """Tu es un copywriter expert Facebook Ads.
Produit : {product}
Audience : {audience}
Objectif : {objective}
Crée 3 variantes (PAS framework, corps max 125 car).
"""
summary = test_prompt(prompt_template, test_cases, evaluate_facebook_ad)
# Rapport
print(f"\n{'='*50}")
print(f"📊 RÉSUMÉ")
print(f"{'='*50}")
print(f"Tests réussis : {summary['passed']}/{summary['total_tests']} ({summary['pass_rate']:.0%})")
print(f"Coût total : ${summary['total_cost']:.4f}")
print(f"Coût moyen/test : ${summary['avg_cost_per_test']:.4f}")
Métriques d’Évaluation
| Métrique | Description | Implémentation | Use Case |
|---|---|---|---|
| Exactitude | Match exact | output == expected | Classification, extraction données |
| Similarité sémantique | Cosine similarity embeddings | cosine(embed(output), embed(expected)) | Génération texte, paraphrase |
| LLM-as-Judge | GPT-4 évalue qualité | gpt4("Note /10 : {output}") | Créativité, copywriting |
| BLEU/ROUGE | Métriques NLP | nltk.translate.bleu_score | Traduction, résumé |
| Human Eval | Notation humaine | Interface custom | Gold standard (coûteux) |
| Coût | Tokens × prix | total_tokens * rate | Optimisation budget |
| Latence | Temps réponse | time.time() | Apps temps réel |
| Pass@k | % succès sur k essais | sum(passed) / k | Code generation |
Exemple : Similarité Sémantique
from openai import OpenAI
import numpy as np
client = OpenAI()
def semantic_similarity(text1: str, text2: str) -> float:
"""Calcule similarité cosine entre 2 textes"""
# Embeddings
emb1 = client.embeddings.create(input=text1, model="text-embedding-3-small").data[0].embedding
emb2 = client.embeddings.create(input=text2, model="text-embedding-3-small").data[0].embedding
# Cosine similarity
dot_product = np.dot(emb1, emb2)
norm1 = np.linalg.norm(emb1)
norm2 = np.linalg.norm(emb2)
return dot_product / (norm1 * norm2)
# Test
output = "Notre app vous aide à réduire le stress quotidien."
expected = "L'application diminue votre anxiété au travail."
score = semantic_similarity(output, expected)
print(f"Similarité : {score:.2f}") # 0.85+ = très similaire
A/B Testing de Prompts
Signification statistique requise : Ne déployez jamais une variante sans au moins 100 samples et p-value <0.05. Une startup a perdu 15k$ en déployant une ‘amélioration’ testée sur 20 samples qui s’est révélée 12% moins performante à l’échelle.
import random
from collections import defaultdict
from datetime import datetime
from typing import Dict, List
class PromptABTest:
"""A/B testing framework pour prompts"""
def __init__(self, prompts: Dict[str, str], split: Dict[str, float] = None):
"""
Args:
prompts: {"A": prompt_a, "B": prompt_b, "C": prompt_c}
split: {"A": 0.5, "B": 0.3, "C": 0.2} (défaut: équitable)
"""
self.prompts = prompts
self.split = split or {k: 1/len(prompts) for k in prompts}
self.results = defaultdict(list)
def assign_variant(self) -> str:
"""Assigne variant selon split ratio"""
rand = random.random()
cumulative = 0
for variant, ratio in self.split.items():
cumulative += ratio
if rand <= cumulative:
return variant
return list(self.prompts.keys())[-1]
def run(self, user_input: str, model: str = "gpt-4") -> Dict:
"""Exécute A/B test pour 1 requête"""
# Assignment
variant = self.assign_variant()
# Appel LLM
prompt = self.prompts[variant].format(input=user_input)
start = datetime.now()
response = openai.chat.completions.create(
model=model,
messages=[{"role": "user", "content": prompt}]
)
latency = (datetime.now() - start).total_seconds()
output = response.choices[0].message.content
tokens = response.usage.total_tokens
# Track result
self.results[variant].append({
'timestamp': datetime.now(),
'input': user_input,
'output': output,
'latency': latency,
'tokens': tokens,
'cost': calculate_cost(tokens, model)
})
return {
'variant': variant,
'output': output
}
def analyze(self, metric: str = "all") -> Dict:
"""Analyse résultats A/B test"""
analysis = {}
for variant, results in self.results.items():
n = len(results)
if n == 0:
continue
avg_latency = sum(r['latency'] for r in results) / n
avg_tokens = sum(r['tokens'] for r in results) / n
total_cost = sum(r['cost'] for r in results)
avg_output_length = sum(len(r['output']) for r in results) / n
analysis[variant] = {
'sample_size': n,
'avg_latency': avg_latency,
'avg_tokens': avg_tokens,
'total_cost': total_cost,
'avg_cost': total_cost / n,
'avg_output_length': avg_output_length
}
return analysis
def compare(self, baseline: str = "A"):
"""Compare variants vs baseline"""
analysis = self.analyze()
baseline_data = analysis[baseline]
print(f"\n📊 A/B Test Results (Baseline: {baseline})")
print("=" * 80)
for variant, data in analysis.items():
if variant == baseline:
print(f"\n{variant} (BASELINE)")
else:
print(f"\n{variant}")
print(f" Sample size: {data['sample_size']}")
print(f" Avg latency: {data['avg_latency']:.3f}s", end="")
if variant != baseline:
diff = ((data['avg_latency'] - baseline_data['avg_latency']) / baseline_data['avg_latency']) * 100
print(f" ({diff:+.1f}%)")
else:
print()
print(f" Avg tokens: {data['avg_tokens']:.0f}", end="")
if variant != baseline:
diff = ((data['avg_tokens'] - baseline_data['avg_tokens']) / baseline_data['avg_tokens']) * 100
print(f" ({diff:+.1f}%)")
else:
print()
print(f" Avg cost: ${data['avg_cost']:.4f}", end="")
if variant != baseline:
diff = ((data['avg_cost'] - baseline_data['avg_cost']) / baseline_data['avg_cost']) * 100
print(f" ({diff:+.1f}%)")
else:
print()
# Utilisation
prompts = {
"A": "Explique {input} simplement.",
"B": "Tu es un professeur. Explique {input} à un élève de 10 ans.",
"C": "Explique {input} en 3 points clés avec analogies."
}
ab_test = PromptABTest(prompts, split={"A": 0.33, "B": 0.33, "C": 0.34})
# Simuler 100 requêtes
questions = [
"la photosynthèse",
"les trous noirs",
"la blockchain",
# ... 97 autres
]
for q in questions:
ab_test.run(q)
# Analyser
ab_test.compare(baseline="A")
Output exemple :
📊 A/B Test Results (Baseline: A)
================================================================================
A (BASELINE)
Sample size: 33
Avg latency: 1.245s
Avg tokens: 287
Avg cost: $0.0172
B
Sample size: 33
Avg latency: 1.512s (+21.4%)
Avg tokens: 356 (+24.0%)
Avg cost: $0.0213 (+23.8%)
C
Sample size: 34
Avg latency: 1.103s (-11.4%) ← MEILLEUR
Avg tokens: 245 (-14.6%) ← MEILLEUR
Avg cost: $0.0147 (-14.5%) ← MEILLEUR
Conclusion : Variant C est meilleur (plus rapide, moins cher, plus concis).
Optimisation Automatique
DSPy (Stanford) : Auto-optimization
Concept : Au lieu d’écrire prompts manuellement, décrire la tâche et laisser DSPy optimiser le prompt automatiquement.
Installation :
pip install dspy-ai
Exemple : Classification de Sentiment
import dspy
from dspy.datasets import DataLoader
# Configurer LLM
lm = dspy.OpenAI(model="gpt-3.5-turbo")
dspy.settings.configure(lm=lm)
# Définir la tâche (signature)
class SentimentClassifier(dspy.Signature):
"""Classifier le sentiment d'un texte"""
text = dspy.InputField(desc="Le texte à analyser")
sentiment = dspy.OutputField(desc="positive, negative, ou neutral")
# Créer module
classifier = dspy.Predict(SentimentClassifier)
# Test AVANT optimisation
print(classifier(text="J'adore ce produit !"))
# Output: sentiment='positive'
# Données d'entraînement
train_data = [
dspy.Example(text="J'adore ce film !", sentiment="positive").with_inputs("text"),
dspy.Example(text="C'est horrible.", sentiment="negative").with_inputs("text"),
dspy.Example(text="Pas mal.", sentiment="neutral").with_inputs("text"),
dspy.Example(text="Incroyable expérience !", sentiment="positive").with_inputs("text"),
dspy.Example(text="Décevant.", sentiment="negative").with_inputs("text"),
# ... 20-50 exemples
]
# Métrique d'évaluation
def accuracy(example, prediction, trace=None):
return example.sentiment.lower() == prediction.sentiment.lower()
# OPTIMISER automatiquement le prompt
from dspy.teleprompt import BootstrapFewShot
optimizer = BootstrapFewShot(metric=accuracy, max_bootstrapped_demos=3)
optimized_classifier = optimizer.compile(classifier, trainset=train_data)
# Test APRÈS optimisation
print(optimized_classifier(text="J'adore ce produit !"))
# Même output, mais prompt interne optimisé automatiquement
# Voir le prompt optimisé
print(lm.inspect_history(n=1))
Résultat : DSPy a automatiquement :
- Sélectionné meilleurs exemples (few-shot)
- Ordonné exemples optimalement
- Ajouté instructions de raisonnement (CoT si bénéfique)
- Testé variantes et gardé la meilleure
Gain : +15-30% précision vs prompt manuel.
PromptPerfect (No-code)
URL : promptperfect.jina.ai
Concept : Outil en ligne qui optimise vos prompts automatiquement.
Utilisation :
- Collez votre prompt initial
- Sélectionnez modèle cible (GPT-4, Claude, Gemini, Midjourney, etc.)
- Cliquez “Optimize”
- Récupérez prompt optimisé
Exemple :
Input :
Write a product description for a meditation app.
Output optimisé (par PromptPerfect) :
You are an expert copywriter specializing in wellness and mindfulness products.
Task: Write a compelling product description for a meditation mobile app.
Target audience: Busy professionals aged 25-45 seeking stress relief and better sleep.
Description must include:
- Hook (emotional pain point)
- 3 key benefits (specific, measurable)
- Social proof element
- Clear call-to-action
Tone: Calm, aspirational, science-backed (not woo-woo)
Length: 150-200 words
Format:
[Hook paragraph]
[Benefits paragraph with bullet points]
[Social proof + CTA paragraph]
Résultat : Prompt 5x plus détaillé → output 2-3x meilleur.
Tarifs : Freemium (10 optimizations/mois gratuit), Pro 9.99$/mois.
Best Practices Production
Checklist : Prompts en Production
- Versioning : Git ou platform (Humanloop/PromptLayer)
- Testing : Suite de tests (min 10 cas par prompt)
- Monitoring : Coûts, latence, taux erreurs (dashboard)
- Fallback : Si échec → retry avec backoff OU prompt alternatif
- Logging : Inputs/outputs (attention RGPD/privacy)
- Documentation : Quand utiliser, limitations connues, exemples
- Review process : Validation par pairs avant deploy
- Rollback plan : Retour version N-1 en < 5 min
- Cost alerts : Notification si dépassement budget
- Rate limiting : Protection contre abus
Architecture Recommandée
┌─────────────────┐
│ Application │
└────────┬────────┘
│
↓
┌─────────────────┐
│ Prompt Registry │ ← Charge prompts depuis YAML/DB/Platform
└────────┬────────┘
│
↓
┌─────────────────┐
│ Prompt Cache │ ← Cache résultats identiques (économies)
└────────┬────────┘
│
↓
┌─────────────────┐
│ LLM Router │ ← Choisit modèle optimal (coût/qualité)
└────────┬────────┘
│
↓
┌─────────────────┐
│ LLM Provider │ ← OpenAI, Anthropic, etc.
└────────┬────────┘
│
↓
┌─────────────────┐
│ Logger/Monitor │ ← PromptLayer, Humanloop, custom
└─────────────────┘
Points Clés à Retenir
LangChain : Templates réutilisables, few-shot dynamique, intégration facile
Marketplaces :
- Gratuit : LangChain Hub, FlowGPT
- Payant : PromptBase (2-10$/prompt)
- Extension : AIPRM (intégration ChatGPT native)
Versioning :
- Simple : YAML + Git
- Pro : Humanloop, PromptLayer (versioning auto, A/B testing, analytics)
Testing : Framework custom (Python), métriques (exactitude, similarité, LLM-as-judge), A/B testing
Optimisation auto : DSPy (ML-based), PromptPerfect (no-code)
Production : Monitoring, fallbacks, logging, documentation, review process
Suite de la Série
Article 6 : Sécurité et Robustesse : Prompt Injection, Jailbreaking, Guardrails Protéger vos prompts contre attaques et outputs inappropriés
Article 7 : Mesurer et Optimiser Performance : KPIs, A/B Testing, Coûts Métriques clés, optimisation coûts, amélioration continue