Accueil / Articles / Ajustement optimal des LLM : routage, récupération d’informations et évaluation plutôt que la taille brute du modèle.

Ajustement optimal des LLM : routage, récupération d’informations et évaluation plutôt que la taille brute du modèle.

Apprenez à choisir entre les petits et grands modèles de langage en fonction de la charge de travail, en mesurant le coût par tâche réussie, et en utilisant d’abord le routage, RAG, le cache et la validation.

6434 mots

Le nombre de paramètres permet d’obtenir facilement des titres accrocheurs, et il est tentant de les considérer comme un indicateur de la qualité du produit : un modèle de 70 milliards de paramètres doit être supérieur à un modèle de 7 milliards, donc le plus grand modèle que l’on peut se permettre est forcément le choix sûr. En production, cette approche simpliste échoue rapidement. Les modèles plus gros coûtent généralement plus par appel, répondent plus lentement, ajoutent une charge à l’infrastructure et résolvent souvent des problèmes que votre application n’a jamais eus. Ce guide montre comment choisir un modèle en fonction de la charge de travail plutôt que de sa taille, comment prendre en compte conjointement les coûts, la latence et les pannes, ainsi quels leviers architecturaux (affectation des requêtes, récupération des données, validation, mise en cache et code pur) offrent généralement plus qu’une simple mise à niveau.

Pourquoi le principe « plus c’est gros, mieux c’est » ne fonctionne plus en production

L’intuition est compréhensible. Les ingénieurs logiciels ont passé des décennies à constater que les mises à niveau matérielles apportaient des avantages : un CPU plus rapide, plus de RAM, des disques plus grands et une GPU plus récente représentent presque toujours des améliorations. Lorsque les modèles de langage sont devenus plus volumineux et plus performants, il semblait naturel d’appliquer ce même modèle mental. Si un modèle raisonne mieux qu’un autre, pourquoi choisirait-on délibérément le plus faible ?

La réponse apparaît dès qu’un modèle est utilisé pour traiter une tâche réelle. La question que l’on se pose passe de « quel modèle est le plus intelligent ? » à « quel modèle produit le meilleur résultat pour cette tâche spécifique ? ». Ce sont deux questions très différentes. Le modèle le plus puissant peut fournir une réponse légèrement meilleure, mais beaucoup plus lentement. Il peut coûter plusieurs fois plus cher. Pour une simple opération de classification, il peut être inutile, générer des réponses trop longues pour être affichées par l’interface utilisateur, épuiser rapidement les ressources de contexte disponibles et compliquer son déploiement. Plus important encore, il peut résoudre un problème qui n’existe pas réellement.

Commencez par la charge de travail, et non par le nombre de paramètres

Une manière plus fiable de choisir un modèle consiste à commencer par décrire la tâche elle-même. Avant de comparer les différents modèles, répondez aux questions suivantes :

  • À quoi ressemble l’entrée ?
  • Quel est le résultat attendu ?
  • À quel point le raisonnement requis est-il complexe ?
  • Quel contexte chaque demande nécessite-t-elle ?
  • Jusqu’à quel point la fonctionnalité peut-elle tolérer des erreurs ?
  • À quelle vitesse la réponse doit-elle arriver ?
  • Quel est le coût acceptable par demande ?
  • La fonctionnalité a-t-elle vraiment besoin de génération de texte ?
  • Un modèle plus petit, du code déterministe, des mécanismes de récupération, de mise en cache ou une combinaison de ces éléments pourraient-ils accomplir la tâche plus efficacement ?
  • Cette dernière question est la véritable question d’ingénierie, et le reste de ce guide vise à y répondre : pourquoi le modèle le plus grand n’est pas automatiquement le meilleur, comment choisir entre modèles petits et grands, quand un modèle de grande taille justifie réellement son coût, et à quoi ressemble une conception de production judicieuse.

    Un produit de support, deux charges de travail complètement différentes

    Considérons une application de support d’entreprise. Un utilisateur tape « Réinitialiser mon mot de passe ». Que doit faire la couche d’IA dans ce cas ? Il est très probable qu’elle se contente de reconnaître l’intention et de la mapper à une étiquette comme celle ci-dessous, afin que l’application puisse transférer la demande à un flux de travail déterministe et prédéfini.

    PASSWORD_RESET
    

    Aucun modèle de raisonnement lourd n’est nécessaire pour atteindre cette étiquette. Diriger cette demande vers un tel modèle constituerait un choix de conception discutable, puisqu’un modèle léger, ou même une correspondance entre mots-clés et règles, pourrait tout à fait s’en charger.

    Imaginons maintenant un message différent : depuis le déploiement d’hier, les clients européens rencontrent des échecs de paiement intermittents, et l’utilisateur souhaite que le système compare les différences apportées par le déploiement avec les journaux du service de paiement, identifie les schémas d’échec probables, détermine si un nouveau mécanisme de tentative est impliqué, et propose un plan de rollback. Cette demande nécessite bien plus que cela :

    • Récupération des modifications de déploiement et des journaux pertinents
    • Une grande quantité de contexte
    • La capacité à lire et comprendre du code
    • Analyse des sorties de journal
    • Raisonnement s’étendant sur plusieurs étapes
    • Corrélation des événements entre systèmes
    • Une explication technique claire
    • Gestion honnête de l’incertitude

    Ici, un modèle plus puissant peut véritablement apporter de la valeur. L’erreur réside non pas dans l’utilisation d’un modèle volumineux, mais dans le fait de traiter ces deux demandes comme s’il s’agissait du même travail.

    Une définition fonctionnelle de la valeur d’un modèle

    Un moyen utile pour encadrer ce choix est une heuristique approximative :

    Valeur du modèle = capacité × fiabilité × utilité ÷ coût

    Ce n’est pas une formule à calculer. C’est une façon de penser. Un modèle qui est 10 % plus performant mais cinq fois plus cher et trois fois plus lent n’est pas automatiquement la meilleure option de production. De même, un modèle extrêmement bon marché mais peu fiable pour votre tâche est également une mauvaise choix. Ce que vous devez optimiser, ce n’est pas l’intelligence maximale, mais plutôt l’intelligence la plus utile par unité de coût, de latence et de complexité.

    Pourquoi les grands modèles sont tentants, et où apparaissent les contraintes

    Préférer de grands modèles n’est pas irrationnel, car ils offrent des avantages réels. Ils gèrent souvent mieux le raisonnement complexe, performent de manière plus uniforme sur diverses tâches, interprètent des instructions vagues avec plus de finesse, naviguent dans des bases de code complexes de manière plus efficace, nécessitent moins d’indications spécifiques à la tâche, et peuvent être bien plus performants pour des travaux véritablement difficiles.

    Alors pourquoi ne pas utiliser le modèle le plus puissant partout ? Parce que la production introduit des contraintes que les chiffres affichés sur les classements ne mettent que rarement en évidence. Imaginez une interface qui traite 100 000 requêtes par jour : si le modèle plus volumineux coûte nettement plus par appel, cette différence n’est plus abstraite ; elle se reflète dans le budget d’infrastructure. Si en plus ce modèle est plus lent, les utilisateurs s’en aperçoivent. S’il a tendance à fournir des réponses trop longues, la consommation de tokens augmente. Et si l’application exécute des milliers de tâches mineures, envoyer chacune d’elles à un modèle de raisonnement avancé constitue simplement un gaspillage.

    Le choix d’un modèle est un problème d’optimisation, pas une compétition de popularité.

    Le modèle en tête d’une table de benchmarks n’est pas nécessairement celui qui permet d’obtenir la meilleure application.

    Le nombre de paramètres n’est qu’un axe parmi d’autres

    Les comparaisons entre les modèles ont tendance à se concentrer sur la taille : 7B, 13B, 34B, 70B, des centaines de milliards. La taille seule ne vous renseigne pas beaucoup sur l’adéquation du modèle. Une comparaison pratique prend en compte plusieurs dimensions en même temps, par exemple :

    • les capacités pour votre tâche spécifique
    • la latence, tant en termes de temps nécessaire pour générer le premier token que du temps total de génération
    • le coût par requête et par tâche réussie
    • la capacité de traitement sous la charge attendue
    • la taille de contexte réellement requise par la tâche
    • la fiabilité et la cohérence lors de plusieurs exécutions successives
    • les options de déploiement, y compris l’hébergement local ou privé
    • le degré de contrôlabilité

    Le degré de contrôlabilité mérite une attention particulière car il est facile d’en négliger l’importance. Un modèle peut être très performant mais difficile à maîtriser. Dans les workflows d’entreprise, un comportement prévisible vaut souvent plus que la créativité.

    L’extraction structurée est un objectif différent

    Prenons l’extraction de factures. Cette fonctionnalité nécessite une structure fixe comme celle ci-dessous, et non un essai approfondi sur le document.

    {
      "invoiceNumber": "...",
      "invoiceDate": "...",
      "vendor": "...",
      "total": 0
    }
    

    Ce qui compte ici, c’est un résultat fiable et bien formaté que le code suivant puisse parser à chaque fois. C’est un objectif d’optimisation distinct de la capacité de raisonnement général, et les modèles plus petits ou plus restreints y parviennent souvent très bien, surtout lorsqu’ils sont combinés à une validation de schéma.

    Latence : le premier piège en environnement de production

    Dans une démonstration, un temps d’attente de six secondes semble acceptable. La réponse est impressionnante, vous la partagez avec l’équipe, et tout le monde est satisfait. Mais si l’on place la même opération derrière un bouton dans une application réelle, l’expérience change : l’utilisateur clique, un indicateur de chargement apparaît, et trois, cinq ou huit secondes s’écoulent. À ce stade, personne ne s’émerveille de l’intelligence du modèle ; ils se demandent plutôt pourquoi l’application est si lente.

    La latence fait partie des fonctionnalités d’un produit, et dans les logiciels interactifs, elle revêt une importance capitale.

    Pourquoi les modèles plus gros ont tendance à répondre plus lentement

    La relation exacte dépend de nombreux facteurs : l’architecture du modèle, le matériel, la pile de serveur, la quantification, le regroupement des requêtes, le nombre de tokens générés, la taille du prompt ainsi que la conception du modèle. En général, cependant, les modèles nécessitant plus de ressources en termes de calcul ont besoin de davantage de ressources par token et peuvent restituer des résultats plus lentement. Cela est particulièrement important dans :

    • interfaces de chat
    • assistants de codage et complétion automatique
    • assistants vocaux
    • outils d’assistance client
    • tableaux de bord interactifs
    • flux de travail agents, où les temps d’attente s’accumulent à chaque étape

    La complétion automatique illustre bien ce point : une suggestion de code qui nécessite cinq secondes n’est plus une complétion automatique, mais plutôt une interruption. Un modèle plus petit qui répond presque instantanément est souvent bien plus utile qu’un modèle plus puissant qui oblige le développeur à attendre.

    Le streaming améliore la perception, pas le calcul

    Le streaming est la méthode standard pour faire paraître les temps d’attente plus courts. Sans lui, l’utilisateur ne voit rien tant que la réponse complète n’est pas prête :

    [wait...]
    Hello! Here is the answer...
    

    Avec le streaming, le texte apparaît progressivement à l’écran au fur et à mesure que les tokens arrivent :

    Hello
    Hello, here
    Hello, here is
    Hello, here is the
    Hello, here is the answer...
    

    Il convient de maintenir une distinction claire. Le streaming réduit la latence perçue car les premiers mots apparaissent rapidement, mais il ne diminue ni la puissance de calcul requise ni le temps total nécessaire pour obtenir une réponse complète. Il s’agit d’une amélioration de l’expérience utilisateur, et non d’une optimisation des performances ; il n’a aucun effet sur les étapes non interactives telles qu’un classificateur intégré dans une chaîne de traitement.

    Cost : le mesurer par tâche réussie

    C’est précisément à ce stade que de nombreux prototypes se transforment en systèmes coûteux. Pendant le développement, les dépenses semblent négligeables : un ingénieur envoie quelques requêtes et personne ne pense à la facture. Puis le trafic réel arrive, et chaque requête peut contenir bien plus que simplement le message de l’utilisateur :

    • de nombreux utilisateurs simultanés
    • plusieurs requêtes par session
    • des prompts longs
    • des documents récupérés
    • les résultats des outils
    • l’historique de la conversation
    • des réponses générées

    Le volume des tokens augmente rapidement, et le choix du modèle devient alors très important.

    Une métrique plus fiable que le prix par appel est le coût nécessaire pour accomplir correctement la tâche. Comparons deux modèles hypothétiques (les chiffres sont indicatifs, et non des résultats de benchmark) :

    • Modèle A : 0,01 $ par requête, précision de 90 % sur les tâches, environ 1,11 requêtes nécessaires par réussite, soit approximativement 0,011 $ par tâche accomplie avec succès.
    • Modèle B : 0,05 $ par requête, précision de 96 % sur les tâches, environ 1,04 requêtes nécessaires par réussite, soit approximativement 0,052 $ par tâche accomplie avec succès.

    Le nombre d’essais attendu est simplement un divisé par le taux de réussite ; par conséquent, le coût par succès correspond au prix de la demande divisé par la précision. Si le Modèle B coûte cinq fois plus cher tout en améliorant les résultats seulement légèrement, l’entreprise peut raisonnablement préférer le Modèle A. La situation change lorsque la réponse erronée est coûteuse, par exemple lorsqu’elle entraîne un remboursement, un problème de conformité ou une panne. C’est pourquoi le coût doit toujours être évalué en fonction des conséquences de l’échec, et non isolément.

    Modèles trop puissants pour des problèmes insuffisamment complexes

    • des règles déterministes
    • des embeddings
    • un petit modèle de langage
    • un classificateur dédié
    • un modèle plus grand réservé aux cas à faible confiance

    Échelonnement : le modèle coûteux en tant que gestionnaire d’exceptions

    Every request
         ↓
    Large model
    

    Un design d’escalade permet à un modèle peu coûteux de tenter d’abord et d’évaluer son niveau de confiance :

    Every request
         ↓
    Small/cheap model
         ↓
    Confidence check
         ↓
     ┌───────────────┐
     │               │
    High confidence  Low confidence
     │               │
    Fast answer      Large model
    

    Les réponses à forte confiance sont renvoyées immédiatement ; seuls les cas incertains sont transmis au modèle plus puissant. Le modèle coûteux cesse d’être la solution par défaut pour devenir un gestionnaire d’exceptions. Ce schéma repose sur l’existence d’un signal de confiance fiable, tel qu’une note de classeur calibrée, une concordance entre différentes méthodes, ou un validateur capable de rejeter les résultats mal formatés ; il convient donc d’évaluer la fréquence à laquelle des réponses de faible qualité parviennent à passer par le chemin « haute confiance » avant de s’y fier.

    Routage des requêtes entre différents niveaux de modèles

    Lorsque l’on pense de cette manière, les modèles cessent d’apparaître comme des concurrents pour ressembler à des travailleurs spécialisés. Un routeur de demandes peut se situer devant plusieurs niveaux et choisir celui qui convient à chaque demande, avec une étape de validation commune avant que quoi que ce soit n’atteigne l’utilisateur :

    User Request
                          |
                          v
                    Request Router
                          |
              +-----------+-----------+
              |           |           |
              v           v           v
           Simple       Medium       Complex
              |           |           |
              v           v           v
          Small LLM    Mid Model    Large Model
              |           |           |
              +-----------+-----------+
                          |
                          v
                    Validation Layer
                          |
                          v
                       Response
    

    Le routeur a besoin d’une notion de complexité. La version la plus simple consiste en un petit ensemble de catégories :

    SIMPLE
    MEDIUM
    COMPLEX
    

    La logique d’envoi peut alors être aussi simple qu’un interrupteur basé sur le verdict du classificateur. L’exemple ci-dessous est écrit en C#, mais le langage est secondaire ; la même structure convient tout aussi bien à un service TypeScript.

    public async Task<string> ProcessAsync(Request request)
    {
        var complexity = await classifier.ClassifyAsync(request);
        return complexity switch
        {
            Complexity.Simple =>
                await smallModel.GenerateAsync(request),
            Complexity.Medium =>
                await mediumModel.GenerateAsync(request),
            Complexity.Complex =>
                await largeModel.GenerateAsync(request),
            _ => throw new InvalidOperationException()
        };
    }
    

    Ce qui importe, c’est l’affirmation architecturale que le code exprime : toutes les requêtes ne méritent pas un niveau d’intelligence maximal. Appliquée de manière cohérente, cette seule décision peut modifier considérablement les aspects économiques d’un système d’IA. Notez que le classificateur lui-même ajoute une appel et un certain temps de latence à chaque requête ; il devrait donc être bien moins coûteux que les modèles vers lesquels il redirige les requêtes. De plus, une catégorie inconnue doit provoquer une erreur visible, comme c’est le cas avec la branche par défaut ici.

    Lorsque l’écart réside dans les connaissances, et non dans l’intelligence

    Un autre réflexe fréquent est : « Le modèle ne connaît pas notre documentation interne, alors passons à un modèle plus grand. » La taille ne résout pas le manque de connaissances. Lorsque les informations sont propriétaires, récentes ou hautement spécialisées dans un domaine donné, le problème concerne l’accès aux connaissances plutôt que la capacité de raisonnement. C’est précisément ce problème que la génération augmentée par récupération d’informations (RAG) vise à résoudre. Le flux de base est le suivant :

    User Question
          |
          v
    Embedding / Retrieval
          |
          v
    Relevant Documents
          |
          v
    Prompt + Retrieved Context
          |
          v
    Language Model
          |
          v
    Answer
    

    Si un utilisateur demande des informations sur la politique interne de remboursement de votre entreprise pour les clients entreprises, aucun modèle général, aussi performant soit-il, ne connaît la réponse. Vous devez fournir le texte pertinent dans l’instruction donnée au modèle. Pour en savoir plus sur le fonctionnement de cette étape de récupération, consultez notre guide sur la manière dont les systèmes RAG récupèrent des connaissances fraîches sur demande.

    Réparer le flux d’information avant le modèle

    Cela conduit à un principe qui mérite d’être adopté comme règle :

    Mieux préparer les données que vous fournissez au modèle avant d’upgrader ce dernier.

    Les équipes tentent souvent de corriger des réponses insuffisantes en passant à un modèle plus puissant, alors que la véritable cause réside ailleurs :

    • récupération insuffisante
    • dokuments irrelevants
    • metadonnées manquantes
    • fragmentation inadaptée
    • contexte insuffisant
  • informations obsolètes
  • instructions ambiguës
  • Dans de tels cas, le modèle n’est pas le goulot d’étranglement ; c’est plutôt le pipeline d’information.

    La qualité du contexte l’emporte sur sa quantité

    Les fenêtres de contexte étendues sont impressionnantes, mais plus de contexte ne signifie pas automatiquement mieux. Fournir à un modèle 200 pages de documentation alors que deux paragraphes contiennent déjà la réponse lui donne techniquement les informations nécessaires, mais rend en pratique la tâche plus difficile, car il doit maintenant trouver le signal parmi le bruit. Un contexte trop volumineux a tendance à augmenter :

    • la consommation de tokens
    • le temps de réponse
    • les coûts
    • la distraction
    • le risque d’informations contradictoires

    Un objectif plus réaliste est d’utiliser la quantité minimale de contexte de haute qualité permettant au modèle de répondre correctement. C’est pourquoi les systèmes RAG avancés investissent beaucoup dans la couche de récupération, grâce à des techniques telles que :

    • recherche sémantique et hybride
    • filtrage sur les métadonnées
    • réécriture de la requête de l’utilisateur
    • reclassement des passages candidats
    • mise à jour régulière des documents
    • création de segments bien structurés

    Les hallucinations nécessitent une vérification, pas un modèle plus grand

    Une vérité dérangeante : utiliser un modèle suffisamment puissant ne fait pas disparaître les hallucinations. Les modèles plus performants ont en effet tendance à fournir plus de faits corrects et à raisonner mieux dans diverses tâches, mais un modèle de langage reste un générateur de texte, et non une source de vérité que l’on peut interroger comme une base de données. Par conséquent, la solution réside dans la conception : il faut intégrer une vérification explicite dans le flux, par exemple :

    User Request
         ↓
    Retrieve Evidence
         ↓
    Generate Answer
         ↓
    Validate Claims
         ↓
    Return Response
    

    Pour les workflows à haute valeur, vous pouvez renforcer cela en ajoutant :

    • des citations indiquant des preuves
    • des sorties structurées vérifiées contre un schéma
    • une validation selon des règles métier
  • Recherches dans le système de registre et autres appels d’outils
  • Calculs effectués dans le code
  • Validation humaine pour les actions les plus risquées
  • Laissez le modèle raisonner et laissez le logiciel appliquer les règles

    Cela crée une frontière importante dans l’architecture. Si l’on demande à un modèle de calculer le montant total d’une facture, il n’y a aucune raison de faire confiance à ses calculs arithmétiques lorsque votre application peut effectuer ces calculs avec précision. Divisez plutôt les responsabilités :

    Model:
    Extract line items
    
    Application:
    Calculate subtotal
    Application:
    Calculate tax
    Application:
    Calculate total
    Model:
    Explain the result
    

    Le modèle extrait les éléments de la facture et explique le résultat ; l’application calcule le solde partiel, les taxes et le montant total. Chaque partie fait ce pour quoi elle est fiable, et les chiffres affichés à l’utilisateur sont toujours corrects par construction.

    Où les petits modèles brillent, et où ils manquent de potentiel

    Les petits modèles de langage sont souvent considérés comme « moins intelligents », ce qui est techniquement vrai dans de nombreux cas. Mais l’ingénierie ne concerne pas uniquement l’intelligence, et les petits modèles offrent des avantages concrets :

    • coût d’inférence plus faible
    • latence réduite
    • déploiement local simplifié
    • exigences en matière d’infrastructure moindres
    • débit potentiellement plus élevé
    • scalabilité facilitée
    • adaptation idéale pour des tâches spécifiques
    • utilité dans les scénarios edge
    • protection de la vie privée potentiellement améliorée lorsqu’ils fonctionnent localement

    Ils sont particulièrement adaptés à la classification, à l’extraction, à la synthèse, au routage, à l’autocomplétion, aux transformations simples ainsi qu’aux workflows spécifiques à un domaine. Si vous souhaitez approfondir cette tendance, notre article sur les petits modèles spécialisés qui surpassent les grands LLM en traite plus en détail.

    Cependant, petit ne signifie pas automatiquement meilleur. Certaines tâches dépassent les capacités fiables d’un modèle de petite taille : raisonnement sophistiqué à partir de multiples sources, analyse complexe de code, problèmes de planification difficiles ou interprétation nuancée. Dans ces cas, un modèle plus puissant justifie son coût. Les deux extrêmes sont mauvais conseils : « Utiliser toujours le plus grand » gaspille de l’argent, tandis que « utiliser toujours le plus petit » entraîne une qualité médiocre. La règle à suivre est la suivante :

    Utilisez le modèle le plus petit qui répond au seuil de qualité de votre application.

    Chargements de travail justifiant l’utilisation d’un modèle volumineux

    Rien de tout cela n’est un argument contre les modèles volumineux. Ils sont extrêmement utiles, et certains chargements de travail justifient clairement leurs capacités supplémentaires.

    Raisonnement complexe en plusieurs étapes

    Lorsqu’une fonctionnalité dépend d’un raisonnement en chaîne, un modèle plus puissant peut produire des résultats nettement meilleurs.

    Travaux nécessitant un codage rigide

    Les modèles volumineux se révèlent indispensables pour faire face à des exigences complexes, des bases de code inconnues, des décisions architecturales et des sessions de débogage difficiles.

    Langage naturel ambigu

    Certaines demandes ne correspondent pas à des catégories prédéfinies. Un modèle plus puissant est généralement mieux à même de percevoir les subtilités et les intentions.

    Synthèse à partir de nombreux documents

    Lorsque la réponse nécessite de combiner des informations provenant de nombreuses sources, les capacités du modèle deviennent plus importantes.

    Flux de travail agents

    Un agent doit généralement :

    1. comprendre un objectif
    2. planifier des actions
    3. choisir des outils
    4. examiner les résultats
    5. s’adapter en cas d’échec
    6. revoir le plan
    7. terminer la tâche

    Cela est bien plus difficile que la classification, et un modèle plus puissant s’avère alors tout à fait justifié. Le critère d’évaluation reste le même dans tous les cas : utiliser des modèles de grande taille lorsque leurs capacités supplémentaires génèrent une valeur mesurable.

    Le coût opérationnel d’une architecture ingénieuse

    Il existe un coût que les benchmarks ne montrent jamais : la complexité architecturale. La conception la plus simple possible consiste en une seule application, un seul modèle de grande taille et une seule réponse :

    Application
       ↓
    Large Model
       ↓
    Response
    

    Imaginons maintenant optimiser tout cela en même temps :

    Application
       ↓
    Router
       ↓
    Classifier
       ↓
    Small Model
       ↓
    Confidence Evaluator
       ↓
    RAG
       ↓
    Reranker
       ↓
    Large Model
       ↓
    Validator
       ↓
    Fallback Model
       ↓
    Human Review
    

    Cette chaîne de traitement pourrait effectivement produire un système amélioré, mais elle introduit également beaucoup plus de composants, et chaque composant apporte :

    • un suivi et des journaux supplémentaires
    • de nouveaux modes de défaillance
    • une surface de test plus vaste
    • une infrastructure supplémentaire à gérer
    • des déploiements plus difficiles
    • plus de connaissances que l’équipe doit maîtriser pour l’exploiter

    L’optimisation doit donc être réfléchie. Construire une architecture à sept modèles pour économiser quelques centimes par requête n’est rarement un bon échange ; n’ajoutez chaque couche que lorsque des mesures montrent qu’elle justifie son entretien.

    Évaluez en fonction de votre propre charge de travail, et non selon des classements

    Les benchmarks publics ne sont qu’un point de départ, pas une décision. Votre application a son propre benchmark, et c’est le seul qui compte. Pour un assistant d’analyse de code en IA, un ensemble d’évaluation pourrait inclure :

    • Vulnérabilités d’injection SQL
    • Conditions de course
    • Bug de référence nulle
    • Défauts d’autorisation
    • Gestion incorrecte des exceptions
    • Problèmes de performance
    • Violations architecturales

    Pour un assistant de support client, on évalue différents aspects :

    • Conformité aux politiques
    • Précision factuelle
    • Ton utilisé
    • Précision de l’escalade
    • Comportement en cas de refus
    • Validité du résultat structuré

    L’ensemble d’évaluation doit ressembler autant que possible au trafic réel.

    Créer un outil de comparaison

    La procédure de base est simple : collecter des requêtes similaires à celles en production avec des résultats attendus, exécuter chaque modèle candidat sur elles et les comparer.

    Production-like prompts
            ↓
    Expected outcomes
            ↓
    Run Model A
            ↓
    Run Model B
            ↓
    Compare
            ↓
    Measure
    

    Métriques utiles à enregistrer pour chaque exécution :

    • Correctitude et achèvement de la tâche
  • La fréquence à laquelle le modèle hallucine
  • Le temps de latence
  • Les tokens consommés et le coût correspondant
  • La proportion des résultats structurés qui sont valides
  • Les refus et les erreurs
  • Avec cela en place, le choix d’un modèle devient une décision technique plutôt qu’une supposition, et vous pouvez relancer le même outil chaque fois qu’un fournisseur met en ligne une nouvelle version du modèle.

    Un processus de sélection de modèle en quatre étapes

    Pour une nouvelle fonctionnalité d’IA, un processus simple et reproductible est très efficace.

    Étape 1 : Définir précisément la tâche

    N’ commencez pas par « Quel modèle devrions-nous utiliser ? » Commencez plutôt par « Que doit accomplir exactement le modèle ? » et notez la réponse en termes concrets :

    Input:
    Customer email
    Output:
    Intent + urgency + recommended workflow
    

    Une telle spécification, avec une entrée claire et une sortie claire, est bien plus utile qu’un objectif vague.

    Étape 2 : Définir ce que signifie « suffisamment bon »

    Fixez des critères d’acceptation explicites avant de tester quoi que ce soit. Par exemple :

    Intent accuracy >= target threshold
    Structured output must always validate
    Response should normally arrive within target latency
    

    Les seuils réels dépendent de l’application ; ce qui compte, c’est qu’ils existent avant de comparer les modèles, afin que les résultats ne puissent pas être rationalisés par la suite.

    Étape 3 : Essayez d’abord le modèle le plus simple fonctionnel

    C’est l’étape que les équipes sautent le plus souvent. Commencez par quelque chose de simple, mesurez les résultats, et arrêtez-vous si cela fonctionne. N’avançez qu’en cas d’échec :

    Small Model
        ↓
    Evaluation
        ↓
    Pass? ── Yes → Ship
        |
        No
        ↓
    Larger Model
        ↓
    Evaluation
        ↓
    Pass? ── Yes → Ship
        |
        No
        ↓
    Stronger architecture/model
    

    En réalité, vous montez un échelon de capacités à la fois, et chaque échelon doit être obtenu grâce à une évaluation négative.

    Étape 4 : Optimisez le système environnant

    • La récupération fournit-elle le bon matériel ?
    • Le prompt est-il clair et sans ambiguïté ?
    • Tout élément de contexte est-il réellement pertinent ?
    • La sortie est-elle validée avant utilisation ?
  • Le code brut pourrait-il assumer une partie du travail ?
  • Un cache permettrait-il d’absorber les requêtes répétées ?
  • Y a-t-il des tokens que l’on peut supprimer ?
  • Pourriez-vous ne gérer que les requêtes difficiles ?
  • Des améliorations dans ce domaine permettent parfois d’éliminer complètement le besoin d’un modèle plus volumineux.

    Autres leviers à actionner avant une mise à niveau

    Les prompts en tant que contrats

    L’ingénierie des prompts n’est pas de la magie, mais une tâche mal définie peut faire que même un modèle performant se comporte mal. Comparez une instruction vague :

    Analyze this customer message.
    

    à une autre qui définit la sortie attendue ainsi que les règles en cas d’incertitude :

    Analyze the customer message.
    Return JSON with:
    - intent
    - urgency
    - sentiment
    - recommended_action
    Do not invent information that isn't present.
    If the intent is unclear, return "unknown".
    

    La deuxième version offre au modèle un contrat clair : des champs nommés, une interdiction explicite d’inventer des faits, ainsi qu’une valeur de remplacement définie. L’ajout de quelques exemples améliore souvent davantage les résultats. Cependant, il existe une limite : aucune formulation de prompt ne peut conférer au modèle des capacités qu’il manque fondamentalement, et lorsque cette capacité fait défaut, les ajustements des prompts apportent des gains de plus en plus faibles. Considérez les prompts comme une couche parmi d’autres dans l’optimisation, et non la solution complète.

    Ajustement fin, RAG ou validation ?

    Une autre réaction courante face à des résultats faibles est de dire « faisons un ajustement fin ». Cela peut parfois être la bonne solution, mais diagnostiquez d’abord le problème :

    • Si le modèle manque de connaissances à jour ou spécifiques à l’entreprise, comme la politique en vigueur aujourd’hui, la récupération d’informations est généralement plus adaptée que l’ajustement fin, car les connaissances évoluent et le reconditionnement est lent.
  • Si le modèle ne produit pas de manière fiable le format de sortie souhaité, une formulation structurée des instructions accompagnée d’une validation suffit souvent.
  • Si le modèle manque systématiquement d’un comportement spécifique dans de nombreux exemples, comme un style architectural ou un jugement propre à un domaine donné, le réglage fin devient alors une solution attractive.
  • Adapter la solution au problème réel permet d’économiser à la fois du temps et de l’argent.

    Cachage : l’optimisation peu glamour mais efficace

    Le cachage n’est pas très attrayant, mais il est très efficace. Si les utilisateurs posent constamment la question « quelle est votre politique de retour ? », il n’y a aucune raison d’appeler le modèle à chaque fois. Lorsque la réponse est stable, il convient de la stocker en cache. L’exemple en C# ci-dessous vérifie d’abord le cache, n’appelle le modèle que en cas d’échec, et stocke le résultat pendant 30 minutes :

    public async Task<string> GetAnswerAsync(string question)
    {
        var key = CreateCacheKey(question);
        var cached = await cache.GetStringAsync(key);
        if (cached is not null)
            return cached;
        var answer = await model.GenerateAsync(question);
        await cache.SetStringAsync(
            key,
            answer,
            TimeSpan.FromMinutes(30));
        return answer;
    }
    

    Le cache sémantique réel est plus sophistiqué que la correspondance stricte de chaînes de caractères, car deux questions formulées différemment peuvent nécessiter la même réponse, et il faut une politique pour invalider les réponses lorsque les faits sous-jacents changent. L’idée architecturale reste valable :

    La requête d’IA la plus rapide est celle que vous ne lancez jamais.

    Le même principe s’applique à la déduplication, à la précomputation, aux réponses déterministes, à la réutilisation des résultats de recherche, au cache de préfixes de requête lorsque le fournisseur le prend en charge, ainsi qu’à la simple réutilisation des réponses. Avant d’investir dans plus de ressources de calcul, éliminez celles dont vous n’avez pas besoin.

    Considérez les tokens comme un budget de ressources

    Lorsque l’on considère un système d’IA comme un système distribué, les tokens deviennent une ressource de plus à gérer. Les services traditionnels gèrent la CPU, la mémoire, le réseau et le stockage. Les applications d’IA ajoutent des tokens d’entrée, des tokens de sortie, la taille du contexte et le temps d’inférence, ce qui fait que la conception des prompts devient une question de performance.

    Pensez à envoyer l’historique complet des conversations avec chaque demande. Le prompt continue de s’allonger, et puis viennent s’ajouter les documents récupérés, les résultats des outils, les instructions du système et les actions précédentes de l’agent. Une simple question peut finir par contenir une charge énorme. Une conception plus sobre sélectionne uniquement l’historique pertinent avant la récupération et crée un contexte compact :

    Conversation
        ↓
    Relevant history selection
        ↓
    Retrieval
        ↓
    Compact context
        ↓
    Model
    

    au lieu d’envoyer tout ce que le système a déjà vu :

    Everything we've ever seen
            ↓
    Model
    

    Plus de contexte ne coûte jamais rien : on le paie en argent, en latence et, souvent, en qualité des réponses.

    Les agents multiplient chacune de ces décisions

    Les systèmes agents rendent encore plus cruciale la sélection des modèles. Une seule demande de l’utilisateur peut se décomposer en de nombreuses étapes :

    User Request
        ↓
    Planning
        ↓
    Tool Selection
        ↓
    Search
        ↓
    Database Query
        ↓
    Code Execution
        ↓
    Analysis
        ↓
    Final Response
    

    Si chaque étape s’exécute avec le modèle le plus coûteux, les dépenses peuvent exploser. Pourtant, ces étapes n’ont que rarement besoin des mêmes capacités. Une affectation mixte pourrait ressembler à ceci :

    Intent classification → Small model
    Simple tool selection → Small model
    Complex planning → Large model
    Data extraction → Small model
    Final explanation → Medium model
    

    Il s’agit d’une architecture d’IA hétérogène, et c’est là que de nombreux systèmes en production se dirigent : pas un seul modèle géant qui fait tout, mais plusieurs modèles, outils, composants déterministes, pipelines de récupération et validateurs qui travaillent ensemble. Notre analyse de pourquoi les coûts de l’IA agente explosent explore plus en détail cet aspect lié aux coûts.

    Pensez aux modèles comme à des membres d’une équipe

    Une analogie utile : imaginez trois ingénieurs. L’un est très expérimenté, coûteux et surchargé de travail. Un autre est compétent et efficace. Le dernier est junior mais très rapide pour les tâches répétitives. Vous ne confieriez pas toutes les tâches à l’ingénieur le plus expérimenté. Vous attribueriez les tâches en fonction de leur difficulté :

    Simple repetitive task
    → Engineer C
    Normal feature
    → Engineer B
    Complex architecture problem
    → Engineer A
    

    Les modèles peuvent être traités de la même manière. Un modèle plus petit n’est pas « mauvais » ; il peut simplement être adapté à des responsabilités plus restreintes. La compétence essentielle consiste à diviser le travail en parties. Plutôt que de chercher un modèle capable de tout gérer, divisez le flux de travail afin que chaque composant s’occupe de ce qu’il fait le mieux. Cette façon de penser permet une meilleure évolutivité.

    En résumé : une architecture de référence

    En combinant ces idées, un assistant IA d’entreprise pourrait être structuré comme ceci :

    User
                               |
                               v
                        API / Gateway
                               |
                               v
                        Request Router
                               |
                 +-------------+-------------+
                 |                           |
                 v                           v
           Simple Request              Complex Request
                 |                           |
                 v                           v
           Small Model                    Planner
                                             |
                                +------------+------------+
                                |            |             |
                                v            v             v
                             Search       Database       Tools
                                |            |             |
                                +------------+-------------+
                                             |
                                             v
                                          Context
                                             |
                                             v
                                       Strong Model
                                             |
                                             v
                                       Validator
                                             |
                                      +------+------+
                                      |             |
                                    Valid        Invalid
                                      |             |
                                      v             v
                                   Response      Retry/Fallback
    

    Remarquez ce qui ne se passe pas : le modèle le plus puissant n’est pas chargé de tout gérer. Les demandes simples sont adressées à un modèle plus simple. Les demandes complexes passent par un planificateur qui collecte des informations provenant de recherches, de bases de données et d’outils, avant qu’un modèle performant ne travaille sur un contexte soigneusement sélectionné. Un validateur vérifie le résultat, et les résultats invalides déclenchent une tentative de nouveau ou un mécanisme de secours. La conception repose sur :

    • un routeur qui choisit le chemin à suivre
    • des outils et des moyens de récupération d’informations
    • des systèmes déterministes pour des résultats précis
    • des modèles spécialisés selon le rôle
    • une validation associée à des stratégies de tentative répétée et de secours

    Ici, le modèle n’est qu’une partie du système, et non le système tout entier.

    Dix erreurs qui persistent

    1. Choisir d’abord un modèle puis décrire le problème ensuite. Cette ordre est inversé ; il faut d’abord définir la charge de travail avant toute autre chose.
  • Optimisation pour les scores de benchmark. Un benchmark public ne tient pas compte des exigences métier ; votre propre ensemble d’évaluation est plus important.
  • Envoi de chaque requête au modèle le plus puissant. Cela entraîne des coûts et des latences inutiles ; dirigez les requêtes en fonction de la variabilité des charges de travail.
  • Résolution du manque de connaissances grâce à un modèle plus grand. Si les informations ne figurent pas dans les données d’entraînement du modèle, la récupération est généralement la meilleure solution.
  • Demander au modèle d’effectuer des tâches déterministes. Les calculs, le stockage de données, les vérifications d’autorisation et les règles métier doivent être gérés par du code ordinaire, et non par un modèle de langage.
  • Présumer qu’un contexte plus large est toujours préférable. Des informations supplémentaires peuvent devenir du bruit ; privilégiez plutôt la récupération des éléments pertinents.
  • Ignorer les latences jusqu’à la phase de production. Mesurez-les dès le premier prototype.
  • Négliger l’utilisation des tokens. Un prompt qui semble inoffensif en phase de développement peut devenir coûteux à grande échelle.
  • Esperer qu’une mise à jour du modèle résoudra un problème d’architecture. Souvent, c’est la récupération des données, les prompts, les outils, la validation ou le flux de travail lui-même qui constituent le véritable goulot d’étranglement.
  • Never mesurer après le lancement. Les modèles, les prompts, le comportement des utilisateurs et les données évoluent constamment, il est donc nécessaire d’évaluer en continu les systèmes d’IA et de surveiller leur fonctionnement en production.
  • Une liste de contrôle pour choisir un modèle

    Lorsqu’il s’agit de décider du modèle à utiliser, répondez successivement aux questions suivantes :

    • Un code déterministe peut-il le résoudre ? Si oui, écrivez du code. N’utilisez pas l’IA simplement parce qu’elle est disponible.
    • La tâche est-elle simple et répétitive ? Essayez un petit modèle.
  • A-t-il besoin d’informations privées ou en temps réel ? Envisagez l’utilisation de RAG ou d’un accès à des outils.
  • Exige-t-il un raisonnement sophistiqué ? Évaluez l’utilisation d’un modèle plus puissant.
  • La latence est-elle cruciale ? Préférez des options à plus faible latence.
  • Le volume de demandes est-il élevé ? Le coût et la capacité de traitement deviennent alors des facteurs importants.
  • Les demandes complexes peuvent-elles être transférées à un niveau supérieur ? Si c’est le cas, envisagez l’utilisation d’un routeur de modèles.
  • Quel est le coût d’une défaillance ? Pour les tâches à haut risque, combinez des modèles plus puissants avec des mécanismes de validation et une supervision humaine.
  • Cette liste de contrôle est bien plus utile que de se demander simplement quel est le modèle le plus performant disponible.

    Une question à poser aux ingénieurs IA expérimentés

    Une question d’interview pertinente pour un poste en architecture IA est : "Pourquoi ne pas simplement choisir le modèle le plus performant sur le marché pour tout ?"

    Optimiser une application existante étape par étape

    1. Mesurer. Collecter le nombre de requêtes, les tokens d’entrée et de sortie, la latence, le taux d’erreurs, le taux de réussite des tâches et le coût du modèle.
    2. Identifier les charges de travail coûteuses. Déterminer quels types de requêtes consomment le plus de ressources.
    3. Éliminer les appels inutiles. Utiliser le cache, une logique déterministe, la suppression des doublons et la précomputation.
    4. Réduire le contexte. Supprimer l’historique et les documents irrelevants.
    5. Mieux améliorer la récupération. Fournir des éléments de preuve plus pertinents plutôt que davantage d’éléments.
    6. Essayer un modèle plus petit. Vérifier si la qualité reste acceptable.
    7. Introduire un routage. Envoyer uniquement les cas difficiles aux modèles plus puissants.
    8. Vérifier ce qui est important. Appliquer des schémas, des règles, des outils et une révision humaine selon le cas.
  • Réévaluer. Ne supposez jamais qu’une optimisation a fonctionné ; mesurez-la.
  • Si cela vous semble familier, c’est normal. Il s’agit essentiellement de la même discipline utilisée pour optimiser les logiciels conventionnels.

    L’architecture d’IA la meilleure est généralement hybride

    L’image d’une application d’IA représentée comme un frontend appelant une API LLM et renvoyant la réponse s’estompe :

    Frontend
       ↓
    LLM API
       ↓
    Response
    

    Les applications réelles ressemblent de plus en plus à un guichet qui coordonne des règles, des mécanismes de récupération, des modèles, des outils et des processus de validation :

    Application
                          |
                          v
                      AI Gateway
                          |
              +-----------+-----------+
              |           |           |
              v           v           v
           Rules       Retrieval    Models
              |           |           |
              +-----------+-----------+
                          |
                          v
                        Tools
                          |
                          v
                     Validation
                          |
                          v
                     Application
    

    Un tel design combine l’ingénierie logicielle classique avec l’apprentissage automatique, les modèles de langage et les systèmes de récupération d’informations, ainsi que des bases de données, des API, des mesures de sécurité, des outils d’observabilité et une logique métier écrite en code. C’est une bonne nouvelle pour les ingénieurs logiciels : l’ingénierie IA ne remplace pas l’ingénierie logicielle, elle y ajoute un composant puissant.

    Un changement de perspective similaire est utile : cessez de vous demander quel modèle est le plus intelligent et commencez à vous demander quel système l’est. Un modèle brillant intégré dans un système mal conçu peut produire de terribles résultats, tandis qu’un modèle à capacités moyennes placé dans une architecture bien conçue peut permettre de créer un produit excellent. De bons systèmes compensent les faiblesses d’un modèle grâce à des mécanismes de récupération et d’outils, à une gestion efficace du routage et du cache, à des sorties structurées et à une validation rigoureuse, ainsi qu’à du code conçu pour des tâches précises et à une évaluation continue. En ce sens, les capacités de l’IA sont une propriété de l’architecture, et non seulement du modèle.

    Commencez petit et progressez avec des preuves

    Une stratégie de base sensée pour toute nouvelle fonctionnalité d’IA est décrite dans ce flux :

    Start
                       |
                       v
              Define the workload
                       |
                       v
           Can code solve the problem?
                 /           \
               Yes            No
               |               |
            Use code           v
                        Try small model
                               |
                               v
                          Evaluate
                               |
                    +----------+----------+
                    |                     |
                  Pass                  Fail
                    |                     |
                  Ship                    v
                                  Improve architecture
                                          |
                                          v
                                      Evaluate
                                          |
                                          v
                                  Try stronger model
                                          |
                                          v
                                      Evaluate
    

    Cela permet d’éviter une erreur très courante : dépenser de l’argent pour un problème qui aurait pu être résolu par une meilleure conception technique.

    Parfois, le bon modèle, c’est pas de modèle du tout

    La leçon n’est pas que les petits modèles sont meilleurs ; cela serait tout aussi faux que l’affirmation opposée. Le bon modèle est celui qui répond aux exigences de la tâche en équilibrant capacité et fiabilité par rapport à la latence, au coût et à la complexité. Parfois c’est un petit modèle, parfois un grand modèle, parfois une combinaison des deux, et parfois même pas de modèle d’IA du tout. Si un type de demande peut être géré avec une branche simple comme celle-ci, il n’y a aucune raison d’invoquer un LLM :

    if (request.Type == "PasswordReset")
    {
        return StartPasswordResetWorkflow();
    }
    

    Cela n’est pas anti-IA ; c’est de la bonne ingénierie. On ne achèterait pas un serveur avec une puissance CPU illimitée pour un service qui n’a besoin que de deux cœurs, ni une mémoire de un téraoctet pour un processus qui utilise seulement 4 Go. Le même raisonnement s’applique aux modèles : une capacité dont on n’a pas besoin, c’est un coût dont on n’a pas besoin non plus.

    Points clés

    • Remplacez « quel est le modèle le plus puissant que nous pouvons nous permettre ? » par « quelle est l’architecture la plus simple qui résout de manière fiable ce problème ? » Cette question vous mène naturellement au routage, à la récupération des données, au cache, au code déterministe, à l’évaluation, à la latence et à la gestion des pannes.
    • Jugez les modèles en fonction du coût par tâche réussie, en tenant compte des conséquences d’une réponse erronée, et non en fonction du prix par appel ou du nombre de paramètres.
    • Considérez les connaissances manquantes comme un problème de récupération des données et l’arithmétique ou les règles comme un problème logiciel ; aucun de ces deux cas ne se résout avec un modèle plus grand.
    • Préférez le modèle le plus petit qui réussit une évaluation basée sur vos propres données similaires à celles en environnement de production, et n’augmentez pas la complexité qu’en cas d’arguments convaincants.
    • Gardez l’architecture aussi simple que le permettent les économies réalisées, et continuez à mesurer après le lancement, car les modèles, les prompts et les utilisateurs évoluent constamment.

    Démarrez par concevoir en fonction du problème, puis choisissez un modèle adapté à cette conception. Parfois, ce modèle sera très volumineux, parfois étonnamment petit, et parfois la meilleure décision sera de ne pas utiliser de modèle du tout.

    Lectures complémentaires

  • Au-delà du Top-K : seuils de pertinence, recherche hybride et reranking dans RAG — Découvrez pourquoi une base de données vectorielle associée à un LLM ne constitue pas un système RAG opérationnel, et comment le découpage en chunks, les seuils de similarité, la recherche hybride, le reranking et l’évaluation comblent cette lacune.
  • Gestion des pipelines Docling via HTTP : de la mise en place du projet aux chunks indexés — Suivez pas à pas l’API REST des pipelines Docling : lancez le serveur, découvrez les opérateurs, validez et exécutez un DAG d’ingestion, puis consultez les données de suivi de son exécution.
  • Une évaluation de LLM sans dépendances avec un juge en qui on peut vraiment avoir confiance — Créez une petite évaluation de LLM à partir de journaux réels, de vérifications de code et d’un juge basé sur un seul critère, puis calibrez ce juge en fonction des étiquettes fournies par des humains afin que ses scores aient un sens.
  • Changer de modèles LLM en toute sécurité : étiquettes humaines, métriques par étape, paramètres d’effort — Comment migrer un pipeline LLM à plusieurs étapes vers de nouveaux modèles sans subir de régressions invisibles : vérités de référence fournies par des humains, métriques par étape, prompts obsolètes et mesure de l’effort de raisonnement.