mindnet/scripts/debug_edge_loss.py

157 lines
5.2 KiB
Python
Raw Blame History

This file contains invisible Unicode characters

This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

#!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""
FILE: scripts/debug_edge_loss.py
VERSION: 2.1.0 (2025-12-15)
STATUS: Active (Debug-Tool)
COMPATIBILITY: v2.9.1 (Post-WP14/WP-15b)
Zweck:
-------
Debug-Tool zur Analyse von Edge-Verlust-Problemen bei der Chunk-Verarbeitung.
Hilft zu verstehen, warum bestimmte Edges nicht erkannt oder verloren gehen.
Funktionsweise:
---------------
1. Analysiert eine einzelne Markdown-Datei
2. Führt zwei Analyseschritte durch:
a) Pre-Scan: Extrahiert alle Edge-Kandidaten aus dem rohen Text
- Wikilinks
- Typed Relations
- Callout Relations
b) Chunk-Analyse:
- Erstellt Chunks mit konfigurierbarem Profil
- Prüft, welche Edges in jedem Chunk gefunden werden
- Vergleicht mit Pre-Scan-Ergebnissen
3. Gibt detaillierte Analyse pro Chunk aus
Ergebnis-Interpretation:
------------------------
- [1] Globale Kandidaten: Alle Edge-Kandidaten, die im Text vorhanden sind
- [2] Chunk-Struktur: Für jeden Chunk:
* Section-Pfad
* Text-Snippet
* Gefundene explizite Kanten (callout:edge, inline:rel)
* Warnung, falls Callout im Text vorhanden, aber nicht erkannt
Verwendung:
-----------
- Debugging von Edge-Verlust bei Chunk-Grenzen
- Validierung der Edge-Extraktion in verschiedenen Chunk-Kontexten
- Analyse von Problemen mit Callout-Erkennung
Hinweise:
---------
- Asynchrones Skript (nutzt assemble_chunks async API)
- Konfigurierbares Chunking-Profil (Standard: sliding_window, 400/600 chars)
- Smart Edge Allocation ist standardmäßig deaktiviert für klare Analyse
Aufruf:
-------
python3 scripts/debug_edge_loss.py [PFAD_ZUR_DATEI.md]
Parameter:
----------
Keine CLI-Parameter. Dateipfad als erstes Argument oder Standard-Pfad.
Änderungen:
-----------
v2.1.0 (2025-12-15): Kompatibilität mit WP-14 Modularisierung
- Entfernt: _extract_all_edges_from_md (nicht mehr vorhanden)
- Ersetzt durch: extract_wikilinks, extract_typed_relations, extract_callout_relations
- Chunk-Payload-Struktur angepasst (window, type hinzugefügt)
v1.0.0: Erster Release
"""
import asyncio
import os
import sys
from pathlib import Path
# Pfad-Setup
sys.path.insert(0, os.path.abspath("."))
from app.core.chunking import assemble_chunks
from app.core.graph.graph_derive_edges import build_edges_for_note
from app.core.parser import extract_wikilinks
from app.core.graph.graph_extractors import extract_typed_relations, extract_callout_relations
# Mock für Settings, falls nötig
os.environ["MINDNET_LLM_MODEL"] = "phi3:mini"
async def analyze_file(file_path: str):
print(f"\n=== ANALYSE: {file_path} ===")
with open(file_path, "r", encoding="utf-8") as f:
text = f.read()
# 1. Globale Kandidaten (Was sieht der Pre-Scan?)
# Wir extrahieren alle Edge-Kandidaten aus dem Text
note_id = Path(file_path).stem
candidates = []
# Wikilinks extrahieren
wikilinks = extract_wikilinks(text)
for wl in wikilinks:
candidates.append(f"wikilink:{wl}")
# Typed Relations extrahieren
typed_rels, _ = extract_typed_relations(text)
for kind, target in typed_rels:
candidates.append(f"typed:{kind}:{target}")
# Callout Relations extrahieren
callout_rels, _ = extract_callout_relations(text)
for kind, target in callout_rels:
candidates.append(f"callout:{kind}:{target}")
print(f"\n[1] Globale Kandidaten (Pre-Scan):")
for c in candidates:
print(f" - {c}")
# 2. Chunking (Ohne Smart Edges erstmal, um die physische Integrität zu prüfen)
# Wir nutzen ein Profil, das dem User-Setup entspricht
config = {
"strategy": "sliding_window",
"target": 400,
"max": 600,
"overlap": 50,
"enable_smart_edge_allocation": False # Erstmal aus
}
chunks = await assemble_chunks(note_id, text, "concept", config=config)
print(f"\n[2] Chunk-Struktur & Physische Kanten:")
for i, chunk in enumerate(chunks):
print(f"\n--- Chunk {i} (Section: {chunk.section_path}) ---")
print(f"Snippet: {chunk.text[:50]}...")
# Was findet derive_edges in diesem rohen Chunk?
# Wir simulieren das Payload-Dict, das derive_edges erwartet
chunk_pl = {
"text": chunk.text,
"window": chunk.window or chunk.text,
"chunk_id": chunk.id,
"type": "concept"
}
# WP-24c v4.2.0: Übergabe des Markdown-Bodys für Note-Scope Zonen
edges = build_edges_for_note(note_id, [chunk_pl], markdown_body=text)
found_explicitly = [f"{e['kind']}:{e.get('target_id')}" for e in edges if e['rule_id'] in ['callout:edge', 'inline:rel']]
if found_explicitly:
print(f" ✅ Gefundene Explizite Kanten: {found_explicitly}")
else:
print(f" ❌ Keine expliziten Kanten gefunden (trotz Callout im Text?)")
# Check auf Callout im Text
if "> [!edge]" in chunk.text:
print(" HINWEIS: '> [!edge]' String ist im Text vorhanden!")
if __name__ == "__main__":
# Pfad zu deiner problematischen Datei hier anpassen!
target_file = "./vault_master/Dein_Problematisches_File.md"
if len(sys.argv) > 1:
target_file = sys.argv[1]
asyncio.run(analyze_file(target_file))