Skip to main content

Entity-contract per flavor

Status: concept (skeleton v0.1). Definitieve matrix volgt na discussie in de openspec proposal split-into-3-flavors. Zie ook: flavors.md.

Doel

Per flavor vastleggen welke entity-types hij mag claimen. Dit contract:

  • Wordt afgedwongen op requestniveau: entities: [X] waar X niet bij de actieve flavor hoort → 422 validatiefout.
  • Dient als single source of truth bij code-reviews (PR die een engine wijzigt moet de matrix in dezelfde commit bijwerken).
  • Voorkomt dat flavor-smaken stilletjes in elkaar diffunderen.

Huidige set (HEAD)

Alle entity-types die ergens in de code voorkomen:

EntityBronIn DEFAULT_ENTITIESIn ALL_SUPPORTED_ENTITIES
PERSONSpaCy NER, GLiNER
LOCATIONSpaCy NER, GLiNER
ORGANIZATIONSpaCy NER, GLiNER
PHONE_NUMBERpattern (DutchPhoneNumberRecognizer)
EMAILpattern (EmailRecognizer)
IBANpattern (DutchIBANRecognizer)
BSNpattern (DutchBSNRecognizer)
DATE_TIMEpattern (DutchDateRecognizer)
ID_NOpattern (DutchPassportIdRecognizer)
DRIVERS_LICENSEpattern (DutchDriversLicenseRecognizer)
CASE_NOpattern (CaseNumberRecognizer)
VAT_NUMBERpattern (DutchVATRecognizer)
KVK_NUMBERpattern (DutchKvKRecognizer)
LICENSE_PLATEpattern (DutchLicensePlateRecognizer)
IP_ADDRESSpattern (IPv4Recognizer)

Bron: src/api/config.py:19-50.

Voorgestelde matrix per flavor

Leidend principe:

  • Pattern = altijd precies. Regex-entities horen bij elke flavor die pattern recognizers actief heeft.
  • NER-engine bepaalt of PERSON/LOCATION/ORGANIZATION gedekt zijn.
  • Contextual voegt verificatie toe op pattern-resultaten; declareert geen nieuwe entities, maar wél hogere precisie voor BSN/ID_NO.
Entityclassicgpucontextual
PERSONSpaCytransformer-NER (GLiNER default)SpaCy + verifier
LOCATIONSpaCytransformer-NER (GLiNER default)SpaCy + verifier
ORGANIZATIONSpaCytransformer-NER (GLiNER default)SpaCy + verifier
PHONE_NUMBERpatternpatternpattern
EMAILpatternpatternpattern
IBANpatternpatternpattern
BSNpatternpatternpattern + LLM-verifier*
DATE_TIMEpatternpatternpattern
ID_NOpatternpatternpattern + LLM-verifier*
DRIVERS_LICENSEpatternpatternpattern
CASE_NOpatternpatternpattern
VAT_NUMBERpatternpatternpattern
KVK_NUMBERpatternpatternpattern
LICENSE_PLATEpatternpatternpattern
IP_ADDRESSpatternpatternpattern
custom-labels✓ (via entity_mapping van de transformer-NER)

* LLM-verifier = LLM classificeert pattern-kandidaten binair (is-dit-een-BSN ja/nee op basis van context). Geen vrije extractie.

Validatie-regel

  • Request met entities: [X] waar X niet in de actieve flavor's matrix staat → HTTP 422, geen stille fallback.
  • Request zonder entities → alle entities van de flavor worden gerapporteerd.
  • Response bevat per entity het recognizer-veld zodat clients/auditors zien welke engine de detectie deed (uit te breiden in DTO).

Hoe een entity toevoegen

  1. Nieuwe PatternRecognizer-subclass in src/api/utils/patterns.py (voor vormvaste entities) OF nieuwe entry in plugins.yaml onder de juiste flavor-config (voor NER/LLM-entities).
  2. Matrix hierboven bijwerken — in dezelfde PR.
  3. Test toevoegen in tests/ — per flavor.
  4. ALL_SUPPORTED_ENTITIES in config.py bijwerken.
  5. CHANGELOG-entry onder de volgende versie.

Open vragen

  1. Moet elke flavor alle pattern-entities ondersteunen, of kan classic een minimale subset hebben (bv. alleen AVG-kern: PERSON/EMAIL/PHONE/IBAN/ BSN/DATE_TIME)?
  2. Hoe rapporteren we onzekerheid in responses — alleen score, of ook confidence_band: {high, medium, low} afgeleid van de engine?
  3. recognizer-veld in response: vrijgeven of geheim houden (exposeert interne architectuur)?