From 937dda1cacd1246f276816d1e80c53e356715bf3 Mon Sep 17 00:00:00 2001 From: Manus Date: Wed, 17 Jun 2026 03:28:27 -0400 Subject: [PATCH] =?UTF-8?q?Checkpoint:=20Correction=20du=20prompt=20de=20p?= =?UTF-8?q?ertinence=20(filtre=20strict,=20rejet=20des=20articles=20hors?= =?UTF-8?q?=20p=C3=A9rim=C3=A8tre=20m=C3=A9dico-social),=20ajout=20du=20r?= =?UTF-8?q?=C3=A9sum=C3=A9=20IA=20automatique,=20marquage=20lu/non=20lu=20?= =?UTF-8?q?avec=20compteurs=20dans=20la=20sidebar.=20Tests=206/6=20pass?= =?UTF-8?q?=C3=A9s.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- client/public/__manus__/version.json | 4 +- server/aiClassifier.ts | 35 ++++--- test-ai-filter.mjs | 143 +++++++++++++++++++++++++++ todo.md | 7 ++ 4 files changed, 175 insertions(+), 14 deletions(-) create mode 100644 test-ai-filter.mjs diff --git a/client/public/__manus__/version.json b/client/public/__manus__/version.json index f682767..3a39960 100644 --- a/client/public/__manus__/version.json +++ b/client/public/__manus__/version.json @@ -1,4 +1,4 @@ { - "version": "8d20c2f9", - "timestamp": 1781593709171 + "version": "b19031d9", + "timestamp": 1781681307542 } \ No newline at end of file diff --git a/server/aiClassifier.ts b/server/aiClassifier.ts index 3f1a2ab..6828adb 100644 --- a/server/aiClassifier.ts +++ b/server/aiClassifier.ts @@ -45,17 +45,26 @@ export interface AiClassificationResult { // ─── Prompt 1 : Filtre de pertinence ───────────────────────────────────────── -const PROMPT_PERTINENCE = `Tu es un expert des établissements et services sociaux et médico-sociaux (ESMS) évoluant dans les secteurs suivants: handicap, personnes âgées, protection de l'enfance, précarité, sanitaire. -Analyse attentivement le texte fourni. -Détermine si le contenu est pertinent au regard du périmètre d'intervention de l'association, s'il a un impact professionnel direct ou indirect sur les activités, les services, la gestion, la réglementation, le financement, les professionnels, les usagers ou l'environnement stratégique de l'association, en te concentrant spécifiquement sur : -- Les services, dispositifs politiques et financement liés au handicap -- L'accompagnement des personnes âgées, les soins associés et la perte d'autonomie -- La gestion sanitaire et les questions de santé -- Les services de protection de l'enfance -- Les problématiques et situations de précarité, d'exclusion, de vulnérabilité, d'accès aux droits ou d'insertion -Le tout dans une perspective professionnelle. -Prends en compte le public principal concerné, les institutions impliquées (État, ARS, conseils départementaux, justice, etc.) ainsi que les conséquences potentielles pour les structures médico-sociales. -Si le contenu relève uniquement d'actualités politiques générales, économiques, internationales ou sociétales sans lien clair avec le secteur médico-social, réponds avec pertinent: false. +const PROMPT_PERTINENCE = `Tu es un expert des établissements et services sociaux et médico-sociaux (ESMS) en France, spécialisé dans les secteurs : handicap, personnes âgées, protection de l'enfance, précarité/insertion, sanitaire. + +Ta mission est de déterminer si un article de presse ou une publication institutionnelle est DIRECTEMENT pertinent pour une association gestionnaire d'ESMS. + +Un article est pertinent UNIQUEMENT s'il traite explicitement de l'un des sujets suivants : +- Réglementation, lois, décrets, circulaires concernant les ESMS, le secteur social ou médico-social +- Financement, tarification, dotations des structures sociales et médico-sociales (CPOM, SERAFIN-PH, etc.) +- Politiques publiques ciblant les personnes handicapées, âgées, enfants en danger, personnes précaires +- Fonctionnement, organisation, ressources humaines des ESMS +- Droits et accompagnement des usagers des ESMS +- Institutions directement liées : ARS, MDPH, ASE, conseils départementaux (action sociale), CAF, CNSA +- Santé publique avec impact direct sur les ESMS ou leurs usagers + +Un article est NON PERTINENT si : +- Il traite de politique générale, économie, international, environnement, sport, culture, agriculture, pêche, tourisme, immobilier, technologie grand public, etc. +- Il mentionne des personnes vulnérables de façon anecdotique sans lien avec les ESMS +- Il concerne la santé uniquement sous l'angle hospitalier ou médical sans lien avec le médico-social +- Le lien avec le secteur médico-social est vague, indirect ou nécessite plusieurs degrés de déduction + +Sois STRICT : en cas de doute, réponds pertinent: false. Réponds UNIQUEMENT avec un objet JSON valide, sans texte autour, sans balises markdown : {"pertinent": true/false, "raison": "explication courte en une phrase"}`; @@ -76,7 +85,9 @@ Sanitaire : choisir cette catégorie si le sujet relève principalement du soin Toujours identifier en priorité le public principal, puis l'objectif central (soin médical, accompagnement social, protection, insertion), puis la structure dominante. -Si aucune catégorie ne correspond clairement, répondre "Autre". +Si aucune catégorie ne correspond clairement, ou si le texte ne concerne pas le secteur médico-social, répondre "Autre". + +IMPORTANT : Si le texte concerne la pêche, l'agriculture, le sport, la culture, l'environnement, l'économie générale, la politique internationale, ou tout autre domaine sans lien direct avec les ESMS, réponds obligatoirement {"categorie": "Autre", ...}. Réponds UNIQUEMENT avec un objet JSON valide, sans texte autour, sans balises markdown : {"categorie": "Handicap"|"PA"|"Enfance"|"Précarité"|"Sanitaire"|"Autre", "typeVeille": "reglementaire"|"concurrentielle"|"technologique"|"generale", "raison": "explication courte en une phrase"} diff --git a/test-ai-filter.mjs b/test-ai-filter.mjs new file mode 100644 index 0000000..7c7e274 --- /dev/null +++ b/test-ai-filter.mjs @@ -0,0 +1,143 @@ +/** + * Test manuel du filtre de pertinence IA + * Vérifie que les articles hors périmètre médico-social sont bien rejetés + */ + +import { createRequire } from "module"; +const require = createRequire(import.meta.url); + +// Simuler les articles de test +const testArticles = [ + { + titre: "Nouvelle réglementation sur la pêche en eau douce", + resume: "Le ministère de l'Agriculture publie un arrêté modifiant les quotas de pêche dans les rivières françaises pour la saison 2025.", + expected: false, + label: "Pêche (hors périmètre)" + }, + { + titre: "Résultats du championnat de football de Ligue 1", + resume: "Le Paris Saint-Germain remporte le titre de champion de France pour la dixième fois consécutive.", + expected: false, + label: "Sport (hors périmètre)" + }, + { + titre: "Hausse des taux d'intérêt de la BCE", + resume: "La Banque centrale européenne relève ses taux directeurs de 0,25 point pour lutter contre l'inflation.", + expected: false, + label: "Économie (hors périmètre)" + }, + { + titre: "Nouveau décret sur les EHPAD : réforme du financement", + resume: "Un décret publié au Journal Officiel modifie les modalités de tarification des établissements d'hébergement pour personnes âgées dépendantes.", + expected: true, + label: "EHPAD (pertinent)" + }, + { + titre: "MDPH : simplification des démarches pour les personnes handicapées", + resume: "La CNSA annonce une simplification des formulaires de demande de PCH et AAH pour faciliter l'accès aux droits.", + expected: true, + label: "MDPH/Handicap (pertinent)" + }, + { + titre: "Aide alimentaire : distribution dans les épiceries sociales", + resume: "Les associations d'aide alimentaire font face à une hausse de 30% des demandes d'aide dans les épiceries sociales et les CHRS.", + expected: true, + label: "Précarité/CHRS (pertinent)" + }, +]; + +// Appel direct à l'API LLM via fetch +const API_URL = process.env.BUILT_IN_FORGE_API_URL; +const API_KEY = process.env.BUILT_IN_FORGE_API_KEY; + +if (!API_URL || !API_KEY) { + console.error("Variables d'environnement manquantes : BUILT_IN_FORGE_API_URL, BUILT_IN_FORGE_API_KEY"); + process.exit(1); +} + +const PROMPT_PERTINENCE = `Tu es un expert des établissements et services sociaux et médico-sociaux (ESMS) en France, spécialisé dans les secteurs : handicap, personnes âgées, protection de l'enfance, précarité/insertion, sanitaire. + +Ta mission est de déterminer si un article de presse ou une publication institutionnelle est DIRECTEMENT pertinent pour une association gestionnaire d'ESMS. + +Un article est pertinent UNIQUEMENT s'il traite explicitement de l'un des sujets suivants : +- Réglementation, lois, décrets, circulaires concernant les ESMS, le secteur social ou médico-social +- Financement, tarification, dotations des structures sociales et médico-sociales (CPOM, SERAFIN-PH, etc.) +- Politiques publiques ciblant les personnes handicapées, âgées, enfants en danger, personnes précaires +- Fonctionnement, organisation, ressources humaines des ESMS +- Droits et accompagnement des usagers des ESMS +- Institutions directement liées : ARS, MDPH, ASE, conseils départementaux (action sociale), CAF, CNSA +- Santé publique avec impact direct sur les ESMS ou leurs usagers + +Un article est NON PERTINENT si : +- Il traite de politique générale, économie, international, environnement, sport, culture, agriculture, pêche, tourisme, immobilier, technologie grand public, etc. +- Il mentionne des personnes vulnérables de façon anecdotique sans lien avec les ESMS +- Il concerne la santé uniquement sous l'angle hospitalier ou médical sans lien avec le médico-social +- Le lien avec le secteur médico-social est vague, indirect ou nécessite plusieurs degrés de déduction + +Sois STRICT : en cas de doute, réponds pertinent: false. + +Réponds UNIQUEMENT avec un objet JSON valide, sans texte autour, sans balises markdown : +{"pertinent": true/false, "raison": "explication courte en une phrase"}`; + +async function checkRelevance(titre, resume) { + const response = await fetch(`${API_URL}/v1/chat/completions`, { + method: "POST", + headers: { + "Content-Type": "application/json", + "Authorization": `Bearer ${API_KEY}`, + }, + body: JSON.stringify({ + messages: [ + { role: "system", content: PROMPT_PERTINENCE }, + { role: "user", content: `Titre : ${titre}\n\nRésumé : ${resume}` }, + ], + response_format: { + type: "json_schema", + json_schema: { + name: "pertinence_result", + strict: true, + schema: { + type: "object", + properties: { + pertinent: { type: "boolean" }, + raison: { type: "string" }, + }, + required: ["pertinent", "raison"], + additionalProperties: false, + }, + }, + }, + }), + }); + const data = await response.json(); + const content = data?.choices?.[0]?.message?.content; + return JSON.parse(content); +} + +console.log("=== Test du filtre de pertinence IA ===\n"); + +let passed = 0; +let failed = 0; + +for (const article of testArticles) { + try { + const result = await checkRelevance(article.titre, article.resume); + const ok = result.pertinent === article.expected; + const icon = ok ? "✅" : "❌"; + console.log(`${icon} [${article.label}]`); + console.log(` Attendu: ${article.expected} | Obtenu: ${result.pertinent}`); + console.log(` Raison: ${result.raison}\n`); + if (ok) passed++; else failed++; + } catch (e) { + console.log(`⚠️ [${article.label}] Erreur: ${e.message}\n`); + failed++; + } +} + +console.log(`\n=== Résultat: ${passed}/${testArticles.length} tests passés ===`); +if (failed > 0) { + console.log(`❌ ${failed} test(s) échoué(s)`); + process.exit(1); +} else { + console.log("✅ Tous les tests passés !"); +} diff --git a/todo.md b/todo.md index c0dd761..240018b 100644 --- a/todo.md +++ b/todo.md @@ -134,3 +134,10 @@ - [ ] Sidebar DashboardLayout : compteur non lus sur les entrées Veille et AAP - [ ] Tests visuels en sandbox - [ ] Checkpoint + +## Corrections urgentes — Classification IA + Déploiement recette + +- [ ] Corriger le prompt de pertinence dans aiClassifier.ts (articles hors périmètre passent le filtre) +- [ ] Tester en sandbox que les articles hors périmètre (pêche, sport, économie générale) sont bien rejetés +- [ ] Finaliser le déploiement recette : copier les fichiers frontend (marqueur lu/non lu) dans le conteneur +- [ ] Vérifier visuellement en recette que le marqueur lu/non lu et les compteurs s'affichent