# Agent-Memory — pv-agent Rollender Übergabe-Log für agent-Threads. Workflow: `.agents/SKILL.md` (agent-memory-Skill). Ergänzen, nicht überschreiben. ## Current focus M1 und M2 sind **fertig und gegen den echten Ollama validiert**. Offen: Modell-Bake-off (M3) mit den bereits installierten Kandidaten und Prompt-Tuning der Fehlverweigerungen. Odoo-Integration (M4) separat zu planen. ## Completed (2026-09-14) - **Planung** (`planung.md`): Architektur, Grounding-Regeln, Modellfeld, Meilensteine M1–M4; **Skill** `.agents/skills/pv-rag-agent/SKILL.md`. - **Commits**: `25eb285` (Wissensbasis-Import), `bf8191b` (Planung + Skills), `2cba72a` (M1+M2-Implementierung, 41 Tests). - **Implementierung M1+M2** (`agent/`): kb/ingest/retrieve/generate/ ollama_client/api/cli/eval, Goldset 31 Fragen, Test-Chat. - **Ollama-Anbindung verifiziert** (Ziel-Instanz `http://100.103.83.12:11435`, Ollama 0.32.13): `bge-m3` per API gepullt; `qwen3.8:27b` war bereits installiert. Hybrid-Index: 3.005 Chunks, alle eingebettet (144 s). - **M1-Akzeptanz erreicht**: Retrieval Hybrid Hit-Rate 0,968 · Recall@8 **0,952** (>0,9 ✓) · MRR 0,690 (BM25-only: 0,871/0,855/0,476). - **M2-Antwortmodus-Eval** (qwen3.8:27b, Thinking aus): Zitier-Präzision **100 %** (4 Regenerierungen, alle geheilt) · Verweigerung korrekt 94,3 % · erwartete Quelle zitiert 80,6 % · Latenz mean 32 s / p95 53 s. Report: `data/eval-qwen38.json`. - Der ATZ-Konfliktfall (28,5 vs. 27,5 %) wird korrekt mit ⚠ und beiden IDs beantwortet; harte Verweigerung (UStVA, Retrieval nicht leer) funktioniert. - **Topologie geklärt**: `100.103.83.12` ist die **Remote-GPU-Maschine** (Entwicklungsumgebung, R9700, Tailscale); die Dev-Maschine selbst hat einen eigenen, fast leeren Ollama auf localhost:11434 (dorthin ging der erste bge-m3-Pull — auf die GPU-Maschine neu gepullt). Ziel-Instanz ist ausschließlich `http://100.103.83.12:11435`. - **Bake-off M3, Zwischenstand** (Antwortmodus, 35 Fragen): - `qwen3.8:27b` (Baseline): Zitier-Präzision **100 %**, Verweigerung korrekt 94,3 %, erwartete Quelle 80,6 %, mean 32 s/p95 53 s, 4 Regenerierungen (`data/eval-qwen38.json`). - `qwen3.6:27B`: Zitier-Präzision 94,3 % (2 dauerhafte Verstöße), Verweigerung 85,7 %, mean 43 s/p95 89 s, 10 Regenerierungen — klar schwächer (`data/eval-qwen36.json`). - `gemma4:26b`: Lauf abgebrochen (GPU-Maschine crashte mitten im Lauf). - `mistral-small3.1:24b`, `gemma4:12B`: ausstehend (Server-Neustart). - Kandidaten sind installiert; Pro-Kandidat-Befehl: `PV_ANSWER_MODEL= python3 -u -m agent.cli eval --answers --json-out data/eval-.json` (vor jedem Lauf vorheriges Modell entladen: `/api/generate` mit `keep_alive: 0`; `python3 -u` gegen Buffering bei Absturz). ## Open issues / blockers - **Push**: Remote localhost:3003 aus der Sandbox nicht erreichbar — User pusht vom Host. - **Fehlverweigerungen**: q-008 (Abfertigung/Verfügungsmöglichkeiten), q-031 (Mindestlohngesetz) — breite Fragen, Retrieval erfolgreich, Modell verweigert. M3-Tuning: Regel-4-Formulierung lockern („behandle den behandelten Teil“) oder Kontextblöcke erhöhen. Vorher Prompt einfrieren für den Bake-off-Vergleich. - **Latenz**: mean 32 s/ Antwort ist hoch (Dense 27B + große Prompts). Hebel: weniger Kontextblöcke (aktuell 8+6), schnellere Kandidaten. - **Cloud-Modelle** (`*:cloud` auf der Ollama-Instanz) sind für Antworten tabu (Anforderung: lokal). Nicht versehentlich konfigurieren. - **Bake-off M3 — Remote-GPU-Maschine neu starten**: seit ~22:45 sterben dort ALLE llama-server-Loads (auch bge-m3), der Ollama-Hauptprozess antwortet noch (API-Requests 500 „llama-server process has terminated: exit status 1"). Ursache vermutlich GPU-/Runner-Crash beim gemma4:26b- Lauf. **Auf der GPU-Maschine ausführen:** `sudo systemctl restart ollama` (ggf. vorher freien RAM prüfen; Ollama läuft dort auf Port 11435). Danach laufen die restlichen Kandidaten ohne weiteres Zutun. - **M4 Odoo**: native LLM-Module des konkreten Odoo-19-Stands verifizieren (keine API-Annahmen); Option A (dünnes Custom-Modul + Service-API) ist Default. ## Decisions & conventions - **D1 (Planung):** Schlanke Eigen-Pipeline statt LangChain/LlamaIndex — Grounding-Kontrolle schlägt Framework-Komfort bei 601 Dokumenten. - **D2:** Retrieval-Korpus ist **nur Layer 2**; Layer 1 bleibt aus Prompts (Lizenz); Antworten zitieren `[kb-id]` + `(Stand YYYY-MM)`. - **D3:** Umlaut-Folding für FTS (NFKD, ß→ss) — gilt konsistent für Index und Query; ASCII-Slug-Konvention der Wissensbasis bleibt davon unberührt. - **D4:** Post-Validierung strikt: zitierte IDs ⊆ Retrieved-Set (Block-Kopf- IDs); Fließtext-Verweis-IDs sind KEINE Belege (Systemprompt-Regel 2) — Verstoß → 1× Regenerierung → Verweigerung (UNCERTAIN_MESSAGE). - **D5:** Vektoren-Tabelle ist Cache (Content-Hash × Modell), Rebuild löscht sie nicht; `--no-embed` setzt `embed_off` im Config-Copy. - **D6:** Leeres Retrieval → deterministische Verweigerung ohne LLM-Call. - **Bake-off-Protokoll** (Skill): Modellwechsel nur über dokumentierten Goldset-Vergleich; Kriterium: Zitier-Präzision > Verweigerungs- korrektheit > Latenz. ## Files that matter right now - `planung.md` — Plan + Entscheidungspunkte (Abschnitt 12) + Stand. - `.agents/skills/pv-rag-agent/SKILL.md` — verbindliche Regeln. - `agent/README.md` — Betrieb, Konfiguration, Host-Schritte. - `agent/eval/goldset.yaml` — Goldset (IDs gegen kb.json verifiziert). - `agent/generate.py` — Grounding-Kern (Prompt, Post-Validierung). - `wissensbasis/README.md` — Layer-2-Schema (unverändert gültig).