Nommage aveugle au contexte.
Un assistant IA nomme un nouveau code avec des marqueurs génériques ou une convention inédite qui ignore les identifiants existants et le vocabulaire métier du dépôt, érodant la lisibilité et engendrant des concepts dupliqués et mal décrits.
##Signs and Symptoms
Un relecteur repère un nommage aveugle au contexte quand les noms d'un diff rédigé par IA sont localement plausibles mais déconnectés du dépôt environnant. Indices révélateurs :
- Marqueurs génériques dans du code métier :
data,result,temp,item,obj,payload,response,value,handleStuff,processDatalà où le module parle déjà un langage spécifique (grossPremium,Customer,getCustomerById). - Dérive des conventions : un symbole en
snake_casedéposé dans un fichiercamelCase, un préfixe booléenis/hasmanquant, ou un nouveau verbe CRUD (fetch*) dans une base de code qui a standardisé surget*. Chaque diff « suit le style qu'il a rencontré en dernier, introduisant une quatrième convention. Puis une cinquième. » - Prolifération de synonymes / concepts dupliqués : l'IA invente
fetchUseralors quegetCustomerByIdexiste déjà, ou mélangecustomer/client/userpour une même entité — réimplémentant au lieu de réutiliser. - Des noms qui décrivent le mécanisme, pas l'intention — ou qui mentent sur le comportement :
processData()qui calcule en fait la taxe de vente. Les agents (et le prochain agent) « lisentprocessData()et procèdent comme si ce nom racontait toute l'histoire », donc le sens erroné se propage à chaque site d'appel.
// Le dépôt exporte déjà getCustomerById(id: CustomerId): Promise<Customer>
// L'IA ajoute un quasi-doublon avec des noms aveugles au contexte :
async function fetchData(id: string) { // verbe générique, type lâche
const result = await db.query("select * from customers where id = $1", [id]);
const temp = result.rows[0]; // 'temp' cache qu'il s'agit d'un Customer
return temp; // rien ici ne dit « Customer »
}
##Reasons for the Problem
Pourquoi les modèles le produisent
- Biais de fréquence du token suivant. Dans l'ensemble du corpus d'entraînement,
data/result/temp/foosont les identifiants à plus forte probabilité, en particulier dans le code de tutoriel et de boilerplate que les LLM ingèrent massivement. Générer le nom statistiquement moyen est exactement ce pour quoi un prédicteur de token suivant est optimisé, ce qui gomme l'intention métier (Towards Data Science). - Aucun (ou un) contexte de dépôt (tronqué). Le modèle voit rarement le glossaire du module voisin ou le
getCustomerByIdexistant. GitClear relie directement la flambée de duplication à cela : l'assistant « est moins susceptible de proposer de réutiliser une fonction similaire ailleurs… en partie à cause de la taille de contexte limitée » (GitClear 2025). - Optimisation locale / faible instinct de refactorisation. Chaque tour optimise le prompt immédiat, « sans tenir compte de l'impact architectural cumulatif ». OX Security a trouvé un évitement des refactorisations dans 80–90 % du code IA, donc le modèle ajoute un symbole fraîchement nommé plutôt que de renommer ou réutiliser un symbole existant (rapport OX).
- Obsolescence liée à la date limite d'entraînement. Des conventions et des noms d'API issus de corpus plus anciens refont surface même après qu'un projet a évolué.
Pourquoi c'est nuisible
- Lisibilité/maintenabilité : les noms sont la documentation principale d'une base de code ; les noms génériques obligent chaque lecteur à re-déduire l'intention à partir du corps.
- Duplication et défauts : renommer un concept engendre une implémentation parallèle. GitClear a mesuré une hausse d'environ 8× des blocs dupliqués et le copier-coller dépassant pour la première fois les lignes déplacées (refactorisées) en 2024 ; les clones portent un excédent estimé de 15–50 % de défauts.
- Boucle de rétroaction des agents (le préjudice spécifique à l'IA) : les noms sont l'interface que le prochain agent lit au pied de la lettre. Un nom trompeur ou générique « propage les erreurs à travers tout le code généré par les agents qui s'appuie dessus » (AI Pattern Book).
- Charge de revue & exactitude : les relecteurs doivent mentalement faire correspondre
temp/dataaux concepts métier, ce qui masque des bugs ; des noms trompeurs entraînent un mauvais usage aux sites d'appel. - Angles morts de sécurité/audit : un secret ou un jeton garé dans une variable nommée
data/tmpéchappe aux greps et à l'attention de revue basés sur les noms.
Remarque : des recherches comme arXiv 2509.20491 montrent que les outils statiques attrapent bien les smells locaux et explicites, mais la facette de sens métier ici dépend de la valeur/l'intention et échappe largement à la détection automatisée.
##Treatment
Tactiques de revue & de prompting
- Injectez les conventions et le glossaire dans le contexte. Tenez un court guide de nommage (casse, préfixes booléens, verbes CRUD, termes métier) dans
CLAUDE.md/les docs de style et exigez que le modèle le suive. Appliquez les termes du glossaire métier de manière cohérente afin que les synonymes se réduisent à un seul mot. - Forcez la réutilisation avant la création. Prompt : « Cherche dans le dépôt une fonction/un type existant pour ceci avant d'en ajouter un ; réutilise-le. » Cela contre directement l'échec de concept dupliqué signalé par GitClear et OX.
- Nommez les choses dans le prompt. « Nomme le handler
createRefund» vaut mieux que « ajoute le traitement des remboursements ». Spécifiez des noms métier (monthlyRevenue, pasfloat1). - Exigez l'exécution du linter + du scan de duplication sur le diff (naming-convention +
id-denylist+ jscpd) et faites en sorte que le modèle corrige les violations plutôt que vous à la main.
Le refactoring — appliquez Renommer une variable/fonction (le « Modifier la déclaration d'une fonction » de Fowler), corrigeant le smell Nom mystérieux, et Consolider le code dupliqué en réutilisant le symbole existant au lieu du nouveau.
Avant :
async function fetchData(id: string) {
const result = await db.query("select * from customers where id = $1", [id]);
const temp = result.rows[0];
return temp;
}
Après (réutilise la fonction de dépôt existante ; des noms et types révélateurs d'intention et conformes aux conventions) :
// Ne re-requête pas — réutilise getCustomerById et garde le vocabulaire métier.
async function getCustomerById(id: CustomerId): Promise<Customer | null> {
const { rows } = await db.query<Customer>(
"select * from customers where id = $1",
[id],
);
return rows[0] ?? null;
}
Si un nom trompeur a déjà été livré, renommez-le pour qu'il corresponde au comportement (processData → calculateSalesTax) avant de construire dessus, afin que les agents et les humains en aval héritent du bon signal.
##Detected by
- ESLint (core) id-denylist — Interdire des identifiants spécifiés
- ESLint (core) id-length — Imposer une longueur minimale/maximale d'identifiant
- typescript-eslint @typescript-eslint/naming-convention — Imposer des conventions de nommage (casse/préfixes)
- eslint-plugin-unicorn unicorn/prevent-abbreviations — Empêcher les abréviations / noms trop génériques
- SonarQube / SonarSource typescript:S117 — Les noms de variables locales et de paramètres doivent respecter une convention de nommage
- jscpd copy-paste-detection — Détecte les blocs dupliqués créés lorsqu'un concept renommé en double un existant