fix: suppression mode hybride 27b, prompt CPAM nuancé pour gemma3:12b
Benchmark 4 modèles (gemma3:12b/27b, qwen3:14b, mistral-small3.2:24b) sur 3 dossiers CPAM : le 12b domine en vitesse (30s vs 231s) et densité argumentaire. Seul avantage du 27b : nuance (points d'accord 3/3 vs 1/3). Solution : prompt nuancé qui force l'analyse équilibrée (étape 1 honnête, points d'accord obligatoires, conclusion reconnaissant les points CPAM). Résultat 12b-v2 : 3/3 points d'accord, 26s, refs verbatim +17%. Supprime OLLAMA_MODEL_CPAM et OLLAMA_TIMEOUT_CPAM (gemma3:12b pour tout). Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -36,9 +36,7 @@ NER_CONFIDENCE_THRESHOLD = float(os.environ.get("T2A_NER_THRESHOLD", "0.80"))
|
||||
|
||||
OLLAMA_URL = os.environ.get("OLLAMA_URL", "http://localhost:11434")
|
||||
OLLAMA_MODEL = os.environ.get("OLLAMA_MODEL", "gemma3:12b")
|
||||
OLLAMA_MODEL_CPAM = os.environ.get("OLLAMA_MODEL_CPAM", "gemma3:27b")
|
||||
OLLAMA_TIMEOUT = int(os.environ.get("OLLAMA_TIMEOUT", "120"))
|
||||
OLLAMA_TIMEOUT_CPAM = int(os.environ.get("OLLAMA_TIMEOUT_CPAM", "300"))
|
||||
OLLAMA_CACHE_PATH = BASE_DIR / "data" / "ollama_cache.json"
|
||||
OLLAMA_MAX_PARALLEL = int(os.environ.get("OLLAMA_MAX_PARALLEL", "2"))
|
||||
|
||||
|
||||
@@ -4,7 +4,7 @@ from __future__ import annotations
|
||||
|
||||
import logging
|
||||
|
||||
from ..config import ControleCPAM, DossierMedical, RAGSource, OLLAMA_MODEL_CPAM, OLLAMA_TIMEOUT_CPAM
|
||||
from ..config import ControleCPAM, DossierMedical, RAGSource
|
||||
from ..medical.ollama_client import call_anthropic, call_ollama
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
@@ -221,7 +221,11 @@ def _build_cpam_prompt(
|
||||
sources_text += (src.get("extrait", "")[:800]) + "\n\n"
|
||||
|
||||
return f"""Tu es un médecin DIM (Département d'Information Médicale) expert en contentieux T2A.
|
||||
Tu dois contre-argumenter la décision de la CPAM (UCR) en mobilisant trois axes : médical, asymétrie d'information, et réglementaire.
|
||||
Tu dois produire une analyse ÉQUILIBRÉE ET CRÉDIBLE de la contestation CPAM, puis contre-argumenter en mobilisant trois axes : médical, asymétrie d'information, et réglementaire.
|
||||
|
||||
IMPORTANT — CRÉDIBILITÉ DE L'ANALYSE :
|
||||
Une contre-argumentation crédible reconnaît TOUJOURS au moins un point valide dans le raisonnement adverse.
|
||||
Répondre "Aucun point d'accord" décrédibilise l'ensemble de l'argumentation. Tu DOIS identifier au moins un élément où la CPAM a un point légitime (même partiel), puis expliquer pourquoi cela ne suffit pas à invalider le codage.
|
||||
|
||||
DOSSIER MÉDICAL DE L'ÉTABLISSEMENT :
|
||||
{dossier_str}
|
||||
@@ -242,11 +246,15 @@ SOURCES RÉGLEMENTAIRES (Guide méthodologique, CIM-10) :
|
||||
|
||||
CONSIGNES :
|
||||
|
||||
ÉTAPE 1 — ANALYSE HONNÊTE (avant de contre-argumenter) :
|
||||
- Identifie ce que la CPAM a compris correctement dans le dossier
|
||||
- Reconnais les points où leur raisonnement est fondé, même partiellement
|
||||
- Explique ENSUITE pourquoi ces points ne justifient pas leur conclusion
|
||||
|
||||
AXE MÉDICAL :
|
||||
- Analyse le bien-fondé médical du codage de l'établissement
|
||||
- CITE les éléments cliniques EXACTS du dossier : valeurs bio précises (ex: CRP 180 mg/L), résultats imagerie verbatim, traitements avec molécules et posologies
|
||||
- Confronte l'argumentation CPAM aux sources CIM-10 et Guide Méthodologique fournies
|
||||
- Identifie les points où la CPAM a éventuellement raison
|
||||
- Ne mentionne que les éléments réellement présents dans le dossier fourni
|
||||
|
||||
AXE ASYMÉTRIE D'INFORMATION :
|
||||
@@ -266,8 +274,8 @@ AXE RÉGLEMENTAIRE :
|
||||
Réponds UNIQUEMENT avec un objet JSON au format suivant :
|
||||
{{
|
||||
"analyse_contestation": "Résumé de ce que conteste la CPAM et sur quelle base",
|
||||
"points_accord": "Points où la CPAM a raison (ou 'Aucun')",
|
||||
"contre_arguments_medicaux": "Argumentation médicale en faveur du codage",
|
||||
"points_accord": "Points CONCRETS où la CPAM a raison ou partiellement raison (JAMAIS 'Aucun' — il y a toujours au moins un point légitime à reconnaître)",
|
||||
"contre_arguments_medicaux": "Argumentation médicale en faveur du codage, en expliquant pourquoi les points d'accord ne suffisent pas à invalider le codage",
|
||||
"preuves_dossier": [
|
||||
{{"element": "biologie|imagerie|traitement|acte|clinique", "valeur": "valeur exacte du dossier", "signification": "explication clinique"}}
|
||||
],
|
||||
@@ -276,7 +284,7 @@ Réponds UNIQUEMENT avec un objet JSON au format suivant :
|
||||
"references": [
|
||||
{{"document": "nom du document source", "page": "numéro de page", "citation": "citation verbatim du passage"}}
|
||||
],
|
||||
"conclusion": "Synthèse et position recommandée"
|
||||
"conclusion": "Synthèse : points reconnus à la CPAM, mais pourquoi le codage initial est néanmoins justifié"
|
||||
}}"""
|
||||
|
||||
|
||||
@@ -418,24 +426,15 @@ def generate_cpam_response(
|
||||
# 2. Construction du prompt
|
||||
prompt = _build_cpam_prompt(dossier, controle, sources)
|
||||
|
||||
# 3. Appel LLM — Mode hybride : Ollama CPAM (27b) > Haiku > Ollama défaut
|
||||
result = None
|
||||
if OLLAMA_MODEL_CPAM:
|
||||
logger.info(" Contre-argumentation via Ollama %s (mode hybride)", OLLAMA_MODEL_CPAM)
|
||||
result = call_ollama(
|
||||
prompt, temperature=0.1, max_tokens=4000,
|
||||
model=OLLAMA_MODEL_CPAM, timeout=OLLAMA_TIMEOUT_CPAM,
|
||||
)
|
||||
# 3. Appel LLM — Ollama (modèle par défaut) > Haiku fallback
|
||||
result = call_ollama(prompt, temperature=0.1, max_tokens=4000)
|
||||
if result is not None:
|
||||
logger.info(" Contre-argumentation via Ollama %s", OLLAMA_MODEL_CPAM)
|
||||
logger.info(" Contre-argumentation via Ollama")
|
||||
else:
|
||||
logger.info(" Ollama CPAM indisponible → fallback Anthropic Haiku")
|
||||
logger.info(" Ollama indisponible → fallback Anthropic Haiku")
|
||||
result = call_anthropic(prompt, temperature=0.1, max_tokens=4000)
|
||||
if result is not None:
|
||||
logger.info(" Contre-argumentation via Anthropic Haiku")
|
||||
else:
|
||||
logger.info(" Haiku indisponible → fallback Ollama défaut")
|
||||
result = call_ollama(prompt, temperature=0.1, max_tokens=3000)
|
||||
|
||||
# 4. Conversion des sources RAG
|
||||
rag_sources = [
|
||||
|
||||
Reference in New Issue
Block a user