57 lines
3.8 KiB
Markdown
57 lines
3.8 KiB
Markdown
# Correctif nyora-convert-api : Heuristique text/vision fiabilisee & decoupage multi-lots sans troncature
|
|
|
|
**Instance auteur** : Gemini
|
|
**Date** : 2026-08-30
|
|
**Tags** : [nyora, convert-api, ocr, pdf, vision, bifrost, mimo-v2.5, runbook]
|
|
**Statut** : valide
|
|
|
|
---
|
|
|
|
## Contexte et Probleme
|
|
|
|
Dans le pipeline RAG de documents pedagogiques et professionnels (`yesmine-mp1-rag`, pack-mp1), l'API `nyora-convert-api` presentait deux bugs majeurs degradant severement la qualite d'ingestion :
|
|
|
|
1. **Bug 1 — Selection text/vision non fiable (`MIN_CHARS_NATIVE = 30`)** :
|
|
Le texte natif extrait d'un PDF etait considere exploitable des lors qu'il depassait 30 caracteres bruts, sans controle lexical ni qualite. Pour des scans avec une couche OCR corrompue/bruitee (ex: `Cours-Chimie-pt1-mp1.pdf`, `Cours-physique-mp1-pt1.pdf`), des milliers de caracteres parasites etaient envoyes au LLM en mode texte sans declencher le repli vision, conduisant a des transcriptions inexploitables ou a des rejets HTTP 422.
|
|
|
|
2. **Bug 2 — Troncature silencieuse a 45 000 caracteres et absence de decoupage multi-lots** :
|
|
La constante `MAX_INPUT_CHARS = 45000` tronquait silencieusement tout document de plus de ~15-20 pages avant l'envoi au LLM (sur 8 fichiers de test, seuls 13,6% a 79,1% du contenu reel etait conserve). De plus, le mode vision etait bride par `max_pages = 5`.
|
|
|
|
## Solution validee et Architecture
|
|
|
|
### 1. Heuristique d'evaluation de qualite du texte (`evaluate_text_quality`)
|
|
Remplacement du seuil de longueur fixe par une fonction d'analyse statistique et lexicale dans `app/extractors.py` :
|
|
- **Longueur minimale** : `>= 30` caracteres.
|
|
- **Ratio de caracteres alphabetiques** : `>= 52%`.
|
|
- **Taux de caracteres parasites OCR** (`±¥©®¢¤§¶¬~#|`\\_^{}[]<>±÷×`) : `< 6%`.
|
|
- **Ratio de vocabulaire reel reconnu** : `>= 12%` sur un dictionnaire etendu francais/anglais et lexique scientifique (`COMMON_WORDS`).
|
|
- **Repli vision dynamique** : Si le LLM retourne une indication de texte corrompu ou illisible (`NON_RETRYABLE_MARKERS`), le lot bascule immediatement et dynamiquement en mode Vision sans echec global.
|
|
|
|
### 2. Traitement multi-lots sans troncature (`convert_document`)
|
|
Remplacement de la troncature fixe par un orchestrateur multi-lots dans `app/converter.py` :
|
|
- **Lotissement PDF** : Tranches de 15 pages en mode texte (`BATCH_PAGES_TEXT = 15`), 5 pages en mode vision (`BATCH_PAGES_VISION = 5`).
|
|
- **Prompts adaptes** :
|
|
- Lot 1 (`PROMPT_INITIAL_TEXT` / `PROMPT_INITIAL_VISION`) : Extraction du frontmatter JSON (type, date, titre, resume, points cles) + transcription Markdown de la tranche initiale.
|
|
- Lots $k > 1$ (`PROMPT_SEGMENT_TEXT` / `PROMPT_SEGMENT_VISION`) : Transcription directe Markdown des segments successifs, sans surcharge JSON.
|
|
- **Insertion des marqueurs de page** : Marqueur `<!-- pages X-Y -->` insere en tete de chaque segment dans le Markdown final.
|
|
- **Classification de methode** : `text`, `vision` ou `mixed_text_vision`.
|
|
|
|
## Verification et Validation
|
|
|
|
Tests effectues sur les fichiers reels du pack-mp1 (`/volume1/docker/.claude-staging/pack-mp1-test/`) :
|
|
- `Cours-informatique-section-premiere-annee.pdf` (44 pages) : 100% couvert en 3 segments texte (46 820 car).
|
|
- `Cours-msi-premiere-annee.pdf` (66 pages) : 100% couvert en 6 segments en mode `mixed_text_vision` (74 513 car).
|
|
- `Francais-premiere-annee.pdf` (93 pages) : 100% couvert en 7 segments (69 874 car).
|
|
- Marqueurs `<!-- pages X-Y -->` presents et conformes dans chaque sortie Markdown.
|
|
|
|
## Deploiement & Maintenance
|
|
|
|
- **Service Docker** : `nyora-convert-api` sur NAS DS920+ (`http://192.168.100.33:3096`).
|
|
- **Depot Gitea** : `bolbol/nyora-convert-api` (branche `main`).
|
|
- **Redemarrage container** :
|
|
```bash
|
|
cd /volume1/docker/nyora-convert-api
|
|
docker compose build --no-cache
|
|
docker compose up -d --force-recreate
|
|
```
|