Mises à jour et suppressions
- Leçon 16
- 50 min
- Module 6 : Maintenir et protéger la base de connaissances
Leçon 16 sur 18 · RAG : créer une IA qui utilise vos donnéesMises à jour et suppressions
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
Gardez l’index conforme à la collection pendant que les documents changent. Lisez seulement les fichiers modifiés, retirez les anciennes versions selon leurs dates et refusez les doublons. Faites disparaître un document supprimé de la recherche et des réponses.
Avant de commencerCe qu’il faut savoir et avoir sous la main
Ce que vous devez savoir
- Les identifiants stables des segments, les dates d’entrée en vigueur et les étiquettes d’accès, vus dans Conserver les métadonnées.
- Le filtre de date, vu dans Recherche lexicale, dense et hybride.
- Les réponses enregistrées et la vérification de leurs citations, vues dans Répondre et citer.
Ce qu’il vous faut sur votre ordinateur
- Le projet à la fin du module 5 (l’instantané
end-of-m05).python -m pytestaffiche77 passed, 1 deselected(77 tests réussis, 1 exclu). - Un index créé avec
python -m policy_assistant ingest, et un terminal dans~/projects/policy-assistantavec.venvactif.
Aucun appel de modèle et aucun compte : les réponses viennent des enregistrements. Testé avec Python 3.12.13 sur macOS (Apple silicon). Les commandes Windows ne sont pas testées.
Une bibliothèque qui tient son catalogue à jour
Section intitulée « Une bibliothèque qui tient son catalogue à jour »Une bibliothèque reçoit de nouveaux livres chaque semaine. La bibliothécaire ne refait pas tout le catalogue chaque fois. Elle compare la livraison au catalogue. Un nouveau livre reçoit une fiche, et une nouvelle édition remplace l’ancienne fiche. Un livre inchangé ne demande aucun travail.
Retirer un livre est plus difficile qu’il n’y paraît. Le livre quitte le rayon. Mais sa fiche reste au catalogue, il reste dans la liste des « nouveautés », et les notes d’un lecteur le citent encore. Tant que toutes les copies de la référence ne sont pas supprimées, les gens continuent de demander ce livre. Pourtant, la bibliothèque ne l’a plus.
Le problème : la recherche trouve encore un document supprimé
Section intitulée « Le problème : la recherche trouve encore un document supprimé »La commande ingest du module 5 reconstruit tout l’index chaque fois. Elle supprime chaque ligne, puis analyse, découpe et transforme de nouveau les 36 documents en plongements. C’est simple et toujours correct. Sur le Mac du cours, cela a pris 2.09 s, avec le modèle de plongement déjà chargé. Une collection de 36 000 documents prendrait environ mille fois plus de temps, pour chaque petite modification.
Mei écrit donc la version plus rapide qui semble évidente. Pour chaque fichier du dossier, elle ignore ceux que l’index contient déjà et lit ceux qui sont nouveaux ou modifiés. C’est rapide. Puis l’équipe People déplace les règles de rabais du personnel vers son propre système. Elle demande à Grace de retirer staff-discount-and-perks.md de la collection du service de soutien. Mei supprime le fichier et lance sa synchronisation. Voici une version construite de ce code, exécutée sur une copie de la collection (reference/c09/m06/naive_incremental.py) :
NaiveStore: after deleting staff-discount-and-perks.md: 0 added, 0 updated, 35 unchanged, 0 removed | chunks: +0 -0 chunks in the index: 185; keyword search for 'What is the staff discount?': ['[f02ee0910bbf] staff-discount-and-perks', '[c13d27947ed1] staff-discount-and-perks']Rien n’a échoué, et le rapport semble rassurant : 35 fichiers inchangés. Mais la synchronisation regarde seulement les fichiers qui existent. Elle ne remarque donc jamais un fichier disparu. L’index contient encore les 185 segments, et la recherche renvoie encore le document supprimé en premier. C’est une des idées fausses contre lesquelles ce cours vous met en garde : laisser le contenu supprimé accessible par la recherche. Le fichier a disparu, alors les gens croient que le texte a disparu. Ce n’est pas le cas.
L’idée : comparer les empreintes et supprimer partout
Section intitulée « L’idée : comparer les empreintes et supprimer partout »La correction comporte deux parties.
La première consiste à reconnaître ce qui a changé. Quand ingest lit un fichier, il conserve son empreinte de contenu : l’empreinte SHA-256 de ses octets. C’est la même fonction de hachage qui produit les identifiants des segments. Au prochain passage, il recalcule l’empreinte de chaque fichier et compare les deux listes. C’est comme la bibliothécaire qui compare la livraison au catalogue. Chaque fichier correspond à l’un de ces quatre cas :
- Nouveau (aucune ligne pour ce fichier) : l’analyser, le découper, créer ses plongements et l’ajouter.
- Modifié (une empreinte différente) : supprimer d’abord les anciennes lignes, puis ajouter de nouveau le fichier.
- Inchangé (la même empreinte) : l’ignorer. Rien n’est analysé ni transformé en plongements.
- Disparu (une ligne, mais aucun fichier) : le supprimer.
C’est l’ingestion incrémentale : chaque exécution fait seulement le travail nécessaire pour les changements. Mei avait oublié le quatrième cas.
La deuxième partie concerne le sens de « supprimer ». Un document existe à plusieurs endroits : sa ligne dans documents, ses segments, leurs lignes de mots-clés et leurs vecteurs. Tout processus en cours peut aussi garder des copies en mémoire. Des réponses qui le citent peuvent aussi être stockées quelque part. Une suppression est complète seulement quand tous ces endroits ont oublié le document.
Un petit exemple détaillé : un fichier modifié
Section intitulée « Un petit exemple détaillé : un fichier modifié »Prenez la politique sur les cartes-cadeaux. Comparez d’abord l’empreinte du fichier à celle que l’index a conservée au dernier ingest :
from pathlib import Pathfrom policy_assistant.store import Store, file_hashfile_hash(Path("corpus/documents/gift-cards.md"))[:12][d["content_hash"][:12] for d in Store("index.sqlite").documents() if d["doc_id"] == "gift-cards"]'dbfb9792f883'['dbfb9792f883']Les deux sont égales, alors ingest ignore ce fichier. Grace corrige maintenant une phrase dans Utiliser une carte-cadeau : « votre compte » devient « votre compte Larkfield ». La nouvelle empreinte est 7b83eafaf8b6. Un seul mot modifié suffit à changer toute l’empreinte, alors ingest voit le changement :
0 added, 1 updated, 35 unchanged, 0 removed | chunks: +3 -3 updated: documents/gift-cards.mdindex index.sqlite: 36 documents, 185 chunks | chunker structure | embeddings intfloat/multilingual-e5-smallIl a supprimé les 3 anciens segments, avec leurs lignes de mots-clés et leurs vecteurs, puis en a ajouté 3 nouveaux. Comparez les identifiants des segments avant et après :
| Segment | Avant | Après | Pourquoi |
|---|---|---|---|
| #0 Acheter une carte-cadeau | 8c4bc4299042, caractères 12–125 |
8c4bc4299042, caractères 12–125 |
Même version, même position : même identifiant |
| #1 Utiliser une carte-cadeau | f27bb50ce8b7, 127–230 |
76f2d13b502f, 127–240 |
La phrase compte 10 caractères de plus |
| #2 Cartes perdues et retours | 52ad3a57c1d1, 232–424 |
6c36ce3a91a6, 242–434 |
Sa position s’est déplacée de 10 caractères |
Les identifiants des segments viennent du document, de la version et de la position. La section modifiée et la suivante ont donc reçu de nouveaux identifiants. Une ancienne réponse qui cite f27bb50ce8b7 cite maintenant un segment inexistant, et la vérification des citations le signale. C’est correct : le texte cité a réellement changé.
Toute la vie d’un document, du premier ingest à la dernière vérification, ressemble à ceci :
Description textuelle du diagramme
Six étapes en deux groupes. Le premier groupe est « Dans l’index ». Étape 1, Publié : un nouveau fichier dans corpus/documents. Étape 2, Ingéré : son empreinte est enregistrée, et ses segments, lignes de mots-clés et vecteurs sont ajoutés. Étape 3, En vigueur : à partir de sa date effective_from, la recherche le renvoie. Une flèche pointillée va de l’étape 3 à l’étape 2 : une correction donne une nouvelle empreinte au fichier. Il est donc ingéré de nouveau. Quand la version suivante entre en vigueur, le document passe au deuxième groupe, « Vers la sortie ». Étape 4, Retiré selon la date : après sa date effective_to, il reste dans l’index, mais le filtre de date l’exclut. Étape 5, Supprimé : le fichier est retiré, et ingest supprime chaque ligne créée à partir de celui-ci. Étape 6, Vérifié : aucune réponse, aucun cache ni processus en cours ne l’utilise encore.
L’index de Larkfield : retirer selon la date, supprimer par décision
Section intitulée « L’index de Larkfield : retirer selon la date, supprimer par décision »Retirer une version ne demande aucune suppression
Section intitulée « Retirer une version ne demande aucune suppression »Le 1 novembre 2026, la version 4 de la politique de retour remplace la version 3. Personne n’a besoin de toucher à l’index ce jour-là. La version 3 a effective_to: 2026-10-31, alors le filtre de date du module 3 la retire à minuit :
python -m policy_assistant search "Can a customer return an unused item?" --method bm25 --k 2 --as-of 2026-10-311. 11.6078 [7839ded2d52b] returns-policy v3 | Return window | public Return window You can return an unused item within 30 days of delivery for a full refund of the ite…2. 10.9722 [c236034e24d2] help-centre-faq v7 | How do I return an item? | public How do I return an item? Go to Orders in your account, choose the item and select Return an item. O…bm25, top 2, as of 2026-10-31, audience staffAvec --as-of 2026-11-01, le premier résultat est [963dae4229eb] returns-policy v4 | Return window (délai de retour : « dans les 45 jours »). L’article d’aide reste deuxième. La version 3 doit rester dans l’index. Comment les politiques de Larkfield sont gérées indique que l’ancienne version reste dans les archives. Il précise aussi qu’un retour suit la version en vigueur à la date de livraison. En décembre, un agent posera encore une question sur une commande livrée le 20 octobre. Seule la version 3 y répond.
La règle est donc simple. Une nouvelle version reçoit son propre fichier, un nouveau numéro de version et sa valeur effective_from. L’ancienne version reçoit une valeur effective_to. Supprimez une version seulement quand aucune question encore ouverte ne peut en avoir besoin.
Supprimer un document
Section intitulée « Supprimer un document »Le document sur le rabais du personnel est différent : l’équipe People veut le retirer de la collection. Avec le nouveau ingest du projet, la suppression atteint l’index :
0 added, 0 updated, 35 unchanged, 1 removed | chunks: +0 -2 removed: documents/staff-discount-and-perks.mdindex index.sqlite: 35 documents, 183 chunks | chunker structure | embeddings intfloat/multilingual-e5-smallLa recherche par mots-clés renvoie maintenant Utiliser un code de rabais en premier. La commande chunks staff-discount-and-perks répond No chunks for staff-discount-and-perks (aucun segment pour staff-discount-and-perks). Posez maintenant la question que les enregistrements connaissent :
python -m policy_assistant ask Q51Question (date 2026-10-09): What is the staff discount?Passages: 094a8535171c, 1b1c047750bf, d753fb02bc8c, b16f983ce250, a559fb986971 (568 tokens, estimated)Note: Recorded with passages c13d27947ed1, f02ee0910bbf, 094a8535171c, 1b1c047750bf, d753fb02bc8c; yours: 094a8535171c, 1b1c047750bf, d753fb02bc8c, b16f983ce250, a559fb986971. The recorded answer is replayed; its citations are checked against your passages.Answer (answerable): The staff discount is 20% off all products except gift cards, on up to $2,000 of purchases per calendar year. It cannot be combined with other promotions or discount codes. - The discount is 20% off all products except gift cards, and applies to at most $2,000 of purchases per calendar year. [c13d27947ed1] CHECK: missing_id:c13d27947ed1 - The staff discount cannot be combined with other promotions or discount codes. [c13d27947ed1] CHECK: missing_id:c13d27947ed1gpt-6-luna-2026-09-22 | 951 tokens in, 127 out | 1.416 sLa recherche ne trouve plus le document, mais la réponse dit encore « 20 % de rabais ». Le simulateur rejoue la réponse donnée plus tôt par chat-small (gpt-6-luna sur Azure), quand le document existait. Dans ce projet, c’est ainsi que fonctionne le simulateur. Dans un véritable assistant, la même chose arrive avec un cache de réponses. Ce stockage conserve les réponses précédentes pour économiser du temps et de l’argent. Un cache qui trouve les réponses seulement par le texte de la question fournit du texte supprimé à la prochaine personne. Ici, la vérification des citations le détecte (missing_id), mais seulement parce que chaque affirmation cite sa source.
La nouvelle commande audit examine donc chaque réponse enregistrée. Elle énumère chaque citation d’un passage que l’index ne fournit plus pour cette question. Le passage est supprimé, ou n’est pas en vigueur à la date de la question :
Q51 chat-small rerank answer_v1: [c13d27947ed1] removed from the indexQ51 chat-small bm25 answer_v1: [c13d27947ed1] removed from the indexQ51 chat-strong rerank answer_v1: [c13d27947ed1] removed from the indexQ51 chat-strong rerank answer_v1: [f02ee0910bbf] removed from the indexQ51 chat-strong bm25 answer_v1: [c13d27947ed1] removed from the indexQ51 chat-strong bm25 answer_v1: [f02ee0910bbf] removed from the index268 recorded answers | 6 citations to passages that are removed, not in force or not allowedCes quatre réponses à Q51 sont celles à retirer de tout cache de réponses. Un autre endroit garde le souvenir du document : le fichier inventory.csv de Grace. inventory contient encore staff-discount-and-perks, parce que personne n’a modifié la liste. Le schéma rassemble tous les endroits et montre ce que chaque synchronisation a fait :
Description textuelle du diagramme
Un tableau de six lignes pour le fichier supprimé staff-discount-and-perks.md. Ses deux colonnes sont une synchronisation qui ajoute et met à jour seulement, et l’ingest du projet. Ligne 1, le dossier corpus/documents : le fichier a disparu dans les deux colonnes. Ligne 2, les tables documents et chunks de l’index : la première synchronisation n’a rien supprimé et contient encore 185 segments. Elle ne cherche jamais les fichiers disparus. L’ingest du projet indique 1 suppression et 2 segments de moins, donc 183 segments. Ligne 3, l’index de mots-clés et les vecteurs sur disque : avec la première synchronisation, « Quel est le rabais du personnel? » trouve encore f02ee0910bbf et c13d27947ed1 en premier. Avec le projet, les lignes sont supprimées avec les segments. Le premier résultat est promotions-and-discount-codes. Ligne 4, la mémoire d’un processus qui continue de fonctionner : avec le code du module 5, la recherche vectorielle renvoyait encore c13d27947ed1 à partir des vecteurs en mémoire. Le projet vérifie la version de l’index avant chaque recherche et recharge la mémoire. Ligne 5, les réponses enregistrées, qui fonctionnent comme un cache de réponses : Q51 rejoue encore « 20 % de rabais sur tous les produits » dans les deux colonnes. audit trouve 6 citations de segments supprimés, et ces réponses doivent être retirées. Ligne 6, le fichier inventory.csv de Grace : il contient encore le document dans les deux colonnes; le mettre à jour à la main.
Doublons : une version de document, un fichier
Section intitulée « Doublons : une version de document, un fichier »Un doublon est le même contenu stocké deux fois. Dans ce projet, il prend trois formes.
- Le même fichier deux fois. Quelqu’un enregistre
gift-cards-copy.mdà côté degift-cards.md. Les deux indiquent qu’ils sont la version 1 degift-cards.ingestrefuse, et l’index reste inchangé :Nothing changed in the index. documents/gift-cards-copy.md and documents/gift-cards.md are both gift-cards version 1. Keep one file per document version; a new version needs a new version number.(Rien n’a changé dans l’index. Les deux fichiers sont la version 1 de gift-cards. Gardez un fichier par version de document; une nouvelle version exige un nouveau numéro.) Sans cette vérification, les deux copies se disputeraient une place parmi les 5 premiers résultats à chaque recherche. - Un fichier renommé. Mei renomme
gift-cards.mdengift-cards-2025.md.ingestsupprime d’abord les fichiers disparus, puis ajoute le nouveau nom :1 added, 0 updated, 35 unchanged, 1 removed | chunks: +3 -3(1 ajouté, 0 mis à jour, 35 inchangés, 1 supprimé; segments : +3 -3). Les identifiants des segments restent les mêmes. Ils viennent du document, de la version et de la position, pas du nom de fichier. - Des paragraphes presque identiques dans différents documents. « Comment commencer un retour » apparaît dans quatre documents. Chacun est une véritable source avec son propre responsable, alors l’index garde les quatre. Assembler le contexte élimine les répétitions quand les passages entrent dans une même requête (prompt). Deux versions d’un document ne sont jamais fusionnées : leurs dates diffèrent, et la réponse doit préciser celle qu’elle utilise.
Erreur courante
Le serveur qui connaît encore le texte supprimé
Symptôme : l’assistant fonctionne comme un service : un processus Python qui répond aux questions toute la journée. Dans un autre terminal, Mei supprime le fichier du rabais du personnel et lance ingest. Le service répond encore à « Quel est le rabais du personnel? » à partir des segments supprimés. Voici une exécution réelle avec le code du module 5 (reference/c09/m06/running_process.py) :
end-of-m05: before: dense [c13d27947ed1] staff-discount-and-perks, [f02ee0910bbf] staff-discount-and-perksanother process: 35 documents, 183 chunks (rebuilt from scratch)end-of-m05: after: dense [c13d27947ed1] staff-discount-and-perks, [f02ee0910bbf] staff-discount-and-perksend-of-m05: after: bm25 [ea0bff365b2c] promotions-and-discount-codes, [f78646d93435] policy-governanceCause : pour gagner du temps, le service charge tous les vecteurs et segments en mémoire une seule fois. La recherche par mots-clés interroge SQLite chaque fois, alors elle voit la suppression. La recherche vectorielle utilise la copie en mémoire, qui contient encore les vecteurs supprimés. La mémoire est un cache, et personne ne l’a averti que l’index avait changé.
Correction : vérifiez la version de l’index avant chaque recherche, et rechargez la mémoire quand elle a changé. SQLite compte les changements effectués par les autres connexions (PRAGMA data_version). Le nouveau store.py combine ce compte avec celui de ses propres écritures dans Store.generation(), et search.py l’utilise. Avec l’instantané end-of-m06, la même exécution renvoie deux segments de privacy-policy après la suppression. Le test test_a_running_assistant_sees_the_deletion garantit ce comportement.
Pour un véritable assistant : énumérez tous les caches avant de faire confiance à une suppression. Par exemple : vecteurs en mémoire, caches de réponses, résultats de recherche conservés par un serveur Web et copies sur d’autres machines. Chacun a besoin d’une règle qui indique quand le recharger.
Quand l’ingestion incrémentale vaut la peine, et ce qu’elle coûte
Section intitulée « Quand l’ingestion incrémentale vaut la peine, et ce qu’elle coûte »Sur le Mac du cours, un deuxième ingest sans changement a pris 2 ms. Un document modifié a pris 28.4 ms. Une reconstruction complète a pris 2.09 s. Avec 36 documents, les deux sont rapides. L’écart compte quand la collection grandit, ou quand les plongements viennent d’un service payant. Chaque reconstruction paie de nouveau pour chaque segment.
Le coût, c’est davantage de cas à traiter correctement. Les renommages, doublons, suppressions et processus en cours ont chacun demandé du code et un test ici. Un changement d’outil de découpage ou de modèle de plongement ne peut pas être incrémental. Les vecteurs de deux modèles ne peuvent pas être mélangés. Alors ingest le refuse, et ingest --rebuild crée un nouvel index.
Utilisez l’ingestion incrémentale quand les documents changent souvent et que la collection est grande. Gardez la reconstruction complète pour les petites collections et après un changement d’outil de découpage ou de modèle. Utilisez-la aussi comme vérification régulière : un index reconstruit doit donner les mêmes identifiants de segments et les mêmes mesures.
Exercice guidé : ajouter l’ingestion incrémentale
Section intitulée « Exercice guidé : ajouter l’ingestion incrémentale »-
Copiez le nouveau code d’indexation, le code de recherche, la ligne de commande et les tests du stockage depuis l’instantané :
Fenêtre de terminal cp ../nextia-learning-labs/C09/snapshots/end-of-m06/policy_assistant/store.py policy_assistant/cp ../nextia-learning-labs/C09/snapshots/end-of-m06/policy_assistant/search.py policy_assistant/cp ../nextia-learning-labs/C09/snapshots/end-of-m06/policy_assistant/__main__.py policy_assistant/cp ../nextia-learning-labs/C09/snapshots/end-of-m06/tests/test_store.py tests/Fenêtre de terminal Copy-Item ..\nextia-learning-labs\C09\snapshots\end-of-m06\policy_assistant\store.py policy_assistant\Copy-Item ..\nextia-learning-labs\C09\snapshots\end-of-m06\policy_assistant\search.py policy_assistant\Copy-Item ..\nextia-learning-labs\C09\snapshots\end-of-m06\policy_assistant\__main__.py policy_assistant\Copy-Item ..\nextia-learning-labs\C09\snapshots\end-of-m06\tests\test_store.py tests\Le nouveau
__main__.pycomprend aussi--prompt,auditetinfo. Les deux prochaines leçons les utilisent. -
Ouvrez
policy_assistant/store.pyet trouvezsync. Repérez les quatre cas : supprimé, inchangé, modifié et nouveau. -
Exécutez les tests. Vous voyez
83 passed, 1 deselected(83 tests réussis, 1 non sélectionné) :Fenêtre de terminal python -m pytest -
Mettez l’index à jour. Votre index du module 5 contient déjà une empreinte pour chaque fichier :
Fenêtre de terminal python -m policy_assistant ingestSortie 0 added, 0 updated, 36 unchanged, 0 removed | chunks: +0 -0index index.sqlite: 36 documents, 185 chunks | chunker structure | embeddings intfloat/multilingual-e5-small -
Dans VS Code, ouvrez
corpus/documents/gift-cards.md. Remplacez « in your account » (dans votre compte) par « in your Larkfield account » (dans votre compte Larkfield), puis enregistrez. -
Exécutez
ingest, puischunks gift-cards. Vous voyez1 updated | chunks: +3 -3(1 mis à jour | segments : +3 -3) et les nouveaux identifiants76f2d13b502fet6c36ce3a91a6, comme dans l’exemple détaillé. -
Rétablissez le fichier d’origine et exécutez de nouveau
ingest:Fenêtre de terminal cp ../nextia-learning-labs/C09/corpus/documents/gift-cards.md corpus/documents/python -m policy_assistant ingestFenêtre de terminal Copy-Item ..\nextia-learning-labs\C09\corpus\documents\gift-cards.md corpus\documents\python -m policy_assistant ingestchunks gift-cardsaffiche de nouveauf27bb50ce8b7et52ad3a57c1d1: le même texte donne les mêmes identifiants. -
Supprimez le document sur le rabais du personnel et mettez l’index à jour :
Fenêtre de terminal rm corpus/documents/staff-discount-and-perks.mdpython -m policy_assistant ingestFenêtre de terminal Remove-Item corpus\documents\staff-discount-and-perks.mdpython -m policy_assistant ingestVous voyez
1 removed | chunks: +0 -2(1 supprimé | segments : +0 -2). -
Cherchez-le avec des mots-clés :
Fenêtre de terminal python -m policy_assistant search "What is the staff discount?" --method bm25 --k 3Le premier résultat est
[ea0bff365b2c] promotions-and-discount-codes v2 | Using a discount code(utiliser un code de rabais). Aucun résultat ne vient du document supprimé. -
Exécutez
ask Q51, puisaudit. Vous voyez la réponse enregistrée « 20 % de rabais » avecmissing_id(identifiant manquant), et6 citations to passages that are removed(6 citations de passages supprimés). -
Rétablissez le document et vérifiez que tout est comme avant :
Fenêtre de terminal cp ../nextia-learning-labs/C09/corpus/documents/staff-discount-and-perks.md corpus/documents/python -m policy_assistant ingestpython -m policy_assistant auditFenêtre de terminal Copy-Item ..\nextia-learning-labs\C09\corpus\documents\staff-discount-and-perks.md corpus\documents\python -m policy_assistant ingestpython -m policy_assistant auditSortie 1 added, 0 updated, 35 unchanged, 0 removed | chunks: +2 -0added: documents/staff-discount-and-perks.mdindex index.sqlite: 36 documents, 185 chunks | chunker structure | embeddings intfloat/multilingual-e5-small268 recorded answers | 0 citations to passages that are removed, not in force or not allowed
Si ingest affiche Nothing changed in the index (rien n’a changé dans l’index), une version de document figure deux fois dans corpus/documents. Supprimez la copie et exécutez de nouveau ingest. Si ingest signale un autre outil de découpage ou modèle de plongement, exécutez python -m policy_assistant ingest --rebuild.
À vous : renommez corpus/documents/gift-cards.md en gift-cards-2025.md et prédisez le rapport de ingest avant de l’exécuter. Rétablissez ensuite le nom d’origine.
Afficher la réponse
1 added, 0 updated, 35 unchanged, 1 removed | chunks: +3 -3 (1 ajouté, 0 mis à jour, 35 inchangés, 1 supprimé | segments : +3 -3), avec added: documents/gift-cards-2025.md (ajouté) et removed: documents/gift-cards.md (supprimé). Les identifiants des segments ne changent pas, car le nom du fichier n’en fait pas partie. Rétablir le nom d’origine donne le même rapport, avec les deux noms inversés.
Vérifiez votre compréhension
La première synchronisation de Mei ignorait les fichiers inchangés et ajoutait les nouveaux. Pourquoi un fichier supprimé restait-il accessible par la recherche? Pourquoi le rapport ne signalait-il aucun problème?
Afficher la réponse
La synchronisation parcourait les fichiers du dossier. Un fichier supprimé n’est plus dans le dossier. La boucle ne le traitait donc jamais, et ses lignes restaient dans toutes les tables. Le rapport comptait seulement les fichiers qu’il voyait : 35 inchangés, 0 supprimé. Pour trouver les suppressions, comparez aussi dans l’autre sens : supprimez chaque document de l’index dont le fichier a disparu.
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
Prédisez : le 2 novembre 2026, Grace devrait-elle supprimer returns-policy.v3.md de la collection? Quel problème cela causerait-il?
Afficher la réponse
Non. Le filtre de date écarte déjà la version 3 pour les questions datées du 1er novembre ou après. Mais les retours suivent la version en vigueur à la date de livraison. Un agent posera encore des questions sur des commandes livrées en octobre, comme Q22 (livrée le 20 octobre). Sans la version 3, la recherche trouverait seulement la version 4, et l’assistant répondrait 45 jours plutôt que 30. Supprimez une version seulement quand aucune question en suspens ne peut en avoir besoin.
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
Après la suppression, ask Q51 affichait encore « 20 % de rabais ». Quelle partie du système était en cause? Comment corriger ce problème dans un véritable assistant?
Afficher la réponse
L’index était correct : la recherche ne retournait aucun passage sur le rabais du personnel. La réponse stockée posait problème. Le simulateur rejoue un enregistrement trouvé à partir de la question, comme un cache de réponses indexé par le texte de la question. Dans un véritable assistant, supprimez les réponses en cache qui citent un segment supprimé, comme celles que audit liste. Vous pouvez aussi inclure les identifiants des passages dans la clé du cache. La vérification des citations (missing_id) est une dernière mesure de protection, pas la correction.
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
- L’ingestion incrémentale compare l’empreinte du contenu de chaque fichier à celle qui est stockée. Elle relit les fichiers nouveaux et modifiés, et ignore les fichiers inchangés. Elle supprime les documents dont le fichier a disparu. Un deuxième
ingesta pris 2 ms plutôt que 2.09 s. - Une suppression doit atteindre chaque copie : les tables, l’index par mots-clés, les vecteurs, la mémoire des processus actifs, les caches de réponses et l’inventaire. Une synchronisation qui ne faisait qu’ajouter et mettre à jour laissait le rabais du personnel supprimé en premier dans la recherche.
- Retirer une version du service relève du filtre de date : la version 3 de la politique de retour reste dans l’index pour les livraisons avant le 1er novembre.
- Une version de document provient d’un seul fichier : les copies sont refusées, et les fichiers renommés sont déplacés. Les quasi-doublons dans différents documents sont traités lors de l’assemblage du contexte.
auditliste les réponses enregistrées qui citent des passages supprimés ou périmés. La vérification des citations les détecte aussi, mais seulement comme dernier garde-fou.
Votre projet contient maintenant le store.py incrémental. Ensuite, les étiquettes d’accès : qui peut voir quel passage.
Leçon suivante : Autorisations et isolation