BAV_KI / src /norm_rang.py
AlixJabda's picture
Aktualisierung der AM-RL-Module und Retrieval-Logik
d80690d
Raw
History Blame Contribute Delete
3.73 kB
"""Welchen Rang eine Fundstelle hat — damit die Antwort sie einordnen kann.
Der Quellenblock nennt bisher das Dokument („Rahmenvertrag nach § 129 Absatz 2
SGB V"), und das reicht, um § 16 des Vertrages von § 16 SGB V zu unterscheiden.
Es reicht nicht, um zu entscheiden, welche der beiden die Frage **trägt**.
Die Metadaten helfen dabei nicht: `container_type` steht bei rv129, amabrv
*und* amrl auf „vertrag" — die Richtlinie ist über denselben Ingest-Pfad
gelaufen wie die Vertragswerke. Wer den Rang daraus liest, hält die
Arzneimittel-Richtlinie für einen Vertrag. Deshalb eine kuratierte Zuordnung
über die Korpus-Id, wie bei den übrigen Registern dieses Projekts.
**Warum der Rang in den Kontext gehört.** Die Auswertung zeigte Antworten, die
eine Anlage oder eine Ausführungsregelung als „Maßgebliche Norm" führten,
obwohl die tragende Vorschrift im selben Kontext stand. Das ist kein
Zitierfehler, sondern eine falsche Herleitung: Anlage VII Teil A sagt, welche
Darreichungsformen austauschbar sind, aber *dass* ausgetauscht werden darf,
ordnet § 129 Abs. 1 SGB V an und konkretisiert § 40 AM-RL. Wer nur die Anlage
nennt, nennt das Ergebnis ohne seinen Grund.
**Der Rang ist eine Angabe, keine Rangfolge.** Dieses Modul sagt, was eine
Quelle *ist* — Gesetz, Richtlinie, Vertrag, Anlage. Es sagt nicht, welche
Vorschrift vorgeht; das hängt am Fall und bleibt beim Modell und beim
Ankerregister. Eine automatische Regel „Gesetz schlägt Vertrag" wäre hier
falsch: der Rahmenvertrag konkretisiert § 129 SGB V bindend, und für die Frage,
welches Fertigarzneimittel abzugeben ist, ist er die genauere Vorschrift.
"""
from __future__ import annotations
from typing import Any, Dict
# Korpus-Id -> Rang, mit der Norm, auf der das Regelwerk beruht. Die Klammer
# ist der eigentliche Nutzen: sie nennt dem Modell die Ermächtigungsgrundlage,
# die es sonst erraten müsste.
RANG_JE_KORPUS: Dict[str, str] = {
"sgb5": "Gesetz",
"rv129": "Vertrag nach § 129 Abs. 2 SGB V",
"amabrv": "Vertrag nach § 300 Abs. 3 SGB V",
"amrl": "Richtlinie nach § 92 Abs. 1 Satz 2 Nr. 6 SGB V",
}
# Fällt die Korpus-Id aus (Einzelkorpus-Betrieb, alte Trefferdicts), trägt die
# doc_id dieselbe Auskunft — sie wird vom Ingest aus dem Dokument gebildet.
_RANG_JE_DOC_PREFIX = (
("SGB_V", "Gesetz"),
("RV_129", "Vertrag nach § 129 Abs. 2 SGB V"),
("AMAbrV", "Vertrag nach § 300 Abs. 3 SGB V"),
("AM_RL", "Richtlinie nach § 92 Abs. 1 Satz 2 Nr. 6 SGB V"),
)
def _wert(hit: Dict[str, Any], *keys: str) -> str:
metadata = hit.get("metadata") or {}
for key in keys:
value = hit.get(key) or metadata.get(key)
if value:
return str(value)
return ""
def rang(hit: Dict[str, Any]) -> str:
"""Der Rang einer Fundstelle, als eine Zeile für den Quellenblock.
Anlagen werden gesondert ausgewiesen, weil sie im Index Container ihres
eigenen Regelwerks sind: § 10 gibt es im Rahmenvertrag und in dessen Anlage
11. Eine Fundstelle aus der Anlage als „Vertrag" auszuweisen, verwischt
genau den Unterschied, den die Zeile sichtbar machen soll.
"""
korpus = _wert(hit, "corpus_id")
grundrang = RANG_JE_KORPUS.get(korpus, "")
if not grundrang:
doc_id = _wert(hit, "doc_id")
for prefix, wert in _RANG_JE_DOC_PREFIX:
if doc_id.startswith(prefix):
grundrang = wert
break
container = _wert(hit, "container", "container_id")
if container.strip().lower().startswith("anlage"):
return f"Anlage zum Regelwerk ({container})" if not grundrang else (
f"Anlage zu: {grundrang} ({container})"
)
return grundrang