From 5baac082f9b9c4dc7ba73c5eb177625ff8aa6095 Mon Sep 17 00:00:00 2001 From: Lars Date: Thu, 4 Dec 2025 11:52:18 +0100 Subject: [PATCH] app/core/graph_adapter.py aktualisiert --- app/core/graph_adapter.py | 52 +++++++++++++++++++++++++++++++++++---- 1 file changed, 47 insertions(+), 5 deletions(-) diff --git a/app/core/graph_adapter.py b/app/core/graph_adapter.py index 599c48b..2ab73a1 100644 --- a/app/core/graph_adapter.py +++ b/app/core/graph_adapter.py @@ -14,8 +14,10 @@ Kompatibilität: (tests/test_retriever_edges.py patcht expand()). Version: - 0.3.0 (2025-12-04 – note_id-bewusste Expansion, zusätzliche Edge-Typ-Gewichte, - Subgraph.edge_bonus() für Kompatibilität zum Retriever) + 0.3.1 (2025-12-04 – note_id-bewusste Expansion: + * Seeds = Note-IDs + * Subgraph pflegt zusätzlich Adjazenz auf note_id-Basis, + damit der Retriever mit note_id arbeiten kann) """ from __future__ import annotations @@ -161,14 +163,31 @@ class Subgraph: self.out_degree: DefaultDict[str, int] = defaultdict(int) def add_edge(self, e: Dict) -> None: - src = e["source"] - tgt = e["target"] - kind = e["kind"] + """ + Fügt eine Kante zum Subgraph hinzu. + + e enthält: + - source: Knoten-ID (z. B. source_id) + - target: Knoten-ID (z. B. target_id) + - kind: Kantentyp + - weight: bereits berechnetes Gewicht + - note_id: (optional) Kontext-Note dieser Kante + + Wichtig für den Retriever: + - Wir pflegen Adjazenz primär unter `source`. + - Zusätzlich pflegen wir, falls vorhanden, eine Adjazenz + unter `note_id`, damit der Retriever mit note_id arbeiten kann. + """ + src = e.get("source") + tgt = e.get("target") + kind = e.get("kind") weight = e.get("weight", EDGE_BASE_WEIGHTS.get(kind, 0.0)) + owner = e.get("note_id") if not src or not tgt: return + # Primäre Adjazenz (z. B. source_id → target_id) self.adj[src].append( { "target": tgt, @@ -179,6 +198,27 @@ class Subgraph: self.out_degree[src] += 1 self.in_degree[tgt] += 1 + # Sekundäre Adjazenz auf Note-Ebene: + # Falls eine Kontext-Note existiert, bekommt diese ebenfalls + # "Ausgangskanten" angerechnet. So kann der Retriever über note_id + # edge_bonus(...) und centrality_bonus(...) abfragen. + if owner: + # same edge unter owner registrieren (falls nicht identisch mit src), + # damit edge_bonus(owner) > 0 werden kann. + if owner != src: + self.adj[owner].append( + { + "target": tgt, + "kind": kind, + "weight": weight, + } + ) + self.out_degree[owner] += 1 + + # Zentralität der Kontext-Note leicht erhöhen + if owner != tgt: + self.in_degree[owner] += 1 + def aggregate_edge_bonus(self, node_id: str) -> float: """ Summe der ausgehenden Kantengewichte für einen Knoten. @@ -245,12 +285,14 @@ def expand( src = pl.get("source_id") tgt = pl.get("target_id") kind = pl.get("kind", "edge") + owner = pl.get("note_id") e = { "source": src, "target": tgt, "kind": kind, "weight": _edge_weight(pl), + "note_id": owner, } sg.add_edge(e)