Remplacer un modèle payant par une option moins chère - voire gratuite - peut sembler simple. Quelques requêtes de démonstration, un benchmark un peu flatteur, puis on change l'endpoint. Le hic, c'est que les premiers exemples sont rarement ceux qui font dérailler un système en production. Les cas limites, les formats bizarres et les prompts oubliés ressortent plus tard, quand les utilisateurs tombent sur une réponse vide, ou quand un parseur ne reconnaît plus le résultat.
Le shadow replay, ou rejeu en parallèle, sert justement à tester avant la bascule. Concrètement : vous envoyez un corpus de requêtes déjà observées vers le modèle actuel et vers le modèle candidat, puis vous comparez leurs réponses. L'idée n'est pas de prouver qu'ils répondent exactement pareil. C'est plutôt de repérer les écarts, d'en estimer la gravité, et de décider lesquels sont vraiment acceptables.
Voici une approche simple et praticable : constituer un jeu de test représentatif, normaliser les sorties sans effacer ce qui compte, classer les divergences et exécuter le rejeu avec un budget maîtrisé. On verra aussi ce que ce test ne garantit pas, les précautions liées au RGPD, et les éléments opérationnels à garder après la migration.
Pourquoi une migration de modèle peut échouer sans alerte
Changer de modèle ne provoque pas forcément une panne spectaculaire. Souvent, c'est plus sournois : le service se dégrade par petites touches. Le résultat devient moins complet, la structure JSON bouge, une réponse « valide » se transforme en refus, ou le modèle s'arrête avant la fin. Et si vous ne testez que quelques prompts faciles à la main, vous risquez de ne rien voir. L'interface peut afficher quelque chose qui a l'air correct, alors qu'un traitement en aval casse silencieusement.
C'est encore plus visible quand le modèle est intégré à un processus métier. Un assistant de support peut produire une synthèse lisible, tout en cessant de respecter le format attendu par votre système de tickets. Un outil d'extraction peut oublier un champ, sans que ça saute aux yeux dans l'écran principal. Parfois, une réponse plus courte donne l'illusion d'une « carte » presque vide, sans déclencher d'alarme.
Bref : le point n'est pas uniquement la qualité rédactionnelle. C'est le contrat entre le modèle et le reste du produit.
Le rejeu en parallèle rend ces écarts visibles sur des entrées déjà rencontrées. Il ne remplace ni les tests fonctionnels ni la validation humaine. Il réduit surtout l'écart entre « ça marche dans la démo » et « on a regardé un échantillon réaliste des usages ».
Cinq familles de divergence Ă distinguer
Classer les différences aide à transformer une liste de constats en tâches concrètes (responsable + priorité).
| Type d'écart | Symptôme courant | Priorité indicative | Action à envisager |
|---|---|---|---|
| Format | JSON invalide, clé renommée, structure modifiée | Élevée | Valider le schéma et corriger le contrat |
| Troncature | Réponse interrompue ou incomplète | Élevée | Vérifier les limites de jetons et la longueur du prompt |
| Refus | Le modèle décline une demande pourtant autorisée | Élevée | Examiner le cas, les règles et le routage |
| Présentation | Puces, espaces ou ponctuation différents | Faible | Ignorer si le produit tolère ces variations |
| Sens | Réponse différente, mais plausible ou contradictoire | Variable | Faire relire selon l'impact métier |
La priorité dépend du risque, pas de la « surprise ». Une clé JSON manquante peut casser un traitement pour tout le monde. À l'inverse, une reformulation sans conséquence peut être acceptable. Et un changement de refus mérite d'être traité sérieusement dès que vous touchez à la facturation, au recrutement, à la santé ou à l'accès à des droits.
L'autre piège : résumer les résultats par un seul score de similarité. Un taux global peut masquer quelques erreurs graves noyées dans une masse de réponses « proches ». Il faut pouvoir répondre à trois questions simples : combien d'écarts, de quel type, et qu'est-ce que ça implique pour le produit.
Constituer un corpus de rejeu exploitable
La première étape, c'est de figer un ensemble de requêtes issues d'usages réels. Pas besoin que ce soit énorme pour que ce soit utile : quelques centaines de cas bien choisis peuvent apprendre plus que des milliers d'exemples pris au hasard. La qualité de l'échantillon compte plus que le volume.
Incluez les paramètres réellement envoyés au modèle : température, limite de sortie, messages système, et options propres au fournisseur. Si ces paramètres changent entre la référence et le candidat, vous ne comparez plus deux modèles. Vous comparez deux configurations.
Un format JSONL - un objet JSON par ligne - facilite le versionnement et le rejeu. Exemple :
{"id":"support-001","source":"ticket","messages":[{"role":"system","content":"Résumez la demande en deux points."},{"role":"user","content":"Texte du ticket..."}],"params":{"temperature":0,"max_tokens":300},"baseline":{"model":"modele-actuel","text":"..."}}
Conservez aussi la réponse de référence dans le corpus. Si vous gardez uniquement un identifiant renvoyant à des journaux, vous risquez de devoir rappeler l'ancien endpoint pour reconstruire la comparaison. Ça coûte du temps, ça dépend de la disponibilité du fournisseur, et vous introduisez un biais : si le service a évolué entre-temps, la « référence » n'est peut-être plus la même.
Échantillonner les cas qui comptent
Évitez de sélectionner uniquement les requêtes les plus fréquentes. Une sélection raisonnable mélange plusieurs catégories :
- les parcours courants (le gros du volume) ;
- les demandes longues ou mal structurées ;
- les entrées avec négations, nombres ou dates ;
- les cas qui déclenchent des règles métier, ou des refus ;
- les formats qui alimentent directement une API, un formulaire ou un outil interne ;
- les exemples déjà liés à un incident ou à une correction manuelle.
Cette sélection doit rester liée au produit. Pour un assistant qui résume des tickets, les demandes ambiguës et les pièces longues valent plus qu'une collection de questions « générales ». Pour une extraction de données, les champs rares mais critiques doivent être présents.
Traiter les données avant le rejeu
Avec des données européennes, vous devez partir du principe que le corpus peut contenir des informations personnelles ou confidentielles. La pseudonymisation n'est pas une anonymisation : parfois, on peut réidentifier une personne à partir d'un contexte, d'une date, ou d'un détail rare. Donc : définissez ce qui est nécessaire, réduisez au minimum, et appliquez vos règles de conservation et d'accès avant de lancer les tests.
L'idéal, c'est d'avoir la rédaction des identifiants dès la capture, pas au moment de la revue. Comme ça, le corpus reste réutilisable pour des migrations futures sans exposer plus de données que nécessaire. Si vous ne pouvez pas conserver certaines informations, ne les ajoutez pas au jeu de rejeu sans une procédure de redaction solide et validée. Pour les obligations, faites vérifier le cadre RGPD par votre équipe ou votre référent, selon votre organisation.
Enfin, donnez un propriétaire au corpus. Sans responsable, le jeu de test finit par vieillir : prompts modifiés, produit qui change, et vous vous retrouvez avec un test qui décrit une version du passé.
Comparer les réponses sans confondre bruit et risque
Comparer par égalité stricte de chaînes est simple, mais ça traite comme « différence » les espaces, les puces, ou la ponctuation. À l'inverse, une normalisation trop poussée peut effacer des différences importantes. Mettre tout en minuscules, par exemple, aide, mais ne règle pas les problèmes de sens : « paiement accepté » et « paiement non accepté » restent proches à l'œil si votre similarité est mal calibrée.
La bonne méthode consiste à découper le travail en trois étapes : normaliser ce qui est purement éditorial, vérifier la structure attendue, puis soumettre les divergences de sens à une revue proportionnée au risque.
Écrire les règles de normalisation
Si votre produit tolère plusieurs styles de listes, vous pouvez ignorer certains changements de puces ou d'espacement. En revanche, les nombres, la négation, les noms de champs et les valeurs métier doivent rester comparables. En clair : ce sont des règles « produit », pas des détails qu'on laisse au hasard.
Un script Python peut servir de point de départ pour normaliser des espaces et une partie de la mise en forme, mais il ne remplace pas une évaluation sémantique. Exemple :
import hashlib
import re
BULLET = re.compile(r"^\s*[-*•]\s+", re.M)
SPACES = re.compile(r"[ \t]+")
def normalize(text: str) -> str:
text = BULLET.sub("- ", text)
text = SPACES.sub(" ", text)
return "\n".join(line.strip() for line in text.strip().splitlines())
def fingerprint(text: str) -> str:
return hashlib.sha256(normalize(text).encode()).hexdigest()[:12]
L'empreinte sert à repérer vite les sorties identiques après normalisation. Mais ça ne dit pas si deux réponses différentes se valent. Pour un JSON, vérifiez aussi que la sortie est analysable et que les clés et types attendus sont présents. Une comparaison des seules clés ne suffit pas : une valeur peut être fausse même quand le schéma tient debout.
Transformer les écarts en décisions
Chaque catégorie doit avoir sa règle de décision. En général :
- format et troncature → correction et validation avant bascule ;
- refus inattendus → revue sur les cas concernés ;
- variations de présentation → souvent « OK », si l'expérience et les traitements en aval ne sont pas impactés.
Les divergences de sens demandent une revue humaine. Mais pas forcément sur tout. Commencez par les cas à fort impact, puis élargissez si nécessaire. Et pour garder de la traçabilité, tenez un journal par exemple : texte de référence, texte candidat, catégorie, sévérité, verdict de revue, décision. Ça rend la migration défendable, et ça facilite un retour en arrière si besoin.
Enfin, évitez de confier toute la décision à un second modèle évaluateur sans garde-fous. Un modèle peut aider à trier ou à signaler des réponses à relire, mais il peut aussi rater précisément les erreurs subtiles qui vous coûtent le plus. Pour les conséquences juridiques, financières ou liées à des droits, la validation doit être définie avec les bonnes équipes, pas « déduite » d'un score automatique.
Organiser le test et décider de la bascule
Le rejeu doit être borné et rejouable. Fixez un maximum de requêtes, une concurrence raisonnable, un délai d'attente, et une politique de reprise en cas d'échec. Enregistrez chaque résultat tout de suite : si le process plante, vous pourrez relancer sans perdre ce qui a déjà été jugé. Une exécution rapide mais non reprise-incurable pousse souvent à « passer à la suite » avant d'avoir regardé tout le corpus.
Avec chaque résultat, consignez l'identifiant du modèle, l'endpoint, la configuration et l'heure du test. Les services évoluent. Sans ça, un rapport de divergence devient flou quelques semaines plus tard. Gardez aussi en tête que les offres « gratuites » viennent avec des quotas, des conditions, et parfois une disponibilité qui change. Vérifiez la documentation du fournisseur avant de baser votre plan dessus.
Une séquence réaliste ressemble à ça :
- Figer le corpus, les paramètres et les réponses de référence.
- Lancer un petit lot pour valider l'intégration et les limites de débit.
- Rejouer le corpus complet dans les limites budgétaires prévues.
- Classer les divergences et corriger les défauts mécaniques.
- Faire relire les changements de sens prioritaires.
- Rejouer les cas corrigés, puis un échantillon après un délai pour vérifier la stabilité.
- Basculer progressivement avec une surveillance et un plan de retour arrière.
Important : le shadow replay n'est pas un test de charge. Il mesure la qualité des réponses sur vos requêtes enregistrées. Il ne prouve pas que le nouvel endpoint encaissera votre concurrence réelle, ne garantit pas vos objectifs de latence, ni la disponibilité. Il faut donc compléter par des tests opérationnels et une surveillance adaptée au service.
OĂą une option gratuite peut ĂŞtre utile
Vous avez besoin d'un second endpoint pour comparer le candidat au modèle actuel. Une offre gratuite peut donc réduire le coût d'une première évaluation, à condition que ses quotas et ses conditions permettent bien le test. Mais ça ne prouve pas, à elle seule, que le service tiendra en production.
MonkeyCode est présenté par son opérateur comme un projet open source donnant accès à des modèles et proposant un serveur gratuit. Cet article a été préparé dans le cadre d'une démarche de présentation du produit ; les caractéristiques, licences, quotas et spécifications n'ont pas été vérifiés indépendamment ici. Vérifiez les informations à jour dans la documentation du projet avant de les reprendre dans une décision technique ou budgétaire. Dans tous les cas, faites d'abord tourner votre propre corpus et laissez les résultats - pas la promesse d'un accès gratuit - guider le choix.
Ce qui reste à votre charge après la migration
Changer d'endpoint ne supprime pas automatiquement toutes les dépendances accumulées autour de l'ancien fournisseur. Les paramètres spécifiques, les préfixes de cache, le comportement du streaming, les schémas d'outils, les champs de journalisation et les seuils d'alerte peuvent continuer de refléter l'ancienne intégration. Certains impacts se voient vite. D'autres ne se révèlent que sur des trajectoires « moins courantes » dans un flux de production.
Avant la bascule, dressez un inventaire :
- paramètres spécifiques au fournisseur et valeurs par défaut ;
- format des messages, appels d'outils et sorties structurées ;
- streaming, délais d'attente, tentatives et erreurs transitoires ;
- métriques de coût, latence et volume ;
- filtres, journaux et règles de conservation des données ;
- mécanisme de retour à l'endpoint précédent.
Le corpus de rejeu est souvent l'actif le plus durable. Versionnez-le, documentez vos règles de normalisation, et nommez un responsable. Ajoutez un cas quand un incident (ou une correction manuelle) révèle une entrée que le jeu ne couvrait pas. Sans cette boucle de retour, le corpus finit comme une photo d'une ancienne version du produit, et sa valeur diminue avec le temps.
Le rejeu a aussi des limites nettes. Il ne couvre que les entrées capturées, et il ne prédit pas ce qui se passe sur des prompts inédits. Il n'évalue pas, à lui seul, la latence sous charge, la disponibilité, les conditions contractuelles, la sécurité, ni l'impact d'une réponse erronée. Si chaque réponse peut avoir des conséquences juridiques ou financières graves et nécessite une validation humaine systématique, ce test ne remplace pas cette validation. Et sans référence figée, comparer deux réponses ressemble vite à confronter deux opinions plutôt qu'à mesurer une migration.
Une règle de décision avant de basculer
La question n'est pas : « Le modèle candidat répond-il comme l'ancien ? » Deux modèles peuvent produire des formulations différentes tout en satisfaisant le besoin.
La question utile est : « Les écarts observés respectent-ils nos contrats, nos exigences métier et notre niveau de risque ? »
Avant de changer, vous devriez pouvoir répondre clairement à quatre points :
- Les réponses restent-elles exploitables par les systèmes en aval ?
- Les erreurs mécaniques importantes ont-elles été corrigées (ou bloquées) ?
- Les divergences de sens à fort impact ont-elles été relues par les bonnes personnes ?
- L'équipe sait-elle surveiller, interrompre, ou annuler la bascule ?
Si une de ces réponses est « non », le test a déjà produit une information utile : la migration n'est pas encore assez maîtrisée. La décision peut être de retarder, de ne router qu'une catégorie de requêtes vers le candidat, ou de garder deux fournisseurs selon les cas d'usage. Une migration n'a pas besoin d'être totale pour créer de la valeur.
Conclusion : mesurer les écarts avant de changer d'endpoint
Un modèle moins cher n'est une vraie économie que si le système autour continue de fonctionner. Le shadow replay en parallèle apporte une preuve utile avant la bascule : il met en évidence les écarts sur vos usages, et il aide à distinguer les défauts bloquants des variations réellement acceptables.
Commencez avec un corpus maîtrisé, des règles de comparaison explicites et une revue humaine ciblée. Ajoutez des contrôles de charge, de sécurité et d'exploitation, puis gardez une possibilité de retour arrière. Avant de modifier votre endpoint, choisissez quelques cas réels et produisez un premier rapport de divergence : c'est plus solide qu'une décision basée sur une démo ou sur un tarif seul.
