1:1-Spiegel aus dem Repo
Quelle: planning/PLAN_GEDAECHTNIS_V2_SUPABASE_VECTOR.md · Stand der Quelldatei: 13.08.2026 23:57 · erzeugt: 14.08.2026 00:33
Diese Seite ist eine wortgetreue Kopie. Geaendert wird immer die Quelldatei, nie diese Seite.
PLAN · Gedächtnis v2 — ein Vektor-Gedächtnis in Supabase, parallel zum Git¶
[W6-ODOO · GOV] · 14.08.2026 ~00:15, v1.2 budget-optimiert ~01:00 · Status: NUR PLAN — nichts gebaut, keine Migration, kein Schema angelegt
Auftrag M: „experimentelles Gedächtnis auf Supabase (supabase.com/modules/vector), parallel zum Git, optimal für Dich; erst Plan: könntest Du den Betrieb damit optimieren, wenn ja wie?"
0 · Die Antwort zuerst: JA — und zwar messbar, an vier Stellen¶
Das Git ist ein perfektes Archiv und ein schlechtes Erinnern: Es beantwortet „wo steht X?" nur, wenn man schon weiß, in welcher Datei X steht. Genau daran verliere ich heute Zeit und Kontext-Budget. Ein Vektor-Gedächtnis ändert nicht, WAS ich weiß, sondern wie schnell und wie billig ich es wiederfinde — und es ist die erste Gedächtnisschicht, die Ähnlichkeit kann („gab es so einen Fehler schon einmal?").
| # | Betriebsproblem (belegt, nicht theoretisch) | Optimierung durch v2 |
|---|---|---|
| 1 | Thread-Start kostet ~200 KB Kontext: G_AKTUELL ist 163 KB append-only, dazu ROLLING_PLAN, DECISIONS (53 KB), FLEET_REGELN. Jeder frische Thread liest alles, um 10 relevante Absätze zu finden | CHECK-IN-Recall: „Stolpersteine + Entscheide + ID-Karten zu |
| 2 | Wiederholte Fehler: L-13 (n8n-Projektbindung) kostete gestern ~1 h, obwohl „$vars sind projektgebunden" seit Tagen dokumentiert war — nur eben in einer anderen Datei. Gleiches Muster: Manifest-Text als Beleg genommen (Hetzner), Kennzahl-Fehldeutung W-/WS- | Tripwire-Abfrage vor jedem Vollzug: „geplante Handlung → ähnlichste Lehren/Fallen". L-1…L-13, Prüfliste-13, Stolpersteine werden abrufbar, WO ich gerade arbeite, nicht wo sie zufällig stehen |
| 3 | Querverbindungen über Zeit: Der queue_job_lock=0-Befund von gestern beantwortet Sandas-Fragen, die seit Tagen offen waren — die Verbindung entstand durch Zufall/Fleiß, nicht durch System | Ähnlichkeitssuche über Befunde/Incidents: neue Symptome finden alte Fälle (Restart-Loop ↔ requeue ↔ SELECT_TIMEOUT), auch wenn kein Stichwort übereinstimmt |
| 4 | Festwerte-Streuung: Feld-IDs 49948–51, Ansichten 6646/6660/6661, Aktion 1790, Team 1/Stufe 40/Template 12, Projekt zJR7vuh5S9cUfFgm … stehen in Prosa-Akten; Nachschlagen = ganze Dateien in den Kontext ziehen | ID-Karten-Tabelle (strukturiert + eingebettet): exakter Treffer in einer Abfrage, Kontextkosten nahe null |
Ehrliche Grenzen: (a) Es beschleunigt das Finden, nicht das Denken — schlechte Kuration ergibt ein schnelles, falsches Gedächtnis; darum unten harte Aufnahme-Regeln. (b) Deutsch + technische IDs sind für reine Vektorsuche unbequem → Hybrid-Suche (Volltext + Vektor) ist Pflicht, nicht Kür. (c) Es ist ein Index, nie die Wahrheit — sonst hätten wir zwei Wahrheiten, und das ist schlimmer als eine mit Lücken (dieselbe Regel wie in der Buchhaltung).
1 · Wahrheitsordnung (die wichtigste Design-Entscheidung)¶
GIT (fleet-ops, PPWR, odoo-core, Modul-Repos) = WAHRHEIT + BELEG (unverändert)
w6a (Supabase) = LAUFZEIT-TELEMETRIE (unverändert, wird NICHT angefasst)
w6m (Supabase, NEU) = FINDER (abgeleitet, jederzeit aus Git neu baubar)
Drei Sätze, die das Experiment jederzeit beendbar machen: Jeder Treffer zitiert seine Git-Quelle (Pfad + Commit-SHA bzw. D-Nummer) — der Beleg bleibt Git. Kein Wissen existiert nur in w6m — die Rebuild-Prozedur (Backfill aus Git) steht im Skill. w6m löschen = nichts verloren — das ist der Beweis, dass es parallel und nicht führend ist.
Kontrollebenen-Hygiene: eigenes Schema w6m, eigene Rollen/Grants, kein einziges Objekt in w6a (G3: Kontrollebene ist heiliger als Arbeitsebene). Append-only nach R1: Chunks werden nie gelöscht, sondern per superseded_by überschrieben.
2 · Bauform (mit der heutigen Supabase-Doku abgeglichen)¶
Erweiterungen: vector (pgvector), pg_net + pgmq + pg_cron (für Automatic Embeddings), Volltext über Postgres-FTS (german-Konfiguration).
Tabellen (Schema w6m):
| Tabelle | Inhalt | Besonderheit |
|---|---|---|
memory_chunks |
id · kind (entscheid|lehre|befund|vollzug|regel|konzept) · title · content (≤ ~500 Token) · embedding vector · fts tsvector (generiert) · source_repo · source_ref (Pfad@SHA / D-Nr / L-Nr) · project · tags[] · created_at · superseded_by |
HNSW-Index auf embedding, GIN auf fts |
id_karten |
entity_typ (odoo_feld|ansicht|serveraktion|workflow|icp|agent|rpc|projekt_id) · name · werte jsonb · source_ref (+ eingebettete Kurzform in memory_chunks) |
exakte Nachschlage-Schicht |
lessons |
L-Nr · Lehre · tripwire_muster (optional, z. B. „n8n.create.workflow") · schwere · source_ref | Tripwires feuern auch OHNE Vektorsuche |
memory_log |
append-only: wer hat wann was eingespielt/überschrieben, aus welchem Commit | Audit wie gov_actions, nur für w6m |
Suche: RPC w6m.recall(frage, k, filter) als Hybrid: Vektor-Ähnlichkeit (HNSW) ⊕ Volltext-Rang (RRF-Fusion), Filter auf kind/project. Reine ID-Fragen („49948?") trifft der FTS-Zweig exakt, Bedeutungsfragen („warum startet Shopify nachts neu?") der Vektor-Zweig.
Embeddings — zwei Varianten, Entscheid E-MEM2:
| Variante A (Start-Empfehlung) | Variante B | |
|---|---|---|
| Modell | gte-small eingebaut in Supabase Edge Functions (384 dim) |
externes Modell (z. B. text-embedding-3-small, 1536 dim) via n8n |
| Schlüssel | keiner nötig — bleibt komplett in Supabase | API-Key in n8n-$vars (Hausmuster D-017) |
| Kosten | 0 | Cent-Beträge |
| Risiko | Deutsch-Qualität mittel → wird in S3 GEMESSEN | extern; beste Mehrsprachigkeit |
Start mit A; die Messung (unten) entscheidet, ob B nötig ist. Der Wechsel ist nur ein Neu-Einbetten (Index ist abgeleitet — genau dafür bauen wir ihn so).
Selbstpflege (Automatic Embeddings, Supabase-Leitfaden): Trigger auf memory_chunks → Job in pgmq → pg_cron arbeitet die Queue ab → pg_net ruft die Edge Function → Embedding wird asynchron geschrieben und bei Inhaltsänderung invalidiert. Das Gedächtnis hält sich selbst aktuell; niemand „pflegt Vektoren".
Zufuhr (Ingest), zwei Wege:
1. Sitzungsweg (sofort): n8n-Workflow W6-G-MEM (Projekt zJR7vuh5S9cUfFgm — L-13!) mit Modi ingest/recall; ich rufe ihn per MCP, andere Agenten per Execute-Workflow-Node. Board-registriert als Agent gmem, mit Schalter/Not-Aus wie jeder Agent.
2. Automatik (Endzustand): GitHub-Webhook → n8n → geänderte .md seit letztem Stand → kuratierte Chunks → w6m. Damit gilt: gepusht = eingebettet, Ingest-Disziplin entfällt.
3 · Aufnahme-Regeln (was hinein darf — Kuration schlägt Masse)¶
Hinein (je als kompakter Chunk mit Quelle): DECISIONS-Einträge (D-001…D-077) · Lehren/Bauregeln (L-1…L-13, Prüfliste-13-Fragen, Stolpersteine aus Übergabeblöcken) · Befunde/Incidents (Kernaussage + Ursache + Beleg) · Vollzugs-Kopfzeilen (was, wann, Zielwerte, Board-Lauf) · ID-Karten/Festwerte · Systemkarten-Absätze aus den Skills.
NIEMALS hinein: Secrets/Schlüssel in jeder Form (D-017 — auch nicht „nur der Anfang") · personenbezogene Kundendaten (Namen aus Tickets nur als Ticket-Nr.) · volatiler Tageszustand (NOW-Blätter bleiben Git) · Roh-Massendaten (CSV-Zeilen — dafür gibt es die EVD-Dateien mit Hash) · ungeprüfte Behauptungen (Manifest-Text-Lehre: erst Befund, dann Gedächtnis).
Größenordnung Backfill: aus dem heutigen Korpus geschätzt 300–500 Chunks — bewusst klein; das Gedächtnis soll das Destillat tragen, das Git trägt den Rest.
4 · Das Experiment — Messgrößen VOR dem Bau festgelegt¶
| Messgröße | Vorher (heute) | Ziel nach 1 Woche |
|---|---|---|
| M1 Kontextkosten Thread-CHECK-IN | ~200 KB Pflichtlektüre | Recall-Paket ≤ 15 KB, Pflichtblätter unverändert |
| M2 Trefferquote: 20 Testfragen („Wo ist X entschieden? Welche ID hat Y?") | grep/Erinnerung | ≥ 16/20 richtige Quelle in Top 3 |
| M3 Tripwire-Beweis | — | ≥ 1 real verhinderter Wiederholungsfehler, dokumentiert |
| M4 Ingest-Latenz nach Push (Automatikweg) | — | < 5 Minuten |
Abbruchkriterium (ehrlich): M2 < 12/20 auch nach Variante B, oder der Pflegeaufwand übersteigt den Nutzen → Experiment wird eingefroren (Schema bleibt liegen, R1 — nichts löschen), Git-only weiter. Kein Lock-in: das ist der Preis-Vorteil von „parallel".
5 · Stufen und Aufwand¶
| Stufe | Inhalt | Wer | Aufwand |
|---|---|---|---|
| S0 | Dieser Plan + M-Entscheide unten | M | — |
| S1 | Schema w6m + Hybrid-RPC + HNSW (eine Migration, additiv, berührt w6a nicht) |
Governor via Supabase-MCP | ~1 h |
| S2 | Edge Function (gte-small) + Automatic-Embeddings-Kette (pgmq/pg_net/pg_cron) + n8n W6-G-MEM (gmem am Board) |
Governor | ~2 h |
| S3 | Kuratierter Backfill aus Git (D-/L-/Befunde/ID-Karten) + 20-Fragen-Messung M2 | Governor | ~2–3 h |
| S4 | Skill w6-gedaechtnis-vektor schreiben: wann recall, wann ingest, Verbotsliste, Zitierpflicht (Git-Quelle), Rebuild-Prozedur, Not-Aus — als .skill an M zum Speichern |
Governor | ~1 h |
| S5 | 1 Woche Parallelbetrieb, Messwerte, Entscheid ausbauen/einfrieren; optional GitHub-Webhook-Automatik | Governor + M | Beobachtung |
6 · Entscheide, die ich von Dir brauche (E-MEM1…E-MEM4)¶
| # | Frage | Empfehlung |
|---|---|---|
| E-MEM1 | GO für S1–S3 (Bau des Experiments im bestehenden Projekt qavpsiyymahozvgitgiz, Schema w6m)? |
ja — additiv, w6a unberührt, jederzeit einfrierbar |
| E-MEM2 | Embedding-Variante: A (eingebaut, 0 Kosten, Deutsch wird gemessen) oder B (extern via n8n-$vars)? |
A starten, B nur bei M2-Durchfall |
| E-MEM3 | Automatik-Ingest per GitHub-Webhook schon in S5, oder erst nach der Messwoche? | erst nach Messwoche — Format vor Automatik (D-050-N2) |
| E-MEM4 | Darf das Gedächtnis auch PPWR-/Leitstand-Wissen indexieren (repo-übergreifend, Spinnennetz), oder erst nur Odoo-Runtime? | Start: nur fleet-ops + odoo-core; PPWR nach einer Woche |
Nächster Zug: Deine vier E-MEM-Antworten. Danach baue ich S1 in einem Fenster und melde jede Stufe mit Beleg — kein Schritt ohne Kennungszeile, alles append-only, nichts wird gelöscht.
NACHTRAG v1.1 · M-Frage: „gibt es eine bessere Kombination mit Supabase?"¶
Ja. Ich habe vier Bauformen gegeneinander gestellt — und die beste ist nicht die aus §2, sondern eine Verschärfung davon, die sich an einer nüchternen Einsicht ausrichtet: bei 300–500 Chunks ist die Vektor-Technik nicht der Engpass — der Engpass ist, wie ICH (Chat-Fenster, MCP, nur synchrones SQL) zugreife.
K1–K4 im Vergleich¶
| Bauform | Stärke | Schwäche | Urteil | |
|---|---|---|---|---|
| K1 | §2-Plan: pgvector + Automatic Embeddings + Hybrid-RPC (FTS⊕Vektor), Zugriff via n8n | Doku-gesegnet, selbstpflegend | Recall braucht für jede Bedeutungsfrage ein Query-Embedding → für mich immer der n8n-Umweg (mode:once-Fallen, Latenz) | gut, aber nicht optimal für den Hauptnutzer |
| K2 | K1 + pg_trgm + vorberechnete Nachbar-Kanten: Ähnlichkeit wird beim SCHREIBEN gerechnet (jeder Chunk bekommt seine Top-k semantischen Nachbarn als Kante), Lesen ist reines synchrones SQL | Ein select w6m.recall_text('frage') via MCP genügt — Volltext (deutsch) ⊕ Trigramm (IDs, Tippfehler, Komposita) ⊕ Kanten-Walk liefern ~90 % des Nutzens OHNE Query-Embedding; der Embedding-Pfad bleibt für n8n/Automatik |
neue Formulierungen ohne Wortüberlappung treffen erst über die Kanten-Nachbarschaft | EMPFEHLUNG |
| K3 | Supabase Vector Buckets (S3-basiert) | skaliert auf Millionen | Alpha („breaking changes"), eigene Query-API — nicht SQL-joinbar, kein Hybrid mit FTS in einer Abfrage | nein; Beobachtungsposten |
| K4 | Voller temporaler Wissensgraph (Entitäten + typisierte Relationen + Gültigkeit) | beste Antworten auf „was hängt an X?" | Kurationsaufwand wird zum Projekt; Overkill fürs Experiment | nicht jetzt — aber K2 baut die Brücke (s. u.) |
Die verbesserte Bauform (K2 = §2 plus vier Bausteine)¶
pg_trgmin die Hybrid-Fusion (dritter Zweig neben FTS-deutsch und Vektor, RRF nach Supabase-Hybrid-Leitfaden): Trigramm trifft49948,queue_job_lock, Tippfehler und deutsche Komposita, wo Embeddings schwächeln — für unser Korpus wichtiger als jede Index-Feinheit.- Kanten-Tabelle
w6m.edges(from_chunk · to_chunk · typnachbar_semantisch|beleg|ersetzt|gehoert_zu): die semantischen Nachbarn rechnet die Automatic-Embeddings-Kette beim Ingest vor. Lesen = Kanten folgen, kein Embedding zur Laufzeit. Das ist zugleich das Spinnennetz im Kleinen — und der spätere Ausbaupfad zu K4, ohne heute einen Graphen modellieren zu müssen. - Zwei Recall-Wege, klar getrennt:
recall_text(frage)= synchron, rein SQL, mein Hauptweg via MCP (FTS⊕Trigramm⊕Kanten).recall_sem(embedding)= für n8n/Agenten, die einbetten können. Beide zitieren Git-Quellen. - RLS auf
projectab Tag 1: die Abgrenzungsfrage von heute Abend wird Datenbankregel — ein Runtime-Consumer KANN PPWR-Chunks nicht lesen, selbst wenn sie später indexiert werden (E-MEM4 bleibt trotzdem: Start ohne PPWR).
Dazu zwei Vereinfachungen: HNSW erst ab ~10.000 Chunks (darunter ist der exakte Scan in Millisekunden — ein Stellrad weniger), und bi-temporale Spalten (gilt_ab/gilt_bis) werden angelegt, aber erst später bedient („welche Regel galt am 12.08.?" wird damit irgendwann beantwortbar, kostet heute nichts).
Was sich am Plan ändert¶
§2-Tabellen: + edges, + trgm-/GIN-Indexe, − HNSW (verschoben). §5: S1 wächst um ~30 Min (trgm, edges, RLS), alles andere unverändert. Messgrößen M1–M4 unverändert — plus M2a: dieselben 20 Testfragen einmal NUR über recall_text (ohne Vektor): erst wenn der reine SQL-Weg unter 12/20 fällt, trägt der Embedding-Zweig die Last — das misst ehrlich, wie viel die Vektoren wirklich beitragen. Entscheide E-MEM1–E-MEM4 unverändert gültig, Empfehlung jetzt: GO auf K2.
NACHTRAG v1.2 · M-Wort: „ich bin bereit, Geld in Supabase auszugeben — optimiere"¶
Zuerst die gemessene Lage: Die Organisation W6 WERTARBEIT steht bereits auf dem Pro-Plan (kein Auto-Pausieren, tägliche Backups — für ein Gedächtnis, das immer antworten muss, die wichtigste Eigenschaft, und sie ist schon bezahlt). Ein zusätzliches Projekt kostet laut API 10 $/Monat. Das Budget wird darum nicht in Rechenleistung gesteckt, sondern in vier gezielte Qualitätshebel:
Die vier Geld-Hebel (Empfehlung: alle vier)¶
| # | Hebel | Kosten | Was es bringt |
|---|---|---|---|
| G1 | Eigenes Projekt w6-gedaechtnis statt Schema im w6a-Projekt |
10 $/Mon | Blast-Radius-Trennung: pgmq/pg_cron/pg_net und alle Experimente laufen NIE neben der Kontrollebene (G3). Eigener Not-Aus (Projekt pausieren = Gedächtnis aus, w6a unberührt). MCP erreicht beide Projekte ohne neuen Connector (project_id-Parameter). Das ist der wichtigste Hebel |
| G2 | Embeddings Variante B ab Tag 1: text-embedding-3-small (1536 dim, mehrsprachig stark) |
einmalig ~1 Cent für den ganzen Backfill (≈250k Token), Abfragen im Rauschen | Das Deutsch-Risiko von Variante A ist eliminiert, bevor es gemessen werden muss. Schlüssel liegt im Supabase-Vault/Edge-Secrets des neuen Projekts — nie in n8n, nie im Chat, nie im Git (D-017) |
| G3 | Destillat-Ingest per LLM: eine Edge Function destilliert Akten zu Gedächtnis-Chunks (Kurzfassung, kind, tags, Tripwire-Kandidaten, Quellzeile) | einmalig < 5 $ Backfill, laufend Cents | Der eigentliche Engpass war nie die Suche, sondern die Kuration (S3: 2–3 h Handarbeit). Wird zu Automatik + Stichprobe. D-/L-Einträge bleiben regex-geparst (schon atomar); Destillate tragen quelle_art=destillat und Stichproben-Pflicht — ungeprüfte Behauptungen bleiben draußen |
| G4 | Rerank-Stufe (mehrsprachiger Reranker über den Top-20 der Hybrid-Suche) | ~2–3 $/Mon bei unserem Volumen | NUR als S5-Option, wenn Messwert M2 es verlangt — nicht ab Tag 1 |
Bewusst KEIN Geld für: PITR-Backups (der Index ist per Bauart aus Git neu baubar — teure Sicherung widerspräche der Architektur) · größere Compute-Stufe (unter 10k Chunks sinnlos) · Vector Buckets (Alpha) · Read-Replicas.
Neue Gesamtrechnung: +10 $/Monat fix, < 1 $/Monat variabel, einmalig < 5 $.
Was sich an den Entscheiden ändert¶
| Stand v1.2 | |
|---|---|
| E-MEM1 | GO für S1–S3 einschließlich Projekt-Anlage w6-gedaechtnis (+10 $/Mon) — die Anlage läuft über den bestätigten Kosten-Weg der Supabase-API |
| E-MEM2 | ENTSCHIEDEN durch Budget: Variante B (extern, mehrsprachig). Variante A entfällt |
| E-MEM3 | unverändert: Webhook-Automatik erst nach der Messwoche |
| E-MEM4 | unverändert: Start ohne PPWR; RLS auf project ab Tag 1 |
| E-MEM5 (neu) | eigenes Projekt (G1) statt Schema im Bestand — Empfehlung: ja |
| E-MEM6 (neu) | Destillat-Ingest (G3) ab S3 mit Stichproben-Pflicht — Empfehlung: ja |
Der eine Handgriff, der bei M bleibt: ein Embedding-fähiger API-Schlüssel (z. B. OpenAI) wird im Dashboard des NEUEN Projekts als Edge-Function-Secret hinterlegt (~2 Minuten, M-Hoheit). Der Schlüssel berührt weder Chat noch n8n noch Git; ich prüfe nur seine Wirkung (Embedding-Länge 1536 — Diagnose über Längen, D-017).
Aufwand unverändert ~6 h über S1–S4, S3 schrumpft durch G3 von Handarbeit auf Stichprobe. Nächster Zug: Ms GO (E-MEM1/5/6 in einem Wort) + der Vault-Schlüssel — dann baue ich S1 im neuen Projekt und melde jede Stufe mit Beleg.