Déplacer ses appels LLM vers un service managé comme AWS Bedrock — souvent pour la résidence des données — semble trivial : « même genre d’API, on change l’endpoint ». En pratique, trois différences nous ont coûté des incidents en production. Ce sont moins des bugs que des contrats implicites qu’on ne découvre qu’avec une vraie charge. Les voici, pour vous les épargner.
Contexte (volontairement générique) : un service qui appelait un LLM via une API directe, migré vers un modèle managé sur Bedrock, dans une région principale (appelons-la région A) avec un profil d’inférence qui peut router vers des régions secondaires (régions B).
Piège 1 — La disponibilité d’un modèle est par région
Un identifiant de modèle qui fonctionne dans une région peut renvoyer « not_found » dans une autre. Bedrock n’expose pas le même catalogue partout. Le service marchait en développement (région A), échouait en production (autre région) — avec une erreur « modèle introuvable ».
Le vrai piège est le type d’erreur : « introuvable », pas « accès refusé ». On part alors déboguer l’IAM pendant une heure, alors que le problème est le choix du modèle pour la région. Leçon : vérifiez la disponibilité du modèle dans votre région de déploiement avant d’écrire la moindre ligne, et choisissez un modèle réellement servi là où vous tournez.
Piège 2 — L’inférence cross-région exige des permissions multi-régions
Pour la capacité et la résilience, Bedrock propose des profils d’inférence qui routent une requête vers plusieurs régions. Excellent pour la disponibilité — piégeux pour l’IAM : votre policy doit autoriser l’invocation du modèle dans chacune de ces régions, pas seulement la principale.
Si vous ne grantez que la région d’origine, vous récoltez un accès refusé intermittent : il n’apparaît que lorsque le profil route vers une région non autorisée. Donc impossible à reproduire de façon fiable, et un cauchemar à diagnostiquer (« ça marche 9 fois sur 10 »). Leçon : grantez l’invocation sur toutes les régions du profil d’inférence, dès le départ, même celles que vous pensez ne jamais utiliser.
Piège 3 — L’API Converse impose un ordre de messages strict
Les API « messages » directes sont souvent tolérantes sur l’ordre. Converse ne l’est pas : les messages doivent alterner utilisateur / assistant et commencer par l’utilisateur. Deux tours consécutifs du même rôle, ou un historique qui ne démarre pas côté utilisateur → erreur serveur en production.
Le sournois : c’est invisible en test unitaire si vos fixtures sont déjà propres, et ça explose dès qu’un vrai historique conversationnel arrive (reprises, messages système mal placés, tours fusionnés côté client). Leçon : normalisez l’ordre avant l’appel — fusionnez les tours consécutifs du même rôle et garantissez un premier message utilisateur.
Récapitulatif
| Contrat implicite | Symptôme en prod | Parade |
|---|---|---|
| Catalogue par région | « not_found » (fausse piste IAM) | Vérifier la dispo du modèle dans la région cible |
| IAM multi-régions | Accès refusé intermittent | Granter l’invocation sur toutes les régions du profil |
| Ordering strict (Converse) | Erreur serveur sur vrai historique | Normaliser l’ordre des messages avant l’appel |
À retenir
Migrer vers un LLM managé, ce n’est pas changer une URL. C’est accepter trois contrats différents : un catalogue par région, une IAM multi-régions, et un format de conversation strict. Les trois se découvrent en production si on ne les anticipe pas — alors testez-les sur un banc qui rejoue un vrai historique, dans votre vraierégion.
Pour aller plus loin sur les arbitrages de modèles et de service : TCO auto-hébergé vs API, comparatif d’API LLM et quel format de service en production.