8.9 KiB
Audit: Informations-Integrität (Clean-Context v4.2.0)
Datum: 2026-01-10
Version: v4.2.0
Status: Audit abgeschlossen - KRITISCHES PROBLEM IDENTIFIZIERT
Kontext
Das System wurde auf den Gold-Standard v4.2.0 optimiert. Ziel ist der "Clean-Context"-Ansatz: Strukturelle Metadaten (speziell > [!edge] Callouts und definierte Note-Scope Zonen) werden aus den Text-Chunks entfernt, um das semantische Rauschen im Vektor-Index zu reduzieren. Diese Informationen müssen stattdessen exklusiv über den Graphen (Feld explanation im QueryHit) an das LLM geliefert werden.
Audit-Ergebnisse
1. Extraktion vor Filterung (Temporal Integrity) ⚠️ TEILWEISE
✅ Note-Scope Zonen: FUNKTIONIERT
Status: ✅ KORREKT
build_edges_for_note()erhältmarkdown_body(Original-Markdown) als Parameterextract_note_scope_zones()analysiert den unbearbeiteten Markdown-Text- Extraktion erfolgt VOR dem Chunking-Filter
- Code-Referenz:
app/core/graph/graph_derive_edges.pyZeile 152-177
# WP-24c v4.2.0: Note-Scope Zonen Extraktion (VOR Chunk-Verarbeitung)
note_scope_edges: List[dict] = []
if markdown_body:
zone_links = extract_note_scope_zones(markdown_body) # ← Original-Markdown
❌ Callouts in Edge-Zonen: KRITISCHES PROBLEM
Status: ❌ FEHLT
Problem:
build_edges_for_note()extrahiert Callouts aus gefilterten Chunks (Zeile 217-265)- Chunks wurden bereits gefiltert (Edge-Zonen entfernt) in
chunking_processor.pyZeile 38 - Callouts in Edge-Zonen werden NICHT extrahiert!
Code-Referenz:
# app/core/graph/graph_derive_edges.py Zeile 217-265
for ch in chunks: # ← chunks sind bereits gefiltert!
raw = _get(ch, "window") or _get(ch, "text") or ""
# ...
# C. Callouts (> [!edge])
call_pairs, rem2 = extract_callout_relations(rem) # ← rem kommt aus gefilterten chunks
Konsequenz:
- Callouts in Edge-Zonen (z.B.
### Unzugeordnete Kantenoder## Smart Edges) werden nicht in den Graph geschrieben - Informationsverlust: Diese Kanten existieren nicht im Graph und können nicht über
explanationan das LLM geliefert werden
Empfehlung:
- Callouts müssen auch aus dem Original-Markdown (
markdown_body) extrahiert werden - Ähnlich wie
extract_note_scope_zones()sollte eine Funktionextract_callouts_from_markdown()erstellt werden - Diese sollte vor der Chunk-Verarbeitung aufgerufen werden
2. Payload-Vollständigkeit (Explanation-Mapping) ✅ FUNKTIONIERT
Status: ✅ KORREKT (wenn Edges im Graph sind)
Code-Referenz: app/core/retrieval/retriever.py Zeile 188-238
Verifizierung:
- ✅
_build_explanation()sammelt alle Edges aus dem Subgraph (Zeile 189-215) - ✅ Edges werden in
EdgeDTO-Objekte konvertiert (Zeile 205-214) - ✅
related_edgeswerden imExplanation-Objekt gespeichert (Zeile 236) - ✅ Top 3 Edges werden als
Reason-Objekte formuliert (Zeile 217-228)
Einschränkung:
- Funktioniert nur, wenn Edges im Graph sind
- Da Callouts in Edge-Zonen nicht extrahiert werden (siehe Punkt 1), fehlen sie auch in der Explanation
3. Prompt-Sichtbarkeit (RAG-Interface) ⚠️ UNKLAR
Status: ⚠️ TEILWEISE DOKUMENTIERT
Code-Referenz: app/routers/chat.py Zeile 178-274
Verifizierung:
- ✅
explain=Truewird inQueryRequestgesetzt (Zeile 211 indecision_engine.py) - ✅
explanationwird imQueryHitgespeichert (Zeile 334 inretriever.py) - ⚠️ Unklar: Wie wird
explanation.related_edgesim LLM-Prompt verwendet?
Untersuchung:
chat.pyverwendetinterview_templatePrompt (Zeile 212-222)- Prompt-Variablen werden aus
QueryHitextrahiert - Fehlend: Explizite Verwendung von
explanation.related_edgesim Prompt
Empfehlung:
- Prüfen Sie
config/prompts.yamlfürinterview_template - Stellen Sie sicher, dass
{related_edges}oder ähnliche Variablen im Prompt verwendet werden - Dokumentieren Sie die Prompt-Struktur für RAG-Kontext
4. Edge-Case Analyse ⚠️ KRITISCH
Szenario: Callout nur in Edge-Zone (kein Wikilink im Fließtext)
Status: ❌ INFORMATIONSVERLUST
Beispiel:
---
type: decision
title: Meine Notiz
---
# Hauptinhalt
Dieser Text wird gechunkt.
## Smart Edges
> [!edge] depends_on
> [[Projekt Alpha]]
## Weiterer Inhalt
Mehr Text...
Aktuelles Verhalten:
- ✅
## Smart Edgeswird als Edge-Zone erkannt - ✅ Zone wird vom Chunking ausgeschlossen
- ❌ Callout wird NICHT extrahiert (weil aus gefilterten Chunks extrahiert wird)
- ❌ Kante fehlt im Graph
- ❌ Kante fehlt in Explanation
- ❌ LLM erhält keine Information über diese Verbindung
Konsequenz:
- Wissens-Vakuum: Die Information existiert weder im Chunk-Text noch im Graph
- Semantische Verbindung verloren: Das LLM kann diese Verbindung nicht berücksichtigen
Zusammenfassung der Probleme
❌ KRITISCH: Callout-Extraktion aus Edge-Zonen fehlt
Problem:
- Callouts werden nur aus gefilterten Chunks extrahiert
- Callouts in Edge-Zonen werden nicht erfasst
- Informationsverlust: Diese Kanten fehlen im Graph
Lösung:
- Erstellen Sie
extract_callouts_from_markdown(markdown_body: str)Funktion - Rufen Sie diese vor der Chunk-Verarbeitung auf
- Integrieren Sie die extrahierten Callouts in
build_edges_for_note()
⚠️ WARNUNG: Prompt-Integration unklar
Problem:
- Unklar, ob
explanation.related_edgesim LLM-Prompt verwendet werden - Keine explizite Dokumentation der Prompt-Struktur
Empfehlung:
- Prüfen Sie
config/prompts.yamlfürinterview_template - Dokumentieren Sie die Verwendung von
related_edgesim Prompt
Empfohlene Fixes
Fix 1: Callout-Extraktion aus Original-Markdown
Datei: app/core/graph/graph_derive_edges.py
Änderung:
def extract_callouts_from_markdown(markdown_body: str, note_id: str) -> List[dict]:
"""
WP-24c v4.2.0: Extrahiert Callouts aus dem Original-Markdown.
Wird verwendet, um Callouts in Edge-Zonen zu erfassen, die nicht in Chunks sind.
"""
if not markdown_body:
return []
edges: List[dict] = []
# Extrahiere alle Callouts aus dem gesamten Markdown
call_pairs, _ = extract_callout_relations(markdown_body)
for k, raw_t in call_pairs:
t, sec = parse_link_target(raw_t, note_id)
if not t:
continue
# Bestimme scope: "note" wenn in Note-Scope Zone, sonst "chunk"
# (Für jetzt: scope="note" für alle Callouts aus Markdown)
payload = {
"edge_id": _mk_edge_id(k, note_id, t, "note", target_section=sec),
"provenance": "explicit:callout",
"rule_id": "callout:edge",
"confidence": PROVENANCE_PRIORITY.get("callout:edge", 1.0)
}
if sec:
payload["target_section"] = sec
edges.append(_edge(
kind=k,
scope="note",
source_id=note_id,
target_id=t,
note_id=note_id,
payload=payload
))
return edges
def build_edges_for_note(
note_id: str,
chunks: List[dict],
note_level_references: Optional[List[str]] = None,
include_note_scope_refs: bool = False,
markdown_body: Optional[str] = None,
) -> List[dict]:
# ... existing code ...
# WP-24c v4.2.0: Callout-Extraktion aus Original-Markdown (VOR Chunk-Verarbeitung)
if markdown_body:
callout_edges = extract_callouts_from_markdown(markdown_body, note_id)
edges.extend(callout_edges)
# ... rest of function ...
Fix 2: Prompt-Dokumentation
Datei: config/prompts.yaml und Dokumentation
Empfehlung:
- Prüfen Sie, ob
interview_template{related_edges}verwendet - Falls nicht: Erweitern Sie den Prompt um Graph-Kontext
- Dokumentieren Sie die Prompt-Struktur
Validierung nach Fix
Nach Implementierung der Fixes sollte folgendes verifiziert werden:
-
✅ Callouts in Edge-Zonen werden extrahiert
- Test: Erstellen Sie eine Notiz mit Callout in
## Smart Edges - Verifizieren: Edge existiert in Qdrant
_edgesCollection
- Test: Erstellen Sie eine Notiz mit Callout in
-
✅ Edges erscheinen in Explanation
- Test: Query mit
explain=True - Verifizieren:
explanation.related_edgesenthält die Callout-Edge
- Test: Query mit
-
✅ LLM erhält Graph-Kontext
- Test: Chat-Query mit Edge-Information
- Verifizieren: LLM-Antwort berücksichtigt die Graph-Verbindung
Fazit
Aktueller Status: ⚠️ INFORMATIONSVERLUST BEI CALLOUTS IN EDGE-ZONEN
Hauptproblem:
- Callouts in Edge-Zonen werden nicht extrahiert
- Diese Information geht vollständig verloren
Lösung:
- Implementierung von
extract_callouts_from_markdown()erforderlich - Integration in
build_edges_for_note()vor Chunk-Verarbeitung
Nach Fix:
- ✅ Alle Callouts werden erfasst (auch in Edge-Zonen)
- ✅ Graph-Vollständigkeit gewährleistet
- ✅ Explanation enthält alle relevanten Edges
- ✅ LLM erhält vollständigen Kontext