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:
dom
2026-02-17 20:45:53 +01:00
parent 01d47f3c4b
commit aad925ebea
2 changed files with 18 additions and 21 deletions

View File

@@ -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 = [