feat: mode hybride Ollama — gemma3:27b pour CPAM, 12b pour codage

Le pipeline utilise désormais gemma3:12b (rapide) pour le codage CIM-10
et gemma3:27b (meilleur raisonnement) pour la contre-argumentation CPAM.
Configurable via OLLAMA_MODEL_CPAM et OLLAMA_TIMEOUT_CPAM.

Inclut aussi : traçabilité source/page DAS, niveaux CMA ATIH, sévérité,
page tracker PDF, améliorations fusion et filtres DAS.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
dom
2026-02-17 17:53:53 +01:00
parent 4ef42dd3d3
commit 01d47f3c4b
20 changed files with 1025 additions and 98 deletions

View File

@@ -34,12 +34,12 @@ def _get_anthropic_client():
return None
def _call_anthropic(
def call_anthropic(
prompt: str,
temperature: float = 0.1,
max_tokens: int = 2500,
) -> dict | None:
"""Appelle l'API Anthropic en fallback."""
"""Appelle l'API Anthropic (Haiku)."""
client = _get_anthropic_client()
if client is None:
return None
@@ -82,6 +82,8 @@ def call_ollama(
prompt: str,
temperature: float = 0.1,
max_tokens: int = 2500,
model: str | None = None,
timeout: int | None = None,
) -> dict | None:
"""Appelle Ollama en mode JSON natif, avec fallback Anthropic si indisponible.
@@ -89,16 +91,20 @@ def call_ollama(
prompt: Le prompt à envoyer.
temperature: Température de génération (défaut: 0.1).
max_tokens: Nombre max de tokens (défaut: 2500).
model: Modèle Ollama à utiliser (défaut: OLLAMA_MODEL global).
timeout: Timeout en secondes (défaut: OLLAMA_TIMEOUT global).
Returns:
Le dict JSON parsé, ou None en cas d'erreur.
"""
use_model = model or OLLAMA_MODEL
use_timeout = timeout or OLLAMA_TIMEOUT
for attempt in range(2):
try:
response = requests.post(
f"{OLLAMA_URL}/api/generate",
json={
"model": OLLAMA_MODEL,
"model": use_model,
"prompt": prompt,
"stream": False,
"format": "json",
@@ -107,7 +113,7 @@ def call_ollama(
"num_predict": max_tokens,
},
},
timeout=OLLAMA_TIMEOUT,
timeout=use_timeout,
)
response.raise_for_status()
raw = response.json().get("response", "")
@@ -115,13 +121,14 @@ def call_ollama(
if result is not None:
return result
if attempt == 0:
logger.info("Ollama : retry après échec de parsing")
logger.info("Ollama (%s) : retry après échec de parsing", use_model)
except requests.ConnectionError:
logger.info("Ollama indisponible → fallback Anthropic (%s)", _ANTHROPIC_MODEL)
return _call_anthropic(prompt, temperature, max_tokens)
return call_anthropic(prompt, temperature, max_tokens)
except requests.Timeout:
logger.warning("Ollama timeout après %ds → fallback Anthropic", OLLAMA_TIMEOUT)
return _call_anthropic(prompt, temperature, max_tokens)
logger.warning("Ollama (%s) timeout après %ds → fallback Anthropic",
use_model, use_timeout)
return call_anthropic(prompt, temperature, max_tokens)
except (requests.RequestException, json.JSONDecodeError) as e:
logger.warning("Ollama erreur : %s", e)
return None