"""Prompts GLM-OCR par type de page OGC. Pour chaque type structuré, on demande un JSON strict. Pour les pages libres (concertation 2, éléments de preuve…) on sort du texte brut. """ # Prompt court pour détecter le type de page depuis l'en-tête. PROMPT_HEADER = "Text Recognition:" # --- Page 1 : Fiche médicale de recueil du praticien conseil --- # Note : accord_desaccord retiré du prompt — géré par pipeline.checkboxes # (densité de pixels) car GLM-OCR ne sait pas lire les checkboxes # (cf. test_prompt_crop_v2.py). # SCHEMA_RECUEIL = """Lis la fiche médicale OGC et renvoie STRICTEMENT le JSON suivant, sans commentaire ni markdown. Les codes CIM-10 sont au format lettre + 2 à 4 chiffres (ex: K650, T814). Les codes CCAM sont au format 4 lettres + 3 chiffres (ex: EBFA012). Les codes GHM sont au format 2 chiffres + lettre + 3 chiffres (ex: 11M122). Les codes GHS sont des nombres à 3-5 chiffres (ex: 4323). Si un champ est illisible, laisse une chaîne vide. Ne devine pas. { "etablissement": "", "finess": "", "date_debut_controle": "", "n_ogc": "", "n_champ": "", "dates_sejour": "", "sejour_etab": { "age": "", "sexe": "", "duree_sejour": "", "mode_entree": "", "provenance": "", "mode_sortie": "", "destination": "" }, "sejour_reco": { "age": "", "sexe": "", "duree_sejour": "", "mode_entree": "", "provenance": "", "mode_sortie": "", "destination": "" }, "rum_etab": {"um": "", "igs": "", "duree": "", "dates": ""}, "codage_etab": { "dp": "", "dp_libelle": "", "dr": "", "das": [{"code": "", "position": "", "libelle": ""}] }, "codage_reco": { "dp": "", "dr": "", "das": [{"code": "", "position": ""}] }, "actes_etab": [{"code": "", "position": "", "libelle": ""}], "actes_reco": [{"code": "", "position": ""}], "ghm_etab": "", "ghs_etab": "", "ghm_reco": "", "ghs_reco": "", "recodage_impactant": "", "ghs_injustifie": "", "praticien_conseil": "" }""" # --- Second passage dédié : colonne Recodage de la page recueil --- # Qwen-VL sous-extrait la colonne droite du tableau Codage quand on lui donne # la page entière (27% de couverture sur `codage_reco.dp` en V2.0). En lui # donnant directement un crop zonal de cette seule colonne, il lit beaucoup # mieux (la structure à une seule colonne lève l'ambiguïté). # # Zone cropée (coordonnées relatives dans l'image complète) : # Zone restreinte au seul bloc codage (DP/DR/DAS de la colonne Recodage). # On exclut la partie Actes (qui commence autour de y=0.680) pour éviter que # Qwen confonde les codes CCAM (actes) avec des codes CIM-10 (DAS). RECUEIL_RECODAGE_ZONE = (0.77, 0.330, 0.97, 0.490) SCHEMA_RECUEIL_RECODAGE = """Cette image est un extrait d'une colonne d'un tableau médical. La colonne peut contenir ZÉRO, UN ou PLUSIEURS codes médicaux CIM-10 (format : 1 lettre majuscule + 2 à 4 chiffres, ex: K650, T810, Z954, R31, I652). Un code peut avoir un suffixe `*`. À droite d'un code, une position numérique (1-9) peut être visible. IMPORTANT — LIS UNIQUEMENT CE QUI EST PHYSIQUEMENT VISIBLE : - La plupart des lignes de ce tableau sont VIDES. C'est NORMAL. - Ne liste QUE les codes effectivement écrits dans l'image. N'INVENTE rien. - Si l'image ne contient qu'un seul code, ta réponse doit lister exactement un code (pas plusieurs). - Si l'image ne contient aucun code, renvoie `"codes": []`. - Ne déduis pas les codes d'autres cases non montrées dans l'image. Pour chaque code réellement visible, indique sa position à droite si elle est écrite, sinon "". Renvoie STRICTEMENT ce JSON, sans commentaire ni markdown : { "codes": [ {"code": "", "position": ""} ] }""" # --- Page 5 : Fiche administrative de concertation 2/2 (décision finale) --- SCHEMA_CONCERTATION_2 = """Lis la fiche de concertation et renvoie STRICTEMENT le JSON suivant, sans commentaire ni markdown. Si un champ est illisible, laisse une chaîne vide. { "ghs_initial": "", "ghs_avant_concertation": "", "ghs_final": "", "decision": "", "date_concertation": "", "praticien_controleur": "", "medecin_dim": "" } Pour "decision", choisis UNIQUEMENT une de ces valeurs selon la case cochée : - "maintien_avis_controleur" si "Maintien de l'avis initial" est coché - "retour_groupage_dim" si "Retour groupage initial DIM" est coché - "autre_groupage" si "Autre groupage" est coché - "" si rien n'est coché""" # --- Page 6 : Fiche administrative de concertation 1/2 (argumentaire) --- SCHEMA_CONCERTATION_1 = """Lis la fiche d'argumentaire du médecin contrôleur et renvoie STRICTEMENT le JSON suivant, sans commentaire ni markdown. { "date_concertation": "", "argumentaire": "" } Pour "argumentaire", transcris TOUT le paragraphe sous "ARGUMENTAIRE DU MEDECIN CONTROLEUR" tel quel, sans reformuler.""" # --- Page 4 : Éléments de preuve --- SCHEMA_PREUVES = """Lis le tableau des éléments de preuve et renvoie STRICTEMENT le JSON suivant, sans commentaire ni markdown. Pour chaque ligne, indique si la case "Présent" ou "Photocopié" est cochée (true/false). { "date": "", "praticien_controleur": "", "medecin_dim": "", "pieces": [ {"intitule": "", "present": false, "photocopie": false, "absent_date": "", "date_obtention": ""} ] }""" # Types de page reconnus PAGE_TYPES = { "recueil": {"keywords": ["RECUEIL DU PRATICIEN"], "prompt": SCHEMA_RECUEIL}, "concertation_2": {"keywords": ["CONCERTATION 2/2"], "prompt": SCHEMA_CONCERTATION_2}, "concertation_1": {"keywords": ["CONCERTATION 1/2"], "prompt": SCHEMA_CONCERTATION_1}, "preuves": {"keywords": ["ELEMENTS DE PREUVE", "PREUVE"], "prompt": SCHEMA_PREUVES}, "concertation_med": {"keywords": ["FICHE MEDICALE DE CONCERTATION"], "prompt": PROMPT_HEADER}, "hospitalisation":{"keywords": ["SEJOUR D'HOSPITALISATION", "HOSPITALISATION COMPLETE"], "prompt": PROMPT_HEADER}, }