Zum Inhalt

Architektur

Code Analyzer ist als zweiteilige Anwendung mit gemeinsamem YAML-Speicher konzipiert. Eine erste Anwendung erfasst und analysiert den Quellcode, eine zweite wertet die Ergebnisse aus und erzeugt Berichte. Beide kommunizieren ausschließlich über das Dateisystem und können unabhängig voneinander betrieben werden. Innerhalb jeder Anwendung sind Datenzugriff, Aggregation, Visualisierung und LLM-Anbindung in eigenen Schichten gekapselt; die Datei-Analyse läuft asynchron mit konfigurierbarer Parallelität.

Auf einen Blick

  • Zweiteilige Architektur mit Code Scanner und Code Analyzer als getrennten Gradio-Anwendungen.
  • YAML-Verzeichnis als persistente Schnittstelle zwischen Erfassung und Auswertung.
  • Statische Strukturanalyse vor jedem LLM-Aufruf zur Reduktion von Halluzinationen.
  • Mehrstufige LLM-Pipeline mit rollenbasierter Spezialisierung (vier Prompts pro Datei, sieben Prompts systemweit).
  • Asynchrone Datei-Verarbeitung mit Semaphore-gesteuerter Parallelität.
  • OpenAI-kompatibler LLM-Adapter; lokale und Cloud-Endpoints austauschbar.
  • Hilfsskripte für Re-Analyse und YAML-Diagnose ergänzen das Kernsystem.

Architekturüberblick

Die Anwendung gliedert sich in vier funktionale Schichten.

Die Erfassungsschicht im Code Scanner traversiert das Projektverzeichnis und identifiziert die zu analysierenden Quelldateien anhand sprachspezifischer Muster. Sie wird durch eine Strukturanalyse-Schicht ergänzt, die Packages, Schichten und Build-Module rein statisch (per Regex und Keyword-Listen) bestimmt und daraus den Architekturstil ableitet.

Die Analyse-Schicht wickelt die LLM-gestützten Untersuchungen ab. Pro Datei laufen vier voneinander unabhängige Aufrufe gegen einen OpenAI-kompatiblen Endpoint, jeder mit eigener fachlicher Rolle und strukturierter JSON-Antwort. Eine Orchestrierung steuert die Parallelität über eine Semaphore.

Die Speicher-Schicht persistiert sämtliche Ergebnisse als YAML in einer hierarchischen Verzeichnisstruktur (analysis/files/<package>/<ClassName>.yaml) und ergänzt eine projektweite Strukturdatei sowie eine Summary mit Projektkennzahlen.

Die Auswertungs-Schicht im Code Analyzer liest diese YAMLs ein, aggregiert sie nach unterschiedlichen Achsen (Package, Modul, Domain, Issue-Kategorie, Interface) und stellt das Ergebnis in einem Tab-basierten Dashboard dar. Eine eigene LLM-Komponente erzeugt darauf eine systemweite Tiefenanalyse in sieben Schritten und einen vollständigen Bericht.

Workflow und Datenfluss

flowchart TB
    subgraph Quellen
        SRC[Quellcode-Projekt<br/>Java / PHP / Python]
        LLM[OpenAI-kompatibler<br/>LLM-Endpoint]
    end

    subgraph Scanner["Code Scanner"]
        FS[FileScanner<br/>Datei-Erkennung]
        PSA[ProjectStructureAnalyzer<br/>Schichten, Module, Stil]
        ORCH[Orchestrierung<br/>Async-Semaphore]
        CA[CodeAnalyzer<br/>4 LLM-Prompts pro Datei]
        SM[StorageManager]
    end

    subgraph Speicher
        YAML[("analysis/<br/>project_structure.yaml<br/>summary.yaml<br/>files/{pkg}/{Cls}.yaml")]
    end

    subgraph Analyzer["Code Analyzer"]
        ADR[AnalysisDataReader<br/>Cached YAML-Loader]
        DA[DeepAnalyzer<br/>Aggregation]
        UIH[UIHierarchyAnalyzer]
        FA[FunctionalityAnalyzer]
        LLA[LLMAnalyzer<br/>7-stufige Tiefenanalyse<br/>+ Bericht-Generator]
        DASH[Tab-Dashboard]
    end

    subgraph Hilfsskripte
        SA[storage_analyzer<br/>Re-Analyse]
        YF[yaml_fixer<br/>Diagnose]
    end

    subgraph Ausgaben
        REPORT[Markdown-Bericht]
        CSV[CSV-Export<br/>Capabilities / Issues]
    end

    SRC --> FS
    FS --> PSA
    FS --> ORCH
    PSA --> SM
    ORCH --> CA
    CA <--> LLM
    CA --> SM
    SM --> YAML

    YAML --> ADR
    ADR --> DA
    ADR --> UIH
    ADR --> FA
    DA --> DASH
    UIH --> DASH
    FA --> DASH
    DA --> LLA
    UIH --> LLA
    FA --> LLA
    LLA <--> LLM
    LLA --> REPORT
    DASH --> CSV

    YAML -.-> SA
    YAML -.-> YF
    SA -.-> CA

Der Workflow beginnt im Code Scanner: Der FileScanner ermittelt die relevanten Quelldateien, der ProjectStructureAnalyzer baut den Package-Baum auf und leitet den Architekturstil ab. Die Orchestrierung steuert die anschließende parallele LLM-Analyse: Eine asyncio-Semaphore begrenzt die parallel laufenden Datei-Analysen (Default: 3). Pro Datei führt der CodeAnalyzer vier separate Aufrufe gegen den LLM-Endpoint aus — Business-Logik, technische Aspekte, Interfaces und Issues. Jede Analyse wird einzeln durch den StorageManager als YAML in eine package-orientierte Verzeichnisstruktur geschrieben, ergänzt um eine Strukturdatei und eine Summary mit Projektkennzahlen.

Der Code Analyzer setzt auf diesen YAML-Bestand auf. Der AnalysisDataReader lädt und cached die Daten; spezialisierte Analysatoren (DeepAnalyzer, UIHierarchyAnalyzer, FunctionalityAnalyzer) bilden Aggregationen je nach Sicht (Package, Domain, Interface, Issue-Kategorie). Die Ergebnisse werden in mehreren Tabs des Gradio-Dashboards dargestellt, einschließlich einer matplotlib-basierten Visualisierung der API-Hierarchie. Der LLMAnalyzer nutzt die Aggregate, um eine systemweite Tiefenanalyse in sieben spezialisierten Aufrufen sowie einen vollständigen Markdown-Bericht zu erzeugen.

Mehrstufige LLM-Pipeline

Die LLM-Anbindung folgt einem rollen- und stufenbasierten Muster. Auf Datei-Ebene werden vier separate Prompts ausgeführt, jeweils mit einer eigenen Rolle: Senior Software Architect für Business-Logik, technische Aspekte und Interfaces; Senior Security Engineer für Issues. Alle Prompts erzwingen eine reine JSON-Antwort und nutzen eine niedrige Temperatur (0.2) sowie ein moderates Token-Budget (1500). Auf Systemebene laufen sieben weitere Aufrufe gegen aggregierte Daten, die zusammen die Tiefenanalyse bilden (Übersicht, Architektur, Business-Domains, Interfaces, Qualität, Modernisierung, Executive Summary). Ein abschließender Aufruf mit erhöhtem Token-Budget (8000) erzeugt den vollständigen Bericht in neun Abschnitten. Diese Trennung in spezialisierte, fokussierte Aufrufe ist eine zentrale Eigenschaft der Architektur — sie ersetzt einen einzelnen Generalprompt durch eine kontrollierte Sequenz mit klaren Verantwortlichkeiten.

Nebenläufigkeit und Robustheit

Die Datei-Analyse läuft asynchron über asyncio.gather mit einer Semaphore zur Begrenzung der parallelen LLM-Aufrufe. Fehler einzelner Dateien werden gefangen und als status: error in der jeweiligen YAML markiert, ohne dass die Gesamtanalyse abbricht. Eine Validierungsoberfläche im Code Analyzer prüft den YAML-Bestand auf Vollständigkeit und Konsistenz; bei fehlenden Analysen kann das CLI-Werkzeug storage_analyzer.py gezielt nachfahren. Das zweite CLI-Werkzeug yaml_fixer.py diagnostiziert Diskrepanzen zwischen Summary und Datei-Bestand. Quellcode wird vor dem LLM-Aufruf auf eine konfigurierte Maximallänge gekürzt, um Token-Limits zu wahren.

Konfiguration und Deployment

Beide Anwendungen werden als eigenständige Python-Prozesse gestartet (Code Scanner auf Port 7860, Code Analyzer auf Port 7861) und stellen eine Gradio-Weboberfläche bereit. Konfiguration erfolgt über Umgebungsvariablen (LLM-Endpoint, Modellname, API-Key) bzw. die Oberfläche selbst (Projektpfad, Sprache, Parallelität). Voraussetzung ist Python 3.9 oder höher; eine requirements.txt listet die direkten Abhängigkeiten.

Technologie-Übersicht

  • Sprache und Laufzeit — Python 3.9 oder höher; asynchrone Verarbeitung mit asyncio und aiofiles.
  • Web-Oberfläche — Gradio (≥ 4.0) für beide Anwendungen.
  • LLM-Anbindung — OpenAI Python SDK (≥ 1.0) gegen einen beliebigen OpenAI-kompatiblen Endpoint (OpenAI-API, Ollama, vLLM, LM Studio).
  • Datenhaltung — YAML als Zwischen- und Austauschformat, gelesen und geschrieben über PyYAML.
  • Aggregation und Tabellen — pandas für die Datenrahmen im Dashboard.
  • Visualisierung — matplotlib (Agg-Backend) und Pillow für die Hierarchie-Darstellungen.
  • Tabellenformatierung — tabulate für Markdown-Ausgaben.
  • Deployment — eigenständige Python-Prozesse; kein Containerisierungs-Setup mitgeliefert.