DeepbitDesktop v0 β RAG Support Desk
Logfiles und Dokumente rein. Wissen aufbauen. Crew fragt. Antwort kommt.
Multi-Channel RAG-System fΓΌr RZ-Support-Teams β mit lokalem LLM-Coding-Assistenten.
Inhalt
- Was ist das?
- Stack
- Quickstart
- Architektur
- Wissen ingestieren
- Channels
- OpenCode β Ollama
- Deployment & Updates
- Troubleshooting
Was ist das?
ozmai (OZM AI) ist ein RAG-System (Retrieval-Augmented Generation) das intern lΓ€uft.
Kein Cloud-Speicher fΓΌr die Dokumente. Kein Dritter sieht die Logfiles.
Wie es funktioniert:
Dokument / Logfile einmal ingestieren
β
βΌ
Ollama zerlegt es in Chunks und erstellt Vektoren
β
βΌ
pgvector speichert Vektoren + Inhalt in PostgreSQL
β
βΌ
Crew stellt Frage im Browser
β
βΌ
Frage β Vektor β Γ€hnliche Chunks gesucht β Claude formuliert Antwort
Das Wissen bleibt lokal in PostgreSQL. Claude sieht nur den Kontext fΓΌr eine Anfrage β keine Daten wandern dauerhaft in die Cloud.
Stack
| Komponente | Rolle | Port |
|---|---|---|
| FastAPI | REST-Backend, alle Endpunkte | 8080 |
| PostgreSQL 17 + pgvector | Vektordatenbank + Chat-History | intern |
Ollama (nomic-embed-text) |
Lokale Embeddings (768 dim) | 11434 |
| Anthropic Claude | LLM-Reasoning, Antwortgenerierung | API |
| Vanilla JS SPA | Frontend, IRC-Style, kein Framework | β |
| Docker Compose | Orchestrierung: db, ollama, app |
β |
Quickstart
Voraussetzungen
- Docker + Docker Compose
- Anthropic API Key
1. Einrichten
git clone <dieses-repo> DeepbitDesktop_v0
cd DeepbitDesktop_v0
2. API Key eintragen
# .env ΓΆffnen und ANTHROPIC_API_KEY eintragen
nano .env
DATABASE_URL=postgresql://rag:rag@db:5432/supportdesk
OLLAMA_URL=http://ollama:11434
ANTHROPIC_API_KEY=sk-ant-...
POSTGRES_USER=rag
POSTGRES_PASSWORD=rag
POSTGRES_DB=supportdesk
3. Starten
docker compose up --build
Beim ersten Start:
- Ollama lΓ€dt nomic-embed-text β je nach Verbindung 1β5 Minuten
- PostgreSQL importiert seed/02-seed.sql automatisch (nur einmal, auf leerem Volume)
- App wartet bis beide Services healthy sind
4. Γffnen
http://localhost:8080
Das Wissen aus dem Seed ist sofort verfΓΌgbar β kein Re-Ingest nΓΆtig.
Architektur
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
β Browser (public/index.html) β
β IRC-Style SPA Β· Channels Β· Vektor- und LLM-Modus β
βββββββββββββββββββββββββ¬ββββββββββββββββββββββββββββββββββββββ
β HTTP
βββββββββββββββββββββββββΌββββββββββββββββββββββββββββββββββββββ
β FastAPI (api.py) Β· Port 8080 β
β β
β POST /query β Frage stellen (Vektor oder LLM) β
β POST /ingest-text β Text direkt ingestieren β
β POST /ingest β Datei ingestieren β
β POST /analyze-log β Anonymisierte Log-Analyse β
β GET /history β Chat-History eines Channels β
β GET /channels β Alle Channels β
β POST /admin/reset β Chunks lΓΆschen (channel-scoped) β
ββββββββββββ¬βββββββββββββββββββββββ¬ββββββββββββββββββββββββββββ
β β
ββββββββββββΌβββββββββββ ββββββββββΌβββββββββββββββββββββββββββββ
β Ollama β β PostgreSQL 17 + pgvector β
β nomic-embed-text β β β
β 768-dim Embeddings β β channels β Kanal-Definitionen β
β Port 11434 β β chunks β Vektoren + Inhalt β
β (auch fΓΌr β β chat_history β GesprΓ€chsprotokoll β
β OpenCode) β β β
βββββββββββββββββββββββ βββββββββββββββββββββββββββββββββββββββββ
β
ββββββββββββΌβββββββββββ
β Anthropic Claude β
β Sonnet API β
β Antwortgenerierung β
βββββββββββββββββββββββ
Query-Pipeline
Frage β Ollama Embedding β pgvector cosine search (TOP 5)
β Claude (Vektor-Modus: nur Kontext | LLM-Modus: + eigenes Wissen)
β Antwort + Quellen β Chat-History β Browser
Channel-Scoping
Jede Anfrage sucht im Ziel-Channel. Der general-Channel wird immer als Fallback einbezogen. Das verhindert tote Anfragen wenn ein Channel leer ist.
Wissen ingestieren
Text direkt (API)
curl -X POST http://localhost:8080/ingest-text \
-H "Content-Type: application/json" \
-d '{
"text": "Inhalt des Dokuments...",
"source": "mein_dokument.md",
"channel_id": "dns"
}'
Markdown-Datei via Browser
Im Frontend: Channel wΓ€hlen β Ingest β Datei hochladen oder Text einfΓΌgen.
Empfohlene Chunk-Struktur
Chunks werden nach 20 Zeilen aufgeteilt. FΓΌr gute Retrieval-QualitΓ€t:
- FAQ-Format fΓΌr Grundbegriffe: Frage direkt in die erste Zeile des Abschnitts:
Frage: Was ist X und wie funktioniert es? Antwort: X ist ... - Kommando-BlΓΆcke fΓΌr Procedures: Kommentare + Befehl in einem Block
- Nicht vermischen: Ein Chunk = ein Thema
Log-Analyse (anonym)
curl -X POST http://localhost:8080/analyze-log \
-H "Content-Type: application/json" \
-d '{
"log_text": "Apr 1 03:22:11 srv01 sshd[1234]: Failed password...",
"question": "Was ist hier auffΓ€llig?"
}'
IPs, Hostnamen und User werden automatisch anonymisiert. Die Rohdaten werden nie gespeichert.
Channels
| Channel | Kategorie | Inhalt |
|---|---|---|
general |
β | Fallback, Cross-Channel-Wissen |
dns |
Service | DNS-Records, AuflΓΆsung, Debugging |
ssh |
Service | Key-Auth, HΓ€rtung, sshd_config |
iptables |
Service | Tables/Chains, Regeln, Persistenz |
ozm |
Repos | OZMAI-Systemdoku, Architektur |
debian |
System | Debian-Administration |
ubuntu |
System | Ubuntu-spezifische Docs |
bashpanda-admin |
Repos | Bashpanda Admin Tools |
bashpanda-magic |
Repos | Bashpanda Magic |
ckl |
Repos | CKL-Projektdoku |
claudcat |
Repos | ClaudCat-Projektdoku |
Neuen Channel anlegen:
curl -X POST http://localhost:8080/channels \
-H "Content-Type: application/json" \
-d '{"name": "Nginx", "category": "Service"}'
OpenRouter
OpenRouter gibt Zugriff auf 200+ Modelle ΓΌber eine einzige OpenAI-kompatible API β Claude, GPT-4o, Llama, Mistral, Gemini und mehr.
API Key besorgen
- https://openrouter.ai/keys β Key erstellen
- In
.enveintragen:
OPENROUTER_API_KEY=sk-or-v1-...
OPENROUTER_MODEL=anthropic/claude-3.5-haiku
Modell wΓ€hlen
Beliebtes Modell fΓΌr Kosten/QualitΓ€t:
| Modell | StΓ€rke | Kosten |
|---|---|---|
anthropic/claude-3.5-haiku |
Schnell, gut | gΓΌnstig |
anthropic/claude-sonnet-4-5 |
Stark | mittel |
meta-llama/llama-3.1-70b-instruct |
Open-Source | sehr gΓΌnstig |
google/gemini-flash-1.5 |
Schnell | sehr gΓΌnstig |
openai/gpt-4o-mini |
Allround | gΓΌnstig |
VollstΓ€ndige Liste: https://openrouter.ai/models
Im Frontend nutzen
Nach dem Stack-Neustart erscheint im Header ein Provider-Toggle:
π Vektor π§ LLM β π΅ Claude π OpenRouter
- π΅ Claude β Anthropic API direkt
- π OpenRouter β konfiguriertes
OPENROUTER_MODEL
Der Nick zeigt welcher Provider geantwortet hat: ππ ozmai oder π΅π§ ozmai.
Stack neu starten nach .env-Γnderung
docker compose down && docker compose up --build
OpenCode β Ollama
OpenCode ist ein KI-Coding-Assistent fΓΌr das Terminal β Γ€hnlich wie Claude Code, aber mit lokalem LLM. Der Ollama-Stack lΓ€uft bereits auf Port 11434 und ist OpenAI-API-kompatibel.
OpenCode installieren
curl -fsSL https://opencode.ai/install | bash
Coding-Modell laden
nomic-embed-text ist nur fΓΌr Embeddings. FΓΌr Code-Assistance ein Coding-Modell nachladen:
# Empfohlen: Qwen 2.5 Coder (7B β lΓ€uft auf 16 GB RAM)
docker compose exec ollama ollama pull qwen2.5-coder:7b
# Alternativ kleiner (8 GB RAM):
docker compose exec ollama ollama pull qwen2.5-coder:3b
# Oder CodeLlama:
docker compose exec ollama ollama pull codellama:7b
OpenCode konfigurieren
Das Setup-Script legt die Konfiguration automatisch an. Manuell:
~/.config/opencode/config.json
{
"$schema": "https://opencode.ai/config.json",
"autoshare": false,
"providers": {
"ollama": {
"npm": "@opensdks/runtime",
"baseURL": "http://localhost:11434/v1",
"apiKey": "ollama"
}
},
"model": "ollama/qwen2.5-coder:7b"
}
Starten
# Im Projektverzeichnis
opencode
OpenCode nutzt dann das lokale Coding-Modell ΓΌber den laufenden Stack. Keine Daten gehen nach auΓen.
VerfΓΌgbare Modelle prΓΌfen
docker compose exec ollama ollama list
# oder direkt:
curl http://localhost:11434/api/tags | python3 -m json.tool
Deployment & Updates
Setup-Script (bei neuem Rechner / neuem Deploy)
# Laufenden Original-Stack vorausgesetzt:
bash setup_deploy_crewscript.sh
Das Script:
1. Exportiert den aktuellen DB-Stand (pg_dump)
2. Kopiert App-Quellcode
3. Erstellt docker-compose.yml mit Seed
4. Legt .env-Vorlage an
5. Konfiguriert OpenCode β Ollama (falls installiert)
Wissen aktualisieren (neuen Snapshot machen)
# Neuen Seed aus laufendem Stack exportieren:
docker exec rkl-ozm-chat-hook-v00-db-1 \
pg_dump -U rag -d supportdesk --data-only --no-privileges --no-owner \
> seed/02-seed.sql
# Vollbackup mit Zeitstempel:
docker exec rkl-ozm-chat-hook-v00-db-1 \
pg_dump -U rag -d supportdesk --no-privileges --no-owner \
> seed/backup_$(date +%Y%m%d_%H%M%S).sql
Wissen auf neuer Instanz zurΓΌckspielen
# pgdata-Volume lΓΆschen (erzwingt Neu-Import beim nΓ€chsten Start):
docker compose down -v
docker compose up --build
Der Seed wird beim ersten Start automatisch importiert.
Troubleshooting
Ollama startet nicht / Modell fehlt
# Logs prΓΌfen:
docker compose logs ollama
# Modell manuell ziehen:
docker compose exec ollama ollama pull nomic-embed-text
DB nicht erreichbar
# Health-Check:
docker compose ps
curl http://localhost:8080/health
# DB direkt:
docker compose exec db psql -U rag -d supportdesk -c "SELECT COUNT(*) FROM chunks;"
Seed wurde nicht importiert
Der docker-entrypoint-initdb.d-Mechanismus greift nur auf leerem Volume. Wenn das Volume schon Daten hat:
docker compose down -v # Volume lΓΆschen
docker compose up # Neu starten mit Seed-Import
"Keine Information im Vektor" trotz vorhandenem Wissen
Das passiert wenn:
- Die Frage im Vektor-Modus ist, aber kein passender Chunk im Top-5 landet
- LΓΆsung A: LLM-Modus wΓ€hlen (Claude darf eigenes Wissen ergΓ€nzen)
- LΓΆsung B: Fehlendes Wissen als FAQ-Chunk ingestieren (Frage + Antwort direkt im Text)
Port 8080 belegt
# Original-Stack stoppen:
cd /Users/bmt/Documents/RKL-OZM-Chat-Hook-v.0.0 && docker compose down
# Dann hier:
docker compose up
OpenCode findet Ollama nicht
# Stack lΓ€uft?
curl http://localhost:11434/api/tags
# Modell geladen?
docker compose exec ollama ollama list
# Config prΓΌfen:
cat ~/.config/opencode/config.json
Dateien
DeepbitDesktop_v0/
βββ api.py β FastAPI App, alle Endpunkte
βββ ingest.py β Ingest-Pipeline
βββ query.py β RAG-Query + Log-Analyse
βββ embeddings.py β Ollama Embedding-Client
βββ requirements.txt
βββ Dockerfile
βββ schema.sql β DB-Schema (DDL)
βββ ollama-entrypoint.sh β Modell-Autoload beim Start
βββ docker-compose.yml β Stack-Definition
βββ .env β Secrets (nicht ins Git!)
βββ public/ β Frontend SPA
β βββ index.html
βββ seed/
β βββ 02-seed.sql β Aktueller Wissens-Snapshot
β βββ backup_*.sql β Vollbackups mit Zeitstempel
βββ logs/ β Runtime-Logs
βββ docs/
β βββ opencode_config_example.json
βββ setup_deploy_crewscript.sh β Dieses Script
kein Wald ist einfach β aber jeder Baum fΓ€ngt mit einem Samen an.