Implémenter les Predicted Outputs en Python
Du concept au code de production
Vous comprenez le principe des Predicted Outputs et leurs cas d’usage. Cette leçon vous donne le code Python complet, prêt à intégrer dans vos applications, avec gestion d’erreurs et mesure de performance.
Implémentation de base
Voici le pattern minimal pour utiliser les Predicted Outputs :
from mistralai import Mistral
client = Mistral(api_key="votre-clé-api")
code_source = """
import pandas as pd
def load_data(filepath):
df = pd.read_csv(filepath)
df['date'] = pd.to_datetime(df['date'])
df = df.dropna(subset=['value'])
return df
def compute_stats(df):
return {
'mean': df['value'].mean(),
'median': df['value'].median(),
'std': df['value'].std()
}
"""
prompt = (
"Ajoutez un paramètre 'separator' à la fonction load_data "
"(défaut ',') et utilisez-le dans read_csv. "
"Répondez uniquement avec le code complet modifié."
)
response = client.chat.complete(
model="codestral-latest",
messages=[
{"role": "user", "content": prompt},
{"role": "user", "content": code_source}
],
prediction={"type": "content", "content": code_source}
)
code_modifie = response.choices[0].message.content
print(code_modifie)
Classe utilitaire pour la production
En production, vous voudrez encapsuler la logique dans une classe réutilisable :
from mistralai import Mistral
import time
from dataclasses import dataclass
@dataclass
class PredictionResult:
content: str
latency_ms: float
tokens_input: int
tokens_output: int
model: str
class PredictedEditor:
"""Éditeur de contenu utilisant les Predicted Outputs."""
def __init__(self, api_key: str, model: str = "mistral-large-latest"):
self.client = Mistral(api_key=api_key)
self.model = model
def edit(
self,
original: str,
instruction: str,
system_prompt: str | None = None
) -> PredictionResult:
"""Édite un contenu avec prédiction de sortie."""
messages = []
if system_prompt:
messages.append({"role": "system", "content": system_prompt})
messages.extend([
{"role": "user", "content": instruction},
{"role": "user", "content": original}
])
start = time.perf_counter()
response = self.client.chat.complete(
model=self.model,
messages=messages,
prediction={"type": "content", "content": original}
)
latency = (time.perf_counter() - start) * 1000
choice = response.choices[0]
return PredictionResult(
content=choice.message.content,
latency_ms=round(latency, 1),
tokens_input=response.usage.prompt_tokens,
tokens_output=response.usage.completion_tokens,
model=self.model
)
def edit_code(self, code: str, instruction: str) -> PredictionResult:
"""Raccourci pour l'édition de code."""
return self.edit(
original=code,
instruction=instruction,
system_prompt=(
"Vous êtes un assistant de programmation. "
"Répondez uniquement avec le code modifié, "
"sans explication ni markdown."
)
)
def edit_text(self, text: str, instruction: str) -> PredictionResult:
"""Raccourci pour l'édition de texte."""
return self.edit(
original=text,
instruction=instruction,
system_prompt=(
"Vous êtes un éditeur de texte professionnel. "
"Appliquez la modification demandée en préservant "
"le style et la structure du texte original. "
"Répondez uniquement avec le texte modifié."
)
)
Utilisation de la classe
editor = PredictedEditor(api_key="votre-clé-api", model="codestral-latest")
# Éditer du code
result = editor.edit_code(
code=mon_fichier_python,
instruction="Remplacez tous les print() par des appels logging.info()"
)
print(f"Latence : {result.latency_ms} ms")
print(f"Tokens : {result.tokens_input} in / {result.tokens_output} out")
print(result.content)
Benchmark : avec vs sans prédiction
Voici un script de benchmark complet pour mesurer le gain dans votre contexte :
import statistics
def benchmark_prediction(
client, model, messages, prediction_content, runs=5
):
"""Compare la latence avec et sans Predicted Output."""
times_normal = []
times_predicted = []
for _ in range(runs):
# Sans prédiction
start = time.perf_counter()
client.chat.complete(model=model, messages=messages)
times_normal.append((time.perf_counter() - start) * 1000)
# Avec prédiction
start = time.perf_counter()
client.chat.complete(
model=model,
messages=messages,
prediction={"type": "content", "content": prediction_content}
)
times_predicted.append((time.perf_counter() - start) * 1000)
avg_normal = statistics.mean(times_normal)
avg_predicted = statistics.mean(times_predicted)
gain_pct = (1 - avg_predicted / avg_normal) * 100
return {
"sans_prediction_ms": round(avg_normal, 1),
"avec_prediction_ms": round(avg_predicted, 1),
"gain_pourcentage": round(gain_pct, 1),
"runs": runs
}
Gestion des erreurs
En production, anticipez les cas limites :
def safe_edit(editor, original, instruction):
"""Édition avec gestion d'erreurs robuste."""
try:
result = editor.edit(original, instruction)
# Vérifier que la réponse n'est pas vide
if not result.content or len(result.content.strip()) < 10:
raise ValueError("Réponse trop courte ou vide")
return result
except Exception as e:
# Fallback : réessayer sans prédiction
print(f"Predicted Output échoué ({e}), fallback standard...")
response = editor.client.chat.complete(
model=editor.model,
messages=[
{"role": "user", "content": instruction},
{"role": "user", "content": original}
]
)
return PredictionResult(
content=response.choices[0].message.content,
latency_ms=0,
tokens_input=response.usage.prompt_tokens,
tokens_output=response.usage.completion_tokens,
model=editor.model
)
Contraintes à connaître
Avant de déployer en production, gardez ces contraintes en tête :
- Le paramètre
n(nombre de complétions) est incompatible avecprediction - La position du contenu dans la réponse n’a pas d’importance : le modèle gère la correspondance
- Fournir une mauvaise prédiction ne dégrade pas la qualité — seulement le gain de latence
- Les deux seuls modèles compatibles sont
mistral-large-latestetcodestral-latest
Points clés à retenir
- Le paramètre
predictions’ajoute simplement à l’appelchat.complete() - Encapsulez la logique dans une classe réutilisable pour la production
- Mesurez systématiquement le gain avec un benchmark avant de déployer
- Prévoyez un fallback sans prédiction en cas d’erreur
- Une mauvaise prédiction ne dégrade pas la qualité, seulement la latence