Article · SaaS & dev

Mesurer la complexité d’un prompt avant de générer du code

Pourquoi la complexité du code produit peut masquer la difficulté réelle d’une tâche de génération.

Un cristal relie plusieurs représentations abstraites à une structure de code.

La complexité du code arrive parfois trop tard

Pour analyser un agent de programmation, on peut mesurer la taille ou la complexité cyclomatique du programme généré. Mais une tâche difficile peut produire un petit programme qui échoue immédiatement. Dans ce cas, une mesure calculée après génération confond la difficulté de la demande avec la forme d’un échec. Le preprint étudié propose donc un indice de complexité structurelle du prompt, évalué avant la génération et séparé de la correction fonctionnelle.

Cette distinction ne cherche pas à prédire qu’un programme sera correct. Elle vise à décrire la structure de la tâche indépendamment du résultat du modèle. Les auteurs recommandent de lire l’indice comme une mesure de contexte de benchmark, pas comme une étiquette universelle de difficulté ni comme une règle de déploiement.

Un benchmark de 5 000 prompts

L’étude sélectionne 5 000 prompts Python répartis dans six bandes d’un rubric préliminaire évalué par un seul annotateur. Quatre évaluateurs LLM extérieurs au panel rescorrent ensuite les prompts verrouillés, ce qui produit 19 997 lignes de notation pour 4 998 prompts complets. L’accord inter-évaluateurs composite atteint un ICC de 0,872 dans cet ensemble.

Les auteurs évaluent 21 modèles sur chaque prompt, soit 105 000 générations. Le résultat est donc une relation entre une mesure construite avant génération et les taux de réussite observés ensuite. Le choix d’un échantillon équilibré par bandes permet d’étudier la forme de la relation, mais il ne reproduit pas nécessairement la distribution naturelle de prompts rencontrés par un produit de code.

Les six dimensions de l’indice

L’indice agrège six dimensions structurelles du prompt. Le papier insiste surtout sur le fait que le score est composite et qu’il doit rester lié à son rubric, à ses évaluateurs et à son cadre de construction. Un score de 13,75 n’a de sens que dans cette échelle et ce benchmark ; il ne peut pas être transformé directement en seuil général applicable à JavaScript, au débogage en production ou à une autre famille de modèles.

La mesure est placée avant l’action du modèle. Elle évite ainsi une dépendance mécanique : un échec produit souvent moins de code, moins de branches et moins de complexité mesurable qu’une solution correcte. Parmi les générations sans succès et dont la complexité Lizard est calculable, 28,5 % associent un prompt de composite supérieur à 8 à une sortie de complexité au plus égale à 10. Ce résultat illustre le problème de la mesure postérieure ; il ne prouve pas que toute faible complexité de sortie signale un échec.

Le point de rupture n’est pas un seuil universel

Dans l’analyse moyenne non ajustée, une recherche de rupture sélectionne un composite de 13,75. Les prompts à ce niveau ou en dessous ont un taux de réussite moyen de 79,9 %, contre 87,6 % au-dessus. Cette forme non monotone peut sembler surprenante : les prompts les plus complexes ne sont pas automatiquement les moins bien résolus.

Les contrôles changent cependant fortement la lecture. Les effets fixes de type de tâche déplacent la rupture à 10,75 et réduisent l’écart de 7,6 à 2,1 points. Un contrôle du cadre de construction la déplace à 8,50 et inverse l’écart brut entre régimes. Les modèles individuels ne vont pas tous dans le même sens : 16 affichent une hausse au-dessus de leur propre rupture, cinq une baisse. La conclusion prudente est donc descriptive : le benchmark présente une courbe et une composition, pas une loi de la difficulté du code.

L’audit de la zone haute

Les auteurs ajoutent une extension de 365 prompts à haute complexité, en retenant des contrats dont la solution de référence passe tous les tests fournis. Dans un cadre apparié sur cinq modèles, les moyennes des bins 15 et 16 sont proches de celles du benchmark initial : les différences rapportées sont de -1,4 et -0,9 point, sans signal statistique fort selon les tests indiqués.

L’extension apporte en revanche peu de support au-delà du bin 16 : seulement 14 prompts supplémentaires s’y trouvent. Les bins 17 et 18 restent donc descriptifs et sous-alimentés. C’est un exemple concret de la règle générale du papier : publier une rupture sans publier le support de chaque zone donne une précision apparente supérieure à l’information disponible.

Pourquoi le résultat n’est pas causal

Le preprint teste également une construction économétrique par variables instrumentales, mais les restrictions de suridentification sont fortement rejetées. Les statistiques de Sargan et de Wooldridge ne soutiennent pas l’interprétation causale ; les dimensions produisent des coefficients incompatibles. Les auteurs refusent donc de présenter l’indice comme une cause de la fiabilité.

Cette réserve est centrale pour un benchmark utilisé par une équipe produit. Une corrélation entre une classe de prompt et un taux de passage peut résulter du type de tâche, de la façon dont les exemples ont été sélectionnés, du modèle ou du cadre de construction. Elle peut aider à planifier des tests, mais elle ne garantit pas que rendre un prompt « plus complexe » améliore ou dégrade mécaniquement le modèle.

Applications pour les agents de code

Un indice pré-génération peut compléter les mesures de sortie. Un tableau de benchmark peut afficher le score de tâche, le type de tâche, la complexité du prompt, le nombre de cas soutenus et la distribution des modèles. Les erreurs devraient être stratifiées par difficulté prévue, sans supprimer les prompts dont le programme est vide ou non exécutable.

Pour une évaluation continue, il serait utile de conserver le rubric et la version des évaluateurs. Une nouvelle famille de langages ou un nouveau type de tâche mérite une calibration propre. Le papier indique que le réordonnancement des scores est préservé après paraphrase et réexpression en Java ou C++, mais la génération et l’exécution évaluées restent Python. Le transfert de l’ordre ne vaut donc pas validation complète dans ces langages.

L’indice peut aussi guider la sélection d’un échantillon de revue humaine. Il ne doit pas décider seul de la capacité d’un agent. Un prompt très complexe mais bien couvert peut être moins risqué qu’un prompt moyen dont les outils, dépendances ou critères d’acceptation sont mal spécifiés.

Limites et statut de la source

Le cadre d’échantillonnage est construit à partir d’une sélection de prompts, d’un rubric de départ et d’une extension de haute complexité. Les évaluateurs LLM peuvent partager des biais communs, et l’accord humain sur un sous-ensemble enrichi de désaccords reste modéré. Le benchmark n’est pas une distribution naturelle de production, l’exécution complète n’est pas testée pour Java ou C++, et l’extrémité de la queue reste peu soutenue.

Le document est un preprint ArXiv, pas nécessairement évalué par les pairs. Ses seuils et coefficients doivent être reproduits dans le même cadre avant toute utilisation opérationnelle.

La recommandation la plus sûre est donc de publier la courbe complète plutôt qu’un seuil isolé : nombre de prompts par bin, choix de l’agrégation, composition des tâches, version du rubric et incertitude des évaluateurs. Une équipe peut alors utiliser l’indice pour répartir la revue humaine ou comparer deux modèles sur des tâches de structure similaire, sans prétendre qu’un score supérieur impose une difficulté objective. Cette présentation protège aussi contre une amélioration apparente causée par un changement de mélange de prompts.

Sources

Michael Hernandez et Tian Zhao, « The Complexity Kink: A Prompt-Side Structural Complexity Index for Code-Generation Reliability », ArXiv 2609.19616v1 : preprint, PDF.