File size: 2,759 Bytes
7e3f910 5c1d1c7 7e3f910 5c1d1c7 7e3f910 | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 | """Modèles Pydantic pour le fact-checker."""
from __future__ import annotations
from enum import Enum
from typing import List, Optional
from pydantic import BaseModel, ConfigDict, Field
class Status(str, Enum):
SUPPORTED = "supported" # JDM confirme directement le triplet
CONTRADICTED = "contradicted" # JDM contient une info incompatible
UNKNOWN = "unknown" # JDM ne dit rien à ce sujet
class Claim(BaseModel):
"""Une affirmation atomique extraite d'un texte, sous forme structurée.
`polarity = False` signifie une négation ("La baleine N'EST PAS un poisson").
"""
model_config = ConfigDict(extra="ignore")
text: str = Field(..., description="Formulation originale de l'affirmation")
subject: str = Field(..., description="Terme source (en minuscule, à l'infinitif si verbe)")
relation: str = Field(..., description="Nom technique JDM (r_isa, r_carac, r_has_color, r_agent, r_patient, ...)")
object: str = Field(..., description="Terme cible de la relation")
polarity: bool = Field(True, description="True = affirmation, False = négation")
class Evidence(BaseModel):
"""Un triplet JDM qui sert de preuve pour/contre une claim."""
source: str
relation: str
target: str
w: float
# Identifiants bruts si refinements (rarement nécessaires pour le fact-checking).
source_id: Optional[str] = None
target_id: Optional[str] = None
class Verdict(BaseModel):
"""Le verdict de vérification pour une `Claim`.
`inference_schema` est `None` pour un verdict obtenu par lookup DIRECT
(contenance JDM). Il porte le nom du schéma quand le verdict provient du
moteur d'inférence (Phase 11) — la `inference_proof` détaille alors la
chaîne de déduction.
"""
claim: Claim
status: Status
confidence: float = Field(0.0, ge=0.0, le=1.0,
description="Confiance dans le verdict (0-1)")
evidence_for: List[Evidence] = Field(default_factory=list)
evidence_against: List[Evidence] = Field(default_factory=list)
explanation: str = ""
inference_schema: Optional[str] = Field(
None, description="Nom du schéma d'inférence (None = verdict direct)")
inference_proof: List[Evidence] = Field(
default_factory=list,
description="Chaîne de triplets justifiant un verdict inféré")
class Report(BaseModel):
"""Rapport global d'un fact-check (sur un texte ou une batch de claims)."""
text: str = ""
verdicts: List[Verdict] = Field(default_factory=list)
def summary(self) -> dict:
c = {s.value: 0 for s in Status}
for v in self.verdicts:
c[v.status.value] += 1
return {"total": len(self.verdicts), **c}
|