Files
ai-agent/CLAUDE.md
Christoph K. b1a576f61e tests
2026-03-20 07:08:00 +01:00

6.6 KiB
Raw Blame History

CLAUDE.md

This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.

Project Overview

my-brain-importer is a personal AI assistant and RAG (Retrieval-Augmented Generation) system written in Go. It ingests Markdown notes into a Qdrant vector database, answers questions using a local LLM (LocalAI), and is primarily controlled via Discord. A background daemon sends proactive email summaries and a daily morning briefing.

Commands

# Build all binaries (Linux + Windows cross-compile)
bash build.sh

# Primary entry point: Discord Bot (includes daemon)
go run ./cmd/discord/

# CLI tools
go run ./cmd/ingest/                    # Markdown importieren
go run ./cmd/ingest/ bild.json          # JSON importieren
go run ./cmd/ask/ "your question here"  # Frage stellen

# Test: IMAP-Verbindung
go run ./cmd/mailtest/

# Test: LLM-Zusammenfassung ohne IMAP
go run ./cmd/mailtest/ -llm-only

# Run tests
go test ./...

# Tidy dependencies
go mod tidy

# Deployment auf Remote-Server (192.168.1.118)
cp deploy.env.example deploy.env   # einmalig: Credentials eintragen
bash deploy.sh                     # build + upload + systemctl restart

Binaries are output to ./bin/. The config.yml file must exist in the working directory at runtime.

Architecture

Discord (primäres Interface)
    ↓ Slash-Commands + @Mention
cmd/discord/main.go
    ├── internal/agents/research/   → brain.AskQuery() + Konversationsverlauf
    ├── internal/agents/memory/     → brain.RunIngest(), brain.IngestChatMessage()
    ├── internal/agents/task/       → tasks.json (atomisches JSON, DueDate + Priority)
    └── internal/agents/tool/email/ → IMAP + LLM-Zusammenfassung + Move to Processed
              ↓
    [Daemon-Goroutine] startDaemon()
        ├── Email-Check (alle N min)      → #localagent Discord-Channel
        └── Morgen-Briefing (täglich 8h)  → Tasks + Emails kombiniert

cmd/ingest/ + cmd/ask/  (CLI-Tools, direkt nutzbar)
    ↓
internal/brain/         (Core RAG-Logik)
    ↓
Qdrant (gRPC) + LocalAI (HTTP, OpenAI-kompatibel)

Packages

Package Zweck
cmd/discord/ Discord Bot + Daemon (primärer Einstiegspunkt)
cmd/ask/ CLI-Tool: Fragen stellen
cmd/ingest/ CLI-Tool: Markdown/JSON importieren
cmd/mailtest/ Testprogramm: IMAP + LLM-Test
internal/brain/ Core RAG: Embeddings, Qdrant-Suche, LLM-Streaming
internal/config/ Konfiguration + Client-Initialisierung (globale Cfg)
internal/agents/ Agent-Interface (Request/Response/HistoryMessage)
internal/agents/research/ Research-Agent: Wissensdatenbank-Abfragen (mit History)
internal/agents/memory/ Memory-Agent: Ingest + Chat-Speicherung
internal/agents/task/ Task-Agent: Aufgabenverwaltung (tasks.json)
internal/agents/tool/ Tool-Dispatcher
internal/agents/tool/email/ IMAP-Client + LLM-Email-Analyse + Move to Processed

Discord Commands

Slash-Command @Mention Funktion
/ask, /research @bot <frage> Wissensdatenbank abfragen (mit Chat-Gedächtnis)
/asknobrain Direkt an LLM (kein RAG)
/memory store @bot remember <text> Text speichern
/memory ingest @bot ingest Markdown neu einlesen
/task add <text> [faellig] [prioritaet] @bot task add <text> [--due YYYY-MM-DD] [--priority hoch] Task hinzufügen
/task list/done/delete @bot task <aktion> Aufgaben verwalten
/email summary/unread/remind @bot email <aktion> Email-Analyse
/remember Alias für /memory store
/ingest Alias für /memory ingest

Key Patterns

  • Deterministic IDs: SHA256 of source:text — upserting the same content is always idempotent
  • Excluded directories: 05_Agents and .git are skipped during markdown ingest
  • config.yml must be present in the working directory at runtime
  • Agent Interface: alle Agenten implementieren Handle(Request) Response
  • Defer-first Pattern: Discord-Handlers senden sofort Defer, dann berechnen — nie >3s warten
  • LLM-Fallback: Email-Zusammenfassung zeigt Rohliste wenn LLM nicht erreichbar
  • Daemon: läuft als Goroutine im Discord-Bot-Prozess (startDaemon())
  • config.Cfg: globale Variable — bei Tests muss config.LoadConfig() aufgerufen oder Cfg direkt gesetzt werden
  • Konversationsverlauf: Pro Discord-Channel werden die letzten 10 Frage-Antwort-Paare in-memory gehalten und als History an brain.AskQuery() übergeben
  • Task-Felder: DueDate *time.Time und Priority string (hoch/mittel/niedrig) — rückwärtskompatibel (omitempty)
  • Email processed_folder: Nach Zusammenfassung werden ungelesene Emails in konfigurierten IMAP-Ordner verschoben (leer = deaktiviert)
  • Morgen-Briefing: dailyBriefing() kombiniert offene Tasks (mit Fälligkeits-Highlighting) + ungelesene Emails täglich um 8:00

config.yml Neue Felder

email:
  processed_folder: "Processed"  # Zielordner nach Zusammenfassung (leer = kein Verschieben)

daemon:
  task_reminder_hour: 8           # Uhrzeit des Morgen-Briefings (Standard: 8)

Deployment

# deploy.env (nicht in Git):
DEPLOY_HOST=192.168.1.118
DEPLOY_USER=christoph
DEPLOY_PASS=...
DEPLOY_DIR=/home/christoph/brain-bot
SERVICE_NAME=brain-bot
DEPLOY_CONFIG=true

# Systemd-Service (einmalig):
sudo systemctl unmask brain-bot   # falls masked

Script deploy.sh baut das Linux-Binary, überträgt es per sshpass/scp und startet den systemd-Service neu.

Model Limitations

Das konfigurierte Modell (Qwen3.5-4B-Claude-4.6-Opus-Reasoning-Distilled-GGUF) hat folgende Grenzen:

  • Kontextfenster: Begrenzt — bei sehr langen Email-Listen oder vielen Chunks kann die Antwort abgeschnitten werden (MaxTokens: 600)
  • Latenz: Lokales Modell auf NAS — Antwortzeiten variieren (560s je nach Last)
  • Encoding: Betreffzeilen in windows-1252 (Strato) werden nicht dekodiert — das LLM interpretiert sie trotzdem meist korrekt
  • Halluzinationen: Das Modell kann bei unklarem Kontext eigenes Wissen einmischen — ist im System-Prompt mit "Aus meinem Wissen:" markiert
  • Streaming-Timeout: Kein expliziter Timeout auf LLM-Calls — bei Hänger wird Discord-Interaktion erst nach 15min ungültig

External Services

  • Qdrant (192.168.1.4:6334) — Vektordatenbank, gRPC
  • LocalAI (192.168.1.118:8080) — lokales LLM, OpenAI-kompatibles API
  • Strato IMAP (imap.strato.de:143, STARTTLS) — Email-Abruf
  • Discord — primäres Interface (Bot-Token in config.yml)