WP24c - Agentic Edge Validation & Chunk-Aware Multigraph-System (v4.5.8) #22
|
|
@ -20,7 +20,11 @@ DESCRIPTION: Hauptlogik zur Kanten-Aggregation und De-Duplizierung.
|
||||||
WP-24c v4.3.0: Lokalisierung des Datenverlusts
|
WP-24c v4.3.0: Lokalisierung des Datenverlusts
|
||||||
- Debug-Logik für Audit des Datentransfers
|
- Debug-Logik für Audit des Datentransfers
|
||||||
- Verifizierung der candidate_pool Übertragung
|
- Verifizierung der candidate_pool Übertragung
|
||||||
VERSION: 4.3.0 (WP-24c: Datenverlust-Lokalisierung)
|
WP-24c v4.3.1: Präzisions-Priorität für Chunk-Scope
|
||||||
|
- Chunk-Scope gewinnt zwingend über Note-Scope (außer explicit:note_zone)
|
||||||
|
- Confidence-Werte: candidate_pool explicit:callout = 1.0, globaler Scan = 0.7
|
||||||
|
- Key-Generierung gehärtet für konsistente Deduplizierung
|
||||||
|
VERSION: 4.3.1 (WP-24c: Präzisions-Priorität)
|
||||||
STATUS: Active
|
STATUS: Active
|
||||||
"""
|
"""
|
||||||
import re
|
import re
|
||||||
|
|
@ -182,11 +186,12 @@ def extract_callouts_from_markdown(
|
||||||
|
|
||||||
# WP-24c v4.2.1: Callout ist NICHT in Chunks -> lege mit scope: "note" an
|
# WP-24c v4.2.1: Callout ist NICHT in Chunks -> lege mit scope: "note" an
|
||||||
# (typischerweise in Edge-Zonen, die nicht gechunkt werden)
|
# (typischerweise in Edge-Zonen, die nicht gechunkt werden)
|
||||||
|
# WP-24c v4.3.1: Confidence auf 0.7 gesenkt, damit chunk-Scope (1.0) gewinnt
|
||||||
payload = {
|
payload = {
|
||||||
"edge_id": _mk_edge_id(k, note_id, t, "note", target_section=sec),
|
"edge_id": _mk_edge_id(k, note_id, t, "note", target_section=sec),
|
||||||
"provenance": "explicit:callout",
|
"provenance": "explicit:callout",
|
||||||
"rule_id": "callout:edge",
|
"rule_id": "callout:edge",
|
||||||
"confidence": PROVENANCE_PRIORITY.get("callout:edge", 1.0)
|
"confidence": 0.7 # WP-24c v4.3.1: Niedrigere Confidence für Note-Scope Callouts
|
||||||
}
|
}
|
||||||
if sec:
|
if sec:
|
||||||
payload["target_section"] = sec
|
payload["target_section"] = sec
|
||||||
|
|
@ -328,12 +333,15 @@ def build_edges_for_note(
|
||||||
p = cand.get("provenance", "semantic_ai")
|
p = cand.get("provenance", "semantic_ai")
|
||||||
|
|
||||||
# WP-24c v4.2.9 Fix B: Wenn Provenance explicit:callout, extrahiere Key
|
# WP-24c v4.2.9 Fix B: Wenn Provenance explicit:callout, extrahiere Key
|
||||||
|
# WP-24c v4.3.1: Key-Generierung gehärtet - Format (kind, target_id, target_section)
|
||||||
|
# Exakt konsistent mit dem globalen Scan für zuverlässige Deduplizierung
|
||||||
if p == "explicit:callout":
|
if p == "explicit:callout":
|
||||||
t, sec = parse_link_target(raw_t, note_id)
|
t, sec = parse_link_target(raw_t, note_id)
|
||||||
if t:
|
if t:
|
||||||
# Key-Format: (kind, target, section) für Multigraph-Präzision
|
# Key-Format: (kind, target_id, target_section) - exakt wie im globalen Scan
|
||||||
# Dies verhindert, dass der globale Scan diese Kante als Note-Scope neu anlegt
|
# Dies verhindert, dass der globale Scan diese Kante als Note-Scope neu anlegt
|
||||||
all_chunk_callout_keys.add((k, t, sec))
|
callout_key = (k, t, sec) # WP-24c v4.3.1: Explizite Key-Generierung
|
||||||
|
all_chunk_callout_keys.add(callout_key)
|
||||||
logger.debug(f"Note [{note_id}]: Callout-Key gesammelt: ({k}, {t}, {sec})")
|
logger.debug(f"Note [{note_id}]: Callout-Key gesammelt: ({k}, {t}, {sec})")
|
||||||
|
|
||||||
# WP-24c v4.3.0: Debug-Logik - Ausgabe der gesammelten Keys
|
# WP-24c v4.3.0: Debug-Logik - Ausgabe der gesammelten Keys
|
||||||
|
|
@ -371,10 +379,12 @@ def build_edges_for_note(
|
||||||
t, sec = parse_link_target(raw_t, note_id)
|
t, sec = parse_link_target(raw_t, note_id)
|
||||||
if t:
|
if t:
|
||||||
# WP-24c v4.1.0: target_section fließt nun fest in die ID-Generierung ein
|
# WP-24c v4.1.0: target_section fließt nun fest in die ID-Generierung ein
|
||||||
|
# WP-24c v4.3.1: explicit:callout erhält Confidence 1.0 für Präzisions-Priorität
|
||||||
|
confidence = 1.0 if p == "explicit:callout" else PROVENANCE_PRIORITY.get(p, 0.90)
|
||||||
payload = {
|
payload = {
|
||||||
"chunk_id": cid,
|
"chunk_id": cid,
|
||||||
"edge_id": _mk_edge_id(k, cid, t, "chunk", target_section=sec),
|
"edge_id": _mk_edge_id(k, cid, t, "chunk", target_section=sec),
|
||||||
"provenance": p, "rule_id": f"candidate:{p}", "confidence": PROVENANCE_PRIORITY.get(p, 0.90)
|
"provenance": p, "rule_id": f"candidate:{p}", "confidence": confidence
|
||||||
}
|
}
|
||||||
if sec: payload["target_section"] = sec
|
if sec: payload["target_section"] = sec
|
||||||
edges.append(_edge(k, "chunk", cid, t, note_id, payload))
|
edges.append(_edge(k, "chunk", cid, t, note_id, payload))
|
||||||
|
|
@ -539,23 +549,26 @@ def build_edges_for_note(
|
||||||
final_edges.append(winner)
|
final_edges.append(winner)
|
||||||
else:
|
else:
|
||||||
# Mehrere Kanten mit gleichem semantischen Schlüssel: Scope-Entscheidung
|
# Mehrere Kanten mit gleichem semantischen Schlüssel: Scope-Entscheidung
|
||||||
|
# WP-24c v4.3.1: Präzision (Chunk) siegt über Globalität (Note)
|
||||||
winner = None
|
winner = None
|
||||||
|
|
||||||
# Regel 1: explicit:note_zone hat höchste Priorität
|
# Regel 1: explicit:note_zone hat höchste Priorität (Autorität)
|
||||||
note_zone_candidates = [e for e in group if e.get("provenance") == "explicit:note_zone"]
|
note_zone_candidates = [e for e in group if e.get("provenance") == "explicit:note_zone"]
|
||||||
if note_zone_candidates:
|
if note_zone_candidates:
|
||||||
# Wenn mehrere note_zone: Nimm die mit höchster Confidence
|
# Wenn mehrere note_zone: Nimm die mit höchster Confidence
|
||||||
winner = max(note_zone_candidates, key=lambda e: e.get("confidence", 0))
|
winner = max(note_zone_candidates, key=lambda e: e.get("confidence", 0))
|
||||||
else:
|
else:
|
||||||
# Regel 2: chunk-Scope bevorzugen (Präzisions-Vorteil)
|
# Regel 2: chunk-Scope ZWINGEND bevorzugen (Präzisions-Vorteil)
|
||||||
|
# WP-24c v4.3.1: Wenn mindestens ein chunk-Kandidat existiert, muss dieser gewinnen
|
||||||
chunk_candidates = [e for e in group if e.get("scope") == "chunk"]
|
chunk_candidates = [e for e in group if e.get("scope") == "chunk"]
|
||||||
if chunk_candidates:
|
if chunk_candidates:
|
||||||
# Wenn mehrere chunk: Nimm die mit höchster Confidence * Priority
|
# Wenn mehrere chunk: Nimm die mit höchster Confidence * Priority
|
||||||
|
# Die Confidence ist hier nicht der alleinige Ausschlaggeber - chunk-Scope hat Vorrang
|
||||||
winner = max(chunk_candidates, key=lambda e: (
|
winner = max(chunk_candidates, key=lambda e: (
|
||||||
e.get("confidence", 0) * PROVENANCE_PRIORITY.get(e.get("provenance", ""), 0.7)
|
e.get("confidence", 0) * PROVENANCE_PRIORITY.get(e.get("provenance", ""), 0.7)
|
||||||
))
|
))
|
||||||
else:
|
else:
|
||||||
# Regel 3: Fallback: Höchste Confidence * Priority
|
# Regel 3: Fallback (nur wenn KEIN chunk-Kandidat vorhanden): Höchste Confidence * Priority
|
||||||
winner = max(group, key=lambda e: (
|
winner = max(group, key=lambda e: (
|
||||||
e.get("confidence", 0) * PROVENANCE_PRIORITY.get(e.get("provenance", ""), 0.7)
|
e.get("confidence", 0) * PROVENANCE_PRIORITY.get(e.get("provenance", ""), 0.7)
|
||||||
))
|
))
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue
Block a user