J'ai analysé 90 jours de prompts utilisateurs — et ce que j'ai découvert m'a surpris

Il y a quelques semaines, j'ai décidé de faire quelque chose que la plupart des équipes ne font jamais : auditer réellement les prompts que mes agents IA reçoivent au quotidien.

Pas pour faire du ménage. Pas pour optimiser les coûts. Juste pour voir.

Ce que j'ai trouvé m'a pris par surprise.


Avant de continuer de lire la suite de l'article, je vous invite à vous inscrire à ma newsletter, pour connaître en avant première les futurs sujets traités chaque semaine.


Ce que révèlent vraiment 90 jours de prompts

Sur 90 jours de sessions dans mon infrastructure Claude Code, j'ai extrait et catégorisé chaque prompt passé dans le système. Le résultat est brutal.

54 % des prompts problématiques font moins de 30 caractères.

Pas 30 mots. 30 caractères. Des choses comme :

  • "refaire"
  • "les recommandations"
  • "implémenter"
  • "relancer"

Ces prompts ultra-courts ont un score de qualité moyen de 2,83 sur 5, contre 3,55 pour les prompts détaillés — soit une dégradation de 26 % de la qualité des réponses.

Et ce n'est pas tout.

Pattern identifié Occurrences % des ambigus
Prompts < 30 chars 395 54 %
"les recommandations" sans contexte 150 20 %
"refaire / relancer" 100 14 %
"implémenter les recommandations" 55 8 %
Références déictiques ("ce plan", "cette stratégie") 12

Ces patterns ne sont pas des erreurs utilisateur. Ce sont des réflexes naturels dans une conversation continue. On suppose que l'IA sait de quoi on parle. Mais elle ne sait pas toujours.


Le vrai problème : l'anaphore et la déixis

Il y a un phénomène linguistique derrière tout ça.

Quand un humain dit "implémenter les recommandations", il pointe implicitement vers quelque chose qu'il vient de lire ou de dire. En linguistique, on appelle ça une anaphore (référence à un élément précédent) ou une déixis ("ce plan", "cette stratégie" → référence à quelque chose visible dans le contexte).

Le problème : un LLM sans mémoire de contexte suffisante interprète ces références dans le vide.

Si le prompt précédent était "analyse mon infrastructure" et que le suivant est "implémenter les recommandations", l'IA peut inférer. Mais si les deux prompts sont dans des sessions différentes, ou si le contexte a été purgé — elle improvise.

Et l'improvisation d'un LLM, ça donne rarement ce qu'on veut.


Ma solution : un système de clarification automatique en 4 modules

Plutôt que d'éduquer mes utilisateurs (spoiler : ça ne marche jamais), j'ai décidé d'intercepter les prompts ambigus avant qu'ils atteignent l'IA et de les enrichir automatiquement.

Le tout tourne en local, via Ollama.

Architecture du pipeline (< 500 ms)

prompt entrant
    │
    ▼
[Module 1] Détection heuristique
    │  Score > 0.5 ?
    ▼
[Module 2] Recherche pgvector
    │  (sessions passées quality_score < 3)
    │  Score > seuil critique ?
    ▼
[Module 3] Enrichissement RAG
    │  (historique session + QA pairs)
    ▼
[Module 4] qwen3:4b → clarification ou enrichissement

Point d'injection : hook UserPromptSubmit dans mon pipeline Claude Code. Le prompt est intercepté, analysé et enrichi avant d'être envoyé à l'agent.


Phase 0 : la détection heuristique (4-6 heures de travail)

La première étape ne nécessite pas d'IA. Juste des règles.

const AMBIGUOUS_TRIGGERS = [
  'refaire', 'relancer', 'les recommandations',
  'implementer les recommandations', 'la phase suivante',
  'cette strategie', 'ce plan', 'implementer'
];

async function enrichPrompt(prompt: string, sessionId: string): Promise<string> {
  const isAmbiguous =
    AMBIGUOUS_TRIGGERS.some(t => prompt.toLowerCase().includes(t))
    || prompt.length < 30;

  if (!isAmbiguous) return prompt;

  // Récupérer le dernier prompt non-ambigu de la session
  const lastPrompt = await pgQueryRows(
    `SELECT prompt FROM rag_sessions
     WHERE session_id = $1
       AND NOT (prompt ILIKE ANY($2))
     ORDER BY created_at DESC LIMIT 1`,
    [sessionId, AMBIGUOUS_TRIGGERS.map(t => `%${t}%`)]
  );

  return lastPrompt[0]
    ? `${lastPrompt[0].prompt}\n\n${prompt}`
    : prompt;
}

Impact estimé : 250+ prompts améliorés par mois avec seulement quelques heures de mise en place.


Phase 1 : la désambiguïsation sémantique avec Ollama (1,5 jour)

Pour les cas plus subtils — ceux que les règles ne captent pas — j'ai ajouté une couche sémantique.

Étape 1 — Calculer l'embedding du prompt entrant avec bge-m3 (~80 ms).

Étape 2 — Rechercher dans pgvector les sessions passées avec un quality_score faible et une similarité cosinus élevée :

(SELECT prompt, 'session' as source
 FROM rag_sessions
 WHERE embedding <=> $1 < 0.2 AND quality_score < 3
 ORDER BY embedding <=> $1 LIMIT 2)
UNION ALL
(SELECT question, 'qa' as source
 FROM qa_extracted_pairs
 ORDER BY embedding <=> $1 LIMIT 2);

Étape 3 — Si des patterns similaires sont trouvés, envoyer à qwen3:4b pour générer une question de clarification :

async function getDisambiguation(
  prompt: string,
  context: string[]
): Promise<string> {
  const ollamaPrompt =
    `Prompt ambigu: "${prompt}"\n` +
    `Contexte: ${context.join('\n')}\n` +
    `Pose UNE question de clarification courte. JSON: {"question": "..."}`;

  const response = await ollama.generate('qwen3:4b', ollamaPrompt);
  return JSON.parse(response).question;
}

Le modèle qwen3:4b tourne à 76 tokens/seconde sur ma machine locale. L'appel prend ~350 ms. Budget total du pipeline : ~450 ms — imperceptible pour l'utilisateur.


Le schéma de données : table ambiguity_patterns

Pour rendre le système évolutif, j'ai créé une table dédiée qui stocke les patterns et leurs scores d'impact :

CREATE TABLE ambiguity_patterns (
    id SERIAL PRIMARY KEY,
    pattern_text TEXT NOT NULL,
    pattern_type TEXT NOT NULL,
    -- 'keyword' | 'short_prompt' | 'deictic' | 'embedding_match'
    embedding VECTOR(1024),
    -- NULL pour keyword, rempli pour embedding_match
    ambiguity_score_impact FLOAT NOT NULL
);
CREATE INDEX ON ambiguity_patterns USING HNSW (embedding vector_cosine_ops);

La table est seedée avec les patterns identifiés dans l'audit. Avec le temps, elle s'enrichit des nouveaux patterns détectés.


La fusion d'appels : l'autre problème que personne ne résout

En parallèle de l'ambiguïté, l'audit a révélé un second problème : les appels redondants.

Des séquences du type :

  1. "analyse mon infrastructure"
  2. "fais les recommandations"
  3. "implémenter les recommandations"
  4. "relancer l'analyse"

Ces 4 appels pourraient être fusionnés en 2 avec un prompt mieux formulé dès le départ. C'est du gaspillage de tokens, de latence, et d'attention du LLM.

J'ai donc ajouté un module de suggestion de fusion : quand plusieurs prompts d'une même session sont détectés comme formant une séquence logique, le système suggère un prompt consolidé à l'utilisateur avant de l'exécuter.

Ce n'est pas encore automatique — ça reste une suggestion. Mais l'impact est réel.


Ce que j'aurais fait différemment

1. Mesurer avant d'optimiser.
J'aurais dû instrumenter mes sessions dès le début. 98 % de mes sessions n'avaient pas le champ agent_routed renseigné. Des mois de données perdues pour l'analyse.

2. Commencer par les règles.
On a tendance à vouloir tout faire avec du ML. La détection heuristique (règles simples) couvre 80 % des cas avec 10 % de l'effort. Commencer par là.

3. Ne pas éduquer les utilisateurs.
Vous ne changerez pas les habitudes de vos utilisateurs. Adaptez le système à leurs comportements réels plutôt que l'inverse.


Les seuils à tuner selon votre contexte

Paramètre Valeur par défaut Explication
SHORT_PROMPT_THRESHOLD 30 chars En dessous → enrichissement automatique
CRITICAL_AMBIGUITY_THRESHOLD 1.0 Score cumulé pour activer qwen3:4b
VECTOR_SEARCH_SIMILARITY_THRESHOLD 0.8 cosine Seuil similarité pgvector

Ces valeurs sont empiriques. Commencez conservateur (seuils élevés) puis descendez progressivement en mesurant l'impact sur le quality_score de vos sessions.


Résultats attendus

  • +26 % sur le quality_score moyen des sessions courtes
  • 250+ prompts améliorés par mois avec P0 seul
  • Réduction des appels redondants par fusion de séquences
  • Latence ajoutée : < 500 ms (imperceptible dans un workflow agent)
  • Coût : 0 € — tout tourne en local avec Ollama

Conclusion

L'ambiguïté des prompts est un problème systémique, pas un problème utilisateur. Vos utilisateurs ne sont pas mauvais en communication — ils parlent naturellement, avec des références implicites et des raccourcis linguistiques tout à fait normaux.

Le rôle de l'infrastructure IA est de s'adapter à ce comportement naturel, pas d'imposer des contraintes de rédaction.

Un hook de 200 lignes de TypeScript, un modèle local à 4B paramètres, et quelques tables pgvector suffisent à transformer un problème chronique en avantage compétitif.

La prochaine fois que votre IA répond à côté, demandez-vous si le problème est dans le modèle — ou dans le prompt qu'il a reçu.


Qui suis je ?

Je suis Mathieu GRENIER, CTO d'Easystrat une startup de Montpellier, en France. Je manage une équipe d'une dizaine d'ingénieurs (Graphistes, IA, frontend, backend, devOps, AWS) en remote depuis le Japon.

J'ai aussi mon activité de freelance, où je conseille des entrepreneurs dans leurs projets d'application.

Avec mon expérience personnelle de plus de 15 ans en ESN, j'ai pu travailler pour un large panel d'entreprises de différentes tailles. Ma compréhension des problèmes métiers est une de mes grandes forces et permet à mes clients de pouvoir se projeter plus facilement.

L'essentiel de mon travail consiste à canaliser l'énergie des entrepreneurs sur l'essence même de leur projet.

La technologie, les méthodes, le management sont le cœur de mes compétences.

Vous pouvez me faire confiance sur ces points là.

Si vous voulez me parler d'un de vos projets, n'hésitez pas à m'envoyer un email avec vos disponibilités à : contact@mathieugrenier.fr

Tous les articles de ce blog sont écrits par moi, même si je peux m'aider de l'IA pour illustrer mes propos. Mais jamais je ne fournis d'articles 100% IA.

Mathieu Grenier 18 mars 2026
Partager cet articlE