Zum Inhalt

Architektur

Das Umfrage-Analyse-System ist eine Python-Anwendung mit webbasiertem Frontend, einer dienstorientierten Verarbeitungsschicht und einer SQLite-basierten Persistenzschicht. Die Komponenten sind klar getrennt: das Frontend hält keinen Zustand, die Auswertungslogik ist nach Fragetypen modularisiert, und alle Zwischenergebnisse werden in der Datenbank abgelegt. Längerlaufende Verarbeitungsschritte — insbesondere LLM-Aufrufe — sind als wiederaufnehmbare Batch-Operationen realisiert.

Auf einen Blick

  • Vier-Schichten-Aufbau: Web-Oberfläche, Anwendungskern, Verarbeitungsdienste, Persistenz
  • Handler-Registry mit sieben Fragetyp-Handlern hinter einer einheitlichen Schnittstelle
  • Zentrale SQLite-Datenbank mit versionsgeführtem Schema und automatischer Migration
  • Externe LLM-Anbindung über eine OpenAI-kompatible Schnittstelle
  • Pipeline-Orchestrierung mit Caching und Wiederaufnahme nach Abbruch
  • Konfiguration über YAML-Dateien und Umgebungsvariablen
  • Lokale Ausführung als einzelner Prozess; bedienbar über einen Web-Browser

Architekturbeschreibung

Schichten und Komponenten

Die Web-Oberfläche basiert auf Gradio und bündelt die Bedien- und Auswertungstabs (Import, Konfiguration, Item-Extraktion, Analyse, Workbench, Export, Themen). Sie ruft ausschließlich Funktionen des Anwendungskerns auf und führt selbst keine Verarbeitung durch.

Der Anwendungskern verwaltet einen globalen Anwendungszustand (AppState) mit Verweis auf den aktuellen DataFrame, das aktive Projekt, den letzten Import und die geladene Konfiguration. Eine zentrale Handler-Registry stellt für jeden Fragetyp den passenden Handler bereit; die Handler erben von einer abstrakten Basisklasse mit einheitlichen Methoden für Analyse, Visualisierung und Export.

Die Verarbeitungsdienste kapseln die fachliche Logik:

  • der Daten-Import liest CSV/Excel und parsiert optional LimeSurvey-Strukturdateien;
  • der Antwort-Übersetzer erkennt Fremdsprachen (hybrid aus Schlagwortlisten und Spracherkennung) und übersetzt Antworten in die Zielsprache;
  • der Item-Extraktor zerlegt Freitexte regelbasiert und mit LLM-Unterstützung;
  • der Cluster-Dienst gruppiert Items über das LLM mit dynamisch skalierten Schwellen;
  • die Statistik-Module berechnen Chi-Quadrat, Cramér's V und Frage-zu-Frage-Korrelationen;
  • der Zusammenfassungs-Dienst erzeugt Textblöcke pro Frage und Sprache;
  • der Themen-Analyzer extrahiert Schlagwörter und erstellt Themen-Zuordnungen.

Die Persistenzschicht liegt in einer SQLite-Datenbank mit Tabellen unter anderem für Projekte, Importe, Rohantworten, extrahierte Items, Cluster, Übersetzungen, Analyseergebnisse, Themen und Frage-Zusammenfassungen. Beim Programmstart prüft eine Migrationskomponente die Schema-Version und führt notwendige Aktualisierungen automatisch durch.

Die Ausgabeschicht umfasst den strukturierten Word-Export mit Diagrammen, Detailtabellen und Anhängen, einen Dashboard-JSON-Export sowie den Document Builder, der Markdown-Quellen zu mehrsprachigen Publikationsdokumenten zusammenfügt.

Diagramm

flowchart TB
    User([Auswertende:r])

    subgraph UI["Web-Oberfläche (Gradio)"]
        direction LR
        T1[Import]
        T2[Item-Extraktion]
        T3[Analyse]
        T4[Workbench]
        T5[Export]
        T6[Themen]
    end

    subgraph Core["Anwendungskern"]
        State[AppState]
        Config[YAML-Konfiguration]
        Registry[Handler-Registry]
    end

    subgraph Handlers["Fragetyp-Handler"]
        H1[single_choice]
        H2[multi_choice]
        H3[multi_choice_binary]
        H4[matrix_likert]
        H5[ranking]
        H6[freetext]
        H7[cooperation_matrix]
    end

    subgraph Services["Verarbeitungsdienste"]
        Imp[Daten-Import]
        Trans[Antwort-Übersetzung]
        Items[Item-Extraktion]
        Clust[Clustering]
        Stat[Statistik / Korrelation]
        Sum[Zusammenfassungen]
        Themes[Themen-Analyse]
    end

    DB[(SQLite-Datenbank)]
    LLM["LLM-API (extern)"]

    subgraph Output["Ausgabe"]
        Word[Strukturierter Word-Bericht]
        Builder[Document Builder]
        DashJSON[Dashboard-JSON]
        Files[CSV / PNG]
    end

    User --> UI
    UI --> Core
    Core --> Registry
    Registry --> Handlers
    Handlers --> Services
    Services <--> DB
    Services --> LLM
    Builder --> LLM
    Services --> Output
    Builder --> Output

Workflow

Eine typische Verarbeitung beginnt mit dem Import einer Umfrage über die Web-Oberfläche. Der Daten-Import erzeugt einen Eintrag in der Datenbank und legt die Rohantworten ab. Optional ergänzt eine LimeSurvey-Strukturdatei die mehrsprachigen Fragetexte. Anschließend werden fremdsprachige Antworten in die Arbeitssprache übersetzt; Übersetzungen werden gecacht und beim nächsten Lauf wiederverwendet.

Für Freitext-Fragen folgt die Item-Extraktion. Eine regelbasierte Vorprüfung erfasst klar strukturierte Antworten (Trennzeichen, Aufzählungen); für die übrigen Fälle übernimmt ein LLM-Aufruf die Trennung. Die extrahierten Items werden persistiert und stehen als Eingabe für das Clustering bereit.

Im Analyse-Schritt iteriert die Pipeline über alle konfigurierten Fragen und ruft jeweils den passenden Handler auf. Geschlossene Fragen werden direkt aggregiert, Freitextfragen über das LLM geclustert. Anschließend berechnet die Statistik-Komponente Signifikanztests pro Segment sowie Korrelationen zwischen Fragen, und der Zusammenfassungs-Dienst erzeugt für jede Frage einen Beschreibungs-, Interpretations- und Segmenttext.

Im Workbench-Schritt können die automatisch erzeugten Cluster und Items manuell überarbeitet werden. Änderungen werden in der Datenbank persistiert; ein optionaler Re-Clustering-Lauf bringt die Items mit den korrigierten Kategorien in Einklang.

Der Export-Schritt liest die persistierten Ergebnisse, generiert Diagramme über den Chart-Generator und stellt sie zu einem strukturierten Word-Bericht zusammen. Parallel kann ein Dashboard-JSON erzeugt werden, das alle globalen und segmentierten Ergebnisse enthält. Der Document Builder verkettet den Bericht mit übersetzten Markdown-Quellen (Cover, Einführung, Hintergrund) zu einem mehrsprachigen Publikationsdokument.

Rolle des LLM

Das LLM erfüllt mehrere klar abgegrenzte Aufgaben mit jeweils eigenem Prompt und eigener Validierung:

  • Übersetzung mit Glossar-Kontext, sowohl für Antworten als auch für Berichtstexte;
  • Item-Extraktion in zwei Modi (konservativ und thematisch), jeweils mit Beispiel-Prompts;
  • Clustering mit Validierung der Vollständigkeit (jede Antwort-ID muss genau einem Cluster zugeordnet sein) und mit Mehrfach-Versuchen bei unzureichendem Ergebnis;
  • Auswahl repräsentativer Beispiele je Cluster;
  • Frage-Zusammenfassungen in drei Sprachen;
  • Themen-Keyword-Extraktion.

Die LLM-Aufrufe verwenden eine OpenAI-kompatible Schnittstelle. Modellname, Endpunkt, Token-Limits, Timeout und Temperatur sind über Umgebungsvariablen konfigurierbar; Aufrufe werden gezählt und mit Eingangs- und Ausgangslängen dokumentiert. Embedding- oder Reranker-Komponenten kommen nicht zum Einsatz; die KI-Verarbeitung beruht ausschließlich auf prompt-gesteuerten LLM-Aufrufen.

Robustheit und Konfiguration

Lange Pipeline-Operationen sind wiederaufnahmefähig. Beim erneuten Start werden bereits berechnete Übersetzungen, Item-Extraktionen, Cluster und Frage-Zusammenfassungen aus der Datenbank geladen, und nur fehlende Schritte werden ausgeführt. Eine optionale Neuberechnung erzwingt das vollständige Verarbeiten von Grund auf.

Die zentrale Konfiguration liegt in YAML-Dateien (questions.yaml, themes.yaml, glossary.yaml, documents.yaml, translations.yaml, diagram_labels.yaml). Sie definiert Fragengruppen, Handler-Zuordnungen, Antwortoptionen, Segmentierungsvariablen, Berichtsstruktur und Übersetzungsglossar. Server-Parameter und LLM-Zugang werden über .env-Variablen gesetzt.

Die Anwendung läuft als einzelner Python-Prozess; eine Bereitstellung hinter einem Reverse-Proxy ist über die root_path-Konfiguration vorgesehen. Die SQLite-Datenbank ist datei-basiert und benötigt keinen separaten Datenbankdienst.

Technologie-Übersicht

  • Web-Oberfläche: Gradio
  • Datenverarbeitung: pandas, numpy
  • Statistik: scipy
  • Visualisierung: matplotlib
  • Word-Export: python-docx, docxcompose
  • Sprachdetektion: langdetect
  • HTTP-Client: httpx (für die LLM-API)
  • Konfiguration: PyYAML, python-dotenv
  • Persistenz: SQLite (über das Standardmodul)
  • Optionales Diagramm-Rendering: Mermaid (über mermaid.ink)
  • LLM-Endpunkt: OpenAI-kompatible API (z.B. vLLM)