# Audit: Retriever & Scoring (Gold-Standard v4.1.0) **Datum:** 2026-01-10 **Version:** v4.1.0 **Status:** Audit abgeschlossen, Optimierungen implementiert ## Kontext Das Ingestion-System wurde auf den Gold-Standard v4.1.0 aktualisiert. Die Kanten-Identität ist nun deterministisch und hochpräzise mit strikter Trennung zwischen: - **Chunk-Scope-Edges:** Präzise Links aus Textabsätzen (Source = `chunk_id`), oft mit `target_section` - **Note-Scope-Edges:** Strukturelle Links und Symmetrien (Source = `note_id`) - **Multigraph-Support:** Identische Note-Verbindungen bleiben als separate Points erhalten, wenn sie auf unterschiedliche Sektionen zeigen oder aus unterschiedlichen Chunks stammen ## Prüffragen & Ergebnisse ### 1. Scope-Awareness ❌ **KRITISCH** **Frage:** Sucht der Retriever bei einer Note-Anfrage sowohl nach Abgangskanten der `note_id` als auch nach Abgangskanten aller zugehörigen `chunk_ids`? **Aktueller Status:** - ❌ **NEIN**: Der Retriever sucht nur nach Edges, die von `note_id` ausgehen - Die Graph-Expansion in `graph_db_adapter.py` filtert nur nach `source_id`, `target_id` und `note_id` - Chunk-Level Edges (`scope="chunk"`) werden nicht explizit berücksichtigt - **Risiko:** Datenverlust bei präzisen Chunk-Links **Empfehlung:** - Erweitere `fetch_edges_from_qdrant` um explizite Suche nach `chunk_id`-Edges - Bei Note-Anfragen: Lade alle Chunks der Note und suche nach deren Edges - Aggregiere Chunk-Edges in Note-Level Scoring ### 2. Section-Filtering ❌ **FEHLT** **Frage:** Kann der Retriever bei einem Sektions-Link (`[[Note#Sektion]]`) die Ergebnismenge in Qdrant gezielt auf Chunks filtern, die das entsprechende `section`-Attribut im Payload tragen? **Aktueller Status:** - ❌ **NEIN**: Es gibt keine Filterung nach `target_section` - `target_section` wird zwar im Edge-Payload gespeichert, aber nicht für Filterung verwendet - **Risiko:** Unpräzise Ergebnisse bei Section-Links **Empfehlung:** - Erweitere `QueryRequest` um optionales `target_section` Feld - Implementiere Filterung in `_semantic_hits` und `fetch_edges_from_qdrant` - Nutze `target_section` für präzise Chunk-Filterung ### 3. Scoring-Aggregation ⚠️ **TEILWEISE** **Frage:** Wie geht das Scoring damit um, wenn ein Ziel von mehreren Chunks derselben Note referenziert wird? Wird die Relevanz (In-Degree) auf Chunk-Ebene korrekt akkumuliert? **Aktueller Status:** - ⚠️ **TEILWEISE**: Super-Edge-Aggregation existiert (WP-15c), aber: - Aggregiert nur nach Ziel-Note (`target_id`), nicht nach Chunk-Level - Mehrere Chunks derselben Note, die auf dasselbe Ziel zeigen, werden nicht korrekt akkumuliert - Die "Beweislast" (In-Degree) wird nicht auf Chunk-Ebene berechnet - **Risiko:** Unterbewertung von Zielen, die von mehreren Chunks referenziert werden **Empfehlung:** - Erweitere Super-Edge-Aggregation um Chunk-Level Tracking - Berechne In-Degree sowohl auf Note- als auch auf Chunk-Ebene - Nutze Chunk-Level In-Degree als zusätzlichen Boost-Faktor ### 4. Authority-Priorisierung ⚠️ **TEILWEISE** **Frage:** Nutzt das Scoring das Feld `provenance_priority` oder `confidence`, um manuelle "Explicit"-Kanten gegenüber "Virtual"-Symmetrien bei der Sortierung zu bevorzugen? **Aktueller Status:** - ⚠️ **TEILWEISE**: - Provenance-Weighting existiert (Zeile 344-345 in `retriever.py`) - Nutzt aber nicht `confidence` oder `provenance_priority` aus dem Payload - Hardcoded Gewichtung: `explicit=1.0`, `smart=0.9`, `rule=0.7` - `virtual` Flag wird nicht berücksichtigt - **Risiko:** Virtual-Symmetrien werden nicht korrekt de-priorisiert **Empfehlung:** - Nutze `confidence` aus dem Edge-Payload - Berücksichtige `virtual` Flag für explizite De-Priorisierung - Integriere `PROVENANCE_PRIORITY` aus `graph_utils.py` statt Hardcoding ### 5. RAG-Kontext ❌ **FEHLT** **Frage:** Wird beim Retrieval einer Kante der `source_id` (Chunk) direkt mitgeliefert, damit das LLM den exakten Herkunfts-Kontext der Verbindung erhält? **Aktueller Status:** - ❌ **NEIN**: `source_id` (Chunk-ID) wird nicht explizit im `QueryHit` mitgeliefert - Edge-Payload enthält `source_id`, aber es wird nicht in den RAG-Kontext übernommen - **Risiko:** LLM erhält keinen Kontext über die Herkunft der Verbindung **Empfehlung:** - Erweitere `QueryHit` um `source_chunk_id` Feld - Bei Chunk-Scope Edges: Lade den Quell-Chunk-Text für RAG-Kontext - Integriere Chunk-Kontext in Explanation Layer ## Implementierte Optimierungen Siehe: `app/core/retrieval/retriever.py` (v0.8.0) und `app/core/graph/graph_db_adapter.py` (v1.2.0) ### Änderungen 1. **Scope-Aware Edge Retrieval** - `fetch_edges_from_qdrant` sucht nun explizit nach `chunk_id`-Edges - Bei Note-Anfragen werden alle zugehörigen Chunks geladen 2. **Section-Filtering** - `QueryRequest` unterstützt optionales `target_section` Feld - Filterung in `_semantic_hits` und Edge-Retrieval implementiert 3. **Chunk-Level Aggregation** - Super-Edge-Aggregation erweitert um Chunk-Level Tracking - In-Degree wird sowohl auf Note- als auch Chunk-Ebene berechnet 4. **Authority-Priorisierung** - Nutzung von `confidence` und `PROVENANCE_PRIORITY` - `virtual` Flag wird für De-Priorisierung berücksichtigt 5. **RAG-Kontext** - `QueryHit` erweitert um `source_chunk_id` - Chunk-Kontext wird in Explanation Layer integriert ## Validierung - ✅ Scope-Awareness: Note- und Chunk-Edges werden korrekt geladen - ✅ Section-Filtering: Präzise Filterung nach `target_section` funktioniert - ✅ Scoring-Aggregation: Chunk-Level In-Degree wird korrekt akkumuliert - ✅ Authority-Priorisierung: Explicit-Kanten werden bevorzugt - ✅ RAG-Kontext: `source_chunk_id` wird mitgeliefert ## Nächste Schritte 1. Performance-Tests mit großen Vaults 2. Integration in Decision Engine 3. Dokumentation der neuen Features