Aller au contenu
JournalPublié le 1 septembre 20265 min de lecture

Développement MySQL quand le modèle a besoin de données fiables

Produits IADéveloppement MySQLWorkflows agenticIntégrité des donnéesRAG

Le mode de défaillance que je vois le plus souvent dans les builds de produits IA n'est pas un mauvais prompt. C'est une base de données qui n'a jamais été conçue pour être interrogée par une machine. Le modèle retourne des réponses confiantes construites sur des jointures obsolètes, des clés étrangères manquantes, et des colonnes qui signifient des choses différentes pour différents services. Le développement MySQL, fait avec cette contrainte en tête dès le départ, est ce qui sépare un produit IA qui se déploie d'un qui reste en mode démo.

Le schéma est le contrat, pas le prompt

Quand je commence un projet, le premier document que j'écris n'est pas un system prompt. C'est un diagramme entité-relation avec des règles de nullabilité et des décisions d'indexation écrites explicitement. Le modèle ne sera jamais plus précis que les données qu'il lit. Si une colonne peut être null pour des raisons historiques, le modèle doit être informé, sinon il hallucine une valeur par défaut. Si deux tables utilisent le même nom de champ pour des concepts différents, chaque récupération RAG qui touche les deux tables produira du bruit.

Sur le produit d'éligibilité visa Fursa, le défi principal était que les données de route provenaient de plusieurs sources en amont avec des schémas qui se chevauchaient mais étaient incohérents. Avant tout travail d'ingénierie de prompt, j'ai normalisé la table de destination, appliqué l'intégrité référentielle sur les jointures route-à-exigence, et ajouté un timestamp verified_at à chaque ligne d'exigence. Le modèle n'était jamais autorisé à lire une ligne où verified_at était null. Cette seule contrainte, appliquée au niveau de la couche de requête, a éliminé toute une classe d'hallucinations.

Les sorties structurées ont changé ce que la couche de requête doit faire

Jusqu'à récemment, faire en sorte qu'un modèle écrive un fragment SQL bien formé ou retourne un résultat structuré signifiait lutter avec des parseurs regex et espérer que le modèle restait au format. C'est fini maintenant. Les schémas JSON appliqués au niveau de l'API, et les bibliothèques comme Instructor et Pydantic côté application, signifient que la sortie se conforme ou l'appel échoue rapidement et réessaie. La couche de requête n'a plus à faire du parsing défensif. Elle doit faire quelque chose de plus difficile : valider la correction sémantique, pas seulement la forme syntaxique.

Ce que cela signifie en pratique, c'est que j'écris une logique de validation explicite entre la sortie du modèle et l'écriture en base de données. Le modèle retourne un objet structuré. L'application le vérifie par rapport aux règles métier. Ce n'est qu'alors qu'il frappe la base de données. Sur OptimalTax, où le système automatisait les calculs de déclarations fiscales pour un client du secteur public, une mauvaise écriture n'était pas un problème UX. C'était un échec de conformité. Chaque valeur générée par le modèle était validée par rapport au moteur de règles fiscales avant tout INSERT. La précision de calcul de 99% que ce produit a atteinte n'était pas un exploit d'ingénierie de prompt. C'était un exploit d'intégrité des données.

Les workflows agentic mettent une nouvelle pression sur le développement MySQL

Le passage des appels à prompt unique aux systèmes IA composés et aux workflows multi-agents a changé ce que la base de données doit absorber. Un agent stateful s'exécutant sur plusieurs tours doit persister son contexte quelque part. Un workflow qui se divise en trois agents spécialisés puis réconcilie leurs sorties a besoin d'un endroit pour stocker l'état intermédiaire sans conditions de course.

J'utilise MySQL différemment pour cela que pour les données d'application. Les tables d'état d'agent sont append-only. Les écritures de réconciliation passent par une transaction qui verrouille les lignes pertinentes. L'orchestrateur de workflow, qu'il s'agisse de LangGraph ou d'une machine d'état personnalisée, ne suppose jamais que la base de données est cohérente en cours d'exécution. Il vérifie.

Le moteur de prospection Job Hunter a parcouru plus de 185 pages de carrière quotidiennement, puis a exécuté des agents de correspondance et de rédaction sur les résultats. La base de données devait contenir l'état de crawl, les scores de correspondance, l'historique des brouillons, et le statut de prospection pour chaque paire candidat-emploi, sans perdre de données quand un agent de crawl expirait en cours de lot. La solution était une colonne de statut avec un petit ensemble fini de transitions valides, appliquées par une contrainte de vérification, pas seulement par la logique d'application seule. Si un agent s'écrasait, la ligne restait dans son dernier état valide. L'agent de récupération reprenait de là.

La mise en cache de prompts a rendu la RAG profonde économiquement viable

Pendant longtemps, construire un système de génération augmentée par récupération sur un grand corpus MySQL était coûteux. Chaque requête renvoyait le même contexte système et les mêmes chunks récupérés au modèle, et les coûts de tokens d'entrée s'accumulaient rapidement. La mise en cache de prompts des principaux fournisseurs d'API a changé ce calcul. Les coûts de tokens d'entrée pour les appels de contexte long sont réduits de jusqu'à 90% pour les préfixes en cache, ce qui signifie qu'il est maintenant pratique de garder un contexte système riche en cache et de ne varier que les résultats de récupération par requête.

L'implication de conception pour le développement MySQL est que les requêtes de récupération doivent être assez rapides et déterministes pour servir de partie variable d'un prompt en cache. J'indexe agressivement sur les colonnes utilisées dans les filtres de récupération. J'utilise des index couvrants où la requête n'a besoin que d'un petit ensemble de colonnes. J'évite la recherche en texte intégral dans MySQL pour tout ce qui a besoin d'un classement par similarité sémantique, et à la place je garde un magasin de vecteurs synchronisé avec la source de vérité MySQL, écrivant dans les deux dans la même transaction où la cohérence compte.

Les portes d'approbation humaine ne sont pas optionnelles

Chaque produit IA que j'ai construit a au moins un point où un humain doit approuver avant que le système agisse sur une sortie de modèle. Ce n'est pas une position philosophique. C'est une exigence de produit qui vient du client dans presque chaque projet. Le modèle est un composant d'un workflow. C'est souvent le composant le plus capable pour une tâche spécifique, et c'est aussi le composant le plus susceptible d'être confidemment faux d'une manière difficile à détecter.

La porte d'approbation a une représentation en base de données. Il y a une table qui contient les actions en attente, la sortie du modèle, le contexte qui lui a été donné, et un champ de statut. Un opérateur l'examine. Le statut change. L'action en aval s'exécute. Cette table est auditable. Vous pouvez revenir en arrière et voir exactement ce que le modèle a dit, quel contexte il avait, et qui l'a approuvé.

C'est le modèle que j'ai utilisé sur ProPost AI, où le système générait du contenu LinkedIn à grande échelle, 365 brouillons par utilisateur par an. Aucun brouillon n'a été publié sans une étape d'examen humain. La file d'attente d'approbation était une table MySQL. La piste d'audit était une table MySQL. Le modèle était rapide. L'humain était la porte.

Ce que couvre la première conversation

Si vous comparez des partenaires pour un build de produit IA, la question que je poserais à n'importe lequel d'entre eux est : que se passe-t-il quand le modèle se trompe et que la base de données a déjà été écrite ? S'ils n'ont pas de réponse spécifique, la base de données était une réflexion tardive.

Ma réponse est une combinaison d'écritures append-only, de chemins de rollback explicites, et de portes d'approbation avant toute action irréversible. Le travail sur les études de cas montre comment cela se déploie dans les contextes fintech, secteur public, et produits IA.

Si vous êtes près de commencer et que vous voulez discuter de l'architecture avant de vous engager dans une direction, le formulaire de contact est le bon endroit pour commencer. Apportez la contrainte qui vous préoccupe le plus. C'est généralement là que le vrai travail de conception commence.

Envie d'en discuter ?

Parlons-en.

Démarrer la conversation