Files
Aime/README.md
T
Sascha d5b9733e78 feat(gui+search): Inhaltssuche mit Zeitstempel-Verweis, Papierkorb (30 Tage), Titel umbenennen
Drei vom Nutzer angeforderte Funktionen.

Titel umbenennen: PATCH /api/recordings/:id/title. Neue Spalte recordings.title_locked,
damit eine spaetere KI-Analyse einen von Hand gesetzten Titel nicht wieder ueberschreibt.

Papierkorb: DELETE setzt nur noch deleted_at, nichts wird angefasst. Wiederherstellen,
endgueltig loeschen, Aufraeumlauf beim Boot und taeglich (Boot-Lauf, weil das Board oft
tagelang aus ist). Behebt nebenbei einen Altfehler: das bisherige Loeschen liess die
words-Zeilen verwaist in der DB und die WAV/MP3-Dateien auf der Karte zurueck.

Inhaltssuche: neue Tabelle passages (1689 Zeilen aus 22 Aufnahmen) mit Sprecher und
Zeitfenster je Passage. Trefferliste kommt aus SQL in Millisekunden, die formulierte
Antwort mit Belegen [1][2] wird nachgereicht (Qwen3-4B, ~140 s) - deshalb zweistufig.
Hybrid: MariaDB FULLTEXT + Passage-Embedding + Dokument-Embedding aus Titel/Zusammenfassung
(multilingual-e5-small, ONNX/CPU, taskset A55). Ohne Modell degradiert die Suche sauber
auf Volltext statt auszufallen.

Gemessene Grenzen sind dokumentiert statt geschoent: e5-small trennt auf verrauschtem
ASR-Text schwach (Kosinus-Spanne aller Passagen nur 0,8085-0,8560; eine irrelevante
Passage schlug die richtige Antwort). Dokument-Ebene und IDF-Wertung heben die richtige
Passage auf Rang 11 von 296, aber nicht in die Top-8, die das LLM liest. Naechster Hebel
waere multilingual-e5-base.

Relative Datumsangaben werden deterministisch aufgeloest, nicht vom LLM - ein falsches
Kalenderfenster waere schlimmer als gar keins.

Neu: app/search.js, app/emb.js, app/inference/embed_text.py, docs/09-suche-und-verwaltung.md
Board-Backups: .bak-search
2026-07-31 13:20:20 +00:00

4.5 KiB
Raw Blame History

Aime — Dokumentation

Name: Das Projekt heißt Aime (wie der Bluetooth-Name des Boards; vormals „CallRec“). Technische Bezeichner auf dem Board bleiben aus Stabilitätsgründen unverändert: callrec.service, /opt/callrec, DB/User callrec, PipeWire-Quelle „CallRecMix“.

Selbst gehostete Anruf-Aufnahme- und Analyse-Appliance auf einem Youyeetoo R1 (RK3588S) Einplatinenrechner. Nimmt Gespräche auf (PC/Teams über USB-Gadget und iPhone über Bluetooth-HFP), transkribiert mit Whisper (Encoder auf der NPU), trennt Sprecher akustisch (Diarization + Stimm-Profile) und erzeugt eine strukturierte KI-Zusammenfassung (Gemma-3-4B auf der NPU) — komplett offline, keine Cloud.

Inhaltsverzeichnis

Dokument Inhalt
01 – Hardware Board, Audio-Hardware, USB-Gadget, Thermik, NPU
02 – Audio-Topologie PipeWire-Graph: callmix, Loopbacks, Noise-Gate, Volume-Bridges
03 – Aufnahme-Pipeline Aufnahme → Transkription → Diarization → LLM → Datenbank
04 – Sprechertrennung Diarization, Anchor-Merge-Konsolidierung, Stimm-Profile
05 – LLM-Analyse Gemma-3-4B/NPU, Analyse-Pfade, strukturierte Zusammenfassung, Glossar
06 – iPhone-Bluetooth HFP-Pfad, Routing-Watcher, Echo-Fix
07 – Betrieb Services, Zugänge, Backups, Troubleshooting
08 – Changelog Chronik aller Entwicklungsschritte
09 – Suche & Verwaltung Inhaltssuche mit Zeitstempel-Verweis, Papierkorb, Titel umbenennen

System-Überblick

flowchart LR
    subgraph Quellen
        PC["Windows-PC<br/>(Teams, Medien)"]
        IPHONE["iPhone<br/>(Telefonate)"]
        USER(("Nutzer<br/>Logi H390 Headset"))
    end

    subgraph R1["Youyeetoo R1 (RK3588S, Armbian, lüfterlos)"]
        PW["PipeWire<br/>Audio-Routing<br/>(callmix + micgate)"]
        APP["Aime Web-App<br/>Node.js :3000"]
        WH["Whisper large-v3-turbo<br/>Encoder auf NPU"]
        DIAR["Diarization<br/>sherpa-onnx + TitaNet"]
        LLM["Gemma-3-4B<br/>rkllm auf NPU"]
        DB[("MariaDB<br/>callrec")]
    end

    PC -- "USB-C (UAC2-Gadget)" --> PW
    IPHONE -- "Bluetooth HFP (AX210)" --> PW
    USER -- "USB-A" --> PW
    PW -- "callrec_mix" --> APP
    APP --> WH --> DIAR --> LLM --> DB
    APP --- DB

Quick Facts

  • Board: 192.168.1.200 (WLAN, primär) / 192.168.1.50 (LAN), Login root
  • Web-GUI: http://192.168.1.200:3000 — Aufnahme, Transkript, Sprecher-Editor, Glossar
  • App-Verzeichnis: /opt/callrec (Node.js, systemd callrec.service)
  • Harte Anforderungen: immer offline (kein Cloud-LLM), akustische Sprecher-ID, kein aktiver Lüfter
  • Details und alle Zugangsdaten: 07 – Betrieb

Repo-Aufbau

Verzeichnis Inhalt
app/ Spiegel von /opt/callrec auf dem Board: Node-Backend (server.js, recorder.js, llm.js, diar.js, spk.js, db.js, bt.js), Vite-Frontend (web/), Python-Inferenz (inference/), Audio-/Setup-Skripte (aime-*.sh), rkllm_server.cpp
system/ System-Konfiguration, Pfade wie auf dem Board: systemd-Units (etc/systemd/system/, home/callrec/.config/systemd/user/), WirePlumber-Drop-ins, micgate-Filter-Chain, sudoers
docs/ Diese Dokumentation

Nicht im Repo (zu groß / Laufzeit-Artefakte): node_modules, web/dist (per npx vite build erzeugbar), Modelle (*.rkllm, *.rknn, models/), rkllm_server-Binary (aus rkllm_server.cpp kompilierbar), Aufnahmen, milestones/, .bak-*.

Restore-Hinweis: app/ → /opt/callrec, system/… → jeweilige Absolutpfade; danach npm install (Root + web/), npx vite build in web/, User-Units mit systemctl --user enable aktivieren (filter-chain.service maskieren!), Details in 07 – Betrieb.

⚠️ Das Repo ist die Kopie — die Wahrheit läuft auf dem Board. Nach jeder Board-Änderung Code hierher zurückspiegeln.

Doku-Regeln

  • Diese Doku ist die verbindliche Ablage für alle zukünftigen Änderungen am System.
  • Jede Änderung: betroffenes Kapitel aktualisieren und Eintrag in 08 – Changelog.
  • Prozesse/Abläufe immer mit Mermaid-Diagramm dokumentieren (Gitea rendert sie direkt).
  • Auf dem Board bleiben .bak-*-Dateien als Rollback-Punkte; Meilenstein-Snapshots unter /opt/callrec/milestones/.