511 lines
20 KiB
Markdown
511 lines
20 KiB
Markdown
|
|
# System-Integrity & Regression-Audit (v4.5.8)
|
||
|
|
|
||
|
|
**Datum:** 2026-01-XX
|
||
|
|
**Version:** v4.5.8
|
||
|
|
**Status:** Audit abgeschlossen
|
||
|
|
**Auditor:** AI Assistant (Auto)
|
||
|
|
|
||
|
|
## Kontext
|
||
|
|
|
||
|
|
Nach umfangreichen Änderungen in WP24c (insbesondere v4.5.7/8) wurde ein vollständiges System-Integrity & Regression-Audit durchgeführt, um sicherzustellen, dass keine unbeabsichtigten Beeinträchtigungen oder "Logic-Drift" eingeführt wurden.
|
||
|
|
|
||
|
|
## Audit-Scope
|
||
|
|
|
||
|
|
1. **WP-22 Scoring Integrität**: Prüfung der mathematischen Berechnung des `total_score`
|
||
|
|
2. **WP-25a/b MoE & Prompts**: Verifizierung der Profil-Ladung und MoE-Kaskade
|
||
|
|
3. **Deduplizierungs-Logik**: Prüfung der De-Duplizierung von Kanten
|
||
|
|
4. **Phase 3 Validierungs-Gate**: Verifizierung der neuen Validierungs-Logik
|
||
|
|
5. **Note-Scope Kontext-Optimierung**: Prüfung der Kontext-Optimierung
|
||
|
|
|
||
|
|
---
|
||
|
|
|
||
|
|
## 1. WP-22 Scoring Integrität
|
||
|
|
|
||
|
|
### Prüfpunkt: Hat die Einführung von `candidate:` oder `verified` Status Auswirkungen auf die mathematische Berechnung des `total_score`?
|
||
|
|
|
||
|
|
**Status:** ✅ **KEIN PROBLEM**
|
||
|
|
|
||
|
|
**Ergebnis:**
|
||
|
|
- `candidate:` und `verified` sind **KEINE Status-Werte** für die Scoring-Funktion
|
||
|
|
- Sie sind **Präfixe** in `rule_id` und `provenance` für Kanten (Edge-Metadaten)
|
||
|
|
- Die `get_status_multiplier()` Funktion in `retriever_scoring.py` behandelt ausschließlich:
|
||
|
|
- `stable`: 1.2 (Multiplikator)
|
||
|
|
- `active`: 1.0 (Standard)
|
||
|
|
- `draft`: 0.5 (Dämpfung)
|
||
|
|
- Die mathematische Formel in `compute_wp22_score()` bleibt vollständig unangetastet
|
||
|
|
|
||
|
|
**Code-Referenz:**
|
||
|
|
- `app/core/retrieval/retriever_scoring.py` Zeile 49-63: `get_status_multiplier()`
|
||
|
|
- `app/core/retrieval/retriever_scoring.py` Zeile 65-128: `compute_wp22_score()`
|
||
|
|
|
||
|
|
**Bewertung:** Die Scoring-Mathematik ist **vollständig isoliert** von den Edge-Metadaten (`candidate:`, `verified`). Keine Regression festgestellt.
|
||
|
|
|
||
|
|
---
|
||
|
|
|
||
|
|
## 2. WP-25a/b MoE & Prompts
|
||
|
|
|
||
|
|
### Prüfpunkt 2a: Werden die korrekten Profile aus `llm_profiles.yaml` geladen?
|
||
|
|
|
||
|
|
**Status:** ✅ **FUNKTIONIERT KORREKT**
|
||
|
|
|
||
|
|
**Ergebnis:**
|
||
|
|
- `LLMService._load_llm_profiles()` lädt Profile aus `llm_profiles.yaml` (nicht `prompts.yaml`)
|
||
|
|
- Pfad wird korrekt aus Settings geladen: `LLM_PROFILES_PATH` (Default: `config/llm_profiles.yaml`)
|
||
|
|
- Profile werden im `__init__` geladen und im Instanz-Attribut `self.profiles` gespeichert
|
||
|
|
- Fehlerbehandlung vorhanden: Bei fehlender Datei wird leeres Dict zurückgegeben mit Warnung
|
||
|
|
|
||
|
|
**Code-Referenz:**
|
||
|
|
- `app/services/llm_service.py` Zeile 87-100: `_load_llm_profiles()`
|
||
|
|
- `app/services/llm_service.py` Zeile 36: Initialisierung in `__init__`
|
||
|
|
|
||
|
|
**Bewertung:** Profil-Ladung funktioniert korrekt. Keine Regression.
|
||
|
|
|
||
|
|
### Prüfpunkt 2b: Nutzt die neue Validierungs-Logik in Phase 3 die bestehende MoE-Kaskade?
|
||
|
|
|
||
|
|
**Status:** ✅ **FUNKTIONIERT KORREKT**
|
||
|
|
|
||
|
|
**Ergebnis:**
|
||
|
|
- Phase 3 Validierung nutzt `profile_name="ingest_validator"` (siehe `ingestion_processor.py` Zeile 345)
|
||
|
|
- `LLMService.generate_raw_response()` unterstützt vollständig die MoE-Kaskade:
|
||
|
|
- Profil-Auflösung aus `llm_profiles.yaml` (Zeile 151-161)
|
||
|
|
- Fallback-Kaskade via `fallback_profile` (Zeile 214-227)
|
||
|
|
- `visited_profiles` Schutz verhindert Endlosschleifen (Zeile 214)
|
||
|
|
- Rekursiver Aufruf mit `visited_profiles` Parameter (Zeile 226)
|
||
|
|
- Die Kaskade wird **nicht umgangen**, sondern vollständig genutzt
|
||
|
|
|
||
|
|
**Code-Referenz:**
|
||
|
|
- `app/core/ingestion/ingestion_processor.py` Zeile 340-346: Phase 3 Validierung
|
||
|
|
- `app/services/llm_service.py` Zeile 150-227: MoE-Kaskade Implementierung
|
||
|
|
- `config/llm_profiles.yaml`: Profil-Definitionen mit `fallback_profile`
|
||
|
|
|
||
|
|
**Bewertung:** MoE-Kaskade wird korrekt genutzt. Keine Regression.
|
||
|
|
|
||
|
|
### Prüfpunkt 2c: Werden Prompts korrekt aus `prompts.yaml` geladen?
|
||
|
|
|
||
|
|
**Status:** ✅ **FUNKTIONIERT KORREKT**
|
||
|
|
|
||
|
|
**Ergebnis:**
|
||
|
|
- `LLMService._load_prompts()` lädt Prompts aus `prompts.yaml` (Zeile 76-85)
|
||
|
|
- `DecisionEngine` nutzt `prompt_key` und `variables` für Lazy-Loading (Zeile 108-113, 309-315)
|
||
|
|
- `LLMService.get_prompt()` unterstützt Hierarchie: Model-ID → Provider → Default (Zeile 102-123)
|
||
|
|
- Prompt-Formatierung erfolgt via `template.format(**(variables or {}))` (Zeile 179)
|
||
|
|
|
||
|
|
**Code-Referenz:**
|
||
|
|
- `app/services/llm_service.py` Zeile 76-85: `_load_prompts()`
|
||
|
|
- `app/services/llm_service.py` Zeile 102-123: `get_prompt()` mit Hierarchie
|
||
|
|
- `app/core/retrieval/decision_engine.py` Zeile 107-113: Intent-Routing mit `prompt_key`
|
||
|
|
- `app/core/retrieval/decision_engine.py` Zeile 309-315: Finale Synthese mit `prompt_key`
|
||
|
|
|
||
|
|
**Bewertung:** Prompt-Ladung funktioniert korrekt. Keine Regression.
|
||
|
|
|
||
|
|
---
|
||
|
|
|
||
|
|
## 3. Deduplizierungs-Logik
|
||
|
|
|
||
|
|
### Prüfpunkt: Gefährden die Änderungen an `all_chunk_callout_keys` in v4.5.7/8 die gewollte De-Duplizierung von Kanten (WP-24c)?
|
||
|
|
|
||
|
|
**Status:** ✅ **FUNKTIONIERT KORREKT**
|
||
|
|
|
||
|
|
**Ergebnis:**
|
||
|
|
- `all_chunk_callout_keys` wird **VOR jeder Verwendung** initialisiert (Zeile 531-533)
|
||
|
|
- Initialisierung erfolgt **VOR** Phase 1 (Sammeln aus `candidate_pool`) und **VOR** Phase 2 (Chunk-Verarbeitung)
|
||
|
|
- Die De-Duplizierungs-Logik ist **vollständig intakt**:
|
||
|
|
- Phase 1: Sammeln aller `explicit:callout` Keys aus `candidate_pool` (Zeile 657-697)
|
||
|
|
- Phase 2: Prüfung gegen `all_chunk_callout_keys` vor Erstellung neuer Callout-Kanten (Zeile 768)
|
||
|
|
- Globaler Scan: Nutzung von `all_chunk_callout_keys` als Ausschlusskriterium (Zeile 855)
|
||
|
|
- LLM-Validierungs-Zonen: Callouts werden korrekt zu `all_chunk_callout_keys` hinzugefügt (Zeile 615)
|
||
|
|
|
||
|
|
**Code-Referenz:**
|
||
|
|
- `app/core/graph/graph_derive_edges.py` Zeile 531-533: Initialisierung
|
||
|
|
- `app/core/graph/graph_derive_edges.py` Zeile 657-697: Phase 1 (Sammeln)
|
||
|
|
- `app/core/graph/graph_derive_edges.py` Zeile 768: Phase 2 (Prüfung)
|
||
|
|
- `app/core/graph/graph_derive_edges.py` Zeile 855: Globaler Scan (Ausschluss)
|
||
|
|
|
||
|
|
**Bewertung:** De-Duplizierungs-Logik ist intakt. Keine Regression.
|
||
|
|
|
||
|
|
---
|
||
|
|
|
||
|
|
## 4. Phase 3 Validierungs-Gate
|
||
|
|
|
||
|
|
### Prüfpunkt: Ist das Phase 3 Validierungs-Gate korrekt implementiert und nutzt es die MoE-Kaskade?
|
||
|
|
|
||
|
|
**Status:** ✅ **GEWOLLTE ÄNDERUNG** (v4.5.8)
|
||
|
|
|
||
|
|
**Ergebnis:**
|
||
|
|
- Phase 3 Validierung ist **korrekt implementiert** in `ingestion_processor.py` (Zeile 274-371)
|
||
|
|
- **Trigger-Kriterium:** Kanten mit `rule_id` ODER `provenance` beginnend mit `"candidate:"` (Zeile 292)
|
||
|
|
- **Validierung:** Nutzt `validate_edge_candidate()` mit `profile_name="ingest_validator"` (Zeile 340-346)
|
||
|
|
- **Erfolg:** Entfernt `candidate:` Präfix aus `rule_id` und `provenance` (Zeile 349-357)
|
||
|
|
- **Ablehnung:** Kanten werden zu `rejected_edges` hinzugefügt und **nicht** weiterverarbeitet (Zeile 362-363)
|
||
|
|
- **MoE-Kaskade:** Wird vollständig genutzt via `llm_service.generate_raw_response()` (siehe Prüfpunkt 2b)
|
||
|
|
|
||
|
|
**Code-Referenz:**
|
||
|
|
- `app/core/ingestion/ingestion_processor.py` Zeile 274-371: Phase 3 Implementierung
|
||
|
|
- `app/core/ingestion/ingestion_validation.py` Zeile 24-91: `validate_edge_candidate()`
|
||
|
|
|
||
|
|
**Bewertung:** Phase 3 Validierungs-Gate ist korrekt implementiert. **Gewollte Änderung**, keine Regression.
|
||
|
|
|
||
|
|
---
|
||
|
|
|
||
|
|
## 5. Note-Scope Kontext-Optimierung
|
||
|
|
|
||
|
|
### Prüfpunkt: Ist die Note-Scope Kontext-Optimierung korrekt implementiert?
|
||
|
|
|
||
|
|
**Status:** ✅ **GEWOLLTE ÄNDERUNG** (v4.5.8)
|
||
|
|
|
||
|
|
**Ergebnis:**
|
||
|
|
- Kontext-Optimierung ist **korrekt implementiert** in Phase 3 Validierung (Zeile 311-326)
|
||
|
|
- **Note-Scope:** Verwendet `note_summary` oder `note_text` (aggregierter Kontext) (Zeile 314-316)
|
||
|
|
- **Chunk-Scope:** Versucht spezifischen Chunk-Text zu finden, sonst Note-Text (Zeile 318-326)
|
||
|
|
- **Note-Summary:** Wird aus Top 5 Chunks erstellt (Zeile 282)
|
||
|
|
- **Note-Text:** Wird aus `markdown_body` oder aggregiert aus allen Chunks erstellt (Zeile 280)
|
||
|
|
|
||
|
|
**Code-Referenz:**
|
||
|
|
- `app/core/ingestion/ingestion_processor.py` Zeile 278-282: Note-Summary/Text Erstellung
|
||
|
|
- `app/core/ingestion/ingestion_processor.py` Zeile 311-326: Kontext-Optimierung
|
||
|
|
|
||
|
|
**Bewertung:** Note-Scope Kontext-Optimierung ist korrekt implementiert. **Gewollte Änderung**, keine Regression.
|
||
|
|
|
||
|
|
---
|
||
|
|
|
||
|
|
## 6. Weitere Prüfungen
|
||
|
|
|
||
|
|
### 6.1 Edge-Registry Integration
|
||
|
|
|
||
|
|
**Status:** ✅ **FUNKTIONIERT KORREKT**
|
||
|
|
|
||
|
|
**Ergebnis:**
|
||
|
|
- Edge-Registry wird korrekt für Typ-Auflösung genutzt (Zeile 383 in `ingestion_processor.py`)
|
||
|
|
- Symmetrie-Generierung nutzt `edge_registry.get_inverse()` (Zeile 397)
|
||
|
|
- Keine Regression festgestellt
|
||
|
|
|
||
|
|
### 6.2 Context-Reuse Logik
|
||
|
|
|
||
|
|
**Status:** ✅ **FUNKTIONIERT KORREKT**
|
||
|
|
|
||
|
|
**Ergebnis:**
|
||
|
|
- Context-Reuse ist in `decision_engine.py` implementiert (Zeile 154-196)
|
||
|
|
- Bei Kompressions-Fehlern wird Original-Content zurückgegeben (Zeile 232-235)
|
||
|
|
- Bei Synthese-Fehlern wird Fallback mit vorhandenem Context genutzt (Zeile 328-365)
|
||
|
|
- Keine Regression festgestellt
|
||
|
|
|
||
|
|
### 6.3 Prompt-Template Validierung
|
||
|
|
|
||
|
|
**Status:** ✅ **FUNKTIONIERT KORREKT**
|
||
|
|
|
||
|
|
**Ergebnis:**
|
||
|
|
- Prompt-Validierung in `llm_service.py` prüft auf leere Templates (Zeile 172-175)
|
||
|
|
- Fehlerbehandlung vorhanden: `ValueError` bei fehlendem oder leerem `prompt_key`
|
||
|
|
- Keine Regression festgestellt
|
||
|
|
|
||
|
|
---
|
||
|
|
|
||
|
|
## Zusammenfassung
|
||
|
|
|
||
|
|
### ✅ Keine Regressionen festgestellt
|
||
|
|
|
||
|
|
Alle geprüften Funktionen arbeiten korrekt und entsprechen den ursprünglichen WP-Spezifikationen:
|
||
|
|
|
||
|
|
1. **WP-22 Scoring:** Mathematik bleibt unangetastet ✅
|
||
|
|
2. **WP-25a/b MoE & Prompts:** Profile und Prompts werden korrekt geladen, MoE-Kaskade funktioniert ✅
|
||
|
|
3. **Deduplizierungs-Logik:** `all_chunk_callout_keys` funktioniert korrekt ✅
|
||
|
|
4. **Phase 3 Validierung:** Korrekt implementiert, nutzt MoE-Kaskade ✅
|
||
|
|
5. **Note-Scope Kontext-Optimierung:** Korrekt implementiert ✅
|
||
|
|
|
||
|
|
### 📋 Gewollte Änderungen (v4.5.8)
|
||
|
|
|
||
|
|
Die folgenden Änderungen sind **explizit gewollt** und stellen keine Regressionen dar:
|
||
|
|
|
||
|
|
1. **Phase 3 Validierungs-Gate:** Neue Validierungs-Logik für `candidate:` Kanten
|
||
|
|
2. **Note-Scope Kontext-Optimierung:** Optimierte Kontext-Auswahl für Note-Scope vs. Chunk-Scope Kanten
|
||
|
|
|
||
|
|
### 🔍 Empfehlungen
|
||
|
|
|
||
|
|
**Keine kritischen Probleme gefunden.** Das System ist in einem stabilen Zustand.
|
||
|
|
|
||
|
|
**Optional (nicht kritisch):**
|
||
|
|
- Erwägen Sie zusätzliche Unit-Tests für Phase 3 Validierung
|
||
|
|
- Dokumentation der `candidate:` → `verified` Transformation könnte erweitert werden
|
||
|
|
|
||
|
|
---
|
||
|
|
|
||
|
|
## Audit-Methodik
|
||
|
|
|
||
|
|
1. **Code-Analyse:** Vollständige Analyse der relevanten Dateien
|
||
|
|
2. **Semantic Search:** Suche nach Verwendungen von `candidate:`, `verified`, `all_chunk_callout_keys`
|
||
|
|
3. **Grep-Suche:** Exakte String-Suche nach kritischen Patterns
|
||
|
|
4. **Dokumentations-Review:** Prüfung der technischen Dokumentation
|
||
|
|
|
||
|
|
**Geprüfte Dateien:**
|
||
|
|
- `app/core/retrieval/retriever_scoring.py`
|
||
|
|
- `app/services/llm_service.py`
|
||
|
|
- `app/core/retrieval/decision_engine.py`
|
||
|
|
- `app/core/graph/graph_derive_edges.py`
|
||
|
|
- `app/core/ingestion/ingestion_processor.py`
|
||
|
|
- `app/core/ingestion/ingestion_validation.py`
|
||
|
|
- `config/prompts.yaml`
|
||
|
|
- `config/llm_profiles.yaml`
|
||
|
|
|
||
|
|
---
|
||
|
|
|
||
|
|
## 7. Zusätzliche Prüfungen & Bekannte Schwachstellen
|
||
|
|
|
||
|
|
### 7.1 Callout-Extraktion aus Edge-Zonen (aus AUDIT_CLEAN_CONTEXT_V4.2.0)
|
||
|
|
|
||
|
|
**Status:** ⚠️ **POTENZIELL BEHOBEN** (verifizieren erforderlich)
|
||
|
|
|
||
|
|
**Hintergrund:**
|
||
|
|
- AUDIT_CLEAN_CONTEXT_V4.2.0 identifizierte ein kritisches Problem: Callouts in Edge-Zonen wurden nicht extrahiert
|
||
|
|
- Problem: Callouts wurden nur aus gefilterten Chunks extrahiert, nicht aus Original-Markdown
|
||
|
|
|
||
|
|
**Aktueller Status:**
|
||
|
|
- ✅ Funktion `extract_callouts_from_markdown()` existiert in `graph_derive_edges.py` (Zeile 263-501)
|
||
|
|
- ✅ Funktion wird in `build_edges_for_note()` aufgerufen (Zeile 852-864)
|
||
|
|
- ⚠️ **VERIFIZIERUNG ERFORDERLICH:** Prüfen, ob Callouts in LLM-Validierungs-Zonen korrekt extrahiert werden
|
||
|
|
|
||
|
|
**Code-Referenz:**
|
||
|
|
- `app/core/graph/graph_derive_edges.py` Zeile 263-501: `extract_callouts_from_markdown()`
|
||
|
|
- `app/core/graph/graph_derive_edges.py` Zeile 852-864: Aufruf in `build_edges_for_note()`
|
||
|
|
|
||
|
|
**Empfehlung:**
|
||
|
|
- Test mit Callout in LLM-Validierungs-Zone durchführen
|
||
|
|
- Verifizieren, dass Edge in Qdrant `_edges` Collection existiert
|
||
|
|
- Prüfen, ob `candidate:` Präfix korrekt gesetzt wird
|
||
|
|
|
||
|
|
---
|
||
|
|
|
||
|
|
### 7.2 Rejected Edges Tracking & Monitoring
|
||
|
|
|
||
|
|
**Status:** ⚠️ **POTENZIELLE SCHWACHSTELLE**
|
||
|
|
|
||
|
|
**Problem:**
|
||
|
|
- Phase 3 Validierung lehnt Kanten ab und fügt sie zu `rejected_edges` hinzu (Zeile 363)
|
||
|
|
- `rejected_edges` werden geloggt, aber **nicht persistiert** oder analysiert
|
||
|
|
- Keine Möglichkeit, abgelehnte Kanten zu überprüfen oder zu debuggen
|
||
|
|
|
||
|
|
**Konsequenz:**
|
||
|
|
- **Fehlende Transparenz:** Keine Nachvollziehbarkeit, warum Kanten abgelehnt wurden
|
||
|
|
- **Keine Metriken:** Keine Statistiken über Ablehnungsrate
|
||
|
|
- **Schwieriges Debugging:** Bei Problemen keine Möglichkeit, abgelehnte Kanten zu analysieren
|
||
|
|
|
||
|
|
**Code-Referenz:**
|
||
|
|
- `app/core/ingestion/ingestion_processor.py` Zeile 363: `rejected_edges.append(e)`
|
||
|
|
- `app/core/ingestion/ingestion_processor.py` Zeile 370-371: Logging, aber keine Persistierung
|
||
|
|
|
||
|
|
**Empfehlung:**
|
||
|
|
- Optional: Persistierung von `rejected_edges` in Log-Datei oder separater Collection
|
||
|
|
- Metriken: Tracking der Ablehnungsrate pro Note/Typ
|
||
|
|
- Debug-Modus: Detailliertes Logging der Ablehnungsgründe
|
||
|
|
|
||
|
|
---
|
||
|
|
|
||
|
|
### 7.3 Transiente vs. Permanente Fehler in Phase 3 Validierung
|
||
|
|
|
||
|
|
**Status:** ✅ **FUNKTIONIERT KORREKT**
|
||
|
|
|
||
|
|
**Ergebnis:**
|
||
|
|
- `validate_edge_candidate()` unterscheidet korrekt zwischen transienten und permanenten Fehlern (Zeile 79-91)
|
||
|
|
- Transiente Fehler (Netzwerk) → Kante wird erlaubt (Integrität vor Präzision)
|
||
|
|
- Permanente Fehler → Kante wird abgelehnt (Graph-Qualität schützen)
|
||
|
|
|
||
|
|
**Code-Referenz:**
|
||
|
|
- `app/core/ingestion/ingestion_validation.py` Zeile 79-91: Fehlerbehandlung
|
||
|
|
|
||
|
|
**Bewertung:** Korrekt implementiert. Keine Regression.
|
||
|
|
|
||
|
|
---
|
||
|
|
|
||
|
|
### 7.4 Note-Scope Kontext-Optimierung: Chunk-Text Fallback
|
||
|
|
|
||
|
|
**Status:** ⚠️ **POTENZIELLE SCHWACHSTELLE**
|
||
|
|
|
||
|
|
**Problem:**
|
||
|
|
- Bei Chunk-Scope Kanten wird versucht, spezifischen Chunk-Text zu finden (Zeile 319-325)
|
||
|
|
- Fallback auf `note_text`, wenn Chunk-Text nicht gefunden wird
|
||
|
|
- **Risiko:** Bei fehlendem Chunk-Text wird Note-Text verwendet, was weniger präzise ist
|
||
|
|
|
||
|
|
**Code-Referenz:**
|
||
|
|
- `app/core/ingestion/ingestion_processor.py` Zeile 318-326: Chunk-Text Suche
|
||
|
|
|
||
|
|
**Empfehlung:**
|
||
|
|
- Prüfen, ob Chunk-Text immer verfügbar ist
|
||
|
|
- Bei fehlendem Chunk-Text: Warnung loggen
|
||
|
|
- Optional: Bessere Fehlerbehandlung für fehlende Chunk-IDs
|
||
|
|
|
||
|
|
---
|
||
|
|
|
||
|
|
### 7.5 LLM-Validierungs-Zonen: Callout-Key Tracking
|
||
|
|
|
||
|
|
**Status:** ✅ **FUNKTIONIERT KORREKT**
|
||
|
|
|
||
|
|
**Ergebnis:**
|
||
|
|
- Callouts aus LLM-Validierungs-Zonen werden korrekt zu `all_chunk_callout_keys` hinzugefügt (Zeile 615)
|
||
|
|
- Verhindert Duplikate im globalen Scan
|
||
|
|
- Korrekte `candidate:` Präfix-Setzung
|
||
|
|
|
||
|
|
**Code-Referenz:**
|
||
|
|
- `app/core/graph/graph_derive_edges.py` Zeile 604-616: LLM-Validierungs-Zone Callout-Tracking
|
||
|
|
|
||
|
|
**Bewertung:** Korrekt implementiert. Keine Regression.
|
||
|
|
|
||
|
|
---
|
||
|
|
|
||
|
|
### 7.6 Scope-Aware Edge Retrieval (aus AUDIT_RETRIEVER_V4.1.0)
|
||
|
|
|
||
|
|
**Status:** ⚠️ **POTENZIELL BEHOBEN** (verifizieren erforderlich)
|
||
|
|
|
||
|
|
**Hintergrund:**
|
||
|
|
- AUDIT_RETRIEVER_V4.1.0 identifizierte ein Problem: Retriever suchte nur nach Note-Level Edges, nicht Chunk-Level
|
||
|
|
- Problem: Chunk-Scope Edges wurden nicht explizit berücksichtigt
|
||
|
|
|
||
|
|
**Aktueller Status:**
|
||
|
|
- ⚠️ **VERIFIZIERUNG ERFORDERLICH:** Prüfen, ob `fetch_edges_from_qdrant` Chunk-Level Edges korrekt lädt
|
||
|
|
- Dokumentation besagt, dass Optimierungen implementiert wurden
|
||
|
|
|
||
|
|
**Empfehlung:**
|
||
|
|
- Test mit Chunk-Scope Edge durchführen
|
||
|
|
- Verifizieren, dass Edge im Retrieval-Ergebnis enthalten ist
|
||
|
|
- Prüfen, ob `chunk_id` Filter korrekt funktioniert
|
||
|
|
|
||
|
|
---
|
||
|
|
|
||
|
|
### 7.7 Section-Filtering im Retrieval (aus AUDIT_RETRIEVER_V4.1.0)
|
||
|
|
|
||
|
|
**Status:** ⚠️ **POTENZIELL BEHOBEN** (verifizieren erforderlich)
|
||
|
|
|
||
|
|
**Hintergrund:**
|
||
|
|
- AUDIT_RETRIEVER_V4.1.0 identifizierte fehlende Filterung nach `target_section`
|
||
|
|
- Problem: Section-Links (`[[Note#Section]]`) wurden nicht präzise gefiltert
|
||
|
|
|
||
|
|
**Aktueller Status:**
|
||
|
|
- ⚠️ **VERIFIZIERUNG ERFORDERLICH:** Prüfen, ob `target_section` Filter im Retrieval funktioniert
|
||
|
|
- Dokumentation besagt, dass Optimierungen implementiert wurden
|
||
|
|
|
||
|
|
**Empfehlung:**
|
||
|
|
- Test mit Section-Link durchführen
|
||
|
|
- Verifizieren, dass nur relevante Chunks zurückgegeben werden
|
||
|
|
- Prüfen, ob `QueryRequest.target_section` korrekt verwendet wird
|
||
|
|
|
||
|
|
---
|
||
|
|
|
||
|
|
### 7.8 Prompt-Integration: Explanation Layer
|
||
|
|
|
||
|
|
**Status:** ⚠️ **UNKLAR** (aus AUDIT_CLEAN_CONTEXT_V4.2.0)
|
||
|
|
|
||
|
|
**Problem:**
|
||
|
|
- Unklar, ob `explanation.related_edges` im LLM-Prompt verwendet werden
|
||
|
|
- Keine explizite Dokumentation der Prompt-Struktur für RAG-Kontext
|
||
|
|
|
||
|
|
**Code-Referenz:**
|
||
|
|
- `app/core/retrieval/retriever.py` Zeile 150-252: `_build_explanation()`
|
||
|
|
- `app/routers/chat.py`: Prompt-Verwendung
|
||
|
|
|
||
|
|
**Empfehlung:**
|
||
|
|
- Prüfen Sie `config/prompts.yaml` für `interview_template` und andere Templates
|
||
|
|
- Stellen Sie sicher, dass `{related_edges}` oder ähnliche Variablen im Prompt verwendet werden
|
||
|
|
- Dokumentieren Sie die Prompt-Struktur für RAG-Kontext
|
||
|
|
|
||
|
|
---
|
||
|
|
|
||
|
|
### 7.9 Fallback-Synthese: Hardcodierter Prompt (aus AUDIT_WP25B_CODE_REVIEW)
|
||
|
|
|
||
|
|
**Status:** ⚠️ **ARCHITEKTONISCHE INKONSISTENZ**
|
||
|
|
|
||
|
|
**Problem:**
|
||
|
|
- Fallback-Synthese in `decision_engine.py` verwendet `prompt=` statt `prompt_key=` (Zeile 361)
|
||
|
|
- Inkonsistent mit WP25b-Architektur (Lazy-Loading)
|
||
|
|
- Keine modell-spezifischen Prompts im Fallback
|
||
|
|
|
||
|
|
**Code-Referenz:**
|
||
|
|
- `app/core/retrieval/decision_engine.py` Zeile 360-363: Hardcodierter Prompt
|
||
|
|
|
||
|
|
**Empfehlung:**
|
||
|
|
- Umstellen auf `prompt_key="fallback_synthesis"` mit `variables`
|
||
|
|
- Konsistenz mit WP25b-Architektur
|
||
|
|
- Modell-spezifische Optimierungen auch im Fallback
|
||
|
|
|
||
|
|
**Schweregrad:** 🟡 Mittel (funktional, aber architektonisch inkonsistent)
|
||
|
|
|
||
|
|
---
|
||
|
|
|
||
|
|
### 7.10 Edge-Registry: Unbekannte Kanten
|
||
|
|
|
||
|
|
**Status:** ✅ **FUNKTIONIERT KORREKT**
|
||
|
|
|
||
|
|
**Ergebnis:**
|
||
|
|
- Unbekannte Kanten-Typen werden in `unknown_edges.jsonl` protokolliert
|
||
|
|
- Edge-Registry normalisiert Kanten-Typen korrekt
|
||
|
|
- Keine Regression festgestellt
|
||
|
|
|
||
|
|
**Code-Referenz:**
|
||
|
|
- `app/services/edge_registry.py`: Edge-Registry Implementierung
|
||
|
|
|
||
|
|
**Bewertung:** Korrekt implementiert. Keine Regression.
|
||
|
|
|
||
|
|
---
|
||
|
|
|
||
|
|
## 8. Zusammenfassung der zusätzlichen Prüfungen
|
||
|
|
|
||
|
|
### ✅ Bestätigt funktionierend:
|
||
|
|
1. **Transiente vs. Permanente Fehler:** Korrekte Unterscheidung ✅
|
||
|
|
2. **LLM-Validierungs-Zonen Callout-Tracking:** Korrekt implementiert ✅
|
||
|
|
3. **Edge-Registry:** Funktioniert korrekt ✅
|
||
|
|
|
||
|
|
### ⚠️ Verifizierung erforderlich:
|
||
|
|
1. **Callout-Extraktion aus Edge-Zonen:** Funktion existiert, aber Verifizierung erforderlich
|
||
|
|
2. **Scope-Aware Edge Retrieval:** Potenziell behoben, Verifizierung erforderlich
|
||
|
|
3. **Section-Filtering:** Potenziell behoben, Verifizierung erforderlich
|
||
|
|
|
||
|
|
### ⚠️ Potenzielle Schwachstellen:
|
||
|
|
1. **Rejected Edges Tracking:** Keine Persistierung oder Metriken
|
||
|
|
2. **Note-Scope Kontext-Optimierung:** Chunk-Text Fallback könnte verbessert werden
|
||
|
|
3. **Prompt-Integration:** Unklar, ob `explanation.related_edges` verwendet werden
|
||
|
|
4. **Fallback-Synthese:** Architektonische Inkonsistenz (hardcodierter Prompt)
|
||
|
|
|
||
|
|
---
|
||
|
|
|
||
|
|
## 9. Empfohlene Follow-up Prüfungen
|
||
|
|
|
||
|
|
### 9.1 Funktionale Tests
|
||
|
|
|
||
|
|
1. **Callout in LLM-Validierungs-Zone:**
|
||
|
|
- Erstellen Sie eine Notiz mit Callout in `### Unzugeordnete Kanten`
|
||
|
|
- Verifizieren: Edge existiert in Qdrant mit `candidate:` Präfix
|
||
|
|
- Verifizieren: Edge wird in Phase 3 validiert
|
||
|
|
|
||
|
|
2. **Chunk-Scope Edge Retrieval:**
|
||
|
|
- Erstellen Sie eine Note mit Chunk-Scope Edge
|
||
|
|
- Query mit `explain=True`
|
||
|
|
- Verifizieren: Edge erscheint in `explanation.related_edges`
|
||
|
|
|
||
|
|
3. **Section-Link Retrieval:**
|
||
|
|
- Erstellen Sie einen Section-Link (`[[Note#Section]]`)
|
||
|
|
- Query mit `target_section="Section"`
|
||
|
|
- Verifizieren: Nur relevante Chunks werden zurückgegeben
|
||
|
|
|
||
|
|
### 9.2 Metriken & Monitoring
|
||
|
|
|
||
|
|
1. **Phase 3 Validierung Metriken:**
|
||
|
|
- Tracking der Validierungsrate (verified/rejected)
|
||
|
|
- Tracking der Ablehnungsgründe
|
||
|
|
- Monitoring der LLM-Validierungs-Performance
|
||
|
|
|
||
|
|
2. **Edge-Statistiken:**
|
||
|
|
- Anzahl der `candidate:` Kanten pro Note
|
||
|
|
- Anzahl der verifizierten Kanten pro Note
|
||
|
|
- Anzahl der abgelehnten Kanten pro Note
|
||
|
|
|
||
|
|
### 9.3 Dokumentation
|
||
|
|
|
||
|
|
1. **Prompt-Struktur:**
|
||
|
|
- Dokumentieren Sie die Verwendung von `explanation.related_edges` in Prompts
|
||
|
|
- Erstellen Sie Beispiele für RAG-Kontext-Integration
|
||
|
|
|
||
|
|
2. **Phase 3 Validierung:**
|
||
|
|
- Dokumentieren Sie den Validierungs-Prozess
|
||
|
|
- Erstellen Sie Troubleshooting-Guide für abgelehnte Kanten
|
||
|
|
|
||
|
|
---
|
||
|
|
|
||
|
|
**Audit abgeschlossen:** ✅ System-Integrität bestätigt mit zusätzlichen Prüfungen
|