Chercher dans une documentation technique
- Étude de cas 2
- 120 min
- Facultative · 1 étude de cas requise pour le certificat
Étude de cas 2 sur 3 · RAG : créer une IA qui utilise vos donnéesChercher dans une documentation technique
1. Définir le problème de connaissances
2. Ingérer les documents de façon reproductible
3. Créer et comparer la récupération
4. Construire des réponses fondées sur les sources
5. Évaluer et déboguer le pipeline
6. Maintenir et protéger la base de connaissances
Ce que vous saurez faire
Choisissez une méthode de recherche pour une vraie documentation technique, avec des preuves tirées de vos propres questions. Vous comparez la recherche par mots-clés, vectorielle, hybride et avec reclassement sur la documentation de SQLite. Vous mesurez leurs résultats par type de question, avec leur durée et leur coût. Et vous constatez que la méthode gagnante ici n’est pas celle qui gagnait sur les politiques de Larkfield.
Le carnet (notebook) Jupyter exécute chaque étape de cette page avec le même code et les mêmes sorties. Il ajoute trois tâches avec des vérifications. Sa configuration télécharge l’instantané de la documentation et les vecteurs précalculés (environ 20 Mo), ainsi que les deux modèles locaux du cours. L’exécution a pris environ 2 minutes sur le portable de test, avec les modèles déjà téléchargés.
Avant de commencerCe qu’il faut savoir et avoir sous la main
Ce que vous devez savoir
Cette étude de cas utilise tout le cours. Ces leçons sont les plus importantes :
- BM25 et hit@5, dans Une référence de base par mots-clés.
- L’analyse HTML avec provenance et les segments adaptés à la structure, dans Analyser et normaliser et Découper de façon réfléchie.
- Les plongements (embeddings), la fiche du modèle et
embed-small, dans Les plongements pour la recherche. - La recherche hybride avec fusion par rang réciproque et le résultat sans embellissement sur les données de Larkfield, dans Recherche lexicale, dense et hybride.
- Le cross-encoder (encodeur croisé) et son coût en temps, dans Reclassement et reformulation des requêtes.
- Les affirmations avec citations et ce que le code peut vérifier, dans Répondre et citer.
Ce qu’il vous faut sur votre ordinateur (uniquement pour l’exécution locale; Colab et Kaggle n’en ont pas besoin)
- Un environnement virtuel avec les paquets du cours, comme dans le projet de Les plongements pour la recherche. Le carnet installe seulement pandas et matplotlib s’ils manquent.
- Le carnet, téléchargé à partir du lien ci-dessus. Sa cellule de configuration crée un dossier
sqlite-docsà côté de lui. Pour recommencer, supprimez ce dossier.
Aucun compte ni aucune clé. Testé sur macOS (Apple silicon) avec Python 3.12.13, sentence-transformers 6.1.0 et SQLite 3.53.4. Windows, Linux, Colab et Kaggle n’ont pas encore été testés.
La situation
Section intitulée « La situation »Dana dirige le service de soutien aux développeurs d’une petite entreprise de logiciels. Son produit stocke ses données dans SQLite. Son équipe reçoit environ 40 questions par semaine. La moitié vient de personnes qui collent un nom exact tiré d’une erreur ou d’un journal (log) : SQLITE_BUSY, PRAGMA journal_size_limit, .once. L’autre moitié décrit un problème dans ses propres mots : « J’ai supprimé la moitié des lignes et le fichier n’a pas diminué. »
Felix, un développeur de l’équipe, veut un champ de recherche dans la documentation officielle de SQLite. Plus tard, il veut un assistant qui répond avec des citations. Il a lu que « la recherche hybride gagne toujours » et veut la mettre en production. Dana demande d’abord des preuves : quelle méthode trouve la bonne section pour les deux types de questions, et à quel coût? Un mauvais premier résultat fait perdre quelques minutes à son équipe. Une réponse assurée tirée de la mauvaise page coûte plus cher, car un client peut agir en s’y fiant.
Ce que vous allez construire
Section intitulée « Ce que vous allez construire »Vous construisez une comparaison équitable de six méthodes de recherche sur un instantané fixe de la documentation, avec des questions étiquetées. Vous mesurez chaque méthode par type de question, avec sa durée et son coût, puis vous rédigez une recommandation pour Dana. À la fin, vous traitez une nouvelle question de bout en bout et examinez la réponse avec citations fournie par un modèle.
Les compétences viennent de tous les modules du cours. Le module 2 analyse avec provenance, et le module 3 compare la recherche par mots-clés, vectorielle, hybride et le reclassement. Le module 4 rédige et vérifie des réponses avec citations, et Mesurer la récupération définit les mesures. Une idée est nouvelle : comment étiqueter les passages pertinents quand vous ne pouvez pas lire toute la collection. Elle a sa propre section ci-dessous.
Les données
Section intitulée « Les données »L’auteur a d’abord comparé deux autres possibilités. La documentation de pytest 9.1.1 (licence MIT) a une étiquette de version claire, mais ses sources Sphinx exigent une étape de compilation. La documentation de Kubernetes (CC BY 4.0) compte 1 721 pages, sans versions étiquetées, et exige une attribution à chaque réutilisation. SQLite l’a emporté pour quatre raisons. Sa documentation est dans le domaine public, elle est versionnée et elle contient de nombreux types de noms exacts. Sa taille convient après une sélection claire. Et SQLite est le moteur de la recherche par mots-clés du cours. Vous cherchez dans la documentation de l’outil que vous utilisez.
L’archive contient 224 pages au premier niveau. L’instantané en conserve 195. Il exclut 29 pages qui ne sont pas de la documentation technique : listes de liens, index de références croisées, actualités, historique des versions, pages organisationnelles et juridiques. Un fichier pages.csv indique chaque page et la raison. L’analyseur suit les règles du cours. Il ignore ce que SQLite marque comme navigation (<div class=nosearch>) et conserve chaque section avec son titre et son ancre. Ainsi, chaque segment renvoie à son emplacement exact, par exemple https://sqlite.org/pragma.html#pragma_busy_timeout.
195 pages, 2231 sections, 4300 chunksYour chunks are identical to the shipped ones.597,305 words; median chunk 151 words; longest 571Ce que cela nous apprend. L’instantané est environ 90 fois plus volumineux que les 36 politiques de Larkfield (6 520 mots). Chaque segment correspond à une section, découpée à 200 mots entre les paragraphes. Certains tableaux sont beaucoup plus longs : celui des codes d’opération du moteur de code intermédiaire contient environ 16 000 mots. Ces tableaux sont découpés entre les lignes, et chaque partie répète la ligne d’en-tête du tableau. L’outil de découpage du cours ne divise jamais un tableau, mais à cette taille, il faut le faire.
Le carnet repère aussi deux pièges qui auront de l’importance plus tard :
fileformat: 106 chunks; identical text in fileformat2: 106 (100%)The C language interface to SQLite Version 2Ce que cela nous apprend. Deux pages, fileformat.html et fileformat2.html, contiennent exactement le même texte, comme sur le site Web. Une recherche peut donc retourner deux fois la même réponse et occuper deux des cinq places. Et c_interface.html décrit l’interface C de SQLite version 2, vieille de plus de 20 ans, dans la documentation 3.53.4. Une recherche sur « database is locked » (la base de données est verrouillée) peut la trouver, et une réponse peut la citer. Une vraie documentation conserve son propre historique.
Définir le problème
Section intitulée « Définir le problème »L’unité est une question. Une méthode de recherche retourne une liste classée de segments. Les 5 premiers vont au lecteur ou au modèle, comme dans le projet du cours. Une seule version s’applique (3.53.4) et toutes les pages sont publiques. Il n’y a donc ici ni filtre de date ni filtre d’accès.
La mesure principale est hit@5 : y a-t-il au moins un segment pertinent parmi les 5 premiers? À côté figurent recall@5 et recall@10 : la proportion des passages pertinents d’une question parmi les 5 ou 10 premiers. MRR@10 est la moyenne de 1 ÷ le rang du premier segment pertinent, ou 0 s’il n’est pas parmi les 10 premiers. hit@1 indique si le premier segment est pertinent. Une personne qui utilise un champ de recherche regarde d’abord le premier résultat. hit@1 et MRR comptent donc autant que hit@5. Les tableaux donnent chaque mesure par type de question, car une moyenne cache les endroits où une méthode échoue.
Les questions sans réponse n’ont aucun passage pertinent; elles sont donc exclues de ces mesures. S’abstenir d’y répondre relève de l’étape de réponse (Traiter les preuves difficiles).
Les questions et leurs étiquettes
Section intitulée « Les questions et leurs étiquettes »L’étude de cas comprend 53 questions, rédigées par l’auteur du cours dans le style des demandes reçues par Dana. 18 contiennent un identifiant exact; 5 demandent uniquement ce que signifie le nom, comme « Qu’est-ce que SQLITE_BUSY_SNAPSHOT? ». 15 sont des reformulations sans identifiant, et 15 demandent comment accomplir une tâche. L’instantané ne peut pas répondre aux 5 dernières. Elles portent sur un autre produit (un code d’erreur PostgreSQL, un paramètre Django), une page hors de l’instantané ou un nom inventé comme PRAGMA wal_buffer_size.
Chaque question a besoin de ses passages pertinents : les sections qui y répondent. Pour les 36 documents de Larkfield, Grace pouvait tout lire. Ici, il y a 2 231 sections, et personne ne les lit toutes pour chacune des 53 questions.
Imaginez un enseignant qui corrige un questionnaire avec un corrigé. Un élève donne une réponse correcte qui n’y figure pas. Un enseignant attentif la lit et l’ajoute au corrigé. La recherche a le même problème. L’auteur a rédigé chaque question à partir d’une section et a étiqueté les sections qu’il connaissait déjà. Mais la documentation dit souvent la même chose à deux endroits. La FAQ dit : « Vous pouvez utiliser PRAGMA integrity_check pour effectuer un test… approfondi », et la page du pragma le dit aussi. Le corrigé considérerait comme incorrecte une méthode qui trouve la FAQ.
La solution habituelle porte un nom : mise en commun (pooling). Exécutez chaque méthode, réunissez leurs premiers résultats dans un ensemble commun, puis lisez chaque segment pour le juger. Un segment est pertinent si un lecteur peut répondre à la question avec ce seul segment. L’ensemble est assez petit pour être lu. Chaque méthode a la même chance de voir ses trouvailles comptées.
Description textuelle du diagramme
Six étapes de gauche à droite. 1 : 53 questions, chacune rédigée à partir d’une section. 2 : les étiquettes initiales, 82 sections connues de l’auteur. 3 : les six méthodes sont exécutées. 4 : l’ensemble commun, les 5 premiers résultats de chaque méthode pour chaque question. Il contient 637 segments sans étiquette initiale. 5 : l’auteur lit et juge chacun. Deux flèches partent de l’étape 5. L’une donne 31 passages pertinents supplémentaires à la première lecture. L’autre, en pointillé, en donne 9 autres à une deuxième lecture du texte intégral. 6 : les étiquettes figées, 122 passages.
La première lecture jugeait chaque segment de l’ensemble commun à partir de ses 420 premiers caractères. Elle a trouvé 31 passages pertinents supplémentaires. Puis une réponse enregistrée (ci-dessous) a cité un segment de fileformat2.html jugé « non pertinent » à la première lecture. Son texte intégral donne la réponse, « environ 281 téraoctets », après les 420 premiers caractères. Chaque segment jugé « non pertinent » dont le texte intégral contient un terme clé de la réponse de référence a donc été relu entièrement. 9 autres sont devenus pertinents. Les étiquettes ont ensuite été figées.
Énoncez clairement les limites. C’est la lecture d’une seule personne, sans deuxième juge. Une section pertinente qu’aucune méthode n’a placée dans ses 5 premiers résultats manque toujours, pour toutes les méthodes. Et les étiquettes ont changé après les premières mesures. L’ordre des méthodes aux résultats proches a changé aussi. Avec les étiquettes initiales, la recherche hybride avec e5 était légèrement en dessous d’e5 seul (hit@5 de 0,667 contre 0,688). Avec les étiquettes finales, elle est au-dessus (0,792 contre 0,729). Une différence d’une ou deux questions dépend des étiquettes. La procédure et chaque jugement se trouvent dans les fichiers de référence de l’étude de cas.
Une référence de base : la recherche par mots-clés
Section intitulée « Une référence de base : la recherche par mots-clés »Commencez par la méthode la plus simple, comme au module 1 : SQLite FTS5 avec BM25 sur les 4 300 segments. La requête est celle du cours : chaque mot entre guillemets, relié par OR.
index built in 0.04 sbm25 {'hit@1': 0.458, 'hit@5': 0.708, 'recall@5': 0.555, 'recall@10': 0.604, 'MRR@10': 0.553}hit@5 by kind: {'identifier': 0.944, 'paraphrase': 0.533, 'howto': 0.6}Ce que cela nous apprend. La recherche par mots-clés trouve 17 des 18 questions avec identifiant, mais seulement environ la moitié des reformulations et des tâches pratiques. « Comment voir si ma requête utilise un index? » partage très peu de mots avec « EXPLAIN QUERY PLAN ». BM25 classe donc la bonne section au 18e rang. Voici le résultat à dépasser : 0,708.
Les modèles
Section intitulée « Les modèles »Recherche vectorielle avec le modèle local, e5. Le carnet charge les vecteurs e5 des 4 300 segments, créés avec le modèle du cours à sa révision fixée. Il vérifie le modèle et la révision avant toute comparaison de vecteurs. Créer les plongements de tous les segments a pris 108 secondes sur le portable de test (2 fils d’exécution). Les vecteurs sont donc fournis avec leur somme de contrôle. Définissez RECOMPUTE = True pour les créer vous-même.
e5 vectors: 4300 x 384dense-e5 {'hit@1': 0.542, 'hit@5': 0.729, 'recall@5': 0.547, 'recall@10': 0.629, 'MRR@10': 0.621}hit@5 by kind: {'identifier': 0.889, 'paraphrase': 0.6, 'howto': 0.667}Ce que cela nous apprend. Sur les courtes politiques de Larkfield, e5 battait clairement BM25 (0,915 contre 0,831). Ici, il ne fait mieux que d’une question pour hit@5. Son premier résultat est toutefois correct plus souvent (hit@1 de 0,542 contre 0,458). e5 est un petit modèle multilingue, et ces textes sont longs, techniques et en anglais. Il manque -bail, une option dans une longue liste --help (aide), que BM25 classe au 2e rang.
Recherche vectorielle avec le modèle hébergé, embed-small. Ses vecteurs ont été enregistrés une fois : 828 297 jetons (tokens) pour les segments, 0,0166 $ US, environ 10 minutes avec les limites de débit du déploiement partagé. Le carnet les réutilise, donc vous n’avez besoin d’aucune clé.
dense-embed-small {'hit@1': 0.688, 'hit@5': 0.917, 'recall@5': 0.691, 'recall@10': 0.75, 'MRR@10': 0.789}hit@5 by kind: {'identifier': 1.0, 'paraphrase': 0.867, 'howto': 0.867}Ce que cela nous apprend. Le modèle hébergé est la meilleure méthode seule pour chaque type de question. Sur les données de Larkfield, e5 l’égalait. Un modèle « aussi bon » sur une collection peut être nettement plus faible sur une autre.
Recherche hybride et reclassement. La recherche hybride combine les 20 premiers résultats de BM25 et d’une recherche vectorielle par fusion par rang réciproque. Le reclassement suit le réglage par défaut du cours : le cross-encoder relit les 20 premiers résultats de la recherche hybride avec e5.
hybrid-e5 {'hit@1': 0.604, 'hit@5': 0.792, 'recall@5': 0.58, 'recall@10': 0.724, 'MRR@10': 0.695}hybrid-embed-small {'hit@1': 0.667, 'hit@5': 0.833, 'recall@5': 0.625, 'recall@10': 0.789, 'MRR@10': 0.752}rerank {'hit@1': 0.625, 'hit@5': 0.875, 'recall@5': 0.69, 'recall@10': 0.751, 'MRR@10': 0.723}rerank: 789 ms per question on this computerCe que cela nous apprend. Ici, la recherche hybride avec e5 aide : 0,729 → 0,792. BM25 et e5 échouent sur des questions différentes, donc leurs votes se complètent. Avec embed-small, la recherche hybride nuit : 0,917 → 0,833, car la liste plus faible de BM25 fait descendre les bons résultats. Larkfield montrait cet effet avec e5; ici, il apparaît avec l’autre modèle. Le reclassement ajoute quatre questions à la recherche hybride avec e5 (six gagnées, deux perdues), pour environ 0,8 seconde par question.
La comparaison équitable
Section intitulée « La comparaison équitable »Les six méthodes ont utilisé les mêmes segments et les mêmes 48 questions évaluées. Elles partagent les étiquettes figées et les mesures.
- Mots-clés
- Modèles locaux (e5, encodeur croisé)
- embed-small hébergé (enregistré)
Description textuelle du graphique
Un graphique à colonnes du hit@5 de six méthodes, sur 48 questions. Recherche par mots-clés, BM25 : 0.708. Modèles locaux : e5 seul 0.729, hybride avec e5 0.792, hybride e5 avec reclassement 0.875. Modèle hébergé : embed-small seul 0.917, hybride avec embed-small (e-s) 0.833. L’axe va de 0 à 1.
Par type de question, le portrait est plus clair :
| hit@5 | Identifiant (18) | Paraphrase (15) | Marche à suivre (15) | MRR@10, toutes |
|---|---|---|---|---|
| Mots-clés (BM25) | 0.944 | 0.533 | 0.600 | 0.553 |
| Vectorielle, e5 | 0.889 | 0.600 | 0.667 | 0.621 |
| Hybride, e5 | 0.889 | 0.733 | 0.733 | 0.695 |
| Hybride e5 + reclassement | 1.000 | 0.800 | 0.800 | 0.723 |
| Vectorielle, embed-small | 1.000 | 0.867 | 0.867 | 0.789 |
| Hybride, embed-small | 0.944 | 0.800 | 0.733 | 0.752 |
Chaque méthode trouve les 5 identifiants seuls (« Qu’est-ce que SQLITE_BUSY_SNAPSHOT? ») au premier rang. Dans le jeu de Larkfield, la recherche vectorielle échouait sur « Qu’est-ce que LB-1? ». Pourquoi cette différence? Les noms de SQLite sont longs et composés de mots (BUSY, SNAPSHOT, cacheflush). Chaque section nomme aussi son sujet dans son titre. Un code court comme LB-1 n’a aucun sens pour un modèle de plongement. Les identifiants seuls ne sont pas difficiles en général; les codes courts sans signification le sont.
Les vraies différences concernent les paraphrases et les questions sur une marche à suivre. La recherche par mots-clés en trouve environ la moitié. Le modèle hébergé en trouve 26 sur 30.
- embed-small (hébergé, pointillés)
- Hybride e5 + reclassement
- e5 seul (pointillés)
- BM25
Description textuelle du graphique
Un graphique à courbes du recall@k pour k = 1, 3, 5 et 10. embed-small : 0.408, 0.628, 0.691, 0.750. Hybride e5 avec reclassement : 0.370, 0.603, 0.690, 0.751. e5 seul : 0.333, 0.503, 0.547, 0.629. BM25 : 0.312, 0.465, 0.555, 0.604.
Le rappel reste sous 0,8 même à k = 10 pour chaque méthode. Plusieurs questions ont trois ou quatre sections pertinentes sur des pages différentes. L’utilisateur a besoin d’une bonne section; hit@5 est donc la mesure de décision ici. Un assistant qui doit montrer à la fois la FAQ et la page du pragma aurait besoin de plus de 5 segments.
La différence est-elle réelle?
Section intitulée « La différence est-elle réelle? »Avec 48 questions, une question représente 0,021 de hit@5. Comptez donc les questions qu’une seule des deux méthodes trouve. Tirez ensuite 10 000 échantillons par bootstrap (rééchantillonnage) des questions pour obtenir un intervalle à 95 % de la différence :
dense-embed-small vs rerank: only dense-embed-small ['D26', 'D27', 'D39', 'D41', 'D44']; only rerank ['D30', 'D40', 'D45']; 95% interval of the hit@5 difference [-0.062, +0.146]rerank vs hybrid-e5: only rerank ['D04', 'D18', 'D29', 'D32', 'D40', 'D43']; only hybrid-e5 ['D19', 'D41']; 95% interval of the hit@5 difference [-0.021, +0.208]rerank vs bm25: only rerank ['D18', 'D22', 'D23', 'D32', 'D33', 'D35', 'D43', 'D45', 'D48']; only bm25 ['D41']; 95% interval of the hit@5 difference [+0.042, +0.292]Ce que cela nous dit. Le modèle hébergé bat le modèle de reclassement sur 5 questions et perd sur 3. Ce n’est pas une preuve : l’intervalle va de −0,062 à +0,146. Une seule comparaison est claire ici : le reclassement contre la recherche par mots-clés seule, 9 questions contre 1. Les données n’appuient pas le « l’hybride gagne toujours » de Felix. Et « embed-small est meilleur » est probable, mais 48 questions ne le prouvent pas.
Où chaque méthode échoue
Section intitulée « Où chaque méthode échoue »La question « Comment vérifier si un fichier de base de données est corrompu? » est facile pour une personne : PRAGMA integrity_check. Regardez les 5 premiers résultats après reclassement :
1 5.589 howtocorrupt | Mispairing database files and hot journals2 4.241 howtocorrupt | Carrying an open database connection across a fork()3 4.074 howtocorrupt | False corruption reports due to database shrinkage4 3.611 howtocorrupt | File locking problems5 3.479 howtocorrupt | Memory corruptionfirst relevant rank: {'bm25': 5, 'dense-e5': 7, 'dense-embed-small': 1, 'hybrid-e5': 1, 'hybrid-embed-small': 1, 'rerank': 8}Description textuelle du diagramme
La recherche par mots-clés classe le segment de la FAQ contenant la réponse au 5e rang, et la recherche vectorielle au 7e. La recherche hybride additionne 1/65 + 1/67 = 0,0303 et le classe premier, car les deux listes le favorisaient. L’encodeur croisé relit ensuite les 20 candidats. Cinq sections de la page How To Corrupt An SQLite Database File obtiennent des scores de 5,59 à 3,48. La réponse de la FAQ obtient 2,55. Elle tombe au 8e rang, hors des 5 premiers.
La page How To Corrupt An SQLite Database File contient le plus de mots sur la corruption. Elle semble donc la plus pertinente pour chaque modèle qui lit les mots. La section du pragma dit « vérification de cohérence », pas « corruption ». Ici, la fusion a trouvé la bonne réponse et le modèle de reclassement l’a retirée. Avec les 5 premiers résultats reclassés, la réponse enregistrée s’est abstenue. Elle disait : « Les passages de la documentation ne disent pas comment vérifier si un fichier de base de données est corrompu. » C’est prudent, mais la documentation le dit.
Les autres échecs suivent le même schéma. Quand les mots de l’utilisateur diffèrent de ceux de la documentation, la recherche par mots-clés échoue. Le petit modèle e5 échoue souvent aussi. « Une colonne peut-elle se remplir toute seule avec l’heure d’ajout de la ligne? » signifie DEFAULT CURRENT_TIMESTAMP. Seul le modèle hébergé le trouve parmi ses 5 premiers résultats.
Changez une seule chose. Le reclassement peut seulement réordonner ce que la première étape a trouvé. Donnez-lui donc plus : 40 candidats plutôt que 20, sur les 30 questions de paraphrase et de marche à suivre (tâche 3 du carnet) :
40 candidates: 0.733 (1367 ms per question)20 candidates: 0.8 (789 ms per question)Plus de candidats ont empiré les résultats, en prenant presque deux fois plus de temps. Les candidats supplémentaires ont donné à l’encodeur croisé plus de mauvais segments à faire monter. « Plus » est un réglage à mesurer, pas un gain gratuit.
Temps et coût
Section intitulée « Temps et coût »| Méthode | Indexer les 4 300 segments | Par question (médiane, ordinateur portable) | Argent | Les questions quittent l’ordinateur |
|---|---|---|---|---|
| BM25 | 32.7 ms | 3.93 ms | 0 | Non |
| e5 | 108 s (2 fils d’exécution du processeur) | 6.65 ms, plus 1.06 ms pour chercher | 0 (un téléchargement de 470 Mo) | Non |
| Hybride e5 | les deux ci-dessus | environ 10 ms | 0 | Non |
| Hybride e5 + reclassement | les deux ci-dessus | 790 ms | 0 (un second modèle de 470 Mo) | Non |
| embed-small | 0,0166 $ US, environ 10 minutes | 180–770 ms par appel (8 appels, enregistrés) | environ 0,0000003 $ US par question | Oui, chaque question est envoyée au fournisseur |
Chercher parmi 4 300 vecteurs avec NumPy prend environ 1 ms. Cette collection n’a donc pas encore besoin de base de données vectorielle. L’étape lente est le reclassement : environ 0,7 à 0,8 seconde par question sur le processeur d’un ordinateur portable. Le modèle hébergé ne coûte presque rien en argent ici. Ses vrais coûts sont un appel réseau par question, un compte et une clé. Chaque question d’utilisateur quitte aussi l’entreprise.
La recommandation
Section intitulée « La recommandation »Le slogan de Felix ne tient pas. Sur cette collection, la recherche hybride aide un modèle de plongement et nuit à l’autre. Voici la recommandation pour l’équipe de Dana :
- Si l’équipe peut envoyer les questions de ses utilisateurs à un fournisseur externe, utilisez
embed-smallseul. Il offre le meilleur hit@5 (0,917), le meilleur premier résultat (hit@1 de 0,688) et le meilleur MRR (0,789), sans reclassement. Vérifiez d’abord les conditions du fournisseur : la documentation est publique, mais les questions peuvent contenir des noms de clients ou des journaux d’erreurs. - Si les questions doivent rester sur les ordinateurs de l’entreprise, utilisez l’hybride e5 avec reclassement (0,875). Acceptez environ 0,8 seconde par question. Si c’est trop lent pour un champ de recherche, l’hybride e5 sans reclassement (0,792) répond en environ 10 ms.
- Ne choisissez pas entre les options 1 et 2 selon ces chiffres seulement. La différence est de 5 questions contre 3. Ajoutez les 50 prochaines vraies questions de l’équipe, étiquetez-les de la même façon et mesurez à nouveau.
Quelle que soit la méthode, gardez la recherche par mots-clés accessible pour les noms exacts. Elle est rapide et gratuite, et elle trouve 17 questions d’identifiant sur 18.
De bout en bout : une nouvelle question avec une réponse citée
Section intitulée « De bout en bout : une nouvelle question avec une réponse citée »Voici une nouvelle question de soutien, absente du jeu : « Une tâche cron nocturne et mon application web écrivent dans le même fichier SQLite. L’application échoue parfois avec “database is locked” (la base de données est verrouillée). Que puis-je changer? » Le carnet exécute le pipeline local de reclassement sur cette question. Il rejoue ensuite la réponse que chat-small (gpt-6-luna sur Azure) a donnée aux mêmes cinq passages. La requête (prompt) suit Répondre et citer, avec « Documentation SQLite, version 3.53.4 » à la place des politiques de Larkfield.
65ef89eb3990 https://sqlite.org/rtree.html#reading_and_writing_at_the_same_time | The SQLite R*Tree Module 398ca44b61b8 https://sqlite.org/c_interface.html#4_error_codes | The C language interface to SQLite Version 2 ed0c02ce8939 https://sqlite.org/lockingv3.html#writing | File Locking And Concurrency In SQLite Version 3 db447e805ee1 https://sqlite.org/tclsqlite.html#the_timeout_method | The Tcl interface to the SQLite library 9c8a6b3b7716 https://sqlite.org/c_interface.html#4_error_codes | The C language interface to SQLite Version 2
chat-small (gpt-6-luna on Azure, recorded): SQLite allows only one writer at a time, so coordinate the cron job and app to avoid overlapping writes. If your app uses the Tcl interface, increase its lock wait with the `timeout` method; the default is 0 milliseconds. [398ca44b61b8] [db447e805ee1] - SQLite permits only one process or thread to have the database open for writing at a time, and the lock applies to the entire database. ['398ca44b61b8'] problems: none - The Tcl `timeout` method controls how long SQLite waits for locks; its default is 0 milliseconds, and it can be set to a positive value. ['db447e805ee1'] problems: noneDescription textuelle du diagramme
Deux affirmations, chacune reliée à son passage. L’affirmation 1, un seul processus ou fil d’exécution peut écrire à la fois, cite la page sur l’interface C de SQLite version 2. L’affirmation 2, sur la méthode timeout de Tcl, cite la page de l’interface Tcl. Les vérifications du code passent pour les deux. À part, dans un cadre en pointillés : la réponse dont un développeur a besoin, PRAGMA busy_timeout ou sqlite3_busy_timeout(), n’était pas parmi les 5 premiers.
Chaque affirmation passe les vérifications du code, et la réponse est mauvaise. Une source concerne la version 2, et l’autre, l’interface Tcl, que l’utilisateur n’a jamais mentionnée. Le bon conseil, un délai d’attente en cas de verrouillage, n’était pas parmi les 5 premiers. Le modèle ne pouvait donc pas le donner. C’est la leçon de Répondre et citer sur de nouvelles données : une citation montre d’où vient une affirmation. Elle ne montre pas que la source convient à cette version et à cet utilisateur.
Les autres réponses enregistrées se comportent comme prévu. Avec un segment pertinent parmi les 5 premiers, chat-small répondait correctement. Par exemple : « L’option -bail fait arrêter l’interpréteur de commandes après une erreur » et la limite de 281 téraoctets. Sans segment pertinent, il s’abstenait, sur trois questions auxquelles on pouvait répondre et sur les deux sans réponse de l’enregistrement. Encore une fois, une meilleure récupération améliorerait le plus ces réponses. Les 9 réponses enregistrées ont coûté 0,0020 $ US au total.
Erreur courante
Un seuil de score pour détecter les questions sans réponse
Symptôme : Felix propose un raccourci : « Si le meilleur score du modèle de reclassement est bas, dites que la documentation ne couvre pas le sujet. » Pour « Quelle est la valeur par défaut de PRAGMA wal_buffer_size? », un pragma inexistant, le meilleur score est 6,12.
Cause : le nom inventé ressemble à de vrais pragmas (wal_autocheckpoint, journal_size_limit). L’encodeur croisé leur donne donc un score élevé. La moitié des vraies questions auxquelles on peut répondre (24 sur 48) ont un meilleur score inférieur à 6,12. Aucun seuil ne sépare les deux groupes.
Correction : laissez l’étape de réponse décider de s’abstenir. Elle lit les passages et doit dire « les passages de la documentation ne disent pas » quand ils ne répondent pas (Traiter les preuves difficiles). chat-small s’est abstenu sur cette question.
Pour un vrai service d’IA : testez l’abstention avec des questions sur des noms inventés et d’autres produits, comme dans ce jeu. Les scores classent les segments pour une question; ils ne permettent pas de comparer les questions entre elles.
Constats et limites
Section intitulée « Constats et limites »- La meilleure méthode dépend de la collection et du modèle de plongement. Sur les politiques de Larkfield, la recherche hybride avec e5 nuisait aux résultats. Ici, elle aide, et la recherche hybride avec embed-small nuit. Mesurez sur vos propres questions.
- Les noms exacts sont faciles quand ils sont longs et composés de mots, et que chaque section nomme son sujet dans un titre. Les paraphrases et les questions sur une marche à suivre déterminent la comparaison.
- Un second modèle n’est pas toujours un meilleur juge : le reclassement a retiré le bon segment pour D41. Et 40 candidats ont donné de moins bons résultats que 20.
- La documentation elle-même contient des pièges : des pages identiques, une page de la version 2 et des sections aux titres en gras que l’analyseur ne voit pas (
limits.html).
Les limites : 48 questions évaluées, rédigées et étiquetées par une seule personne; un seul outil de découpage et une seule taille de segment; un seul instantané (3.53.4). Les vecteurs hébergés ont été enregistrés une fois, et le fournisseur peut changer le modèle derrière le nom. Les temps proviennent d’un seul ordinateur portable avec 2 fils d’exécution.
Utilisation responsable
Section intitulée « Utilisation responsable »- Citez la version. Chaque réponse devrait nommer SQLite 3.53.4 et fournir un lien vers la section exacte. La documentation change avec les versions : une valeur par défaut ou une limite peut changer. Les anciennes pages (version 2) restent dans les archives.
- Ne présentez pas les réponses comme le soutien officiel du projet. Les développeurs de SQLite n’ont pas rédigé ni révisé ces réponses. Dites que l’assistant cherche dans une copie de la documentation du domaine public, et liez sqlite.org.
- Gardez les questions des utilisateurs privées. La documentation est publique, mais les questions peuvent contenir des données de clients et des journaux d’erreurs. Un modèle de plongement hébergé envoie chaque question au fournisseur.
- Gardez une personne dans le processus pour les actions. Une mauvaise réponse sur la récupération, la corruption ou la suppression de données peut causer du tort. L’assistant montre les preuves; un développeur décide.
Faites-en un projet de portfolio
Section intitulée « Faites-en un projet de portfolio »Placez le carnet dans un dépôt public avec un court README. Voici un modèle :
# Searching the SQLite documentation: keyword, vector, hybrid and reranking
## ProblemA support team needs the right section of the SQLite 3.53.4 documentation,both for exact names (SQLITE_BUSY, PRAGMA journal_size_limit)and for questions in plain words.
## Data and licence195 pages of the official SQLite 3.53.4 documentation (public domain),4,300 chunks with page, section and URL. 53 questions (identifier,paraphrase, how-to, unanswerable), labelled by pooling the top 5 ofsix methods and reading 637 chunks.
## ApproachBM25 (SQLite FTS5), e5 (local), embed-small (hosted, recorded),hybrid with RRF, cross-encoder reranking. hit@5, recall@k, MRR@10 andhit@1 by kind of question; paired counts and a bootstrap interval.
## Resultshit@5: BM25 0.708, e5 0.729, hybrid e5 0.792, rerank 0.875,embed-small 0.917. Hybrid helps e5 and hurts embed-small.Only rerank vs BM25 is a clear difference on 48 questions.
## LimitsOne labeller, 48 scored questions, one snapshot. Not SQLite's official support.En entrevue, dites-le en quelques phrases :
J’ai comparé six méthodes de recherche dans la documentation SQLite, avec 53 questions que j’ai étiquetées en regroupant les résultats. Le modèle de plongement hébergé en a trouvé le plus. Mais sur 48 questions, une seule différence était claire. J’ai donc recommandé de mesurer à nouveau avec de vraies questions d’utilisateurs.
Allez plus loin : ajoutez 50 questions d’un vrai forum et étiquetez-les de la même façon. Essayez une seconde taille de segment avec une taille de contexte égale, comme dans Découper de façon réfléchie. Retirez les pages fileformat2 en double et mesurez le changement. Étiquetez chaque page avec la version qu’elle décrit, et excluez des résultats les pages sur la version 2.
Vérification des connaissances
Section intitulée « Vérification des connaissances »Vérifiez votre compréhension
Sur les politiques de Larkfield, la recherche hybride avec e5 obtenait un score inférieur à e5 seul. Ici, elle fait mieux. Expliquez pourquoi les deux résultats peuvent être vrais et ce que Felix devrait conclure.
Afficher la réponse
La recherche hybride additionne les votes de deux listes. Elle aide quand les deux méthodes échouent sur des questions différentes et que les deux listes sont raisonnables. C’est le cas ici : BM25 trouve des noms exacts qu’e5 manque (-bail), et e5 trouve des paraphrases. Elle nuit quand une liste est faible pour beaucoup de questions et que ses mauvais classements font descendre les bons résultats. C’est arrivé avec les questions en français du jeu de Larkfield, et avec embed-small ici (0,917 → 0,833). Felix devrait conclure qu’aucune méthode ne gagne partout et mesurer les résultats sur ses propres questions avant la mise en production.
Votre réponse contient-elle les points principaux de la nôtre ?
Connectez-vous et inscrivez-vous au cours pour enregistrer vos réponses. Chaque vérification compte pour le certificat.
Vérifiez votre compréhension
Le modèle hébergé obtient un hit@5 de 0,917 et le modèle de reclassement, de 0,875. Dana demande si cela prouve que le modèle hébergé est meilleur. Que répondez-vous?
Afficher la réponse
Pas sur 48 questions. La différence nette est de 2 questions. Le modèle hébergé trouve 5 questions que le modèle de reclassement manque, et ce dernier en trouve 3 que l’autre manque. Un intervalle obtenu par bootstrap pour la différence va de −0,062 à +0,146; il inclut donc 0. La décision devrait aussi tenir compte des coûts. Le modèle hébergé envoie chaque question à un fournisseur, et le modèle de reclassement prend environ 0,8 seconde par question. Ajoutez d’autres questions réelles, étiquetez-les de la même façon et mesurez de nouveau.
Votre réponse contient-elle les points principaux de la nôtre ?
Connectez-vous et inscrivez-vous au cours pour enregistrer vos réponses. Chaque vérification compte pour le certificat.
Vérifiez votre compréhension
La réponse enregistrée à la question « database is locked » (la base de données est verrouillée) réussit toutes les vérifications des citations. Nommez deux raisons pour lesquelles elle reste une mauvaise réponse, et un changement qui corrigerait la cause.
Afficher la réponse
Premièrement, une de ses sources décrit SQLite version 2, et non 3.53.4. Deuxièmement, ses conseils concernent l’interface Tcl, que l’utilisateur n’a jamais mentionnée. La cause est la récupération. Les sections sur PRAGMA busy_timeout et sqlite3_busy_timeout() ne figuraient pas parmi les 5 premiers résultats. Le modèle ne pouvait donc pas les utiliser. Une solution : étiquetez chaque page avec la version qu’elle décrit et excluez les pages de la version 2 des résultats. Une autre : comparez les méthodes sur ce type de question. Pour la question similaire D19 du jeu, la recherche hybride e5 classe une section pertinente au 2e rang. Le modèle de reclassement la place au 14e rang. Dans tous les cas, affichez la page et la version avec chaque affirmation pour qu’une personne puisse la juger.
Votre réponse contient-elle les points principaux de la nôtre ?
Connectez-vous et inscrivez-vous au cours pour enregistrer vos réponses. Chaque vérification compte pour le certificat.
Récapitulatif
- Sur 195 pages de documentation SQLite et 48 questions évaluées, le modèle de plongement hébergé seul a trouvé le plus de réponses (hit@5 de 0,917). La meilleure méthode locale était la recherche hybride e5 avec reclassement (0,875). La recherche par mots-clés seule a obtenu 0,708.
- La recherche hybride a aidé e5 et nui à embed-small. La plupart des écarts entre les méthodes fortes étaient de 1 à 3 questions : ce n’est pas une preuve.
- Regrouper les meilleurs résultats de chaque méthode et les lire a permis de trouver 40 passages pertinents manqués par les premières étiquettes.
- Une réponse avec citations peut réussir toutes les vérifications et quand même provenir de la mauvaise version ou interface. Citez la version et ne présentez pas les réponses comme du soutien officiel.
Ensuite, la dernière étude de cas ajoute la dimension du temps : répondre à partir de règlements qui changent. Il faut citer la version en vigueur à une date donnée.
Leçon suivante : Répondre à partir de règlements versionnés