v1.36: Mieterverwaltung (Mieter 1:1 pro Wohnung, Kaution/Vertrag/Dokumente) + v1.37: KI-Assistent (N8N + Kimi, 6 Portal-Tools)

This commit is contained in:
2026-10-04 20:51:00 +02:00
parent 9e74813e22
commit 9d14d367ee
22 changed files with 1840 additions and 107 deletions
+52
View File
@@ -0,0 +1,52 @@
# KI-Assistent (v1.37) – Einrichtung N8N + Kimi
Der Assistent läuft so: **Portal-Chat → N8N-Webhook → Kimi (Moonshot API) mit 6 Portal-Tools → Antwort zurück ins Portal.**
## 1. Voraussetzungen
- N8N läuft auf dem VPS (Container `n8n`).
- Kimi-API-Key von <https://platform.moonshot.ai> (Aufladung ab ~5 $; Verbrauch des Assistenten liegt typisch unter 5 €/Monat bei 20 Fragen/Tag, Modell `kimi-k2.6`: ~0,4 US-Cent pro Frage).
## 2. N8N-Workflow importieren
1. N8N öffnen → **Workflows → Import from File** → `assist-workflow.json` aus diesem Ordner.
2. Nach dem Import drei Platzhalter anpassen:
| Wo | Was |
|---|---|
| Webhook-Node → Credentials | **Header Auth** anlegen: Name `x-assist-secret`, Wert = `ASSIST_SHARED_SECRET` |
| Kimi-Node → Credentials | **OpenAI API**-Credential anlegen: API Key = Moonshot-Key, Base URL `https://api.moonshot.ai/v1` |
| Alle 6 Tool-Nodes | Im Header `x-assist-key` den Wert `ASSIST_API_KEY` durch das echte Geheimnis ersetzen |
3. Workflow **aktivieren** (Toggle oben rechts). Die Webhook-URL steht dann im Webhook-Node, z. B.
`https://n8n.hocks.eu/webhook/mp-assist` – sie wird in Schritt 3 gebraucht.
## 3. Portal-Env auf dem Server ergänzen
In `/opt/mieterportal/portal.env` (Datei auf dem VPS):
```bash
N8N_ASSIST_WEBHOOK=https://n8n.hocks.eu/webhook/mp-assist
ASSIST_SHARED_SECRET=<langes-zufaelliges-geheimnis-1>
ASSIST_API_KEY=<langes-zufaelliges-geheimnis-2>
```
Danach: `cd /opt/mieterportal && docker compose up -d` (nimmt die neuen Env-Variablen mit).
## 4. Test
Im Portal als Verwaltung: **KI-Assistent** in der Navigation → „Welche Wohnungen stehen leer?“
Der erste Aufruf dauert ggf. 10–30 s (Agent lädt Tools).
## Fehlerbilder
| Fehlermeldung im Chat | Ursache |
|---|---|
| „noch nicht konfiguriert (N8N_ASSIST_WEBHOOK fehlt)" | Env-Variable fehlt / Container nicht neu gestartet |
| „Assistent antwortet nicht (N8N Status …)" | Webhook-URL falsch, Workflow nicht aktiv, oder Header-Secret passt nicht |
| „Assistent hat keine Antwort geliefert" | N8N liefert kein JSON `{ "antwort": "…" }` – Respond-Node prüfen |
| „braucht zu lange" | Kimi-Timeout > 90 s – Modell/Credential prüfen |
## Datenschutz-Hinweis
Das Tool `mieter_kontakt` liefert personenbezogene Daten an Kimi (Serverstandort Singapur, Training laut Anbieter-AGB möglich). Wer das vermeiden will, entfernt das Tool einfach aus dem AI-Agenten – alle anderen Tools liefern nur Bestands- und Zahlen-Daten.
+287
View File
@@ -0,0 +1,287 @@
{
"name": "Mieterportal – KI-Assistent (Kimi)",
"nodes": [
{
"parameters": {
"httpMethod": "POST",
"path": "mp-assist",
"authentication": "headerAuth",
"respondWhen": "lastNode",
"options": {}
},
"id": "a1b2c3d4-0001-4000-8000-000000000001",
"name": "Webhook (Portal)",
"type": "n8n-nodes-base.webhook",
"typeVersion": 2,
"position": [240, 520],
"credentials": {
"httpHeaderAuth": {
"id": "ASSIST_HEADER_AUTH",
"name": "mp-assist-secret"
}
}
},
{
"parameters": {
"text": "={{ $json.frage }}",
"options": {
"systemMessage": "Du bist der KI-Assistent des Mieterportals „Hinterstein Immobilien\". Du antwortest ausschließlich der Verwaltung auf Deutsch, kurz und sachlich. Beantworte Fragen zum Wohnungsbestand, Mietern, Mieteinnahmen, Zählern, Kosten und Schadensmeldungen mit den bereitgestellten Tools. Rufe immer zuerst die passenden Tools ab, bevor du Zahlen nennst – halluziniere keine Daten. Wenn ein Tool keine Treffer liefert, sage das offen. Rechne mit den Tool-Ergebnissen weiter (Summen, Anteile), wenn es hilft. Personenbezogene Daten (Telefon, E-Mail) nur nennen, wenn explizit danach gefragt wird."
}
},
"id": "a1b2c3d4-0002-4000-8000-000000000002",
"name": "AI-Agent",
"type": "@n8n/n8n-nodes-langchain.agent",
"typeVersion": 1.7,
"position": [460, 520]
},
{
"parameters": {
"model": "kimi-k2.6",
"options": {
"baseURL": "https://api.moonshot.ai/v1"
}
},
"id": "a1b2c3d4-0003-4000-8000-000000000003",
"name": "Kimi (OpenAI-kompatibel)",
"type": "@n8n/n8n-nodes-langchain.lmChatOpenAi",
"typeVersion": 1,
"position": [460, 720],
"credentials": {
"openAiApi": {
"id": "MOONSHOT_API_KEY",
"name": "Moonshot (Kimi) API"
}
}
},
{
"parameters": {
"name": "leerstaende",
"description": "Liste der leerstehenden oder unklaren Wohneinheiten mit Haus, Nummer, Etage und Fläche. Keine Parameter nötig.",
"method": "GET",
"url": "https://mieterportal.hocks.eu/api/assist/tools/leerstaende",
"authentication": "none",
"sendHeaders": true,
"headerParameters": {
"parameters": [
{ "name": "x-assist-key", "value": "ASSIST_API_KEY" }
]
},
"sendQuery": false,
"options": {}
},
"id": "a1b2c3d4-0004-4000-8000-000000000004",
"name": "Tool: Leerstände",
"type": "@n8n/n8n-nodes-langchain.toolHttpRequest",
"typeVersion": 4.2,
"position": [700, 160]
},
{
"parameters": {
"name": "mieteinnahmen",
"description": "Monatliches Miet-Soll (Warm- und Kaltmieten aller Mieter), gesamt und je Haus. Optional Parameter: haus (Teil des Hausnamens, z. B. Straße).",
"method": "GET",
"url": "https://mieterportal.hocks.eu/api/assist/tools/mieteinnahmen",
"authentication": "none",
"sendHeaders": true,
"headerParameters": {
"parameters": [
{ "name": "x-assist-key", "value": "ASSIST_API_KEY" }
]
},
"sendQuery": true,
"queryParameters": {
"parameters": [
{ "name": "haus", "value": "" }
]
},
"options": {}
},
"id": "a1b2c3d4-0005-4000-8000-000000000005",
"name": "Tool: Mieteinnahmen",
"type": "@n8n/n8n-nodes-langchain.toolHttpRequest",
"typeVersion": 4.2,
"position": [700, 280]
},
{
"parameters": {
"name": "offene_schaeden",
"description": "Offene Schadensmeldungen mit Titel, Kategorie, Priorität, Status, Mieter und Wohnung, nach Dringlichkeit sortiert. Keine Parameter nötig.",
"method": "GET",
"url": "https://mieterportal.hocks.eu/api/assist/tools/offene-schaeden",
"authentication": "none",
"sendHeaders": true,
"headerParameters": {
"parameters": [
{ "name": "x-assist-key", "value": "ASSIST_API_KEY" }
]
},
"sendQuery": false,
"options": {}
},
"id": "a1b2c3d4-0006-4000-8000-000000000006",
"name": "Tool: Schäden",
"type": "@n8n/n8n-nodes-langchain.toolHttpRequest",
"typeVersion": 4.2,
"position": [700, 400]
},
{
"parameters": {
"name": "mieter_kontakt",
"description": "Kontaktdaten (Telefon, E-Mail) eines Mieters. Genau einen Parameter angeben: name (Nach- oder Vorname) oder wohnung (Hausadresse oder Wohnungsnummer).",
"method": "GET",
"url": "https://mieterportal.hocks.eu/api/assist/tools/mieter-kontakt",
"authentication": "none",
"sendHeaders": true,
"headerParameters": {
"parameters": [
{ "name": "x-assist-key", "value": "ASSIST_API_KEY" }
]
},
"sendQuery": true,
"queryParameters": {
"parameters": [
{ "name": "name", "value": "" },
{ "name": "wohnung", "value": "" }
]
},
"options": {}
},
"id": "a1b2c3d4-0007-4000-8000-000000000007",
"name": "Tool: Mieterkontakt",
"type": "@n8n/n8n-nodes-langchain.toolHttpRequest",
"typeVersion": 4.2,
"position": [700, 520]
},
{
"parameters": {
"name": "zaehler_anomalien",
"description": "Zähler mit Auffälligkeiten im neuesten Verlaufseintrag (Rücklauf, Stillstand, Verbrauchsspitze etc.) mit Zählernummer, Art, Haus, Stand, Datum und Grund. Keine Parameter nötig.",
"method": "GET",
"url": "https://mieterportal.hocks.eu/api/assist/tools/zaehler-anomalien",
"authentication": "none",
"sendHeaders": true,
"headerParameters": {
"parameters": [
{ "name": "x-assist-key", "value": "ASSIST_API_KEY" }
]
},
"sendQuery": false,
"options": {}
},
"id": "a1b2c3d4-0008-4000-8000-000000000008",
"name": "Tool: Zähleranomalien",
"type": "@n8n/n8n-nodes-langchain.toolHttpRequest",
"typeVersion": 4.2,
"position": [700, 640]
},
{
"parameters": {
"name": "kosten",
"description": "Kosten eines Jahres, gesamt und je Haus/Kostenart, aufgeteilt in umlegbar und nicht umlegbar. Parameter: jahr (Pflicht, z. B. 2026), optional haus (Teil des Hausnamens).",
"method": "GET",
"url": "https://mieterportal.hocks.eu/api/assist/tools/kosten",
"authentication": "none",
"sendHeaders": true,
"headerParameters": {
"parameters": [
{ "name": "x-assist-key", "value": "ASSIST_API_KEY" }
]
},
"sendQuery": true,
"queryParameters": {
"parameters": [
{ "name": "jahr", "value": "" },
{ "name": "haus", "value": "" }
]
},
"options": {}
},
"id": "a1b2c3d4-0009-4000-8000-000000000009",
"name": "Tool: Kosten",
"type": "@n8n/n8n-nodes-langchain.toolHttpRequest",
"typeVersion": 4.2,
"position": [700, 760]
},
{
"parameters": {
"respondWith": "json",
"responseBody": "={{ { antwort: $json.output } }}"
},
"id": "a1b2c3d4-0010-4000-8000-000000000010",
"name": "Antwort an Portal",
"type": "n8n-nodes-base.respondToWebhook",
"typeVersion": 1.1,
"position": [680, 900]
}
],
"connections": {
"Webhook (Portal)": {
"main": [
[
{
"node": "AI-Agent",
"type": "main",
"index": 0
}
]
]
},
"AI-Agent": {
"ai_languageModel": [
[
{
"node": "Kimi (OpenAI-kompatibel)",
"type": "ai_languageModel",
"index": 0
}
]
],
"ai_tool": [
[
{
"node": "Tool: Leerstände",
"type": "ai_tool",
"index": 0
},
{
"node": "Tool: Mieteinnahmen",
"type": "ai_tool",
"index": 0
},
{
"node": "Tool: Schäden",
"type": "ai_tool",
"index": 0
},
{
"node": "Tool: Mieterkontakt",
"type": "ai_tool",
"index": 0
},
{
"node": "Tool: Zähleranomalien",
"type": "ai_tool",
"index": 0
},
{
"node": "Tool: Kosten",
"type": "ai_tool",
"index": 0
}
]
],
"main": [
[
{
"node": "Antwort an Portal",
"type": "main",
"index": 0
}
]
]
}
},
"settings": {
"executionOrder": "v1"
}
}