Signature : article de la rédaction
Placé sur une carte du génie logiciel, un relais IA (passerelle d’API / agrégateur) est un proxy de couche application (L7) doté d’un analyseur à machine à états et d’un ordonnanceur de contexte.
La donne a changé lorsque la complétion d’une seule ligne dans l’IDE a cédé la place aux agents en terminal, comme Claude Code CLI et OpenAI Codex CLI, et au développement piloté par les spécifications. Laissons de côté les métriques génériques de passerelle, comme la stabilité du réseau ou la tenue en charge à forte concurrence. Pour la génération de code, la question est de savoir si le proxy casse la syntaxe, interrompt la machine à états de l’agent, perd des dépendances du contexte long ou retire le protocole d’optimisation envoyé par le client de développement.
Quatre dimensions d’ingénierie couvrent cette question.
1. Intégrité de la syntaxe et des échappements
Le code généré est sensible aux caractères et à la mise en forme. Ce n’est pas de la prose ordinaire. Il comporte une indentation, des retours à la ligne, des échappements et du JSON ou du XML intégré.
1. Échappements sans perte
- Pourquoi ça casse : un bloc de code SSE contient
\n,\t,\", un\\dd’expression régulière ou une chaîne JSON. Si le relais déséchappe ou réencode le flux en réassemblant les blocs, un caractère UTF-8 multioctet peut être coupé, et le client reçoit du code qui ne s’analyse pas. - Comment tester : demandez du code aux échappements extrêmes : une expression régulière chargée, du Python qui embarque des chaînes JSON imbriquées, et du C++ avec pointeurs et macros.
- Critère de réussite : écrivez le flux du relais dans un fichier et analysez-le avec un linter local (
eslint,flake8) ou un analyseur AST (Babel ou Tree-sitter). Le taux d’analyse AST réussie doit être de 100 %.
2. Espaces et indentation
- Pourquoi ça casse : Python et YAML délimitent la portée par l’indentation. Passer de
\nà\r\nchange un diff Git. - Comment tester : envoyez une refactorisation de logique profondément imbriquée, par exemple une fonction Python placée à l’intérieur de 8 niveaux de boucles.
- Critère de réussite : les espaces et les tabulations de la sortie du relais doivent correspondre octet pour octet à la sortie amont, à 100 %. Le relais ne doit ni « embellir » ni compresser les espaces.
2. Appels d’outils et sortie structurée
Un agent de programmation ne se contente pas d’émettre du Markdown. Il appelle des outils comme read_file, edit_file et run_terminal_command.
1. Fidélité au schéma JSON
- Pourquoi ça casse : une modification locale est un JSON structuré, avec des champs comme
path,old_stretnew_str. Si le relais casse cette sérialisation ou perd un champ imbriqué, l’agent échoue à l’analyse et plante. - Comment tester : lancez une tâche d’agent qui modifie plusieurs fichiers à la fois, par exemple une refactorisation d’interface sur 5 fichiers TypeScript, et capturez le corps de l’appel d’outil transmis.
- Critère de réussite : l’objet d’appel d’outil transmis doit correspondre à celui de l’API officielle en amont. Aucun champ manquant, aucun changement de type (par exemple une string devenue number) et aucun JSON tronqué prématurément.
2. État multitour
- Pourquoi ça casse : un bug difficile demande souvent 10 à 30 tours : lire un fichier, tenter une modification, lancer les tests, lire l’erreur, modifier à nouveau. Le relais doit transmettre
tool_usesurrole: "assistant"ettool_resultsurrole: "user"pour toute la chaîne. - Comment tester : menez un vrai débogage par agent de plus de 10 tours.
- Critère de réussite : au tour N, le relais transmet encore chaque ID d’appel d’outil et chaque nœud d’état des N−1 tours précédents. L’historique et l’état ne doivent être ni perdus ni mélangés.
3. Contexte de code long et mise en cache des prompts
Le contexte d’une base de code moyenne ou grande atteint souvent 100 000 à 200 000 tokens.
1. Transmission du contrôle de cache
- Pourquoi ça casse : une spécification d’architecture et le code de base partagé restent fixes. L’agent les marque avec
cache_controlpour que le service du modèle puisse réutiliser le cache KV. Si le relais retire ce marqueur, la moindre modification d’une ligne relance le préremplissage de centaines de milliers de tokens. - Comment tester : envoyez à plusieurs reprises un contexte d’ingénierie de 100 000 tokens avec
cache_control. - Critère de réussite :
- Côté requête, le corps envoyé en amont contient toujours
cache_control. - Côté réponse,
usagerenvoiecache_read_input_tokens.
2. Une aiguille dans une base de code
- Pourquoi ça casse : pour réduire ses coûts, un relais peut découper le prompt par RAG, le compresser ou substituer un modèle plus petit, et la vision qu’a le modèle du dépôt se rétrécit.
- Comment tester : dans un dépôt de 150 000 tokens, cachez une définition d’interface au début du fichier A et le site d’appel à la fin du fichier B, remplissez le milieu de code sans rapport, puis demandez comment modifier l’interface.
- Critère de réussite : comparez la modification obtenue via le relais avec celle d’un appel direct à l’API officielle. Si le contexte coupé par le relais fait manquer une variable ou un type partagé entre fichiers, le contexte a été endommagé.
4. Sortie complète et protection des instructions
Le mode d’échec typique : un module de 500 lignes qui s’arrête à la ligne 300.
1. Horizon de sortie maximal
- Pourquoi ça casse : une refactorisation d’un seul fichier peut exiger 4 000, 8 000, voire 16 000 tokens de code en une seule réponse. Un tampon de proxy trop petit ou un délai d’expiration trop court coupe le fichier en deux.
- Comment tester : demandez un long module sans remplissage, par exemple un parseur comportant des centaines d’énumérations et de conversions.
- Critère de réussite : le relais doit pouvoir transporter le
max_tokensmaximal du modèle. Lefinish_reasonfinal doit être"stop"ou"length". Un EOF prématuré est un échec.
2. Intégrité du prompt système
- Pourquoi ça casse : un agent de programmation place des règles strictes dans le prompt système, comme le mode strict de TypeScript ou une JSDoc sur chaque fonction. Certains relais injectent leur propre prompt global ou rognent le prompt système.
- Comment tester : envoyez un prompt système contenant une contrainte de style de code reconnaissable, et demandez du code.
- Critère de réussite : le code respecte cette contrainte, et une capture de paquets montre que le prompt système n’a pas été modifié d’un seul octet.
Grille de vérification
| Dimension | Ce qu’il faut tester | Critère de réussite |
|---|---|---|
| Caractères et syntaxe | Échappements, indentation, retours à la ligne | L’analyse AST / linter locale réussit, correspondance à 100 % |
| Chaîne d’outils de l’agent | Forme des appels d’outils et état multitour | Zéro erreur d’analyse JSON, et une chaîne d’états d’outils de 10 tours ou plus |
| Contexte et cache | Transmission du cache de prompt et contexte réel | cache_control n’est pas retiré, et une base de code de 150 000 tokens conserve les dépendances entre fichiers |
| Génération complète | Limite de sortie longue et protection du prompt système | Au moins 8 000 tokens de code continu, et un prompt système identique octet pour octet |



