درس 11 — Rag engine sync

06. Synchro et exploitation

5 دقائق قراءة

هذا المحتوى غير مترجم بعد. تُعرض النسخة الأصلية.

Le but : comprendre exactement ce que fait la synchro, la régler, la surveiller, et savoir quoi faire quand quelque chose cloche.


1. Une passe de synchro, pas à pas

Le job rag-kit-sync exécute python sync_job.py (fichier app/kit.py, fonction run_sync) :

  1. Lit la liste des dossiers dans gs://<bucket>/config.json.
  2. Pour chaque dossier : lit le dossier lui-même (s'il est illisible → avertissement, et aucune suppression pendant cette passe), puis liste tous ses fichiers, sous-dossiers compris (hors corbeille).
  3. Liste les fichiers déposés (gs://<bucket>/uploads/).
  4. Souhaité = (2) + (3). Présent = fichiers du corpus, chacun identifié par son ID Drive ou son URI gs://.
  5. Supprime du corpus ce qui est présent mais plus souhaité.
  6. Importe, avec les mêmes réglages (découpage 512/100, layout parser) :
    • Drive : seulement les fichiers nouveaux ou modifiés dans Drive depuis leur dernière indexation (date modifiedTime de Drive comparée à la date d'indexation du corpus), par lots de 25. Raison (vérifiée) : RAG Engine réimporte tout fichier Drive à chaque import, même inchangé ; sans ce filtre, chaque passe re-parserait (et refacturerait) tout le dossier.
    • Dépôts : le préfixe uploads/ entier ; là, RAG Engine ignore lui-même l'inchangé (vérifié).
  7. Contrôle : un dossier dont aucun fichier n'est dans le corpus → « Le dossier est-il partagé avec l'agent RAG ? ».
  8. Écrit le rapport gs://<bucket>/sync/last.json (lu par l'interface) ; le détail par fichier est dans gs://<bucket>/sync/runs/<horodatage>-<n>.ndjson (gardé 30 jours).

Un seul import à la fois par corpus (vérifié : sinon FailedPrecondition: There are other operations running). Chaque action (dépôt, suppression, dossier, bouton) lance une nouvelle exécution du job, même si une autre tourne. Une passe qui trouve le corpus occupé attend 15 s et recommence entièrement (listing frais), jusqu'à 15 min : la dernière passe lancée voit donc toujours le dernier état, sans rapport écrasé (statut occupe non écrit). (Une première version posait une demande « à refaire » pendant la passe : elle se perdait quand la passe finissait au même instant — vérifié en test navigateur, d'où ce choix plus simple.)

2. Quand elle tourne

DéclencheurDélai
Cloud Scheduler rag-kit-syncSYNC_SCHEDULE (défaut toutes les 10 min, fuseau Europe/Paris)
Ajout/retrait d'un dossier, dépôt ou suppression d'un fichier dans l'interfaceimmédiat
Bouton « Synchroniser maintenant »immédiat
À la maingcloud run jobs execute rag-kit-sync --region=europe-west4 --wait

Changer la fréquence : modifiez SYNC_SCHEDULE dans le .env, rechargez (source scripts/config.sh …) puis terraform apply (ou relancez deployer_shell.sh). Une passe sans changement coûte quelques secondes de Cloud Run et de listing ; toutes les 5 min est raisonnable, toutes les minutes non (passes qui se chevauchent).

Mettre en pause : gcloud scheduler jobs pause rag-kit-sync --location=europe-west4 (et resume).

3. Surveiller

# Le dernier rapport
gcloud storage cat gs://$BUCKET/sync/last.json

# Les 5 dernières exécutions du job et leur état
gcloud run jobs executions list --job=rag-kit-sync --region=$REGION --limit=5

# Les journaux d'une passe (le rapport JSON est la dernière ligne)
gcloud logging read 'resource.type="cloud_run_job" AND resource.labels.job_name="rag-kit-sync"' --limit=20 \
  --format='value(textPayload)'

# Les fichiers en échec de la dernière passe
gcloud storage cat "gs://$BUCKET/sync/runs/*.ndjson" | grep -v '"Status": "OK"'

Alerte conseillée : dans Cloud Monitoring, une alerte sur les exécutions en échec du job (run.googleapis.com/job/completed_execution_count avec result = failed).

4. Opérations courantes

BesoinComment
Tout réindexer (après changement de parsing, par exemple)Supprimer les fichiers du corpus puis synchroniser : la passe réimporte tout. Avec Terraform : terraform apply -replace=google_vertex_ai_rag_corpus.docs (nouveau corpus vide) puis « Synchroniser »
Changer le modèle de réponseMODEL / MODEL_LOCATION dans le .env puis apply : pas de réindexation
Changer le modèle d'embeddingsImpossible sur un corpus existant : nouveau corpus (-replace, voir au-dessus)
Désactiver le layout parserLAYOUT_PARSER=false puis apply ; tout est réindexé à la passe suivante
Ajouter des collèguesUSERS="user:a@x.com group:equipe@x.com" puis apply
Mettre à jour le codeModifier app/… puis apply : nouvelle image (hachage du code), nouvelle révision

5. Limites

LimiteValeurAu-delà
Fichiers par dossier (listing complet à chaque passe)quelques milliersAPI changes de Drive (jeton stocké dans le bucket)
Taille d'un dépôt par l'interface30 MoMettre le fichier dans le dossier Drive
Durée d'une passe1 h (timeout du job)Plusieurs corpus, ou passes plus fréquentes
Conversationsen mémoire, 1 instanceBase de sessions (Cloud SQL) via SESSION_SERVICE_URI, puis plus d'instances
Décalage Drive → index≤ SYNC_SCHEDULEBouton « Synchroniser »

6. Sources « Google Drive connecté » (v2)

Pour un compte connecté (04-bis), la passe (fichier app/gdrive.py) :

  1. Prend le verrou de la source (locks/<source> dans le bucket : une seule passe à la fois par source, sinon deux canaux push seraient ouverts — vérifié).
  2. Incrémental : lit seulement les changements depuis le dernier jeton de page (changes.list), même sur un Drive entier. Complet (1re fois, changement de périmètre, une fois par jour, ou dossier déplacé en mode « dossiers ») : liste tout et réconcilie.
  3. Recopie le nouveau et le modifié dans gs://<bucket>/mirror/<source>/<fileId>/<nom> (Docs → .docx, Slides → .pptx, Sheets et Dessins → .pdf), supprime du miroir ce qui a disparu, est sorti du périmètre ou a été renommé.
  4. Ouvre ou renouvelle le canal push (changes.watch, 7 jours) si la source est en « auto ».

Puis la passe commune indexe uploads/ et mirror/ (RAG Engine saute l'inchangé) et retire du corpus ce qui n'est plus dans le miroir. Une source en panne (jeton expiré…) garde son miroir tel quel : rien n'est retiré de l'index.

Déclencheurs : notification push (TRIGGER=auto), planification (TRIGGER=auto, toutes les 5 min), bouton et actions de l'interface (TRIGGER=manuel). Une source dont l'« auto » est décochée n'est traitée qu'en manuel (vérifié : passe auto → document absent ; « Synchroniser maintenant » → présent).

État par source : gs://<bucket>/state/<source>.json (jeton de page, fichiers suivis, canal).

التالي