docs: Alicia-Aufgaben für Chat-Agent (Guard + RAG für WhatsApp/Telegram)
Quality Gate / 🛡️ Lint + Type Check + Tests (push) Failing after 12m34s

This commit is contained in:
Hermes Agent
2026-06-25 10:33:04 +02:00
parent 172b33b9be
commit 2fd3b7b887
+184
View File
@@ -0,0 +1,184 @@
# BSN-Chatsystem — Chat-Agent: RAG-Antworten auf WhatsApp/Telegram
> **Für Alicia (Qwen 3.6, 256K Context)**
> **Stand:** 25.06.2026
> **Repo:** `git@git.datenhimmel.work:danielkrause/BSN-Chatsystem.git`
> **Branch:** `main`
> **Arbeitsverzeichnis:** `/home/hermes/workspace/bsn-chatbot/`
> **Issue:** [#14](https://git.datenhimmel.work/danielkrause/BSN-Chatsystem/issues/14)
---
## Ziel
WhatsApp- und Telegram-Nutzer können natürliche Fragen an den Bot stellen und bekommen
RAG-basierte Antworten aus der Datenbank (Submissions, Aussteller, Neuheiten).
Beispielfragen:
- „Welches Spiel ist ausverkauft?"
- „Was passiert in Halle 3?"
- „Wo finde ich eine Katze?"
- „Gibt es Neuheiten von Kosmos?"
---
## Aufgabe 14a — Neues Modul: `chat_agent.py`
### Datei: `chat_agent.py` (neue Datei im Repo-Root)
**Funktionen:**
1. **`is_boardgame_question(text: str) -> bool`**
- Guard-Filter: Prüft ob die Frage Brettspiel/SPIEL-bezogen ist
- Keywords: `spiel`, `brettspiel`, `halle`, `stand`, `verlag`, `aussteller`, `messe`,
`essen`, `spiel'`, `ausverkauft`, `neuheit`, `katze`, `kOSMOS`, `feuerland`,
`catan`, `pegasus`, `asmodee`, `ravensburger`, `schmidt`, `hans im glück`,
`lookout`, `zoch`, `amigo`, `queen games`, `days of wonder`, `rebel`, `portal`
- Auch erlaubt: Fragen mit `?` am Ende + deutschem Text (mind. 10 Zeichen)
- IMMER True bei offensichtlichen Brettspiel-Fragen
- IMMER False bei: Politik, Erwachseneninhalte, Beleidigungen, irrelevante Themen
2. **`answer_question(db, message: str, sender_name: str = "", history: list | None = None) -> str`**
- Baut Kontext aus 3 Tabellen (wie `/api/chat` in `app.py`):
- `submissions` (veröffentlichte Beiträge, LIMIT 40)
- `aussteller` (Verlage/Stände, gefiltert nach Keywords)
- `neuheiten` (Spiele-Neuheiten, gefiltert nach Keywords, mit AUSVERKAUFT-Flag)
- Sendet Kontext + Frage an LLM (`deepseek-v4-flash:cloud` via `https://ui.datenhimmel.work/api/chat/completions`)
- System-Prompt: Nur antworten wenn Info im Kontext, sonst „Dazu habe ich leider keine Informationen."
- Antwort immer auf Deutsch, 2-4 Sätze, mit Markdown-Links zu `/beitrag/ID`
- API-Key aus `~/.hermes/config.yaml` lesen (wie `/api/chat`)
- Timeout: 15 Sekunden, Fallback-Text bei Fehler
**Referenz:** Die bestehende `/api/chat`-Route in `app.py` (Zeilen 40224310) enthält exakt
die gleiche Logik. Extrahiere die Kernlogik in `answer_question()` und lass `/api/chat`
die neue Funktion aufrufen (Refactoring).
### Qualität
```bash
ruff check chat_agent.py --fix && ruff format chat_agent.py
```
**Commit:** `feat(chat): Chat-Agent-Modul mit Guard-Filter + RAG-Antworten`
---
## Aufgabe 14b — WhatsApp-Webhook: Frage-Erkennung + Antwort
### Datei: `app.py` — WhatsApp-Webhook (ab Zeile ~1162)
**Einbau-Ort:** Nach dem Intake-Block (Speichern der Submission), VOR dem `db.commit()`.
**Logik:**
```python
# Nach dem Intake (nach Thread-Erstellung/Aktualisierung):
if msg_type == "text" and not thread_found:
from chat_agent import is_boardgame_question, answer_question
if is_boardgame_question(content):
try:
reply = answer_question(db, content, sender_name)
if reply:
send_whatsapp_message(sender_id, reply)
except Exception as e:
print(f"[chat-agent error] {e}", file=sys.stderr)
```
**Wichtig:**
- Nur bei TEXT-Nachrichten (nicht bei Bild/Audio/Video)
- Nur bei NEUEN Threads (nicht bei Thread-Appends)
- NACH allen anderen Checks (#out, registrieren, code, „Meine Daten löschen", FAQ)
- Exception-Handling: Fehler NIE zum Webhook-500 führen → immer `return "OK", 200`
- Inline-Import (vermeidet Circular-Imports)
### Qualität
```bash
ruff check app.py --fix && ruff format app.py
```
**Commit:** `feat(whatsapp): Frage-Erkennung + Chat-Agent-Antwort im WhatsApp-Webhook`
---
## Aufgabe 14c — Telegram-Webhook: Gleiche Logik
### Datei: `app.py` — Telegram-Webhook (Zeilen 52935317)
Alternativ: `webhook_queue.py``telegram_intake()` (Zeilen 172215).
**Wo einbauen:** Nachdem die Nachricht aus dem Telegram-Update extrahiert wurde.
**Logik:** Gleiche wie WhatsApp:
```python
text = msg.get("text", "")
if text:
from chat_agent import is_boardgame_question, answer_question
if is_boardgame_question(text):
chat_id = msg.get("chat", {}).get("id")
reply = answer_question(db, text, sender_name)
# Sende Antwort via Telegram API
requests.post(f"{TELEGRAM_API}/sendMessage", json={
"chat_id": chat_id, "text": reply, "parse_mode": "Markdown"
})
```
### Qualität
```bash
ruff check app.py --fix && ruff format app.py
```
**Commit:** `feat(telegram): Chat-Agent-Antwort im Telegram-Webhook`
---
## Aufgabe 14d — Testfragen (manuel)
**NICHT automatisieren.** Nachdem Alicia gebaut hat, testet Cody:
```bash
# Test 1: Brettspiel-Frage
curl -X POST http://localhost:5002/api/chat \
-H "Content-Type: application/json" \
-d '{"message": "Welches Spiel ist ausverkauft?"}'
# Test 2: Halle-Frage
curl -X POST http://localhost:5002/api/chat \
-H "Content-Type: application/json" \
-d '{"message": "Was passiert in Halle 3?"}'
# Test 3: Katzen-Frage (Guard muss durchlassen!)
curl -X POST http://localhost:5002/api/chat \
-H "Content-Type: application/json" \
-d '{"message": "Wo finde ich eine Katze?"}'
# Test 4: Off-Topic (Guard muss blocken)
curl -X POST http://localhost:5002/api/chat \
-H "Content-Type: application/json" \
-d '{"message": "Wie wird das Wetter morgen?"}'
```
---
## Qualitätsregeln
```bash
# Vor JEDEM Commit:
ruff check . --fix && ruff format . && pytest -v
```
- **Commit-Messages:** `feat(chat):` / `feat(whatsapp):` / `feat(telegram):`
- **Docstrings:** Deutsch, Google-Style
- **Typ-Annotationen:** Jede Funktion (Python 3.13, PEP 604)
- **Kein `print()`** → `sys.stderr` für Debug
- **BSN-Blau `#20228a`** für Links in Antworten
---
## Wichtige Hinweise
1. **Kein Circular Import:** `chat_agent.py` importiert NICHTS aus `app.py`. Nur `sqlite3` + `requests` + `os` + `re`.
2. **Guard NICHT zu streng:** „Katze" ist ein legitimes Brettspiel-Thema (Die Crew, Katze im Sack, etc.). Der Guard soll nur WIRKLICHEN Missbrauch abwehren.
3. **Timeout:** LLM-Call max 15 Sekunden — WhatsApp erwartet schnelle Antwort (< 20s).
4. **Nie 500er:** Alle Chat-Agent-Fehler werden gefangen → immer `return "OK", 200`.
5. **`bsn-secrets` nicht nötig:** Der API-Key kommt aus `~/.hermes/config.yaml` (lokale Datei).