Zum Inhalt

Architektur

TextTool ist als einzelner Container konzipiert, der ein Web-Interface bereitstellt und Anfragen an einen externen LLM-Endpunkt weiterleitet. Die Anwendung ist nach Verantwortlichkeiten in fünf Module getrennt; der Bearbeitungszustand wird ausschließlich pro Browsersitzung im Speicher gehalten und nicht persistiert.

Auf einen Blick

  • Einzel-Container-Anwendung auf Basis von Python und Gradio mit Konfiguration über Umgebungsvariablen.
  • Modulare Trennung: UI/Orchestrierung, Prompt-Verwaltung, LLM-Client, Export, Konfiguration.
  • Kommunikation mit dem LLM über die OpenAI-kompatible Chat-Completions-Schnittstelle (HTTP).
  • Sitzungsbezogener State (Originaltext, Ergebnis, Historie) ohne Datenbank oder Festplatten-Persistenz.
  • In-Memory-Erzeugung der Export-Dateien; pro Sitzung getrennte Downloads.
  • Synchrones Anfrage-Antwort-Modell mit Timeout- und Fehlerbehandlung im Client.
  • Deployment über Docker bzw. docker-compose; Betrieb hinter einem Reverse Proxy vorgesehen (ROOT_PATH-konfigurierbar).

Architekturbeschreibung

Komponenten und Schichten

Die Anwendung folgt einer klassischen Drei-Schichten-Aufteilung: einer Präsentationsschicht im Browser, einer Server-seitigen Anwendungsschicht im Container und einem externen Inferenzdienst.

Die Präsentationsschicht wird durch das Gradio-Framework erzeugt. Sie umfasst die Tool-Leiste, die nebeneinanderliegenden Textfelder für Originaltext und Ergebnis, die Akkordeons für Zusatz-Anweisung und eigenen Befehl, die Export-Steuerung sowie einen zweiten Tab für die Bearbeitungshistorie. Sitzungsdaten werden in Gradio-State-Variablen gehalten und sind pro Browsersitzung isoliert.

Die Anwendungsschicht im Container besteht aus fünf zusammenarbeitenden Modulen:

  • app.py orchestriert das Interface, bindet Buttons an Verarbeitungsfunktionen, verwaltet den Sitzungs-State (Originaltext, Ergebnis, Historie, Akkordeon-Zustände) und stößt Tool-Ausführung, Übernehmen-Aktion, Wiederherstellung und Export an.
  • prompts.py enthält die fest hinterlegten Tool-Prompts, den gemeinsamen System-Prompt sowie tool-spezifische Generierungsparameter. Eine Hilfsfunktion fügt Tool-Prompt, optionale Zusatz-Anweisung und Eingabetext zu einem vollständigen Prompt zusammen.
  • llm_integration.py kapselt den Aufruf des LLM-Endpunkts. Es baut Chat-Messages aus System- und User-Prompt, setzt Temperatur, Top-P, Maximaltoken und Timeout, misst die Antwortzeit und übersetzt Ausnahmen in benutzerverständliche Fehlermeldungen.
  • export_utils.py erzeugt aus Originaltext und Ergebnis die vier Exportformate. Markdown wird für die DOCX-Erzeugung in Überschriften, Listen, Tabellen und Inline-Formatierung umgesetzt; alle Dateien werden im Speicher zusammengestellt.
  • config.py lädt Konfigurationswerte (Endpunkt-URL, Modellname, Sampling-Parameter, Server-Port, History-Limit, ROOT_PATH für den Reverse-Proxy-Betrieb) aus Umgebungsvariablen mit typsicheren Konvertierungsfunktionen.

Der externe LLM-Endpunkt wird als intern bereitgestellter Inferenzdienst betrachtet. Erwartet wird ausschließlich, dass der Dienst die OpenAI-kompatible Chat-Completions-Schnittstelle anbietet.

Workflow

flowchart TB
    User[Nutzer im Browser]

    subgraph Container[Container]
        UI[Gradio-UI<br/>app.py]
        State[Sitzungs-State<br/>Original, Ergebnis, Historie]
        Prompts[Prompt-Modul<br/>prompts.py]
        Client[LLM-Client<br/>llm_integration.py]
        Export[Export-Modul<br/>export_utils.py]
        Config[Konfiguration<br/>config.py]
    end

    LLM[LLM-Endpunkt<br/>OpenAI-kompatibel]
    Files[(Export-Dateien<br/>txt / md / html / docx)]

    User -->|HTTP| UI
    UI <-->|liest und schreibt| State
    UI -->|Tool-Auswahl, Text, Zusatz| Prompts
    Prompts -->|konstruierter Prompt| Client
    Client -->|Chat-Completions-Request| LLM
    LLM -->|Antwort| Client
    Client -->|Ergebnis, Laufzeit| UI
    UI -->|Export-Anfrage| Export
    Export -->|in-memory erzeugt| Files
    Files -->|Download| User
    Config -.->|Parameter| Client
    Config -.->|Server, Pfade| UI

Ein Bearbeitungsschritt durchläuft den folgenden Ablauf: Nach Eingabe eines Textes und Auswahl eines Tools übernimmt die UI den aktuellen Originaltext sowie eine optionale Zusatz-Anweisung und ruft die Prompt-Konstruktion auf. Das Prompt-Modul kombiniert den hinterlegten Tool-Prompt, die Zusatz-Anweisung und den Eingabetext zu einer vollständigen User-Message und ermittelt etwaige tool-spezifische Generierungsparameter. Der LLM-Client baut daraus eine Chat-Anfrage mit System- und User-Message, sendet sie an den OpenAI-kompatiblen Endpunkt und liefert den Antworttext zusammen mit der gemessenen Laufzeit zurück. Die UI aktualisiert das Ergebnisfeld, ergänzt einen Eintrag in der Sitzungs-Historie und blendet eine kurze Statusmeldung ein.

Die „Übernehmen"-Aktion setzt das Ergebnis als neuen Originaltext und legt einen weiteren Historien-Eintrag an, sodass mehrere Tools sequenziell auf denselben Text angewendet werden können. Aus dem Verlaufs-Tab lässt sich eine frühere Version einsehen und als aktuelle Version wiederherstellen; die zuvor aktive Version wird dabei selbst in der Historie abgelegt. Beim Export wird der gewünschte Inhalt (Original, Ergebnis oder beide) in allen vier Formaten gleichzeitig im Speicher erzeugt und als Datei-Bündel zum Download bereitgestellt.

Robustheit und Nebenläufigkeit

Der LLM-Client setzt einen konfigurierbaren Timeout und übersetzt Verbindungs-, Timeout- und Authentifizierungsfehler in strukturierte Hinweise im Interface. Vor jedem Tool-Aufruf wird die Eingabe auf Vorhandensein geprüft; bei leerem Original- oder Ergebnistext werden Aktionen mit einer Hinweismeldung abgewiesen.

Die Anwendung ist auf parallelen Betrieb mehrerer Sitzungen ausgelegt. Sämtliche Bearbeitungsdaten — Originaltext, Ergebnis, Historie, Akkordeon-Zustände — liegen in Gradio-State-Variablen, die pro Browsersitzung getrennt gehalten werden. Exportdateien werden nicht in einem gemeinsamen Verzeichnis abgelegt, sondern in einem temporären, sitzungsbezogenen Verzeichnis erzeugt, sodass es zwischen Nutzenden nicht zu Datei-Konflikten kommt. Die Historie ist pro Sitzung auf eine konfigurierbare Maximalzahl an Einträgen begrenzt; ältere Einträge fallen nach dem FIFO-Prinzip heraus.

Konfiguration und Deployment

Die Anwendung wird über ein Dockerfile als Python-3.11-Container gebaut und kann eigenständig oder über docker-compose betrieben werden. Eine Health-Check-Definition prüft die Erreichbarkeit des Web-Servers; die Laufzeit erfolgt unter einem Non-Root-Benutzer. Sämtliche Laufzeitparameter — Endpunkt-URL, API-Schlüssel, Modellname, Sampling-Defaults, Maximaltoken, Timeout, Server-Port, Share-Schalter, Reverse-Proxy-Pfad und History-Limit — werden über Umgebungsvariablen gesetzt. Das ermöglicht den Wechsel des LLM-Endpunkts oder Modells ohne Codeänderung. Der Betrieb hinter einem Reverse Proxy (z.B. nginx) wird über die ROOT_PATH-Variable unterstützt.

Technologie-Übersicht

  • UI-Framework: Gradio (Blocks-API, ab Version 5.48).
  • LLM-Client: offizieller openai-Python-Client gegen die Chat-Completions-Schnittstelle.
  • Schnittstelle: HTTP/HTTPS, OpenAI-kompatibel (/v1/chat/completions).
  • Export: python-docx für Word-Dokumente, das markdown-Paket sowie eigene Routinen für Markdown-zu-DOCX-Konvertierung; HTML wird mit eingebettetem Stylesheet erzeugt.
  • Containerisierung: Docker, docker-compose, Python 3.11-Slim-Basis-Image, Health Checks, Resource-Limits.
  • Konfiguration: Umgebungsvariablen mit typsicherer Auswertung; keine persistente Datenhaltung.