// architecture · ia · prompt-engineering · process · engineering · qualité

Le prompt est devenu du code : le versionner, le tester, le gouverner

· 9 min de lecture

Regardez où vivent les prompts dans la plupart des projets. Une chaîne en dur au milieu d’un service. Une variable concaténée à la va-vite, avec un bout de texte qui change selon une condition. Un fragment copié depuis une session de chat un soir où ça marchait, collé dans le code, jamais relu depuis. Personne ne sait vraiment qui l’a écrit, ni quand, ni pourquoi il est formulé exactement ainsi. Le modifier relève du tâtonnement : on change un mot, on relance trois fois, on regarde si ça « semble mieux », et on commit avec un message du genre « tweak prompt ».

C’est précisément la manière dont on écrivait du code avant d’apprendre la discipline. Sans version maîtrisée, sans test, sans revue, sans la moindre gouvernance. Sauf qu’ici, cette chaîne de prose pilote un comportement réel en production. Un prompt qui décide comment un assistant répond à vos clients, comment un agent classe un ticket, comment un système résume un dossier médical, n’est pas un commentaire ni une note de configuration. C’est de la logique applicative, déguisée en texte.

Cet article part d’un constat simple et tire toutes ses conséquences : si on accepte que le prompt est du code, alors on doit lui appliquer ce qu’on applique au code. Rien de plus, mais rien de moins.


Pourquoi un prompt est du code, vraiment

L’objection vient toujours, et vite : un prompt, c’est du langage naturel, pas un programme. C’est vrai sur la forme, et sans importance sur le fond. Ce qui définit du code, ce n’est pas sa syntaxe, ni le fait qu’un compilateur le lise. C’est son rôle dans le système. Si modifier un artefact change le comportement observable de l’application, alors cet artefact est du code, quelle que soit la langue dans laquelle il est écrit.

Or un prompt remplit tous les critères, un par un. Il a des entrées : les variables qu’on y injecte, le contexte qu’on y assemble. Il a une sortie : le comportement du modèle, qui en dépend directement. Il a des régressions : une modification « pour améliorer » casse un cas qui marchait, exactement comme un refactoring maladroit. Il a des dépendances : il est couplé à un modèle précis, à une version de ce modèle, à un format attendu par le code en aval. Et il a des effets de bord, parce que ce qu’il déclenche se répercute sur le reste du système.

Un prompt a même quelque chose que peu de code possède : une sensibilité extrême aux détails. Déplacer une instruction du début à la fin, ajouter un exemple, changer « tu peux » en « tu dois », tout cela modifie le comportement de façon parfois spectaculaire. Cette fragilité devrait nous rendre plus prudents avec les prompts qu’avec le code ordinaire, pas moins. Dans les faits, c’est l’inverse, et c’est tout le problème.

Cette réalité prolonge directement la discipline que je défendais sur la consommation et la stratégie de tokens. Un prompt n’est pas seulement de la logique : c’est aussi un coût récurrent, parce que chaque mot inutile se paie à chaque appel, multiplié par le volume. Le gouverner, c’est gouverner à la fois un comportement et une dépense. Les deux dérivent quand personne ne regarde.


Sortir les prompts du code, et les versionner

La première étape est mécanique mais structurante : extraire les prompts du flot du code applicatif, dans des fichiers ou des entrées de stockage dédiés, sous contrôle de version. Pas pour faire propre, mais pour rendre l’histoire lisible.

Quand un comportement dérape en production, la toute première question d’un architecte est « qu’est-ce qui a changé, et quand ». Si le prompt est une chaîne noyée au milieu d’un service, concaténée à partir de trois fragments, vous ne le saurez pas sans une enquête pénible. S’il est un artefact versionné, un git blame ou un historique de stockage vous donne la réponse en quelques secondes : telle version, modifiée tel jour, par telle personne, pour telle raison.

// Le prompt est un artefact identifié, versionné, chargé explicitement.
public class PromptStore
{
    private readonly IPromptRepository _repo;
    private readonly ILogger<PromptStore> _logger;

    public async Task<PromptTemplate> GetAsync(string nom, string version)
    {
        // On charge une version précise, jamais "le dernier en date" implicite.
        var template = await _repo.LoadAsync(nom, version);
        if (template is null)
            throw new PromptNotFoundException(nom, version);

        return template;
    }
}

// À l'appel, on trace quel prompt, quelle version, a produit quel comportement.
var prompt = await _promptStore.GetAsync("resume_ticket", version: "2026-08-04");
var rendu = prompt.Render(new { ticket = description });

var reponse = await _chatClient.CompleteAsync(rendu);

// La version du prompt voyage avec la réponse, jusque dans les logs et les métriques.
_telemetry.RecordCompletion(promptNom: "resume_ticket",
                            promptVersion: "2026-08-04",
                            tokens: reponse.Usage.TotalTokens);

Le détail qui compte ici n’est pas l’abstraction PromptStore, c’est qu’on charge une version explicite, jamais « la dernière ». Un prompt qui change silencieusement sous les pieds d’un système en production est une bombe à retardement : un jour quelqu’un modifie le « prompt courant », et le comportement de milliers d’appels bascule sans qu’aucun déploiement n’ait eu lieu, sans qu’aucune ligne de code n’ait bougé. On veut pouvoir dire, pour chaque réponse passée, exactement quel texte l’a produite. Cela suppose de tracer la version du prompt à côté de chaque sortie, pour relier un incident à sa cause sans avoir à deviner.

Le prompt embarque ses dépendances

Versionner le texte ne suffit pas si on oublie ce dont il dépend. Un prompt est presque toujours couplé à un modèle précis et à un format de sortie attendu. Un prompt finement ajusté pour un modèle donnera des résultats différents, parfois cassés, sur un autre, ou même sur une version plus récente du même. C’est un point qu’on sous-estime : changer de modèle sans rejouer ses prompts, c’est changer le moteur sans vérifier que la transmission suit.

Je traite donc le couple prompt plus modèle plus format comme une unité cohérente. Quand l’un des trois bouge, je considère que j’ai une nouvelle version à valider, pas un simple ajustement cosmétique. Cette rigueur évite la classe d’incidents la plus sournoise : celle où « rien n’a changé » du point de vue du code, mais où tout a changé du point de vue du comportement.


Tester un prompt, c’est-à-dire l’évaluer

Versionner sans tester, c’est obtenir du code mort sur lequel plus personne n’ose toucher, parce qu’on ne sait pas mesurer l’effet d’une modification. La non-régression d’un prompt passe par les evals dont je détaillais le mécanisme dans tester l’intestable. Chaque prompt important s’accompagne d’un jeu de cas qui décrivent, non pas la sortie exacte attendue, mais les critères qu’une bonne sortie doit remplir.

Le bénéfice est immédiat et très concret. Quand on veut « améliorer » un prompt, on ne juge plus à l’intuition sur deux ou trois essais manuels, biaisés par le cas qu’on avait justement en tête. On modifie, on rejoue le golden set entier, on compare les scores avant et après. Et c’est souvent là que la surprise arrive : une formulation qui paraissait clairement meilleure sur le cas qu’on visait dégrade trois autres cas qu’on avait oubliés, parce qu’on a, sans le voir, supprimé une instruction qui servait à autre chose. Sans evals, on aurait déployé l’amélioration et récolté la régression en production, une semaine plus tard, sans faire le lien.

Il y a un cas particulier qui justifie à lui seul cette discipline : les modifications « inoffensives ». Reformuler une phrase pour la rendre plus claire, corriger une faute, raccourcir une consigne pour économiser des tokens. Tout cela paraît sans risque, et tout cela peut changer le comportement. La seule façon de modifier un prompt avec sérénité, c’est d’avoir un filet qui vous dit, en quelques minutes, si vous venez de casser quelque chose.


Gouverner : qui peut changer quoi, et comment

La revue d’un changement de prompt mérite la même attention qu’une revue de code, et pour une raison psychologique précise qu’il faut nommer. Une modification de prompt paraît anodine. Changer une phrase ne « casse pas la compilation », ne déclenche aucun signal rouge, ne ressemble pas à un changement de logique. La barrière mentale qui nous fait relire sérieusement une modification d’algorithme tombe complètement devant une modification de texte. C’est exactement dans cette zone de relâchement que se glissent les régressions silencieuses.

J’impose donc trois règles, qui ne sont que les règles du code appliquées à un artefact qu’on avait laissé hors périmètre par habitude.

D’abord, un changement de prompt passe par une pull request, au même titre qu’un changement de code. Pas de modification directe en production, pas d’édition « rapide » dans une interface d’administration sans trace ni revue.

Ensuite, il est relu par quelqu’un qui comprend le comportement attendu. Dans l’esprit de la revue à l’ère de l’IA, on ne relit pas la prose pour sa qualité littéraire, on valide la décision qu’elle encode : cette nouvelle formulation change quoi, exactement, dans ce que le système va faire.

Enfin, il ne part en production qu’après passage du golden set, intégré à la chaîne d’intégration continue au même titre que les tests unitaires. Un score qui chute bloque le déploiement, point.

Environnements et déploiement progressif

Comme pour le code, on gagne à séparer les environnements. Un prompt se teste d’abord hors production, sur des données représentatives, avant d’être promu. Et pour les prompts à fort impact, le déploiement progressif a tout son sens : on bascule une fraction du trafic sur la nouvelle version, on compare les métriques de qualité et de coût en conditions réelles, on généralise seulement si les indicateurs tiennent. C’est moins spectaculaire que de « pousser le nouveau prompt parce qu’il est meilleur », mais c’est la différence entre piloter et espérer.


Le prompt rejoint le système

L’enjeu n’est pas bureaucratique, et il ne s’agit pas d’alourdir le travail par principe. Il est de cohérence. On ne peut pas, d’un côté, exiger version maîtrisée, tests et revue sur le moindre bout de code, et de l’autre laisser flotter les chaînes qui pilotent la moitié du comportement intelligent du système. Cette asymétrie crée une zone d’ombre, et les zones d’ombre sont précisément là où s’accumulent les incidents qu’on ne sait pas expliquer, ceux qui finissent en réunion de crise avec un « mais personne n’a rien changé » qui est techniquement vrai et opérationnellement faux.

Traiter le prompt comme du code, ce n’est donc pas le compliquer. C’est arrêter de faire une exception coûteuse pour un artefact qui ne la mérite pas, sous prétexte qu’il ressemble à du texte. Le jour où modifier un prompt ressemble à modifier une fonction, relu, testé, tracé, déployé proprement, vous avez fait rentrer l’IA dans votre ingénierie au lieu de la laisser camper à ses marges.

Et c’est exactement ce qu’on attend d’un architecte : qu’aucune partie critique du système ne reste hors discipline. Ni parce qu’elle est nouvelle, ni parce qu’elle est à la mode, ni parce qu’elle a l’allure inoffensive d’un paragraphe de prose.

// À lire ensuite