Formation à l’IA · Étude et ajustement de modèles de langage
Ce document reprend l’intégralité du contenu fourni, en conservant les idées et la progression, mais en réécrivant la forme pour améliorer la clarté, la lisibilité et la structure. Les formules et exemples de code sont maintenus et présentés de façon cohérente.
Comprendre ce qu’est un modèle de langage et ce qu’il n’est pas
- Un modèle de langage prédit la suite la plus probable d’une séquence de tokens en fonction d’un contexte.
- Ce type de modèle ne fonctionne pas comme une base de données et ne « connaît » pas des faits au sens humain du terme.
- Les erreurs et hallucinations sont une conséquence naturelle d’un système probabiliste de génération.
- Les notions clés de l’apprentissage profond (réseau, neurones, couches, rétropropagation, poids, paramètres, hyperparamètres) structurent la compréhension du fonctionnement.
Intelligence artificielle : ensemble de méthodes et de systèmes conçus pour réaliser des tâches qui, dans d’autres contextes, nécessiteraient des capacités humaines (perception, décision, langage).
Apprentissage automatique : sous-ensemble de l’intelligence artificielle où le système apprend des régularités à partir de données.
Apprentissage profond : famille de modèles d’apprentissage automatique qui s’appuie sur des réseaux de neurones comportant plusieurs couches.
Apprentissage supervisé : apprentissage à partir d’exemples annotés (entrée, sortie attendue).
Apprentissage non supervisé : apprentissage à partir de données non annotées, en cherchant des structures (groupes, facteurs latents, représentations).
Paramètres : valeurs apprises pendant l’entraînement (par exemple les poids d’un réseau).
Hyperparamètres : choix fixés avant l’entraînement qui influencent la manière d’apprendre (taux d’apprentissage, taille des couches, régularisation, taille des lots de données).
Ajustement fin : procédure qui consiste à reprendre un modèle pré-entraîné et à l’entraîner sur un jeu de données plus spécifique pour améliorer des performances sur une tâche donnée.
À un niveau conceptuel, un réseau de neurones peut être décrit comme un système de transformation d’entrées en sorties :
- Les entrées sont des valeurs numériques (dans le cas du langage, des tokens encodés).
- Les couches cachées appliquent des transformations successives.
- Les sorties correspondent à une distribution de probabilité sur le token suivant, ou à une valeur de prédiction selon la tâche.
Les poids sont ajustés pour minimiser une fonction de perte. L’algorithme de rétropropagation calcule les gradients, puis une méthode de descente de gradient met à jour les poids.
Objectif : minimiser une perte L(θ) sur des données (x, y) 1) Calculer la prédiction ŷ = f(x; θ) 2) Calculer la perte L(θ) = perte(ŷ, y) 3) Calculer le gradient ∇θ L(θ) 4) Mettre à jour les paramètres : θ ← θ − η · ∇θ L(θ) où η est le taux d’apprentissage
Lecture vulgariséeFormalisme minimal
On entraîne un modèle f(x;θ) pour prédire y à partir de x, en ajustant θ afin de minimiser une fonction de perte L sur des exemples étiquetés.
- On dispose d’un jeu d’exemples (x, y) : entrées + vérité terrain.
- Le modèle f(x;θ) produit une prédiction ŷ en fonction de paramètres θ.
- On choisit une perte L(ŷ, y) qui pénalise les erreurs (classification, régression…).
- On calcule le gradient ∇θ L et on met à jour θ (descente de gradient / backprop).
- On répète sur des mini-lots jusqu’à stabiliser la performance (validation).
Un modèle de langage génère une suite de tokens en suivant une distribution de probabilité conditionnelle au contexte. Lorsque le contexte est ambigu, incomplet, ou lorsque le modèle a appris des associations erronées, il peut produire une réponse qui paraît plausible mais qui ne correspond pas à un fait vérifiable.
Il faut donc traiter une sortie de modèle comme une proposition à vérifier, et non comme un résultat intrinsèquement exact.
Concevoir des prompts robustes et des workflows agentiques
- Le prompt est une spécification : rôle attendu, objectif, contraintes, format de sortie, exemples.
- Les approches de type chaîne de réflexion et enchaînement de prompts servent à stabiliser l’exécution d’une tâche complexe.
- La rétro-ingénierie de prompt part d’un résultat et infère les éléments de prompt qui ont produit ce résultat.
- Rôle : quel comportement est attendu du modèle.
- Objectif : quel résultat concret doit être produit.
- Contraintes : ce qui est interdit, ce qui est obligatoire, les limites de longueur.
- Format de sortie : structure précise (titres, listes, tableaux, sections).
- Exemples : un ou plusieurs exemples d’entrées et de sorties attendues.
- Persistance : continuer jusqu’à ce que l’élève termine l’exercice.
- Appel d’outils : si nécessaire, appeler une fonction dédiée pour récupérer un exercice (exemple : GET_EXERCICE(niveau, type)).
- Planification : planifier les étapes avant exécution, puis exécuter séquentiellement.
Chaîne de réflexion : demander explicitement au modèle de décomposer son raisonnement pour contrôler la conformité au prompt et détecter des sources de biais dans la génération.
Enchaînement de prompts : découper une tâche complexe en sous-tâches ordonnées. La sortie d’une étape devient l’entrée de l’étape suivante.
Étape 1 : diagnostiquer le besoin (lecture, compréhension, orthographe) Étape 2 : choisir un niveau d’exercice adapté Étape 3 : récupérer un exercice (appel de fonction) Étape 4 : présenter l’exercice (consignes, exemple résolu) Étape 5 : fournir un retour et proposer une question de suivi
Lecture vulgariséeExemple de séquençage
Pseudo-algorithme d’un parcours adaptatif : on observe l’apprenant, on choisit la prochaine étape, puis on boucle avec du feedback.
- Initialiser le profil (niveau, objectifs, contraintes de temps).
- Faire un diagnostic rapide (quiz, exercice, analyse d’erreurs).
- Sélectionner la prochaine activité (niveau + type : rappel, application, défi).
- Produire une consigne + un exemple de sortie attendue.
- Collecter la réponse, donner un feedback court, puis réajuster la difficulté.
La rétro-ingénierie de prompt renverse la logique : au lieu de concevoir le prompt pour obtenir une sortie, on part d’une sortie et l’on cherche à identifier les éléments du prompt qui l’ont produite. Une méthode pratique consiste à générer plusieurs sorties à partir d’entrées proches, puis à analyser les corrélations entre réponses (souvent entre cinq et vingt générations) afin d’inférer des composantes communes.
Référence mentionnée dans le support : Wu, Terry et Cai (2022), « AI Chains » (CHI).
Table ronde : enjeux de l’intelligence artificielle dans l’enseignement supérieur
- L’usage des modèles génératifs est massif côté étudiants. Les usages varient selon les filières et les attentes d’évaluation.
- Les usages côté personnels administratifs et enseignants existent mais sont moins généralisés, souvent par manque de temps, de formation, de cadre ou de confiance.
- Le principal enjeu n’est pas l’outil mais la capacité de cadrage : objectifs pédagogiques explicites, transparence des critères, et conception d’évaluations robustes.
Compétences et formation : la priorité est d’accompagner les étudiants pour qu’ils comprennent ce que l’outil fait, ce qu’il ne fait pas, et comment l’utiliser de manière responsable. Du côté des équipes pédagogiques, la formation doit être adaptée au temps disponible et au contexte disciplinaire.
Qualité des évaluations : il est préférable de concevoir des modalités d’évaluation qui valorisent le raisonnement, l’argumentation, la justification et la contextualisation, plutôt que de se reposer sur des tâches uniquement reproductibles.
Rapport au risque : l’enjeu n’est pas d’interdire, mais de définir des usages autorisés, d’identifier les zones à risque (tricherie, dépendance, biais, confidentialité), et d’outiller l’institution.
Dimensions écologiques et industrielles : la discussion évoque la matérialité des infrastructures (puissance de calcul, centres de données, coûts) et les arbitrages liés au déploiement à grande échelle.
Lectures et ressources de référence
- Brooks, R. « The Seven Deadly Sins of AI Predictions » (2017).
- Lepage, S. « Ce que les intelligences artificielles disent de nous » (France Culture, 2023).
- Klein, M. « Bring Your Own AI: The Rise of Shadow AI » (Wired, 2024).
- Bender, E. M. et Koller, A. « Climbing towards NLU: On Meaning, Form, and Understanding in the Age of Data » (ACL, 2020).
- Dwivedi, Y. K. et al. « So what if ChatGPT wrote it? Multidisciplinary perspectives on opportunities, challenges and implications of generative conversational AI for research, practice and policy » (International Journal of Information Management, 2023).
- Moorhouse, B. L. et Kohnke, L. « Using large language models in academic writing: a tool for outlining, paraphrasing, and summarizing » (Computers and Education: Artificial Intelligence, 2024).
- Chan, C. K. Y. et al. « The potential of ChatGPT for fostering critical thinking in education » (2024).
- Schmidt, J. « Artificial Intelligence: A Negative Externality » (2024).
- Griffin, D. « Research on the effects of AI in writing education: a review » (2024).
Remarque : certaines références existent sous plusieurs versions (prépublication, version revue). Il est conseillé de vérifier la version exacte utilisée dans votre bibliographie finale.
Mesurer les propriétés d’un texte et préparer des variables exploitables
- Construire des indicateurs quantitatifs pour caractériser un texte (lisibilité, longueur, richesse lexicale).
- Comprendre le score de lisibilité de Flesch et le rôle des composants (mots, phrases, syllabes).
- Produire des signaux supplémentaires (fréquences lexicales, longueur moyenne des phrases, variance) utiles pour l’analyse ou la personnalisation.
- Introduire des notions probabilistes (marche aléatoire, mouvement brownien, distribution normale) comme outils de modélisation.
Le score de lisibilité de Flesch (Flesch Reading Ease) est construit à partir du nombre de mots par phrase et du nombre de syllabes par mot.
FRE = 206.835 − 1.015 · (nombre_de_mots / nombre_de_phrases)
− 84.6 · (nombre_de_syllabes / nombre_de_mots)
Lecture vulgariséeFormule
Indice de lisibilité : plus le score est élevé, plus le texte est facile (phrases courtes + mots simples).
- Compter le nombre de phrases (segmentation par ponctuation).
- Compter le nombre de mots (tokens séparés par espaces).
- Estimer le nombre de syllabes (approximations possibles en français).
- Calculer les moyennes : mots/phrase et syllabes/mot.
- Appliquer la formule et interpréter le score (facile vs difficile).
Interprétation : plus le score est élevé, plus le texte est considéré comme facile à lire. En pratique, l’implémentation dépend d’un bon comptage des syllabes.
import re
def compter_syllabes_fr(mot: str) -> int:
"""Estimation simple du nombre de syllabes en français.
Cette heuristique n'est pas parfaite, mais elle fournit un signal exploitable.
"""
mot = mot.lower()
# Regroupe les voyelles pour approximer des noyaux syllabiques
noyaux = re.findall(r"[aeiouyàâäéèêëïîôöùûüœ]+", mot)
n = len(noyaux)
return max(1, n)
def score_flesch(texte: str) -> float:
"""Calcule un score de lisibilité de Flesch à partir d'un texte."""
# Découpe grossière en phrases
phrases = [p.strip() for p in re.split(r"[.!?]+", texte) if p.strip()]
# Découpe grossière en mots
mots = re.findall(r"[A-Za-zÀ-ÖØ-öø-ÿœŒ'-]+", texte)
if not phrases or not mots:
return 0.0
nb_phrases = len(phrases)
nb_mots = len(mots)
nb_syllabes = sum(compter_syllabes_fr(m) for m in mots)
# Formule du FRE
fre = 206.835 - 1.015 * (nb_mots / nb_phrases) - 84.6 * (nb_syllabes / nb_mots)
return fre
Lecture vulgariséePython
Script qui calcule un score Flesch à partir d’un texte brut : nettoyage, comptages, puis application de la formule.
- Importer les modules (regex) et définir les fonctions de comptage.
- Découper le texte en phrases puis en mots (en filtrant les symboles).
- Estimer les syllabes par mot (heuristique : groupes vocaliques).
- Calculer les ratios (mots/phrase, syllabes/mot).
- Retourner le score Flesch et l’afficher / l’exploiter.
Le support introduit une forme discrète de marche aléatoire et le mouvement brownien comme modèle limite :
Marche aléatoire simple :
X_{n+1} = X_n + ε_n
où ε_n ∈ {−1, +1} est une variable aléatoire symétrique.
Mouvement brownien (définition qualitative) :
B(0) = 0
B(t) a des accroissements indépendants et stationnaires
B(t) est presque sûrement continu
et B(t) − B(s) suit une loi normale de moyenne 0 et de variance t−s, pour t > s
Lecture vulgariséeFormalisme
Définition d’une marche aléatoire (somme d’incréments) et de sa limite continue quand le pas devient très petit (mouvement brownien).
- Définir des incréments aléatoires ε_k (ex. ±1, ou gaussiens).
- Construire la somme partielle S_n = Σ ε_k : trajectoire discrète.
- Normaliser par √n pour contrôler la variance quand n augmente.
- Passer à une description continue (t) : W(t) ~ Brownien.
- Interpréter : fluctuations, diffusion, incertitude cumulée.
Ces notions servent ici principalement à donner un cadre mathématique à l’idée de bruit et de variabilité dans les données.
Références citées dans le support : Øksendal (2000) ; Engbert, Nuthmann, Richter et Kliegl (2005).
f(x) = (1 / (σ √(2π))) · exp( − (x − μ)² / (2σ²) ) μ : moyenne σ : écart-type
Lecture vulgariséeFormule
Densité de probabilité d’une loi normale N(μ, σ²) : une cloche centrée en μ, plus ou moins étalée selon σ.
- μ = moyenne : position du centre de la distribution.
- σ = écart-type : largeur (dispersion) autour de μ.
- x = valeur observée ; on mesure son écart à μ.
- Le terme exp(−(x−μ)²/(2σ²)) décroît quand x s’éloigne de μ.
- Le coefficient 1/(σ√(2π)) normalise pour que l’aire totale fasse 1.
La moyenne et la variance sont rappelées comme des statistiques descriptives de base.
Construire une base d’exercices et préparer l’exploitation des réponses
- Structurer une base de données d’exercices (texte, consignes, type de dyslexie ciblée, niveau).
- Définir les champs nécessaires pour relier réponses d’élèves, profils et recommandations.
- Préparer le stockage des embeddings pour la recherche par similarité et la personnalisation.
Une base d’exercices utile doit répondre à des exigences pratiques :
- une structure stable (identifiants, niveaux, types, versions) ;
- des métadonnées exploitables (type d’exercice, compétences mobilisées, difficulté) ;
- des champs textuels propres (consignes, contenus) ;
- une stratégie de stockage des représentations vectorielles (embeddings) pour comparer ou recommander.
Le support indique un fichier de travail associé (lien interne). Dans cette version éditée, le lien est conservé tel qu’il apparaît dans le document source lorsqu’il est disponible.
Comparer des embeddings et analyser des regroupements
- Créer des embeddings pour des textes, puis mesurer leur proximité via la similarité cosinus.
- Projeter des embeddings en deux dimensions pour visualiser des structures (UMAP, PCA).
- Utiliser un clustering hiérarchique (méthode de Ward) pour suggérer des regroupements de textes.
- Interpréter des distributions de similarité (histogrammes) et leurs implications.
sim(u, v) = (u · v) / (||u|| · ||v||) où u et v sont des vecteurs (embeddings)
Lecture vulgariséeFormule
Similarité cosinus : compare deux vecteurs par leur angle (indépendant de l’échelle). 1 = même direction, 0 = orthogonal, −1 = opposé.
- Calculer le produit scalaire x·y (alignement des composantes).
- Calculer les normes ||x|| et ||y|| (longueurs).
- Diviser : (x·y)/(||x||·||y||) pour obtenir un score entre −1 et 1.
- Interpréter : plus le score est haut, plus les contenus sont proches.
- Dans les embeddings, on trie les documents par ce score.
Une valeur proche de 1 indique des vecteurs très alignés (textes proches selon l’espace d’embedding), une valeur proche de 0 indique une faible relation linéaire, et une valeur négative indique une opposition.
import numpy as np def similarite_cosinus(u: np.ndarray, v: np.ndarray) -> float: """Calcule la similarité cosinus entre deux vecteurs. Hypothèse : u et v sont des vecteurs non nuls. """ return float(np.dot(u, v) / (np.linalg.norm(u) * np.linalg.norm(v))) # Exemple d'usage : embeddings déjà calculés par un modèle u = np.array([0.1, 0.2, 0.3]) v = np.array([0.1, 0.2, 0.25]) print(similarite_cosinus(u, v))
Lecture vulgariséePython
Fonction Python (NumPy) qui renvoie la similarité cosinus entre deux vecteurs : dot, norms, puis division avec garde-fou.
- Convertir les listes en tableaux NumPy (float).
- Calculer dot = np.dot(a, b).
- Calculer na = ||a|| et nb = ||b|| via np.linalg.norm.
- Gérer le cas na=0 ou nb=0 (éviter division par zéro).
- Retourner dot/(na*nb) comme score final.
Calculer des scores de profil et recommander des exercices
- Chaque question produit un signal d’erreur combinant exactitude et similarité textuelle.
- Un score par profil de dyslexie est calculé par combinaison pondérée des erreurs observées.
- Les scores sont normalisés pour obtenir une distribution exploitable lors de la recommandation.
- Les embeddings peuvent aider à apparier un profil et une explication d’exercice adaptée.
On définit d’abord un indicateur d’exactitude, puis une mesure d’erreur textuelle :
Indicateur d’exactitude :
1_{exact} = 1 si la réponse correspond exactement à la réponse attendue, sinon 0
Erreur d’exactitude :
err_exact = 1 − 1_{exact}
Erreur textuelle (mesure basée sur une similarité ratio ∈ [0, 1]) :
text_err = 1 − ratio
Lecture vulgariséeDéfinitions
Notation pour scorer un ensemble de réponses : on indexe les questions j, et on compare une réponse observée à une réponse attendue par profil.
- j ∈ {1…K} : index des questions / items.
- i ∈ {1…N} : index des profils (ex. ‘profil A’, ‘profil B’).
- x_j : réponse observée à la question j.
- g_i(j) : réponse attendue si l’utilisateur était du profil i.
- On utilisera ces éléments pour calculer des erreurs puis un score.
Le signal d’erreur final par question combine les deux composantes :
r_j = 0.7 · err_exact + 0.3 · text_err
Lecture vulgariséeSignal d’erreur
Erreur par question : on met 0 si le profil ‘explique’ la réponse, 1 sinon. Ensuite on agrège sur K questions.
- Pour un profil i, prédire la réponse attendue ŷ_j = g_i(j).
- Comparer ŷ_j à la réponse observée x_j.
- Si elles correspondent : r_j = 0 (pas d’erreur).
- Sinon : r_j = 1 (erreur).
- On additionne ensuite r_j sur toutes les questions.
Pour chaque profil i, le score total est une somme pondérée des erreurs sur les questions posées :
S_i = Σ_{j ∈ questions_posées} w_{ij} · r_j
Contrainte sur les poids :
pour toute question j, Σ_i w_{ij} = 1
Lecture vulgariséeScore brut par profil
Score d’adéquation brut d’un profil i : 1 moins la proportion d’erreurs (plus c’est haut, mieux le profil correspond).
- Additionner les erreurs : Σ_{j=1..K} r_j.
- Diviser par K pour obtenir une proportion d’erreurs.
- Calculer S_i = 1 − (Σ r_j)/K.
- Interpréter : S_i proche de 1 = très bon match.
- Comparer S_i entre profils.
Enfin, une normalisation produit une distribution interprétable :
Si Σ_k S_k > 0 : S̃_i = S_i / Σ_k S_k Sinon (aucune erreur détectée) : S̃_i = 1 / nombre_de_profils
Lecture vulgariséeNormalisation
Normalisation : transformer des scores bruts en poids comparables (la somme vaut 1), utile pour lire une ‘probabilité’ relative.
- Calculer la somme des scores : Σ S_n.
- Diviser chaque score : S̃_i = S_i / Σ S_n.
- Vérifier que Σ S̃_i = 1 (à l’arrondi près).
- Gérer le cas Σ S_n = 0 (fallback uniforme).
- Utiliser S̃_i pour classer ou afficher un graphe.
Ces scores peuvent ensuite alimenter un module de recommandation d’exercices ou d’explications associées.
from typing import Dict
def calcul_scores_profils(r_par_question: Dict[str, float],
poids: Dict[str, Dict[str, float]]) -> Dict[str, float]:
"""Calcule des scores bruts S_i par profil i.
r_par_question : dictionnaire {question_id: r_j}
poids : dictionnaire {question_id: {profil_id: w_ij}}
"""
S = {}
for question_id, rj in r_par_question.items():
for profil_id, wij in poids.get(question_id, {}).items():
S[profil_id] = S.get(profil_id, 0.0) + wij * rj
return S
def normaliser(S: Dict[str, float]) -> Dict[str, float]:
"""Normalise des scores pour obtenir une distribution."""
total = sum(S.values())
if total <= 0:
n = max(1, len(S))
return {k: 1.0 / n for k in S}
return {k: v / total for k, v in S.items()}
# Exemple minimal
r = {"Q1": 0.2, "Q2": 0.8}
w = {"Q1": {"profil_A": 0.6, "profil_B": 0.4},
"Q2": {"profil_A": 0.3, "profil_B": 0.7}}
S = calcul_scores_profils(r, w)
S_tilde = normaliser(S)
print(S)
print(S_tilde)
Lecture vulgariséePython
Exemple complet : on encode des réponses, on définit les profils attendus, puis on calcule erreurs, scores bruts et scores normalisés.
- Définir les réponses observées (liste/dict) et K (nombre de questions).
- Définir, pour chaque profil i, une fonction ou table g_i(j).
- Pour chaque profil : calculer r_j (0/1) sur j=1..K.
- Calculer S_i = 1 − (Σ r_j)/K puis normaliser en S̃_i.
- Afficher le classement et (optionnel) les erreurs par question.
Implémentation : base de données, embeddings et calculs (SQLite)
- Créer une base SQLite pour stocker exercices, explications, profils, questions et réponses.
- Ajouter des champs pour stocker des embeddings (vecteurs) et faciliter la recherche par similarité.
- Prévoir des index, puis adapter aux capacités réelles du moteur choisi.
- Introduire un exemple de composition de requêtes et d’insertion de données.
Le support fournit un schéma structuré pour relier profils, questions, réponses et exercices. Ci-dessous, un extrait réécrit pour être directement lisible et exécutable dans un contexte SQLite. Les types et index sont à ajuster si vous utilisez PostgreSQL ou un autre moteur.
-- SQLite : activer les clés étrangères PRAGMA foreign_keys = ON; -- Table des profils (types de dyslexie) CREATE TABLE IF NOT EXISTS dyslexie_type ( dyslexie_type_id INTEGER PRIMARY KEY, nom TEXT NOT NULL UNIQUE, description TEXT ); -- Table des questions posées à l'élève CREATE TABLE IF NOT EXISTS question ( question_id INTEGER PRIMARY KEY, texte TEXT NOT NULL, reponse_attendue TEXT, niveau INTEGER ); -- Lien question → profil avec un poids w_ij CREATE TABLE IF NOT EXISTS question_profil_poids ( question_id INTEGER NOT NULL, dyslexie_type_id INTEGER NOT NULL, poids REAL NOT NULL CHECK (poids >= 0.0), PRIMARY KEY (question_id, dyslexie_type_id), FOREIGN KEY (question_id) REFERENCES question(question_id), FOREIGN KEY (dyslexie_type_id) REFERENCES dyslexie_type(dyslexie_type_id) ); -- Table des exercices CREATE TABLE IF NOT EXISTS exercice ( exercice_id INTEGER PRIMARY KEY, titre TEXT NOT NULL, consigne TEXT NOT NULL, niveau INTEGER, dyslexie_type_id INTEGER, FOREIGN KEY (dyslexie_type_id) REFERENCES dyslexie_type(dyslexie_type_id) ); -- Table des réponses d'élèves (une réponse par question) CREATE TABLE IF NOT EXISTS reponse_eleve ( reponse_id INTEGER PRIMARY KEY, eleve_id TEXT NOT NULL, question_id INTEGER NOT NULL, reponse TEXT NOT NULL, date_reponse TEXT, FOREIGN KEY (question_id) REFERENCES question(question_id) );
Lecture vulgariséeSQL
Schéma minimal pour un système RAG : documents → chunks → embeddings + métadonnées. Les clés assurent la traçabilité et les jointures.
- Créer une table documents (id, titre, source, dates, tags).
- Créer une table chunks (id, document_id, texte, ordre, offsets).
- Créer une table embeddings (chunk_id, vecteur, modèle, date).
- Ajouter des index (document_id, chunk_id) pour les requêtes.
- Prévoir des champs de qualité (langue, longueur, checksum).
Pour exploiter des embeddings, deux approches sont courantes :
- Stocker le vecteur sous forme de tableau sérialisé (JSON) ou de blob binaire dans SQLite.
- Stocker l’embedding dans un système spécialisé (base vectorielle) et garder seulement les identifiants dans SQLite.
Le support s’oriente vers un stockage local simple. Un exemple minimal en JSON :
ALTER TABLE exercice ADD COLUMN embedding_json TEXT; -- Exemple d'insertion (embedding fictif) UPDATE exercice SET embedding_json = '[0.12, 0.04, -0.31]' WHERE exercice_id = 1;
Lecture vulgariséeSQL
Stocker un vecteur d’embedding en JSON (liste de floats) : simple à prototyper, mais le calcul de similarité se fait souvent côté application.
- Définir une colonne JSON/JSONB contenant un tableau de nombres.
- Insérer l’embedding (ex. [0.012, -0.44, …]).
- Récupérer l’embedding et calculer la similarité dans le code applicatif.
- Si besoin de recherche rapide : utiliser un type vecteur et index ANN (ex. pgvector).
- Conserver la version du modèle d’embedding pour la reproductibilité.
Le support mentionne l’index GIN, qui est spécifique à PostgreSQL et généralement utilisé pour des index inversés (textes, tableaux, JSONB). Si l’objectif est une recherche sémantique par embeddings, il faut vérifier que l’infrastructure choisie est cohérente : SQLite seul ne fournit pas nativement une recherche vectorielle performante sans extension. En contexte de prototype, le compromis peut rester acceptable, mais il faut anticiper la montée en charge.