| """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" |
| CONTRADICTED = "contradicted" |
| UNKNOWN = "unknown" |
|
|
|
|
| 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 |
| |
| 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} |
|
|