docs: AI support automation design spec and implementation plan

This commit is contained in:
2026-03-16 15:41:38 +01:00
commit ec581f67da
5 changed files with 1463 additions and 0 deletions

15
.env Normal file
View File

@@ -0,0 +1,15 @@
# DOMAIN_NAME and SUBDOMAIN together determine where n8n will be reachable from
# The top level domain to serve from
DOMAIN_NAME=fft-it.de
# The subdomain to serve from
SUBDOMAIN=n8n
# The above example serve n8n at: https://n8n.example.com
# Optional timezone to set which gets used by Cron and other scheduling nodes
# New York is the default value if not set
GENERIC_TIMEZONE=Europe/Berlin
# The email address to use for the TLS/SSL certificate creation
SSL_EMAIL=patrick.haas@eks-intec.de

61
compose.yaml Normal file
View File

@@ -0,0 +1,61 @@
services:
traefik:
image: "traefik"
restart: always
command:
- "--api.insecure=true"
- "--providers.docker=true"
- "--providers.docker.exposedbydefault=false"
- "--entrypoints.web.address=:80"
- "--entrypoints.web.http.redirections.entryPoint.to=websecure"
- "--entrypoints.web.http.redirections.entrypoint.scheme=https"
- "--entrypoints.websecure.address=:443"
- "--certificatesresolvers.mytlschallenge.acme.tlschallenge=true"
- "--certificatesresolvers.mytlschallenge.acme.email=${SSL_EMAIL}"
- "--certificatesresolvers.mytlschallenge.acme.storage=/letsencrypt/acme.json"
ports:
- "80:80"
- "443:443"
volumes:
- traefik_data:/letsencrypt
- /var/run/docker.sock:/var/run/docker.sock:ro
- ./crts:/opt/custom-certificates
n8n:
image: docker.n8n.io/n8nio/n8n
restart: always
ports:
- "127.0.0.1:5678:5678"
labels:
- traefik.enable=true
- traefik.http.routers.n8n.rule=Host(`${SUBDOMAIN}.${DOMAIN_NAME}`)
- traefik.http.routers.n8n.tls=true
- traefik.http.routers.n8n.entrypoints=web,websecure
- traefik.http.routers.n8n.tls.certresolver=mytlschallenge
- traefik.http.middlewares.n8n.headers.SSLRedirect=true
- traefik.http.middlewares.n8n.headers.STSSeconds=315360000
- traefik.http.middlewares.n8n.headers.browserXSSFilter=true
- traefik.http.middlewares.n8n.headers.contentTypeNosniff=true
- traefik.http.middlewares.n8n.headers.forceSTSHeader=true
- traefik.http.middlewares.n8n.headers.SSLHost=${DOMAIN_NAME}
- traefik.http.middlewares.n8n.headers.STSIncludeSubdomains=true
- traefik.http.middlewares.n8n.headers.STSPreload=true
- traefik.http.routers.n8n.middlewares=n8n@docker
environment:
- N8N_ENFORCE_SETTINGS_FILE_PERMISSIONS=true
- N8N_HOST=${SUBDOMAIN}.${DOMAIN_NAME}
- N8N_PORT=5678
- N8N_PROTOCOL=https
- N8N_RUNNERS_ENABLED=true
- NODE_ENV=production
- WEBHOOK_URL=https://${SUBDOMAIN}.${DOMAIN_NAME}/
- GENERIC_TIMEZONE=${GENERIC_TIMEZONE}
- TZ=${GENERIC_TIMEZONE}
volumes:
- n8n_data:/home/node/.n8n
- ./local-files:/files
- ./crts:/opt/custom-certificates
volumes:
n8n_data:
traefik_data:

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,364 @@
# AI-gestützte IT-Support-Automatisierung mit Wissensdatenbank
**Datum:** 2026-03-16
**Status:** Design-Phase abgeschlossen, zur Implementation bereit
**Autor:** Team
---
## 1. Problemstellung & Ziel
**Problem:** Manuelle IT-Support-Tickets in Freescout erfordern manuelle Bearbeitung. Viele wiederkehrende Probleme könnten automatisiert werden, aber lokales KI-Modell ist noch nicht vollständig vertrauenswürdig.
**Ziel:** Ein Hybrid-System aufbauen, das:
- Eingehende Mails analysiert mit lokalem LLM
- Lösungsvorschläge macht (automatische Behebung oder Baramundi-Job)
- **Mensch genehmigt alle Actions** (Approval-Gate)
- Eine selbstlernende Wissensdatenbank aufbaut und nutzt
- Mit der Zeit immer bessere Vorschläge macht
**Success-Kriterium:**
- ✅ Mindestens 50% der Tickets werden von KI erkannt
- ✅ Mensch kann innerhalb Freescout approven/rejecten
- ✅ Genehmigt → automatische Ausführung (Baramundi oder Antwort)
- ✅ KB wächst mit jeder genehmigten Lösung
---
## 2. Architektur-Übersicht
### Komponenten & Technologien
| Komponente | Technologie | Grund |
|---|---|---|
| **Orchestrierung** | n8n (Docker) | bereits vorhanden, robust |
| **Mail-Quelle** | Freescout API (https://ekshelpdesk.fft-it.de) | direkter API-Zugriff |
| **KI-Engine** | LiteLLM API (http://llm.eks-ai.apps.asgard.eks-lnx.fft-it.de/v1/chat/completions) | lokales, OpenAI-kompatibles Modell |
| **Vector Database** | Milvus oder Weaviate (Docker) | semantische Suche für KB |
| **Knowledge Base** | Vector Embeddings + Metadaten | Problem → Kategorie → Lösung → Häufigkeit |
| **Job-Execution** | Baramundi Management Server API | IT-Jobs auslösen |
| **Approval-UI** | Freescout Notes + Custom Field | Mensch genehmigt direkt in Freescout |
| **Optional Storage** | PostgreSQL (Docker) | Audit Trail, History, Metadaten |
### System-Datenfluss
```
┌─────────────────────────────────────────────────────────────────┐
│ 1. MAIL-INGESTION & KI-ANALYSE │
└─────────────────────────────────────────────────────────────────┘
Freescout (neue Mails)
n8n Polling Workflow (alle 5 Min)
[Für jedes neue Ticket]
├→ Vector DB Query: "Ähnliche Probleme finden?"
├→ LLM-Call mit Mail + KB-Context
├→ Parse KI-Response
└→ Speichere Vorschlag in Freescout (Note + Custom Field)
┌─────────────────────────────────────────────────────────────────┐
│ 2. HUMAN APPROVAL (Mensch-in-the-Loop) │
└─────────────────────────────────────────────────────────────────┘
Freescout Ticket zeigt KI-Vorschlag
Support-Mitarbeiter liest Vorschlag
[Approve] oder [Reject] geklickt
Custom Field "AI_SUGGESTION_STATUS" = "APPROVED" / "REJECTED"
┌─────────────────────────────────────────────────────────────────┐
│ 3. EXECUTION & KB-UPDATE │
└─────────────────────────────────────────────────────────────────┘
n8n Webhook triggert bei Field-Änderung
├→ Branching:
│ ├─ Baramundi-Job? → Baramundi API Call
│ └─ Automatische Antwort? → Mail/Antwort senden
└→ Bei Success: Lösung in Vector DB speichern
├─ Generiere Embedding
├─ Speichere [Problem | Kategorie | Lösung | Häufigkeit]
└─ Update bestehende KB-Einträge (Häufigkeit++)
```
---
## 3. Workflows (n8n)
### Workflow A: Mail-Processing & KI-Analyse
**Trigger:** Cron (alle 5 Minuten)
**Schritte:**
1. **Freescout API:** Hole neue, unverarbeitete Tickets
- Endpoint: `GET /api/conversations?status=active&limit=20`
- Filter: `processed_by_ai == false`
2. **Für jedes Ticket:**
- Extract Mail-Inhalt: `subject`, `body`, `customer_email`
- **Vector DB Query:** Suche semantisch ähnliche Probleme aus KB
- Query: `subject + first 500 chars of body`
- Return: Top 3 Ergebnisse mit Kategorie + Lösung
3. **LLM-Call** mit:
```json
{
"system": "Du bist IT-Support-Assistent. Analysiere das Ticket und nutze die KB.",
"user_content": {
"ticket": { "subject": "...", "body": "..." },
"similar_kb_entries": [ {...}, {...}, {...} ]
}
}
```
4. **Parse Response** (JSON):
```json
{
"kategorie": "Hardware|Software|Account|Netzwerk|Sonstiges",
"problem_verstanden": "Kurze Zusammenfassung",
"lösung_typ": "BARAMUNDI_JOB | AUTOMATISCHE_ANTWORT | ESKALATION",
"baramundi_job": {
"name": "Job-Name",
"parameter": { "..." }
},
"antwort_text": "Kundenfreundliche Antwort für Mail...",
"vertrauen": 0.75,
"begründung": "Dieses Problem ist in KB vorhanden..."
}
```
5. **Filter nach Vertrauen:**
- Wenn `vertrauen >= 0.6`: Vorschlag in Freescout speichern
- Wenn `vertrauen < 0.6`: Als "ESKALATION" markieren
6. **Speichere Vorschlag in Freescout:**
- Note (für Mensch zu lesen):
```
[KI-VORSCHLAG]
Kategorie: Hardware
Lösung: Baramundi-Job "Drucker-Treiber-Update"
Vertrauen: 75%
Begründung: ...
```
- Custom Field `AI_SUGGESTION`: JSON serialisiert
- Custom Field `AI_SUGGESTION_STATUS`: "PENDING"
7. **Markiere Ticket:** `processed_by_ai = true`
---
### Workflow B: Approval & Execution
**Trigger:** Freescout Custom Field `AI_SUGGESTION_STATUS` geändert
**Schritte:**
1. **Validiere:** Status ist "APPROVED" oder "REJECTED"
2. **Wenn REJECTED:**
- Log in PostgreSQL: `{ticket_id, rejected_at, reason}`
- Notify Mensch (optional): "KI-Vorschlag wurde abgelehnt"
- **STOP**
3. **Wenn APPROVED:**
- Hole KI-Vorschlag aus Custom Field
- Parse `lösung_typ`
4. **Branching:**
**A) Wenn `lösung_typ == "BARAMUNDI_JOB"`:**
- Call Baramundi API:
```
POST /api/jobs
{
"name": "...",
"parameter": {...}
}
```
- Speichere Job-ID in Freescout
- Schreibe Reply-Note: "✅ Baramundi-Job #123 ausgelöst"
**B) Wenn `lösung_typ == "AUTOMATISCHE_ANTWORT"`:**
- Sende Email an Kunde:
```
To: customer_email
Subject: Re: [TICKET_SUBJECT]
Body: [antwort_text aus KI-Response]
```
- Schreibe Note in Freescout: "✅ Automatische Antwort gesendet"
- Markiere Ticket als gelöst
**C) Wenn `lösung_typ == "ESKALATION"`:**
- Markiere für manuelles Review
- Notify Manager
5. **Bei Success (A oder B):**
- Gehe zu Workflow C (KB-Update)
---
### Workflow C: Knowledge Base Update
**Trigger:** Nach Workflow B bei Success
**Schritte:**
1. **Extracte Info:**
- Problem-Text: `subject + body`
- Kategorie: aus KI-Response
- Lösung: `antwort_text` oder `baramundi_job.name`
- Timestamp: now
2. **LLM-Embedding generieren:**
- Call LLM API: `/v1/embeddings`
- Input: `category + problem_text`
- Output: `embedding` (vector)
3. **Vector DB Insert:**
```json
{
"id": "uuid()",
"problem_text": "Drucker funktioniert nicht",
"kategorie": "Hardware",
"lösung": "Treiber neu installiert via Baramundi",
"häufigkeit": 1,
"embedding": [0.123, -0.456, ...],
"timestamp": "2026-03-16T10:30:00Z",
"baramundi_job_id": "123" (optional),
"freescout_ticket_id": "999"
}
```
4. **Update bestehende KB-Einträge:**
- Query Vector DB: "Finde ähnliche Probleme"
- Für jeden Hit mit Similarity > 0.85:
- `häufigkeit++`
- Update `last_used_at`
5. **Log in PostgreSQL:**
- `knowledge_base_updates` Tabelle
- Track: wann, was, von welchem Ticket
6. **Cleanup (optional):**
- Einmal pro Woche: Archiviere alte Einträge (> 1 Jahr, häufigkeit = 0)
---
## 4. Data Structures
### Freescout Custom Fields (zu erstellen)
```
1. AI_SUGGESTION (Text/JSON)
- Speichert KI-Vorschlag als JSON
2. AI_SUGGESTION_STATUS (Dropdown)
- Werte: PENDING, APPROVED, REJECTED, EXECUTED
3. PROCESSED_BY_AI (Boolean)
- Markiert ob Mail schon analysiert wurde
```
### Vector DB Schema (Milvus/Weaviate)
```json
{
"id": "uuid",
"problem_text": "string",
"kategorie": "string",
"lösung": "string",
"häufigkeit": "integer",
"embedding": "vector[1024]",
"timestamp": "datetime",
"freescout_ticket_id": "integer",
"baramundi_job_id": "string (optional)"
}
```
### PostgreSQL Schema (optional, für Audit Trail)
```sql
CREATE TABLE knowledge_base_updates (
id UUID PRIMARY KEY,
ticket_id INTEGER,
problem_text TEXT,
kategorie VARCHAR,
lösung TEXT,
created_at TIMESTAMP,
approved_at TIMESTAMP,
executed_at TIMESTAMP,
status VARCHAR -- APPROVED, REJECTED, EXECUTED
);
CREATE TABLE kb_feedback (
id UUID PRIMARY KEY,
kb_entry_id UUID REFERENCES milvus,
feedback VARCHAR -- helpful, not_helpful
created_at TIMESTAMP
);
```
---
## 5. Sicherheit & Governance
### Mensch-in-the-Loop
- ✅ **Keine automatische Ausführung:** Jede Aktion benötigt manuellen Approval
- ✅ **Vertrauen-Scoring:** Nur Vorschläge mit `vertrauen >= 0.6` werden angezeigt
-**Audit Trail:** Alle Decisions werden gelogged (wer, wann, was)
-**Rejection-Tracking:** Abgelehnte Vorschläge werden analysiert → Modell-Improvement
### Fehlerbehandlung
- **LLM-Timeout:** Fallback auf "ESKALATION"
- **Baramundi-API-Fehler:** Retry 3x, dann manuelles Review
- **Vector DB Down:** Ignoriere KB-Context, nutze LLM ohne Context
- **Mail-Parsing-Fehler:** Markiere Ticket, notify Mensch
---
## 6. Phasen & Rollout
### Phase 1: MVP (Woche 1-2)
- ✅ n8n Workflows A (Mail-Processing) + B (Approval) einrichten
- ✅ Freescout API Integration testen
- ✅ LiteLLM Integration testen
- ✅ Manuelle Approval-Flow testen
### Phase 2: KB Integration (Woche 3)
- ✅ Milvus in Docker deployen
- ✅ Workflow C (KB-Update) einrichten
- ✅ Vector DB Query in Workflow A integrieren
### Phase 3: Production (Woche 4+)
- ✅ Monitoring + Alerting
- ✅ KB-Cleanup-Jobs
- ✅ Reporting + Analytics
---
## 7. Success Metrics
| Metrik | Ziel | Messung |
|---|---|---|
| **Mail-Erkennungsrate** | > 50% | (processed_by_ai = true) / total_tickets |
| **Approval-Rate** | > 70% | approved / total_suggested |
| **Baramundi-Job-Success** | > 90% | successful_jobs / total_jobs |
| **KB-Größe** | > 100 Einträge | count(*) from vector_db |
| **Häufigkeits-Improvement** | > 20% weniger Manual-Work | manual_processing_time t1 vs t2 |
---
## 8. Offene Fragen & Next Steps
- [ ] Welche Baramundi-Jobs sind verfügbar?
- [ ] Freescout API-Key vorhanden?
- [ ] LiteLLM API-Key/Auth Setup?
- [ ] PostgreSQL für Audit Trail gewünscht oder Optional?
- [ ] Milvus oder Weaviate bevorzugt?
- [ ] Wie oft soll KB-Cleanup laufen?
---
**Status:** Bereit für Implementation Plan