Zum Hauptinhalt springen

KI-Chat-Architektur

Der KIera-Chat in SpeamCore ist ein LLM-basierter Assistent, der über Tool-Use echte Aktionen im System ausführt. Diese Seite erklärt das technische Konzept, Berechtigungs-Vererbung, Audit-Mechanismen und warum der Sachbearbeiter trotz KI die Endverantwortung behält.

Konzept-Überblick

Komponenten

LLM (Large Language Model)

  • Verarbeitet den natürlich-sprachigen Prompt des Sachbearbeiters
  • Kennt das verfügbare Tool-Set (siehe „Tool-Use" unten)
  • Entscheidet welche Tools wann mit welchen Parametern aufgerufen werden
  • Kennt nicht die echten Daten im Vorfeld — alles geht über Tools

System-Prompt

Der LLM bekommt einen festen Vorab-Kontext:

  • Persona / Rolle des aktuellen Sachbearbeiters
  • Verfügbare Tools (CRUD pro Modul, Reports, Bulk-Aktionen)
  • Verhaltens-Regeln (z.B. „bei Versand-Aktionen immer Vorschau anbieten")
  • Mandanten-Kontext (welche Niederlassung, welche Konfiguration)

Tool-Use-Loop (MCP-basiert)

Tools werden über einen MCP-Server (Model Context Protocol) bereitgestellt — api.speamcore.com/src/mcp/server.ts. Der Tool-Use-Loop ist im chat.service.ts implementiert (verarbeitet tool_use/tool_result-Blocks rekursiv bis ein End-Stop-Reason kommt).

Verfügbare MCP-Tools (Stand 2026-05, src/mcp/tools/):

ToolZweck
model.tool.tsGenerische CRUD-Aktionen auf jedes Sequelize-Modell
model-schema.tool.tsSchema-Introspektion eines Modells für Tool-Auswahl
attribute.tool.tsCustom-Attribute lesen/schreiben
aggregate.tool.tsAggregations-Queries (SUM, COUNT, AVG)
groupBy.tool.tsGruppierungs-Queries
calculate.tool.tsNumerische Berechnungen
keycloak.tool.tsUser-/Rollen-Lookups (Read-Only)
number-circle.tool.tsNummern-Kreis-Operationen
process-expense-recurrence.tool.tsWiederkehrende Spesen-Verarbeitung
run-transaction-matching.tool.tsAuto-Allokations-Lauf triggern
sync-finapi-accounts.tool.tsfinAPI-Bank-Sync triggern
sync-pleo-accounts.tool.tsPleo-Karten-Sync triggern
get-employee-time-balance.tool.ts (Welle 133)Vollständiger Arbeitszeit-Saldo eines Mitarbeiters (Soll/Ist/Saldo, Brutto/Netto, Überstunden, §3-ArbZG-Cap). Optional detailed=true für tägliche Aufschlüsselung + Pausenanalyse + Plausibilitäts-Findings
list-time-overview.tool.ts (Welle 133)Aggregierte Sicht über mehrere MAs — Soll/Ist/Saldo pro MA + KPIs activeEmployees, employeesInMinus, pendingOvertimeHours. Filterbar nach employeeId/departmentId/branchId
aggregate-time-metrics.tool.ts (Welle 133)Statistik-Aggregat über MA-Gruppe — wählbar sum/mean/min/max/median/p90 über Metriken wie workIst, workSoll, saldo, absenceDays
list-time-plausibility-issues.tool.ts (Welle 133)Auffälligkeiten pro MA — doppelte Einträge, Überlappungen, unrealistische Dauer (unrealisticNetto), fehlende Pausen (missingBreak). Nutzt dieselbe computeTimeBalance()-SSoT wie das Time-Overview-Dashboard

Dokument-Tools (Welle 150)

ToolZweck
create-letter.tool.tsGeschäftsbriefe via LetterheadShell, DIN-5008-konform, NumberCircle-Auto, AddressSnapshot-Hook. CASL create:Letter.
create-sales-document.tool.tsAngebote / Rechnungen / Lieferscheine — Marge-Check, Pre-Flight-Validierung. CASL create:SalesDocument.
create-purchase-document.tool.tsBestellungen, Lieferanten-Stamm-Lookup. CASL create:PurchaseDocument.
render-branded-pdf.tool.tsFree-Form PDF (Datenblätter, Handouts, Reports), LetterheadShell-Header/Footer, optionaler QR-Code-Trailing. CASL create:Letter.
list-entity-documents.tool.tsList alle Document-Einträge an einer Entity (Workorder/SalesDocument/Letter/Customer/…). Primär für Verkettung mit send-mail via attachmentDocumentIds.

Bild-Generierung (Welle 150)

ToolZweck
generate-image.tool.tsOpenAI gpt-image-1 — PNG-Attachment, Größen 1024×1024 / 1536×1024 / 1024×1536 / auto, Qualität low / medium / high / auto, Cost-Estimate $0,04–$0,19 pro Bild. CASL create:Letter.

Mail-Tools (Welle 150)

ToolZweck
mail-overview.tool.tsPosteingangs-Übersicht: Aggregate (total/unread/needsReply), Top-Kategorien, Top-Sender. Range: today / yesterday / last_7_days / last_30_days / this_month / custom.
mail-action-items.tool.tsOffene Actions (aiNeedsReply=true && !isHandled) + Termin-Mails (14 Tage Default), je mit aiSummary + aiReplySuggestion.
mail-stats.tool.tsKostenstatistiken — aiActualCostEur30d, CostPerMail, AvgPerDay ab ≥10 Mails / ≥5 Tage. Admin-Bypass für Mandanten-Statistik.
send-mail.tool.tsNeue Mail (Mode send oder draft), mailboxId + subject + body + to[] + cc?[] + bcc?[] + attachmentDocumentIds?[]. CASL create:Mail + MailboxEmployee.permission = write|readwrite.
reply-or-forward-mail.tool.tsmode = reply / reply_all / forward mit korrektem conversationId-Thread + Original-Body-Quote + Auto-Handled-Trigger.
move-mail-to-folder.tool.tsMulti-Mail-Move zu Folder via mailIds[] + folderPath.
mark-mail-handled.tool.tsToggle isHandled = true per MailEmployeeState.
mark-mail-unread.tool.tsToggle isRead = false.
mark-mail-trashed.tool.tsToggle isTrashed = true.

Kalender-Tool (Welle 150)

ToolZweck
create-calendar-event.tool.tsOutlook-Termin via MS Graph + automatische Einladungen. Felder: title, startAt (ISO 8601 + TZ), endAt, timezone?, description?, location?, isAllDay?, isOnlineMeeting?, attendees[], reminderMinutesBefore?, mailboxId?. CASL create:CalendarEvent + MailboxEmployee.calendarPermission = write|readwrite.

Adress-Tool (Welle 150)

ToolZweck
find-or-create-address.tool.tsNominatim-Suche + atomare Address + AddressParent-Anlage in einer Transaktion. Input: postalCode, city, streetAddress?, countryCode?. CASL create:Address.

Web-Fetch-Tools (Welle 150)

ToolZweck
web_searchAnthropic Server-Tool — Web-Suche mit Synthese. Aktiviert via ANTHROPIC_BETAS Header.
web_fetchAnthropic Server-Tool — strukturierter Page-Fetch. Wenn nicht verfügbar, fällt System auf fetch_url zurück.
fetch-url.tool.tsCustom Fallback mit 3-Stufen-Escalation: (1) regulärer Fetch → (2) Headless-Chromium (Playwright + Stealth) → (3) curl-impersonate (TLS-Fingerprint). HTTPS-only, SSRF-Schutz, 5 MB Limit, 15 s Timeout, 25 k char Output-Cap.

Beispiel-Loop:

Prompt: "Welche Kunden haben offene Posten >30 Tage?"

LLM:
→ aggregate.tool({model: "OpenItem", filter: {dueDate__lt: "..."}, groupBy: "customerId"})
← [{customerId: "...", count: 5, sum: 12345}, ...]
→ model.tool({action: "list", model: "Customer", ids: [...]})
← [Liste mit Kunden-Details]

LLM antwortet:
"12 Kunden haben offene Posten >30 Tage. Top-3: ..."

Beispiel Time-Analytics (Welle 133):

Prompt: "Welche Mitarbeiter haben letzte Woche ein Minus-Saldo > 4 h?"

LLM:
→ list-time-overview.tool({from: "...", to: "..."})
← [{employee, workIst, workSoll, saldo, ...}, ...]
→ list-time-plausibility-issues.tool({from, to, employeeId: "..."})
← [{type: "missingBreak", date, detail}, ...]

LLM antwortet:
"3 MA mit Minus-Saldo unter -4h: Max (-5,2h), Anna (-4,1h), Tom (-6,8h).
Bei Tom zusätzlich 2 Tage mit fehlender Pflicht-Pause. Empfehle Gespräch."

Backend-Integration

  • Tools sind echte Backend-Service-Calls über den MCP-Server, nicht separate KI-API.
  • Der Sachbearbeiter ist der API-User — die KI handelt in seinem Namen, der clientId-Tenant-Kontext und CASL-Berechtigungen bleiben aktiv.
  • CASL prüft pro Aufruf über getSystemAbility() und Tool-spezifische Validierung.

Berechtigungs-Vererbung

Wichtigste Regel: Die KI kann nichts, was der Sachbearbeiter nicht darf. Wenn ein Buchhalter keine HR-Lese-Rechte hat, kann auch die KI im Buchhalter-Kontext keine HR-Daten ziehen.

Das ist absichtlich so: keine Privilegien-Eskalation via Chat.

Audit-Trail (Doppel-Spur)

Pro KI-Chat-Aktion entstehen zwei separate Audit-Einträge:

1. Chat-Audit

  • Pro Prompt + KI-Antwort ein ChatMessage-Eintrag
  • Vollständiger Verlauf des Chats nachvollziehbar
  • Wer hat was gefragt, wann

2. Standard-Audit-Log

  • Pro ausgeführter Mutation ein Audit-Eintrag (wie bei UI-Aktionen)
  • Sichtbar dass die Quelle „KI-Chat" war (separates Flag)
  • Vorher/Nachher pro Feld

Bei Streit-Fällen: Cross-Reference zwischen Chat-Prompt und Audit-Eintrag — nachvollziehbar ob Sachbearbeiter die Aktion bewusst angewiesen hat.

Sicherheits-Mechanismen

Vorschau-Pflicht bei kritischen Aktionen

  • Versand (Mail, Mahnung, Rechnung)
  • Lohn-Auszahlung
  • Berechtigungs-Änderungen
  • Bulk-Lösch-Aktionen

→ KI bereitet vor, fragt explizit beim Sachbearbeiter um Freigabe vor Ausführung.

Black-Listed Aktionen

Bestimmte Aktionen kann die KI nicht ausführen, auch nicht mit Bestätigung:

  • Konten-Rahmen-Änderungen
  • Mandanten-Setup
  • Audit-Log-Manipulation
  • Master-Passwort-Änderungen

→ Diese müssen über das UI mit zusätzlicher Authentifizierung erfolgen.

Rate-Limiting

  • Pro Sachbearbeiter max. N Mutationen pro Minute via Chat
  • Bei Bulk-Aktionen explizite Bestätigung mit erwarteter Anzahl

Sensible-Daten-Filter

  • Personal-Daten (Lohn, Bank, Krankheit, Religion) werden nicht im Chat zurückgegeben
  • DSGVO-relevante Bulk-Listen → Hinweis auf manuelle Prüfung

Was die KI gut kann (Stärken)

  • Bulk-Aufgaben — schnell durch viele Datensätze
  • Cross-Modul-Recherche — verbindet Daten aus mehreren Modulen
  • OCR/Dokument-Analyse — Belege, Foto-Mängel
  • Natürlich-sprachige Filter — „alle aus Stuttgart letzten Monat"
  • Custom-Reports — Auswertung ad-hoc

Was die KI nicht kann (Grenzen)

  • Strategische Entscheidungen — KPI-Interpretation, Personal-Entscheidungen
  • Empathische Kommunikation — Kunden-Beschwerde-Telefonat
  • Gesetz-Auslegung — Steuer, Compliance, DSGVO-Sonderfälle
  • Branchen-Wissen-Tiefe — DIN-Norm-Auslegung, Spezial-Fälle
  • Kreativität bei Sonderfällen — wenn der Standard-Workflow nicht passt

Verantwortlichkeiten — wer trägt was

VerantwortungWer trägt?
Endverantwortung der AktionSachbearbeiter (immer)
Genauigkeit der DatenSachbearbeiter (prüft KI-Ergebnis)
Korrekte BerechtigungSystem (CASL) + Admin (Rollen-Pflege)
Audit-TrailSystem (automatisch)
DSGVO-KonformitätMandant + GF
Falsche KI-AntwortSachbearbeiter (hätte prüfen müssen)

Pattern für Sachbearbeiter

Faustregel: vertrauen, aber prüfen.

  1. Klar formulieren — präzise Anweisung mit Constraints
  2. Vor Ausführung sehen — bei Versand/Buchung Vorschau pflicht
  3. Nach Ausführung verifizieren — kurz im UI gegenchecken
  4. Bei Unsicherheit — UI-Weg statt Chat
  5. Niemals blind übernehmen — KI-Ergebnis kritisch lesen

PDF/Mail-Preview im Chat + Action-QuickReplies (Welle 150)

Seit Welle 150 kann die KI im Chat Aktions-Pillen zurückgeben, die nicht einen neuen Prompt auslösen, sondern direkt eine UI-Aktion triggern (PDF öffnen, URL aufrufen, Mail-Vorschau zeigen). Plus eine massive UX-Erweiterung — Mehrfach-Select für Datei-Anhänge und ein einklappbarer Chat-Verlauf.

Action-QuickReplies (parseQuickReplies.ts)

Die KI-Antwort kann jetzt vier Typen von Quick-Replies enthalten:

[QUICK_REPLIES]
- Normale Text-Frage zurück an KI
- [ACTION:open_pdf:349fa362-...]PDF anzeigen[/ACTION]
- [ACTION:open_url:/letter-editor]Im Brief-Editor bearbeiten[/ACTION]
- [ACTION:open_mail:abc123def]Gesendete Mail anzeigen[/ACTION]
[/QUICK_REPLIES]

Pro Typ:

TypMarkerWirkung
textnormales Listen-ItemKlick schickt den Text als neuen Prompt — Standard-Verhalten (Welle 142)
open_pdf[ACTION:open_pdf:<documentId>]Öffnet PdfPreviewModal.tsx mit dem Dokument
open_url[ACTION:open_url:/path/...]Navigiert zu der SpeamCore-Route
open_mail[ACTION:open_mail:<mailId>]Öffnet MailPreviewModal.tsx mit Subject + Von/An/Cc + Body

Die Aktions-Pillen sind erkennbar gestylt (Icon plus Label), damit der User sieht: das ist keine Frage zurück an die KI, sondern eine UI-Aktion.

PDF-Preview-Modal (PdfPreviewModal.tsx, 112 LOC)

  • Lädt das PDF aus Document.url per Iframe (oder bei Bild-MIME als <img>)
  • Schließen via Esc oder X
  • Download-Button daneben
  • Volle Höhe modal, kein Tab-Wechsel nötig

Mail-Preview-Modal (MailPreviewModal.tsx, 208 LOC)

  • Subject + Von + An + Cc-Adressen oben
  • Body (HTML-rendered) im Hauptbereich
  • MailRecipient-Eintrag separat geladen für korrekte Anzeige
  • Direkt-Link zur Mail-Detail-Sicht falls tiefer einsteigen

Multi-Select für Datei-Anhänge

Beim Anhängen mehrerer Dateien an einen Chat-Prompt:

  • Mehrere Dateien gleichzeitig markierbar
  • Labels landen mit Newline-Trenner im Input-Feld
  • Auswahl wird nach erfolgreichem Senden gecleart

Einklappbarer Chat-Verlauf

Der Chat-Verlauf links (Liste der Chats) ist über Chevron-Icon einklappbar:

  • isSidebarCollapsed-State in localStorage persistiert
  • Re-Expand-Streifen mit Chevron wenn eingeklappt
  • Layout-Fix: overflowWrap: anywhere auf Message-Bubbles

Streaming + Quick-Replies (Welle 142)

Die FE-Komponente nutzt seit Welle 142 einen SSE-Streaming-Service (src/services/streamChat.service.ts) statt eines klassischen POST /chats/:id/prompt-Roundtrips:

  • Endpoint: POST /api/chats/:id/prompt/stream — Server schickt Events live als Server-Sent-Events
  • Event-Typen: text_delta, thinking_delta, tool_use_start/end, iteration_start, approval_required, message_stop, final, error
  • Approval-Workflow im Plan-Mode: submitApprovalDecision() über die gleiche Verbindung
  • Error-Handling mit StreamChatError (Kategorie, retryable-Flag, Recovery-Hint)

Zusätzlich gibt es im Chat seit Welle 142 Quick-Reply-Buttons unter jeder Assistant-Antwort:

  • Die KI markiert in ihrer Antwort einen Block [QUICK_REPLIES] - Antwort 1 - Antwort 2 ... [/QUICK_REPLIES]
  • src/utils/parseQuickReplies.ts parst bis zu 4 Replies (Marker -, , *)
  • Streaming-sicher: Replies erscheinen erst nach dem schließenden Tag, der [QUICK_REPLIES]…-Roh-Text bleibt versteckt
  • User klickt einen Reply → wird direkt als nächster Prompt geschickt, kein Tippen nötig

Chat-UI-Politur Runde 2 (Commit 8aabed2d)

  • Popout-Default: Chat-Button im Header öffnet immer ein separates Popout-Fenster (kein Modal mehr); zweiter Klick fokussiert das bestehende Fenster.
  • Footer-Chips statt Key-Value-Tabelle (Modell, Tokens, Kosten, Dauer, Tools) — kompakter.
  • Thinking-Toggle nur sichtbar, wenn das gewählte Modell Extended Thinking unterstützt (Claude 3.7+ / 4.x).
  • AI-Chat-Paste verwandelt eingefügte Inhalte in Plain-Text (kein Word-/Browser-Color-Spam).
  • Hover-Action-Bar an Charts/SVGs mit Download- + Zoom-Button.

Verwandte Doku

Versionshinweise

  • 2026-05-20 (Welle 133): Vier neue Time-Analytics-MCP-Tools (get-employee-time-balance, list-time-overview, aggregate-time-metrics, list-time-plausibility-issues). Nutzen dieselbe computeTimeBalance()-SSoT wie das Time-Overview-Dashboard — kein neuer Pfad zur Berechnung, sondern MCP-Wrapper über bestehende Service-Funktion. CASL: alle vier erfordern view:EmployeeTimeTracking, view:EmployeeContract, view:WorkTimeModel; die drei Multi-MA-Tools zusätzlich view:Employee (Filter über branchId/departmentId/employeeId). Quelle: BE-Commit c9c5b66c.
  • 2026-05-21 (Welle 142): SSE-Streaming via streamChat.service.ts (Endpoint /chats/:id/prompt/stream, Event-Typen text_delta/thinking_delta/tool_use_*/approval_required/…), Quick-Reply-Buttons unter Assistant-Antworten (Marker [QUICK_REPLIES]…[/QUICK_REPLIES], parseQuickReplies.ts, streaming-sicher), Chat-UI-Politur Runde 2 (Popout-Default, Footer-Chips, Thinking-Toggle modell-bewusst, Plain-Text-Paste, Hover-Action-Bar an Charts/SVGs). Verweis auf das in Welle 140 eingeführte AI-Memory-System. Quelle: FE-Commit 8aabed2d, neue Files streamChat.service.ts + parseQuickReplies.ts.
  • 2026-05-26 (Welle 150): 17 neue MCP-Tools in 6 Kategorien — Dokumente (create-letter, create-sales-document, create-purchase-document, render-branded-pdf, list-entity-documents), Bild-Generierung (generate-image via OpenAI gpt-image-1), Mail (mail-overview, mail-action-items, mail-stats, send-mail, reply-or-forward-mail, move-mail-to-folder, mark-mail-handled/-unread/-trashed), Kalender (create-calendar-event via MS Graph), Adresse (find-or-create-address mit Nominatim), Web-Fetch (web_search/web_fetch Anthropic-Server-Tools + fetch-url Custom-Fallback mit 3-Stufen-Escalation Playwright/curl-impersonate). Action-QuickReplies als Discriminated Union mit 4 Typen (text/open_pdf/open_url/open_mail) — UI-Aktionen direkt aus KI-Antwort ohne neuen Prompt. PDF/Mail-Preview-Modals im Chat (PdfPreviewModal, MailPreviewModal). Multi-Select für Datei-Anhänge + einklappbarer Chat-Verlauf. Quelle: FE e23662ff + BE 609d1556 (24 Dateien, 4908 LOC).
  • Audit-Trail-Architektur — Doppel-Spur-Audit
  • Memory-Pattern für Sachbearbeiter — Best Practices