fix: réparation JSON tronqué + retry 429 + whitelist codes CPAM anti-hallucination
- parse_json_response : réparation JSON tronqué par max_tokens (fermeture auto des structures ouvertes), meilleur stripping des blocs fencés avec texte superflu après la fermeture ``` - call_ollama : retry avec backoff exponentiel (1s/2s/4s) pour les erreurs 429 rate limit, 3 tentatives au lieu de 2 - Validation adversariale : max_tokens 800 → 1500 - Prompt CPAM : whitelist PÉRIMÈTRE DE CODES AUTORISÉS (dossier DP+DAS + UCR) avec interdiction explicite des codes hors périmètre - Tests : 19 tests parse_json/_repair_truncated_json, 6 tests whitelist Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -1950,3 +1950,49 @@ class TestCheckDasBioCoherenceExtended:
|
||||
)
|
||||
warnings = _check_das_bio_coherence(dossier)
|
||||
assert len(warnings) >= 1
|
||||
|
||||
|
||||
class TestCodesAutorisesWhitelist:
|
||||
"""Tests pour la whitelist de codes autorisés (anti-hallucination)."""
|
||||
|
||||
def test_whitelist_in_prompt(self):
|
||||
"""Le prompt contient la section PÉRIMÈTRE DE CODES AUTORISÉS."""
|
||||
dossier = _make_dossier() # DP K81.0, DAS K56.0
|
||||
controle = _make_controle() # dp_ucr=K80.1, da_ucr=K56.0
|
||||
prompt, _ = _build_cpam_prompt(dossier, controle, [])
|
||||
assert "PÉRIMÈTRE DE CODES AUTORISÉS" in prompt
|
||||
assert "INTERDICTION" in prompt
|
||||
|
||||
def test_whitelist_contains_dossier_codes(self):
|
||||
"""Tous les codes du dossier sont dans la whitelist."""
|
||||
dossier = _make_dossier() # DP K81.0, DAS K56.0
|
||||
controle = _make_controle()
|
||||
prompt, _ = _build_cpam_prompt(dossier, controle, [])
|
||||
assert "K81.0" in prompt
|
||||
assert "K56.0" in prompt
|
||||
|
||||
def test_whitelist_contains_ucr_codes(self):
|
||||
"""Tous les codes UCR sont dans la whitelist."""
|
||||
dossier = _make_dossier()
|
||||
controle = _make_controle()
|
||||
controle.dp_ucr = "K80.1"
|
||||
prompt, _ = _build_cpam_prompt(dossier, controle, [])
|
||||
assert "K80.1" in prompt
|
||||
|
||||
def test_whitelist_dedup(self):
|
||||
"""Les codes en double (dossier + UCR) ne sont listés qu'une fois."""
|
||||
dossier = _make_dossier() # K56.0 en DAS
|
||||
controle = _make_controle() # da_ucr=K56.0
|
||||
prompt, _ = _build_cpam_prompt(dossier, controle, [])
|
||||
# K56.0 apparaît dans PÉRIMÈTRE mais une seule fois dans cette section
|
||||
perimetre_idx = prompt.index("PÉRIMÈTRE DE CODES AUTORISÉS")
|
||||
interdit_idx = prompt.index("INTERDICTION")
|
||||
perimetre_section = prompt[perimetre_idx:interdit_idx]
|
||||
assert perimetre_section.count("K56.0") == 1
|
||||
|
||||
def test_whitelist_prohibition_message(self):
|
||||
"""Le message d'interdiction est clair et complet."""
|
||||
dossier = _make_dossier()
|
||||
controle = _make_controle()
|
||||
prompt, _ = _build_cpam_prompt(dossier, controle, [])
|
||||
assert "Ne mentionne AUCUN code CIM-10 qui ne figure pas" in prompt
|
||||
|
||||
Reference in New Issue
Block a user