Rücksprung zur Vorwersion, in der 2 Kantentypen angelegt wurden
This commit is contained in:
parent
03d3173ca6
commit
b7d1bcce3d
|
|
@ -4,7 +4,7 @@ DESCRIPTION: Hauptlogik zur Kanten-Aggregation und De-Duplizierung.
|
||||||
AUDIT:
|
AUDIT:
|
||||||
- Nutzt parse_link_target
|
- Nutzt parse_link_target
|
||||||
- Übergibt Section als 'variant' an ID-Gen
|
- Übergibt Section als 'variant' an ID-Gen
|
||||||
- FIXED: Semantische De-Duplizierung via 'sem_key' (löst das Callout-Problem)
|
- Dedup basiert jetzt auf Edge-ID (erlaubt Multigraph für Sections)
|
||||||
"""
|
"""
|
||||||
from typing import List, Optional, Dict, Tuple
|
from typing import List, Optional, Dict, Tuple
|
||||||
from .graph_utils import (
|
from .graph_utils import (
|
||||||
|
|
@ -124,6 +124,7 @@ def build_edges_for_note(
|
||||||
if sec: def_payload["target_section"] = sec
|
if sec: def_payload["target_section"] = sec
|
||||||
edges.append(_edge(rel, "chunk", cid, r, note_id, def_payload))
|
edges.append(_edge(rel, "chunk", cid, r, note_id, def_payload))
|
||||||
|
|
||||||
|
# Für Note-Scope Sammlung nutzen wir den Original-String zur Dedup, aber gesäubert
|
||||||
refs_all.extend([parse_link_target(r, note_id)[0] for r in refs])
|
refs_all.extend([parse_link_target(r, note_id)[0] for r in refs])
|
||||||
|
|
||||||
# 3) Note-Scope & De-Duplizierung
|
# 3) Note-Scope & De-Duplizierung
|
||||||
|
|
@ -144,32 +145,13 @@ def build_edges_for_note(
|
||||||
"provenance": "rule", "confidence": PROVENANCE_PRIORITY["derived:backlink"]
|
"provenance": "rule", "confidence": PROVENANCE_PRIORITY["derived:backlink"]
|
||||||
}))
|
}))
|
||||||
|
|
||||||
# ----------------------------------------------------------------------------------
|
# Deduplizierung: Wir nutzen jetzt die EDGE-ID als Schlüssel.
|
||||||
# FIX: Semantische Deduplizierung
|
# Da die Edge-ID nun 'variant' (Section) enthält, bleiben unterschiedliche Sections erhalten.
|
||||||
# Hier lösen wir das Problem, dass Callout-Kanten andere überschreiben.
|
|
||||||
# Wir nutzen einen Key aus (Source, Target, Kind, Section), um Duplikate
|
|
||||||
# aus verschiedenen Regeln (z.B. callout vs. wikilink) zusammenzuführen.
|
|
||||||
# ----------------------------------------------------------------------------------
|
|
||||||
unique_map: Dict[str, dict] = {}
|
unique_map: Dict[str, dict] = {}
|
||||||
|
|
||||||
for e in edges:
|
for e in edges:
|
||||||
# Semantischer Schlüssel: Unabhängig von rule_id oder edge_id
|
eid = e["edge_id"]
|
||||||
src = e.get("source_id", "")
|
# Bei Konflikt (gleiche ID = exakt gleiche Kante und Section) gewinnt die höhere Confidence
|
||||||
tgt = e.get("target_id", "")
|
if eid not in unique_map or e.get("confidence", 0) > unique_map[eid].get("confidence", 0):
|
||||||
kind = e.get("kind", "")
|
unique_map[eid] = e
|
||||||
sec = e.get("target_section", "")
|
|
||||||
|
|
||||||
# Dieser Key ist für alle Einträge im Callout-Block UNTERSCHIEDLICH,
|
|
||||||
# da 'sec' (1) Integrität, 3) Disziplin...) unterschiedlich ist.
|
|
||||||
sem_key = f"{src}->{tgt}:{kind}@{sec}"
|
|
||||||
|
|
||||||
if sem_key not in unique_map:
|
|
||||||
unique_map[sem_key] = e
|
|
||||||
else:
|
|
||||||
# Konfliktlösung: Die Kante mit der höheren Confidence gewinnt
|
|
||||||
curr_conf = unique_map[sem_key].get("confidence", 0.0)
|
|
||||||
new_conf = e.get("confidence", 0.0)
|
|
||||||
if new_conf > curr_conf:
|
|
||||||
unique_map[sem_key] = e
|
|
||||||
|
|
||||||
return list(unique_map.values())
|
return list(unique_map.values())
|
||||||
Loading…
Reference in New Issue
Block a user