Darstellung
22 – Doku-Assistent (Chat auf docs.work7.net)
Schicht: src/docs-site/ (VitePress + Node-Server)
Surface: öffentliche Dokumentation docs.work7.net
Betriebsumgebung: Azure OpenAI (EU), keine Benutzer-Authentifizierung, keine Speicherung von Fragen/Antworten.
1. Übersicht
Der Doku-Assistent ist ein KI-gestützter Chat im Dokumentationsportal, der Fragen zur Work7-Dokumentation beantwortet und Quellenangaben (Seite › Abschnitt mit Deeplink) angibt. Die Chat-Oberfläche sitzt als schwebender Button „Frag die Doku" in der rechten unteren Ecke jeder Dokumentseite; über Vorschlagsfragen geht es ohne Tippen ins Gespräch.
2. Ablauf
- Benutzer stellt eine Frage oder klickt auf eine Vorschlagsfrage.
- Wortsuche sofort: Die Rohfrage wird um ein kleines Synonymwörterbuch ergänzt (z. B. „ausstempeln“ → „Gehen Stoppuhr“, „API-Key“ → „API-Schlüssel“) und läuft durch MiniSearch (BM25). Kein Modellaufruf, keine Wartezeit.
- Ranking & Zusammenführung: Die Treffer werden nach Relevanz gereiht und auf maximal 8 Abschnitte reduziert (maximal 3 je Seite). Handbuch und Public API werden höher gewichtet als interne Referenz, ADRs und Changelog.
- Antwort aus Auszügen: gpt-5-mini (Reasoning
minimal, SSE-Stream) antwortet ausschließlich aus den Treffern und zitiert die Quellen als[1],[2]usw. - Nachsuche bei Bedarf: Beantworten die Auszüge die Frage nicht, ruft das Modell einmal das Werkzeug
suche_dokumit besseren Suchbegriffen auf. Der Server sucht erneut, schickt die neue Quellenliste (und einreset, falls schon Text gestreamt wurde) und lässt das Modell mit den neuen Auszügen antworten. Das kostet nur bei den Fragen Zeit, bei denen die erste Suche daneben lag. - Quellenliste: Unter der Antwort stehen die zitierten Abschnitte mit Nummer, Seite, Abschnittstitel und Deeplink.
Optional lässt sich vor der Suche eine Suchplanung per Modell einschalten (DOCS_CHAT_PLANNER): dann formuliert das Modell zuerst 1–3 Suchanfragen. Das verbessert die Trefferquote bei Umschreibungen, kostet aber rund 0,8 s je Frage; Standard ist off, weil die Nachsuche denselben Zweck nur im Bedarfsfall erfüllt.
Gemessen auf Test (2026-09-16, sechs Beispielfragen): Suchplanung + Reasoning low: erstes Token nach ~3,1 s, gesamt ~3,8 s. Suchplanung + minimal: ~1,7 s / ~2,3 s, aber das Modell übersah dabei Inhalte in den Auszügen. Aktuelle Variante (ohne Planung, minimal, Nachsuche bei Bedarf): erstes Token nach ~1,2 s, gesamt ~1,6 s, alle sechs Fragen richtig beantwortet; die Nachsuche griff bei keiner davon, bei einer schwer formulierten Frage einmal (gesamt ~1,6 s). Kosten je Frage mit gpt-5-mini (EU Data Zone, Aggregator-Preise): rund 0,1 Cent.
3. Konfiguration und Umgebung
Env-Variablen (auf Test und Prod in den Helm-Values src/deploy/values-*.yaml):
| Variable | Pflicht | Beschreibung |
|---|---|---|
AZURE_OPENAI_API_KEY | ja | Secret aus dem Vault; derselbe Key wie für Agent/App |
AZURE_OPENAI_ENDPOINT | ja | z. B. https://…openai.azure.com/ |
AZURE_OPENAI_API_VERSION | ja | z. B. 2024-12-01-preview |
DOCS_CHAT_DEPLOYMENT | nein | Name des Deployments in Azure OpenAI; Fallback: gpt-5-mini |
DOCS_CHAT_PLANNER | nein | Suchplanung per Modell: off (Standard), same (gleiches Deployment) oder ein Deployment-Name (z. B. gpt-5-nano) |
DOCS_CHAT_REASONING | nein | Reasoning-Stufe der Antwort (gpt-5-Familie): minimal (Standard), low, medium |
DOCS_CHAT_RATE_PER_IP | nein | Rate Limit je IP-Adresse pro 10 Minuten; Fallback: 20 |
DOCS_CHAT_RATE_PER_DAY | nein | Globales tägliches Limit; Fallback: 3000 |
PORT | nein | Server-Port; Fallback: 8080 |
DIST_DIR | nein | Pfad zur statischen VitePress-Build (dist/); Fallback: ./dist |
Lokal entwickeln:
bash
cd src/docs-site
npm install
npm run build-chat-index # Generiert server/generated/chat-index.json
npm run chat-dev # Server auf :8787 mit .env (aus .env.example) + Vite-Proxy für /apiCheck vor Commit:
bash
npm run check
# Prüft: OpenAPI ↔ Routen, Build mit totem-Link-Check, Unit-Tests (Chunking, Suche, Rate-Limit, Chat-Helfer)4. Indexierung und Suchraum
Build-Zeit-Indexierung (scripts/build-chat-index.mjs):
- Beim VitePress-Build werden alle
content/-Seiten in Abschnitte zerlegt (H2/H3-Überschriften). - Nur Seiten aus der Allowlist (
publish.config.json) werden indiziert. - Ergebnis:
server/generated/chat-index.json(nicht öffentlich, intern nur vom Server gelesen).
Suchgewichte (server/retrieval.mjs):
- Handbuch und Anleitungen (
docs/handbuch/) ×1,6, Public API (docs/api/public/) ×1,5 - Funktionsreferenz (
docs/features/) ×1,0; interne REST-API ×0,7; ADRs ×0,6; technischer Changelog ×0,5 - Pläne, Runbooks, Archiv → nicht veröffentlicht und daher nicht indiziert
Keine Embeddings, kein Vector-DB: Die Suche ist lexikalisch (Wörter, Phrasen) über MiniSearch; das reicht für eine Dokumentation und ist wartungsarm.
5. Rate-Limiting
- Pro IP: max. 20 Fragen je 10 Minuten (per CloudFront-Header
X-Forwarded-For). - Global: max. 3000 Fragen pro Kalendertag (über in-Memory Counter; bei Reboot zurück auf 0).
Ist das Limit erreicht, antwortet der Server mit 429 Too Many Requests und einer kurzen Fehlermeldung für den Nutzer.
6. Datenschutz und Sicherheit
- Keine Authentifizierung: Der Chat ist öffentlich, keine Login nötig. Nutzer werden nicht erfasst.
- Azure OpenAI: Fragen werden an Azure OpenAI (EU-Region) übermittelt, nicht an OpenAI. Siehe Datenschutz-Seite für die Nutzer-Information.
- Serverseitige Speicherung: Nur eine Protokoll-Zeile pro Request (Timestamp, IP, Tokens); kein Verlauf oder Session-Speicher.
- Client-seitig:
sessionStoragehält den Gesprächsverlauf lokal (nicht persistent, kein Cookie). Beim Browser-Neuladen ist der Chat leer. - Hinweis in der UI: Das Chat-Panel zeigt einen kurzen Text: „Diese Antwort wird von KI generiert. Deine Frage wird an Azure OpenAI übermittelt. Keine Speicherung auf unserem Server."
7. Komponenten und Dateien
| Datei / Modul | Verantwortung |
|---|---|
src/docs-site/server/index.mjs | Hono-Server; POST /api/chat (SSE), GET /api/chat/health |
server/chat.mjs | Hauptlogik: Suchanfrage-Formulierung, Retrieval, Antwort-Streaming |
server/retrieval.mjs | MiniSearch-Suche mit Gewichtung; lädt chat-index.json |
server/chunk.mjs | H2/H3-Zerlegu ng beim Index-Build |
scripts/build-chat-index.mjs | Erzeugt server/generated/chat-index.json beim npm run build |
server/generated/chat-index.json | Index-Datei (nicht öffentlich) |
.vitepress/theme/DocsChat.vue | Vue-Komponente: Chat-UI, Buttons, Session-State |
src/Dockerfile.docs | Runner node:20-alpine; startet node server/index.mjs |
| Helm-Values | src/deploy/values-test-docs.yaml, values-prod-docs.yaml |
8. Betrieb und Wartung
- Index wird bei jedem Build neu erzeugt. Eine Änderung an der Dokumentation braucht einen neuen Docs-Build und Deploy.
- Server-Logs: Je Antwort eine JSON-Zeile
{"evt":"docs-chat", ms, hits, chars, prompt_tokens, completion_tokens, queries}(Anzahl der Suchanfragen, nicht ihr Text); dazu Fehler der Azure-Aufrufe. Fragen und Antworten werden nicht geloggt. - Ausfall: Fehlt Schlüssel oder Index, antwortet
POST /api/chatmit 503; das Widget zeigt „nicht verfügbar“, die Site selbst läuft weiter. - Health-Check:
GET /api/chat/healthliefert{ ok, index: { chunks, builtAt, sha }, llm }; die Kubernetes-Probes nutzen weiterhin/healthz.
9. Bekannte Grenzen
- Handbuch-Fokus: Der Chat arbeitet nur mit veröffentlichten Seiten. Interne Pläne oder Prompts sind nicht erreichbar.
- Kein Kontext über die Session: Jede Frage steht für sich; der Chat merkt sich nicht die vorherige Frage (Nutzer müssen Kontext mitliefern).
- Keine Realtime-Updates: Der Index wird nur beim Build erneuert, nicht live bei Dokumentationsänderungen.
- Englisch-Support: Der Doku-Assistent arbeitet nur mit deutschem Inhalt; englische Fragen können zu Off-Topic-Antworten führen.
10. Abhängigkeiten
- Azure OpenAI: Deployment
gpt-5-mini(oder konfigurierbar). - Node.js 20+ (im Dockerfile).
- MiniSearch (npm): lexikalische Suche.
- VitePress: Dokumentations-Framework.
- Hono: minimalistisches Web-Framework für den Server.
Siehe src/docs-site/package.json für exakte Versionen.