QUALIFELEC Instruction de dossiers

Paramètres

Tout ce qui se règle dans .env se règle ici, et ce qui est enregistré ici est conservé en base : le réglage survit au redémarrage et l'emporte sur le fichier. Réinitialiser un paramètre le rend au fichier, puis à sa valeur par défaut.

Changer de modèle, de fournisseur ou la résolution d'extraction invalide le cache des pages. Les dossiers déjà traités gardent leurs résultats, mais devront être relancés pour être relus par le nouveau réglage — ce qui en coûte à nouveau le temps d'analyse.

En service actuellement : Mistral Document AI — mistral-ocr-4-1 + zai-glm-5-3. Version de prompts : 7. Modifier les prompts.

Fournisseur

Qui lit les pages. L'arbitrage est d'abord un arbitrage de confidentialité : en local rien ne quitte la machine, chez un hébergeur les scans nominatifs en sortent.

Fichier .env invalide le cache des pages

Où partent les pages. « Local » ne transmet rien mais compte environ 7 minutes par page ; les deux autres répondent en quelques dizaines de secondes, contre l'envoi de scans nominatifs chez un tiers. QE_PROVIDER

LM Studio (local)

Point d'accès local compatible OpenAI — LM Studio, Ollama, llama.cpp. Utilisé seulement si le fournisseur est « local ».

Défaut invalide le cache des pages

L'identifiant exact servi par LM Studio, celui que renvoie « curl http://localhost:1234/v1/models ». Un modèle sans capacité de vision est refusé à la vérification préalable, pas après une heure de calcul. QE_LMSTUDIO_MODEL

Défaut

À changer si LM Studio écoute ailleurs, ou tourne sur une autre machine du réseau local. Attention : le cache des pages retient le nom du modèle, pas l'adresse — deux serveurs servant le même nom se partagent donc son cache. QE_LMSTUDIO_BASE_URL

Scaleway (UE, Paris)

Le même protocole, hébergé en France. Les pages sortent de la machine, sous juridiction UE.

Défaut

Clé non renseignée.

Obligatoire si ce fournisseur est choisi : sans elle l'enregistrement est refusé en nommant la clé, plutôt que de renvoyer un 401 au milieu d'un traitement. À créer sur console.scaleway.com, section Generative APIs. QE_SCALEWAY_API_KEY

Défaut invalide le cache des pages

Le défaut est la famille de modèles sur laquelle les mesures de recadrage ont été faites, ce qui évite de refaire la campagne. Moins cher et doté de vision également : mistral-small-3.2-24b-instruct-2506. QE_SCALEWAY_MODEL

Défaut

Point d'accès des Generative APIs. À ne changer que pour viser une autre région ou un proxy interne. QE_SCALEWAY_BASE_URL

Mistral Document AI

Deux modèles : un OCR qui transcrit la page, puis un modèle de texte qui remplit les champs à partir de cette transcription.

Fichier .env

Clé renseignée.

Obligatoire si ce fournisseur est choisi, pour la même raison que chez Scaleway : échouer ici plutôt qu'à la quarantième minute. À créer sur console.mistral.ai. QE_MISTRAL_API_KEY

Défaut invalide le cache des pages

Celui qui lit les pixels. Il renvoie du markdown, jamais des champs, et il est facturé à la page et non au token. QE_MISTRAL_OCR_MODEL

Défaut invalide le cache des pages

Celui qui remplit les champs à partir de la transcription. Un petit modèle suffit : le plus dur, déchiffrer un scan, est déjà fait à ce stade. QE_MISTRAL_TEXT_MODEL

Défaut

Point d'accès de l'API Mistral. À ne changer que pour un proxy interne. QE_MISTRAL_BASE_URL

Lecture des pages

Les résolutions ne sont pas des réglages de performance : sous un certain seuil le modèle cesse de lire et se met à inventer.

Défaut invalide le cache des pages

Paramètre de JUSTESSE, pas de vitesse. À 100 DPI le bloc de signature manuscrite mesure ~30 px de haut et le modèle invente des noms plausibles au lieu de déclarer la page illisible ; à 150 il la lit. Plancher imposé : 120. Changer cette valeur invalide le cache des pages déjà analysées. QE_RENDER_DPI

Défaut

L'identification du type de document ne lit que des titres imprimés : le détail y est dépensé pour rien. QE_CLASSIFY_DPI

Défaut

La recherche de zone utile ne lit aucun texte, seulement une mise en page. Mesuré sur la page 1 : 153 s à 100 DPI, 22 s à 60, même réponse. C'est ce réglage qui fait du recadrage un gain de temps plutôt qu'un coût. QE_LOCATE_DPI

Défaut

Recadre chaque page sur la zone qui répond aux questions quand le type de document s'y prête, et relit ce morceau plus finement. Un recadrage invraisemblable retombe sur la page entière. Décocher restaure le comportement page entière. QE_ROI

Défaut

Une petite zone est relue plus finement : les pixels économisés par le recadrage sont dépensés sur le détail qui rend l'écriture manuscrite lisible. Ce plafond borne la dépense. QE_ROI_MAX_DPI

Défaut

Demander la transcription mot à mot en plus des champs. Décocher économise environ 80 s par page et améliore légèrement la précision des champs, au prix de l'export Markdown, qui devient vide. QE_TRANSCRIBE

Appels au modèle

Budget, patience et vérification préalable.

Défaut

Le raisonnement du modèle local en consomme la majeure partie avant le premier caractère de réponse : 6000 renvoyait du vide, d'où le plancher de 8000. QE_MAX_TOKENS

Fichier .env

Combien le modèle a le droit de réfléchir avant de répondre. Laisser vide pour ne rien imposer. C'est le réglage le plus rentable du projet quand le modèle de texte raisonne : mesuré sur une page qui échouait, zai-glm-5-3 a dépensé les 16000 tokens du budget en réflexion sans rien répondre, et répond en 2 s et 494 tokens à « low ». Les valeurs acceptées sont celles du modèle, pas les nôtres : zai-glm-5-3 prend low/high/max, mistral-small-2603 prend none/high. Une valeur que le modèle refuse fait échouer l'appel en le disant. QE_REASONING_EFFORT

Défaut

Un appel d'extraction a été mesuré à 390 s. La marge évite qu'une page lente ne bloque le dossier indéfiniment, sans abandonner une page simplement lente. QE_VLM_TIMEOUT_S

Défaut

Un fournisseur hébergé répond à une rafale par une erreur de limitation de débit (429). Elle n'est pas un échec de la page : l'appel est simplement réessayé un peu plus tard, en attendant de plus en plus longtemps. Ne descendre à 0 que pour un diagnostic — la page échouerait alors au premier refus. QE_VLM_MAX_RETRIES

Défaut

Plafond du nombre d'appels envoyés au fournisseur, tous dossiers confondus. Les nouvelles tentatives ci-dessus se remettent d'une limitation de débit ; ce réglage évite de la provoquer. Ne gêne aucun traitement local, qui reste très loin sous cette limite. À 0, aucun plafond. QE_VLM_MAX_REQUESTS_PER_MINUTE

Fichier .env

À 1, les pages sont lues l'une après l'autre : c'est ce qui rend le journal lisible, et en local le serveur sérialise de toute façon les requêtes. Chez un hébergeur, monter à 4 ou 8 divise d'autant l'attente — le débit reste borné par le plafond ci-dessus. QE_PAGE_CONCURRENCY

Défaut

Vérifie avant chaque traitement que le modèle chargé lit bien les images. Ne décocher que pour un diagnostic : sans elle, un modèle aveugle se découvre page par page. QE_PREFLIGHT

Application

Dépôt et écoute du serveur web.

Défaut

Au-delà, le dépôt est refusé en nommant la limite. Les octets reçus ne sont pas conservés. QE_MAX_UPLOAD_MB

Fichier .env pris en compte au prochain démarrage

Rester sur 127.0.0.1 : l'application n'a ni authentification ni chiffrement, et cette page-ci donne la faculté d'effacer une clé d'API. QE_HOST

Défaut pris en compte au prochain démarrage

Port du serveur web. Un port déjà pris fait échouer le démarrage suivant, pas l'enregistrement : la valeur est acceptée ici sans être essayée. QE_PORT

Non modifiable ici

Fichier .env

/data

La base de données vit dans ce répertoire. Un déplacement enregistré dans la base que l'on quitte serait relu depuis la base où l'on arrive, qui ne le contient pas : le réglage s'annulerait de lui-même au redémarrage suivant. Il reste donc réservé à la variable QE_DATA_DIR.

Cette page n'a pas d'authentification, comme le reste de l'application : elle suppose que le serveur n'écoute que sur cette machine.

Prompts

Tout ce qui part au modèle comme texte s'édite ici. Chaque enregistrement crée une révision numérotée, conservée : une formulation essayée reste lisible, y compris après un retour en arrière. C'est le fichier le plus déterminant du dispositif — la largeur d'un prompt est un paramètre de justesse, pas de goût.

Modifier un prompt invalide le cache des pages. La version de prompts est 7 : elle est calculée à partir des textes eux-mêmes et entre dans la clé du cache. Un enregistrement la change donc — aucune incrémentation à retenir — et une réinitialisation rend leur validité aux pages analysées avant l'essai.

Un prompt part au fournisseur : sur un profil hébergé, ce qui est écrit ici quitte la machine avec les pages. Le préambule d'OCR de vlm.py, qui présente une transcription à un modèle de texte quand l'œil ne voit pas, n'est pas éditable ici : c'est un adaptateur de protocole, pas un prompt de la chaîne.

N'est pas éditable non plus ce qui est de la structure et non de la formulation : l'enveloppe fields et le bloc confiance, que parsing.py relit par leur nom. Le bloc confiance est déduit du schéma de chaque type, pour qu'un champ ajouté ne puisse pas rester sans note ; il ne note que les champs que la liste ci-dessous demande encore. Les trois niveaux — haute, moyenne, basse — sont eux aussi un contrat de code ; la manière de choisir entre eux, en revanche, s'édite dans « Règles de confiance ».

Étape 0 — Texte intégral

Le texte d'une page est ce dont toute preuve est citée (V3). Il est gratuit et exact quand le fichier porte une couche texte, ce qui est le cas de quatre dossiers sur six ; sinon il coûte un appel d'OCR, distinct de l'extraction parce que réunir les deux a été mesuré plus lent ET plus faux.

Texte du code

Envoyé seul, avec l'image de la page, quand le fichier ne porte pas de couche texte exploitable. Doit demander le texte et rien d'autre : aucun champ, aucun JSON, aucune analyse.

Étape 1 — Identification

Un mot en réponse, parmi six. Cet appel n'existe que pour rendre l'appel suivant étroit, et l'étroitesse est ce qui rend l'extraction juste (C8).

Texte du code

Doit continuer de proposer les termes exacts (engagement, exigences, diplome, formation, equipement, assurance, identification, autre) : ce ne sont pas des libellés mais un contrat de code — le schéma des champs et la lecture de la réponse en dépendent. Réponse attendue : un mot, rien d'autre.

Texte du code

Ajoutée au prompt d'identification quand le fichier déposé porte un nom parlant. Doit contenir [[nom_du_fichier]], remplacé par le nom du fichier. Le nom est un indice, jamais un verdict : ce fragment doit continuer de le dire, sans quoi un fichier mal nommé imposerait son type à la page (T4.1). Laissé vide : Le nom du fichier n'est pas transmis au modèle..

Texte du code

Ajoutée au prompt d'identification uniquement lorsque le fournisseur sait contraindre sa réponse par un schéma. Le prompt ci-dessus demande un mot nu ; une grammaire, elle, impose un objet. Ce fragment est ce qui réconcilie les deux, et il n'est envoyé qu'au modèle qui reçoit aussi la grammaire. La lecture de la réponse accepte les deux formes, donc le vider ne casse rien. Laissé vide : Le bras contraint envoie le prompt d'identification tel quel..

Étape 2 — Localisation de la zone utile

Sur une page d'engagement, 70 % de la surface est du texte pré-imprimé. Cet appel choisit parmi des bandes numérotées ce qui sera relu finement. Une intention laissée vide veut dire « lire la page entière » pour ce type de document.

Texte du code

Gabarit de la question posée sur une page découpée en bandes. Doit contenir [[nombre_de_bandes]] (remplacé par le nombre de bandes trouvées) et [[zone_utile]] (remplacé par l'intention du type de document, ci-dessous). Ne jamais y demander de coordonnées : un petit modèle choisit bien dans une liste et régresse mal des nombres.

Texte du code

Ce qu'il faut repérer sur une page de ce type, inséré dans la question de localisation. Une attestation d'assurance porte ses réponses du haut en bas de la page : la recadrer perdrait la moitié du texte de garantie. Laissé vide : page entière, aucun recadrage pour ce type.

Texte du code

Ce qu'il faut repérer sur une page de ce type, inséré dans la question de localisation. Une attestation d'assurance porte ses réponses du haut en bas de la page : la recadrer perdrait la moitié du texte de garantie. Laissé vide : page entière, aucun recadrage pour ce type.

Texte du code

Ce qu'il faut repérer sur une page de ce type, inséré dans la question de localisation. Une attestation d'assurance porte ses réponses du haut en bas de la page : la recadrer perdrait la moitié du texte de garantie. Laissé vide : page entière, aucun recadrage pour ce type.

Texte du code

Ce qu'il faut repérer sur une page de ce type, inséré dans la question de localisation. Une attestation d'assurance porte ses réponses du haut en bas de la page : la recadrer perdrait la moitié du texte de garantie. Laissé vide : page entière, aucun recadrage pour ce type.

Texte du code

Ce qu'il faut repérer sur une page de ce type, inséré dans la question de localisation. Une attestation d'assurance porte ses réponses du haut en bas de la page : la recadrer perdrait la moitié du texte de garantie. Laissé vide : page entière, aucun recadrage pour ce type.

Texte du code

Ce qu'il faut repérer sur une page de ce type, inséré dans la question de localisation. Une attestation d'assurance porte ses réponses du haut en bas de la page : la recadrer perdrait la moitié du texte de garantie. Laissé vide : page entière, aucun recadrage pour ce type.

Texte du code

Ce qu'il faut repérer sur une page de ce type, inséré dans la question de localisation. Une attestation d'assurance porte ses réponses du haut en bas de la page : la recadrer perdrait la moitié du texte de garantie. Laissé vide : page entière, aucun recadrage pour ce type.

Texte du code

Ce qu'il faut repérer sur une page de ce type, inséré dans la question de localisation. Une attestation d'assurance porte ses réponses du haut en bas de la page : la recadrer perdrait la moitié du texte de garantie. Laissé vide : page entière, aucun recadrage pour ce type.

Étape 3 — Extraction

Le prompt coûteux. Il ne nomme que les champs du type identifié : élargir cette liste a été mesuré plus lent ET plus faux.

Texte du code

La première ligne du prompt d'extraction : ce que le modèle regarde, et où regarder de près.

Texte du code

Corps de l'objet d'exemple, en JSON : les noms de champs sont ceux du schéma, les chevrons décrivent ce qu'il faut y mettre. Ne nommer que les champs de ce type : énumérer ceux des autres a été mesuré à 536 s pour un résultat faux, contre 308 s et juste. Laissé vide : aucun champ demandé, transcription seule.

Texte du code

Règles qui ne concernent que ce type, ajoutées après les règles communes. C'est ici que se corrige un champ qu'un modèle lit de travers : nommer la bonne ligne ne suffit pas, il faut nommer chaque mauvaise réponse — c'est ce qui les empêche de revenir (C20). Une formulation ne compense toutefois pas une résolution trop basse : sous 225 DPI, le modèle devine au lieu de répondre null (C23). Laissé vide : aucune précision pour ce type, seules les règles communes.

Texte du code

La première ligne du prompt d'extraction : ce que le modèle regarde, et où regarder de près.

Texte du code

Corps de l'objet d'exemple, en JSON : les noms de champs sont ceux du schéma, les chevrons décrivent ce qu'il faut y mettre. Ne nommer que les champs de ce type : énumérer ceux des autres a été mesuré à 536 s pour un résultat faux, contre 308 s et juste. Laissé vide : aucun champ demandé, transcription seule.

Texte du code

Règles qui ne concernent que ce type, ajoutées après les règles communes. C'est ici que se corrige un champ qu'un modèle lit de travers : nommer la bonne ligne ne suffit pas, il faut nommer chaque mauvaise réponse — c'est ce qui les empêche de revenir (C20). Une formulation ne compense toutefois pas une résolution trop basse : sous 225 DPI, le modèle devine au lieu de répondre null (C23). Laissé vide : aucune précision pour ce type, seules les règles communes.

Texte du code

La première ligne du prompt d'extraction : ce que le modèle regarde, et où regarder de près.

Texte du code

Corps de l'objet d'exemple, en JSON : les noms de champs sont ceux du schéma, les chevrons décrivent ce qu'il faut y mettre. Ne nommer que les champs de ce type : énumérer ceux des autres a été mesuré à 536 s pour un résultat faux, contre 308 s et juste. Laissé vide : aucun champ demandé, transcription seule.

Texte du code

Règles qui ne concernent que ce type, ajoutées après les règles communes. C'est ici que se corrige un champ qu'un modèle lit de travers : nommer la bonne ligne ne suffit pas, il faut nommer chaque mauvaise réponse — c'est ce qui les empêche de revenir (C20). Une formulation ne compense toutefois pas une résolution trop basse : sous 225 DPI, le modèle devine au lieu de répondre null (C23). Laissé vide : aucune précision pour ce type, seules les règles communes.

Texte du code

La première ligne du prompt d'extraction : ce que le modèle regarde, et où regarder de près.

Texte du code

Corps de l'objet d'exemple, en JSON : les noms de champs sont ceux du schéma, les chevrons décrivent ce qu'il faut y mettre. Ne nommer que les champs de ce type : énumérer ceux des autres a été mesuré à 536 s pour un résultat faux, contre 308 s et juste. Laissé vide : aucun champ demandé, transcription seule.

Texte du code

Règles qui ne concernent que ce type, ajoutées après les règles communes. C'est ici que se corrige un champ qu'un modèle lit de travers : nommer la bonne ligne ne suffit pas, il faut nommer chaque mauvaise réponse — c'est ce qui les empêche de revenir (C20). Une formulation ne compense toutefois pas une résolution trop basse : sous 225 DPI, le modèle devine au lieu de répondre null (C23). Laissé vide : aucune précision pour ce type, seules les règles communes.

Texte du code

La première ligne du prompt d'extraction : ce que le modèle regarde, et où regarder de près.

Texte du code

Corps de l'objet d'exemple, en JSON : les noms de champs sont ceux du schéma, les chevrons décrivent ce qu'il faut y mettre. Ne nommer que les champs de ce type : énumérer ceux des autres a été mesuré à 536 s pour un résultat faux, contre 308 s et juste. Laissé vide : aucun champ demandé, transcription seule.

Texte du code

Règles qui ne concernent que ce type, ajoutées après les règles communes. C'est ici que se corrige un champ qu'un modèle lit de travers : nommer la bonne ligne ne suffit pas, il faut nommer chaque mauvaise réponse — c'est ce qui les empêche de revenir (C20). Une formulation ne compense toutefois pas une résolution trop basse : sous 225 DPI, le modèle devine au lieu de répondre null (C23). Laissé vide : aucune précision pour ce type, seules les règles communes.

Texte du code

La première ligne du prompt d'extraction : ce que le modèle regarde, et où regarder de près.

Texte du code

Corps de l'objet d'exemple, en JSON : les noms de champs sont ceux du schéma, les chevrons décrivent ce qu'il faut y mettre. Ne nommer que les champs de ce type : énumérer ceux des autres a été mesuré à 536 s pour un résultat faux, contre 308 s et juste. Laissé vide : aucun champ demandé, transcription seule.

Texte du code

Règles qui ne concernent que ce type, ajoutées après les règles communes. C'est ici que se corrige un champ qu'un modèle lit de travers : nommer la bonne ligne ne suffit pas, il faut nommer chaque mauvaise réponse — c'est ce qui les empêche de revenir (C20). Une formulation ne compense toutefois pas une résolution trop basse : sous 225 DPI, le modèle devine au lieu de répondre null (C23). Laissé vide : aucune précision pour ce type, seules les règles communes.

Texte du code

La première ligne du prompt d'extraction : ce que le modèle regarde, et où regarder de près.

Texte du code

Corps de l'objet d'exemple, en JSON : les noms de champs sont ceux du schéma, les chevrons décrivent ce qu'il faut y mettre. Ne nommer que les champs de ce type : énumérer ceux des autres a été mesuré à 536 s pour un résultat faux, contre 308 s et juste. Laissé vide : aucun champ demandé, transcription seule.

Texte du code

Règles qui ne concernent que ce type, ajoutées après les règles communes. C'est ici que se corrige un champ qu'un modèle lit de travers : nommer la bonne ligne ne suffit pas, il faut nommer chaque mauvaise réponse — c'est ce qui les empêche de revenir (C20). Une formulation ne compense toutefois pas une résolution trop basse : sous 225 DPI, le modèle devine au lieu de répondre null (C23). Laissé vide : aucune précision pour ce type, seules les règles communes.

Texte du code

La première ligne du prompt d'extraction : ce que le modèle regarde, et où regarder de près.

Texte du code

Corps de l'objet d'exemple, en JSON : les noms de champs sont ceux du schéma, les chevrons décrivent ce qu'il faut y mettre. Ne nommer que les champs de ce type : énumérer ceux des autres a été mesuré à 536 s pour un résultat faux, contre 308 s et juste. Laissé vide : aucun champ demandé, transcription seule.

Texte du code

Règles qui ne concernent que ce type, ajoutées après les règles communes. C'est ici que se corrige un champ qu'un modèle lit de travers : nommer la bonne ligne ne suffit pas, il faut nommer chaque mauvaise réponse — c'est ce qui les empêche de revenir (C20). Une formulation ne compense toutefois pas une résolution trop basse : sous 225 DPI, le modèle devine au lieu de répondre null (C23). Laissé vide : aucune précision pour ce type, seules les règles communes.

Textes communs à l'extraction

Assemblés autour des champs de chaque type, à chaque appel d'extraction.

Texte du code

Introduit l'objet JSON d'exemple.

Texte du code

Demandée seulement si « Transcrire la page en Markdown » est actif, ce qui n'est plus le cas par défaut : elle coûte ~80 s par page et concurrence les champs pour l'attention du modèle (C9), pour le budget de sortie (C19) et pour survivre à une troncature (C21). Elle est demandée en dernier, justement parce qu'elle est ce qu'une réponse tronquée peut le mieux se permettre de perdre.

Texte du code

La politique du nul, qui est le cœur de la justesse du dispositif : sur un document de conformité, une valeur inventée coûte plus cher qu'un champ manquant, parce qu'elle ne se signale pas au relecteur.

Texte du code

Ajouté aux règles impératives dès qu'une note de confiance est demandée. Doit continuer de parler de la lisibilité de l'encre et non de la véracité du fait : la note sert à diriger l'œil du relecteur vers les deux champs à revoir, pas à filtrer ni à corriger une valeur (R14.8). Les trois niveaux eux-mêmes — haute, moyenne, basse — ne sont pas éditables : `parsing.py` ne reconnaît que ces mots.

Texte du code

Dernière ligne du prompt d'extraction ordinaire.

Texte du code

Ajoutée à l'orientation quand l'image envoyée est une zone et non la page. Énoncée comme un fait, sans suggérer que les réponses y sont nécessairement : un mauvais recadrage doit produire des nulls, pas une supposition confiante.

Texte du code

Utilisée à la seconde tentative, quand la première réponse n'a pas pu être lue comme du JSON (R5.4).

Texte du code

Dernière ligne de la reprise stricte.

Les nouveaux textes s'appliquent aux traitements lancés ensuite ; un traitement en cours termine avec la formulation sous laquelle il a démarré, pour qu'un dossier ne soit pas lu moitié dans l'une, moitié dans l'autre.