docs: AI support automation design spec and implementation plan
This commit is contained in:
15
.env
Normal file
15
.env
Normal 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
61
compose.yaml
Normal 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:
|
||||
1023
docs/superpowers/plans/2026-03-16-ai-support-automation-plan.md
Normal file
1023
docs/superpowers/plans/2026-03-16-ai-support-automation-plan.md
Normal file
File diff suppressed because it is too large
Load Diff
Binary file not shown.
@@ -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
|
||||
Reference in New Issue
Block a user