Text-to-SQL en local : interroger la base de données de l'entreprise sans envoyer les données dans le cloud

Vous avez une base de données avec vos ventes, vos commandes et vos clients, et chaque semaine il vous faut des réponses : « combien de commandes avons-nous enregistrées le mois dernier, par région ? ». Aujourd'hui, cette question, c'est vous qui la répondez en écrivant du SQL, c'est le service data qui la prend en file d'attente, ou c'est une API cloud à qui vous la posez. Il y a une quatrième voie : faire lire le schéma de votre base de données à un modèle de langage qui tourne sur votre matériel, lui faire générer la requête, l'exécuter sur place et récupérer le résultat. Les données — les chiffrements, les adresses, les marges — ne quittent jamais votre infrastructure. C'est le text-to-SQL en local, et c'est le cas d'usage qui rend le plus tangiblement la différence entre une IA qu'on loue et une IA qu'on possède.
Qu'est-ce que le text-to-SQL en local
Le text-to-SQL transforme une question en langage naturel en requête SQL exécutable, et renvoie les résultats. Le flux en local est une boucle fermée qui tourne dans votre périmètre :
- La question — vous l'écrivez en français, comme vous le diriez à un collègue.
- Le schéma — le modèle reçoit les noms de tables, de colonnes, les types et les descriptions. Il ne reçoit pas les données.
- La requête — le modèle génère le SQL.
- L'exécution — la requête tourne sur votre base de données, qui peut être un SQLite de quelques mégaoctets ou un Postgres d'entreprise.
- La réponse — les résultats reviennent à vous, prêts pour le rapport ou le tableau de bord.
Le point qui compte pour la confidentialité : dans ce schéma, le modèle ne voit que le schéma et la question, jamais les lignes. Le calcul s'effectue sur votre base de données. Aucun chiffre d'affaires, aucune liste de clients, aucune marge ne traverse le gateway d'un fournisseur. Pour qui gère des données de clients, c'est la différence entre montrer la grille des cellules et montrer les feuilles elles-mêmes.
Où ça casse vraiment : l'ambiguïté
Ici, il faut des chiffres, et ils viennent d'un benchmark paru à la mi-octobre : ARCS (Ambiguity Resolution Corpus for SQL), le premier benchmark de text-to-SQL construit sur des ambiguïtés naturelles sur des bases de données réelles, publié par Megagon Labs (paper sur arXiv). Il contient 101 questions sur 6 bases de données, avec chaque point d'ambiguïté annoté avec toutes les interprétations possibles et les requêtes correctes pour chacune.
Prenez une question du corpus, issue d'une base de retail : « Report the total revenue for each nation in 1995 ». Ça ressemble à une question banale. Dans le benchmark, elle en porte quatre distinctes :
- « total revenue » — brut ou net, après remise ?
- « for each nation » — la nation du client ou celle du fournisseur ?
- « in 1995 » — date de la commande, de l'engagement, de l'expédition ou de la réception ?
- inclure ou exclure les retours ?
Chaque combinaison produit une requête différente, toutes plausibles, toutes exécutables. ARCS rapporte que le modèle fermé le plus performant mesuré, gpt-6-sol, atteint une justesse d'exécution bout en bout de 51 %, et qu'aucun modèle open source ne dépasse 27 % (dataset).
| Source | Justesse d'exécution bout en bout sur questions ambiguës |
|---|---|
| gpt-6-sol (fermé) | 51 % |
| Meilleur modèle open source | 27 % (aucun ne dépasse ce seuil) |
Deux choses ressortent de ce tableau. D'abord : même avec le meilleur modèle payant, près de la moitié des réponses à des questions réalistes est fausse. Ensuite : l'écart entre modèles ouverts et fermés reste large, mais le goulot d'étranglement n'est pas la connaissance du modèle — c'est l'ambiguïté de la question. Le modèle devine une interprétation au lieu de demander, et l'erreur ne claque pas : elle restitue un chiffre qui a l'air juste. C'est le piège par excellence du text-to-SQL, pire qu'une erreur flagrante.
Ce ne sont pas des cas de laboratoire. Du même corpus :
- « For each team that Marcus Williams played for… » — dans une base de basket, il existe deux joueurs nommés Marcus Williams (nés en 1985 et en 1986) : sans demander, le modèle en choisit un.
- « Find posts with many related posts » — « many » est un seuil non défini. Le modèle l'invente.
- « Which events had a low budget remaining… » — « low » par rapport à quoi ? Encore un seuil que le modèle décide seul.
La solution proposée : désambiguïsation structurée
Le paper introduit un paradigme qui vaut le coup d'être compris, parce qu'il change la façon de construire le système : au lieu de faire discuter le modèle en dialogue libre, on résout l'ambiguïté par des interactions explicites et contraintes. Le flux devient :
- Le modèle identifie les points ambigus de la question.
- Pour chacun, il liste les interprétations plausibles — les mêmes annotations qu'on trouve dans ARCS.
- Vous choisissez, parmi des options fermées, celle que vous entendiez.
- Avec l'interprétation fixée, le modèle génère la requête.
C'est exactement la façon de travailler d'un bon comptable : il ne calcule pas sur un premier élan, il demande d'abord la définition — « chiffre d'affaires brut ou net ? » — puis fait les comptes. L'avantage par rapport au clarification conversationnelle est pratique : chaque question de clarification est courte et à choix multiples, coûte quelques tokens, et la conversation ne s'allonge pas. Et ça marche mieux avec les modèles locaux, qui perdent plus le fil dans les dialogues longs que dans des échanges courts et contraints.
Le construire en local : schéma d'abord et limites du modèle
Le pattern qui fonctionne — et qui reflète la structure du benchmark lui-même — est le schéma d'abord : le contexte qu'on passe au modèle, c'est le schéma avec les noms de colonnes et leurs descriptions, pas les données. ARCS distribue exactement cela : column_meanings.json, une description par colonne (dataset). Dans votre cas, pour une base petite (jusqu'à quelques dizaines de tables), il suffit de décrire les colonnes en une phrase ; pour une grande, il faut d'abord un filtre qui n'apporte au modèle que les tables pertinentes pour la question.
Pour le modèle, le critère de sélection est le même que pour le RAG sur vos documents : mémoire et contexte, pas « le plus intelligent ». Le contexte ici, c'est schéma + question + éventuels exemples, donc peu de tokens de contexte ; la bonne taille, c'est celle qui tient dans la VRAM avec de la marge. Une règle pratique déjà vue dans le guide matériel pour l'IA locale : en Q4, les paramètres comptent en gigaoctets quasiment un pour un (14B ≈ 7–8 Go de poids), puis on ajoute la marge de contexte. Un modèle de 8–14B quantisé est un point de départ raisonnable pour des bases petites ; au-dessus de 32B, on entre dans une autre gamme de matériel.
Une remarque honnête sur les chiffres : ARCS mesure le comportement sur des questions ambigues et des bases de benchmark, pas sur votre question type. Si vos questions sont simples (« nombre de clients actifs », « somme des ventes par mois »), votre modèle open local fera bien mieux que les 27 % cités. Si elles sont riches en termes de domaine (« marge sur produits en promo, retours exclus »), vous vous approcherez de ce chiffre. Le benchmark sert à comprendre le mécanisme de l'échec, pas à prédire votre exactitude avec précision.
Et les limites ?
- L'exactitude sur le réel, c'est à vous de la mesurer. Les 51 % et 27 % d'ARCS sont sur des questions ambigues par définition. Construisez un jeu d'une dizaine de questions sur lesquelles vous connaissez la bonne réponse, et mesurez là : c'est le seul chiffre qui compte.
- Les seuils implicites restent un trou. « Beaucoup », « bas », « récent » n'ont pas de valeur dans la base. La désambiguïsation structurée les expose, mais c'est vous qui devez les fixer.
- SQL généré = code exécuté. Sans garde-fou, un modèle en erreur peut exécuter une requête fausse — rarement destructive (limitez l'exécution aux
SELECT), mais capable de restituer des chiffres que personne ne conteste parce que « c'est sorti du système ». - Schéma grand = contexte long. Au-delà d'une centaine de tables, le schéma ne tient plus dans un contexte raisonnable et il faut un routage préalable des tables.
Par où commencer aujourd'hui
Le cas d'usage PME le plus concret que le text-to-SQL local offre aujourd'hui n'est pas de remplacer le service data : c'est de donner à qui ne sait pas écrire de SQL un premier accès aux chiffres, avec des données qui restent à la maison. Commencez par une base limitée (ventes, inventaire, tickets), par un schéma proprement décrit, et par la couche de désambiguïsation avant de vous fier aux réponses. Traitez le modèle comme un analyste junior : rapide, toujours disponible, mais à revoir. Pas comme le comptable qui signe le bilan. Toute la différence entre les deux usages est là.
Sources
- ARCS: Towards Precise Text-to-SQL via Structured Disambiguation (arXiv 2610.09396)
- Dataset megagonlabs/arcs sur Hugging Face
En résumé : le text-to-SQL en local ferme la boucle de la question en langage naturel dans votre périmètre — schéma et question au modèle, exécution sur votre base, résultats à vous, données qui ne voyagent pas. Le benchmark ARCS montre le vrai goulot d'étranglement : l'ambiguïté des questions réelles, sur laquelle même les modèles fermés dépassent à peine les 50 % et les open restent sous les 27 %. La réponse, c'est la désambiguïsation structurée — des clarifications à choix multiples avant la requête — et un test sur vos questions, avec les réponses que vous connaissez. Commencez petit, mesurez sur le vôtre, et traitez-le comme un analyste junior.
Article généré par IA
Vous avez aimé cet article ?
Abonnez-vous à la newsletter pour recevoir de nouveaux tutoriels et guides.

