Files
pv-agent/.agents/MEMORY.md
T

323 lines
20 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# Agent-Memory — pv-agent
Rollender Übergabe-Log für agent-Threads. Workflow: `.agents/SKILL.md`
(agent-memory-Skill). Ergänzen, nicht überschreiben.
## Current focus
Retrieval-/Antwort-Tuning für komplexe Gestaltungsfragen läuft (D16).
Goldset q-124126 und deterministischer Decision-Support-Pfad sind umgesetzt;
offen ist der vollständige 53-Fragen-Antwortmodus-Eval. Danach folgen die
bewusste Publikations-/Lizenzfreigabe der quellentreuen Rechtsprechungs-
Volltexte und M4 (API-first Odoo-Integration inkl. separat zu planender
Privacy-Grenze für Lohndaten).
## Completed (2026-09-14)
- **Planung** (`planung.md`): Architektur, Grounding-Regeln, Modellfeld,
Meilensteine M1M4; **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 — abgeschlossen (D7)**: alle 6 Kandidaten gemessen
(Tabelle in `planung.md` Abschnitt 13). **`qwen3.8:27b` gewinnt**
(100 % Zitier-Präzision, 94,3 % Verweigerung korrekt, 80,6 % erwartete
Quelle, 32 s mean). `gemma4:26b` = dokumentierter Latenz-Kandidat
(7,9 s mean, 100 % Zitier-Präzision, aber 67,7 % Quellentreue, 3
Fehlverweigerungen). mistral-small3.1: 71,4 % Verweigerungskorrektheit
— Deutsch-Hypothese praktisch widerlegt. **muse-glimmer:latest**
(nachgereicht): 100 % Zitier-Präzision bei nur 1 Regenerierung
(diszipliniertestes Modell), aber 8/35 falsche Verweigerungen
(Überverweigerung teils trotz vorhandener Zitate) und 37,5 s mean —
Rang 5 von 6, schlägt qwen3.8 in keiner Kennzahl. qwen3.6:27B: 2
dauerhafte Zitierverletzungen, 10 Regenerierungen. gemma4:12B:
2 Verletzungen.
Reports: `data/eval-*.json`. q-008/q-031 verweigern alle
Top-Kandidaten — Prompt-/Retrieval-Tuning (nicht modellspezifisch).
- **Remote-GPU-Maschine**: nach `systemctl restart ollama` (User-Aktion)
liefen alle Läufe stabil; zwischen Kandidaten wurde per `keep_alive: 0`
entladen (Crash-Ursache war der Modell-Swap-Stress beim gemma4-Lauf).
## Completed (2026-09-15)
- **KB-Erweiterung um WKO-Kollektivverträge + RIS-Gesetze** (User-Auftrag):
`.firecrawl/kv-portal/wko-kv/docs/` (614 KV-Dokumente: Lohn-/Gehaltsordnungen mit
Lohntabellen, KV-Abschlüsse, Erläuterungen, Zusatz-KVs) und `.firecrawl/ris/gesetze/` (59
Gesetze, nur die im Lexis360-Bestand zitierten §-Ausschnitte, Stand
2026-09-13) → **1 274 Layer-2-Einträge** (`kv-kvt-001…614`,
`ris-<prefix>-nn`), 14 984 Chunks, Reindex 8,5 min (11 947 neue
Embeddings, bge-m3 auf :11435).
- **D9 (2026-09-15):** kv/ris-Einträge sind **quellentreu generiert**
(keine Eigene-Worte-Kuratierung — Gesetze sind amtliche Werke, KV-
Lohntabellen zahlenexakt; Konvention 2 der Wissensbasis gilt nur für
die lizenzierten Quellen lb/wk). Tool-Output: `tools/ingest_sources.py`
+ `tools/build_registry.py` (Registry in diesem Repo neu gebaut — das
Lexis-Tool `build_lexis_kb.py` lebt im Schwesterprojekt), eingefrorene
Kataloge `tools/catalogs/*.json` (nur Metadaten, versioniert).
- **ID-Räume:** `kv-kvt-<nnn>` (ein Cluster `kollektivvertraege`,
Branche als Tag) und `ris-<cluster-prefix>-<nn>` auf der bestehenden
Cluster-Map + 7 neue Cluster (kvt/zvr/avr/agg/lst/abo/nso);
`LAW_MAP` in `tools/kb_common.py` dokumentiert die 59 Zuordnungen.
- **D10 (Retrieval-Kalibrierung, Goldset-Sweep 2026-09-15):** Korpus-
verdopplung drückte Recall@8 auf 0,851 — kalibriert auf
`dense_weight=2.0` (Dense-Liste relativ zu BM25 gewichtet; BM25 ist
durch KV-§-Titel-Matches inflationiert), `rrf_k=20`,
`candidate_pool=150`**Recall@8 0,923 (>0,9 ✓)**, Hit-Rate 0,973
(36/37), MRR 0,667. ENV: `PV_DENSE_WEIGHT`/`PV_RRF_K`/
`PV_CANDIDATE_POOL`. Entry-RRF-Variante getestet: kein Mehrwert.
- **Antwortmodus-Eval (qwen3.8:27b, 42 Fragen):** Zitier-Präzision
95,2 % (2 Verletzungen), Verweigerung korrekt 90,5 % (4 Fehlver-
weigerungen, u.a. q-022/q-029), erwartete Quelle zitiert 83,8 %,
Latenz mean 31 s / p95 53 s, 9 Regenerierungen — **unter den M3-
Gates** (100 % / 94,3 %): Korpusverdopplung macht Grounding härter;
das laufende Fehlverweigerungs-Tuning (uncommittete Änderungen in
generate.py/retrieve.py/goldset.yaml, unangetastet) ist weiteres
Thema. Report: `data/eval-qwen38-kvris.json`.
- **Goldset:** +7 Fragen (q-101106 KV-Preise/§-Fragen, r-005 Branchen-
Refusal) — append-only. q-021 rekalibriert: erwartete ID jetzt
`lb-kar-04` („Karenz - Anspruch, Beginn und Dauer“, Top-1, deckt
Beginn/Dauer vollständig; lb-kar-01 nur Nachbarschaft — dokumentiert
im Goldset-Note).
- **Tests:** 41 → 49, alle grün (neue ID-Räume, html-Source, Konverter,
LAW_MAP-Vollabdeckung, Korpus-Integrationszahl 1 274).
- **D15 (Rechtsprechungs-Intake, 2026-09-15):** `.rechtsprechung/` → neuer
ID-Raum `rj-rjs-*`, gemeinsamer Cluster `rechtsprechung`: 320 RIS-OGD-
Entscheidungen/Rechtssätze, 23 zitierte RIS-Normauszüge und 5 als
nichtamtlich markierte EuGH-lexetius-Textwiedergaben. Parser:
`tools/ingest_sources.py --source rj`; lange Volltexte werden an
Absatzgrenzen in H2-Chunks geteilt. `rj_catalog.json` friert die IDs ein;
Registry/Index und Agent-Zitatvalidierung kennen `rj-*`. Korpus 1.274 →
**1.622** Einträge / 77 Cluster; Reindex: 16.480 Chunks, 1.496 neue
Embeddings in 75 s. Retrieval-Goldset erweitert um q-120123:
Hit-Rate 0,956 · Recall@8 **0,922** (Gate ✓) · MRR 0,661, alle vier
neuen Fälle gefunden. Gezielte Antwortläufe q-120123: alle zitiergültig,
nicht verweigert, keine Regenerierung; Systemprompt verlangt für als
nicht amtlich markierte Quellen die gleiche Einschränkung in der Antwort
(q-123 verifiziert). Voller Antwortmodus-Eval (50 Fragen): **100 %
Zitier-Präzision**, **100 % Verweigerung korrekt**, erwartete Quelle
93,3 %, mean 39,4 s / p95 82,2 s, 5 Regenerierungen; Report
`data/eval-qwen38-rj.json` (lokal/unversioniert). Offline-Tests: 65
grün. **Nicht als generelle
Commit-Freigabe lesen:** Die gelieferten OGH/VwGH/VfGH-Dateien nennen
überwiegend RIS-OGD, der User sprach jedoch von Lexis/opendataloader;
die Publikations-/Lizenzfreigabe der quellentreuen Volltexte ist vor
Commit ausdrücklich zu prüfen. EuGH-Wiedergaben sind als nichtamtlich
markiert und verweisen auf EUR-Lex.
## Completed (2026-09-16)
- **D16 (Gestaltungsfragen / Retrieval-Tuning):** Goldset um q-124126
erweitert (500-Euro-Zusatzzahlung, Alternativen, Mitarbeiterprämie 2026).
`agent/query_planner.py` erkennt Decision-Support deterministisch und zerlegt
in drei gesetzlich gescopte Queries: Mitarbeiterprämie samt §-49-Konflikt,
Zukunftssicherung sowie Sach-/zweckgebundene Leistungen. Decision-Support
läuft als `specific`, nicht als Survey/Map-Reduce. `Retriever.search()` nutzt
denselben Plan im Offline-Eval; `search_multi()` behält Scope/Jahr auch bei
einer einzelnen Query. Ergebnis (53 Goldsetfragen / 48 Retrieval-Fälle):
q-124/q-125/q-126 jeweils Recall@8 **1,00**, gesamt Recall@8 **0,9271**
(Gate >0,9), Hit-Rate 0,9583, MRR 0,6158. Bekannte Altfehler q-015/q-113
bleiben unverändert.
- **Decision-Support-Grounding:** Systemprompt trennt Barzahlung von
zweckgebundenen Leistungen, verbietet pauschale Sieger ohne Kontext,
verlangt vergleichbare Abgabendimensionen und genau eine Rückfrage. Der
bekannte Konflikt Mitarbeiterprämie 2026 wird offen dargestellt:
`wk-akt-04` nennt SV/BV/DB/DZ/KommSt-Pflicht, `lb-sva-03` ordnet die Prämie
systematisch in den taxativen Katalog beitragsfreier Bezüge ein. Zusätzlich
erzwingt ein semantischer Post-Validation-Gate ⚠ + beide IDs + korrekte
Rollen und verhindert interne Regelverweise bzw. Quellenpriorisierung.
Gezielte Real-Läufe: q-124/q-125 nicht verweigert, zitiergültig; q-126 war
bereits sauber. Tests **72 grün**; `git diff --check` sauber. Vollständiger
Antwortmodus-Eval steht noch aus.
## Open issues / blockers
- **Push**: Remote localhost:3003 aus der Sandbox nicht erreichbar — User
pusht vom Host.
- **Fehlverweigerungen — Stand nach Prompt v2:** q-008 und q-031 sind
**behoben** (Section-Priorität + Regel 8). Verbleibend: q-029
(„Welche Neuerungen behandelt WIKU Personal aktuell 2026?“) — breite
Survey-Frage über 12 Hefte; Kontext enthält echte Zusammenfassungen,
Modell verweigert trotzdem (sicherer Fehlermodus). Mögliche spätere
Hebel: Survey-Rule im Prompt, mehr Kontextblöcke oder Map-Reduce-artige
Zusammenfassung. Weitere Iterationen erst mit neuen Evaluationsdaten.
- **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 — erledigt** (siehe Completed; Entscheidung D7 in
`planung.md`). Nach Tuning von Prompt/Retrieval: erneuter kurzer
Bestätigungslauf nur mit dem Sieger.
- **M4 Odoo**: native LLM-Module des konkreten Odoo-19-Stands verifizieren
(keine API-Annahmen); Option A (dünnes Custom-Modul + Service-API) ist
Default.
- **Nach KV/RIS-Erweiterung (2026-09-15)**: Antwortmodus vor dem Tuning
(D10-Follow-up) unter den Gates (Zitier-Präzision 95,2 % — 2 Verlet-
zungen; Verweigerung 90,5 % — 4 Fehlverweigerungen, u.a. q-022/q-029;
erwartete Quelle 83,8 %) — Report `data/eval-qwen38-kvris.json`.
**D11-Fix behoben die 4 Fehlverweigerungen**: Antwortmodus jetzt
Zitier-Präzision 97,6 %, Verweigerung **97,6 %** (>94,3 %-Gate ✓),
erwartete Quelle 91,9 %, Retrieval Recall@8 0,946 — Report
`data/eval-qwen38-kvris-tuned.json`. Verbleibend: q-015 (Branchen-
Noise) und q-024 als transiente Flakiness (leerer Draft — Think-Ghost-
Verdacht bei 32k-Kontext; beobachten).
- **q-015 (Tagesgelder Dienstreisen)** — Branchen-Noise: 8 Branchen-KV-
Einträge verdrängen lb-rei-01/09 (EStG-Taggeld-Abrechnung) aus Top-8;
generische Branchen-Frage ist mehrdeutig geworden. Hebel: Frage
präzisieren (Branche/Kontext) oder KV-§-Titel-Matches dämpfen.
## 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.
- **D7 (Bake-off 2026-09-14):** `qwen3.8:27b` ist das fixierte Antwortmodell
(100 % Zitier-Präzision, 94,3 % Verweigerung korrekt). `gemma4:26b` als
dokumentierter Latenz-Kandidat; ein Modellwechsel läuft nur erneut über
das dokumentierte Protokoll (Skill).
- **D8 (Prompt-Tuning 2026-09-14):** Prompt v2 + Kontext-Section-
Priorität. (a) Regel 4 erlaubt Teilantworten bei unvollständiger Deckung;
Regel 8 verlangt Prämisse-Korrektur statt Verweigerung (Muster-Beispiel
„Mindestlohngesetz“). (b) `_representative_chunk` wählt pro Eintrag die
beste **Inhaltssektion** (Zusammenfassung > Kernwerte > Rechtsgrundlagen
> Payroll > sonstige; „Verweise“ nur als letzter Rückgriff — BM25
rangiert die dünnen Navigations-Chunks bevorzugt, q-008-Ursache).
Ergebnis v1→v2: Zitier-Präzision 100 % gehalten; q-008 + q-031 behoben;
erwartete Quelle 80,6 → 83,9 %; Verweigerung 94,3 % (Fehler getauscht:
neu q-029 — breite Survey-Frage über 12 Hefte, sicherer Fehlermodus).
Report `data/eval-qwen38-v2.json`.
- **D9 (KV/RIS-Erweiterung, 2026-09-15):** kv-/ris-Einträge sind
**quellentreu generiert** (keine Eigene-Worte-Kuratierung — Gesetze
sind amtliche Werke, KV-Lohntabellen zahlenexakt; Konvention 2 der
Wissensbasis gilt nur für die lizenzierten Quellen lb/wk).
Tool-Output: `tools/ingest_sources.py` + `tools/build_registry.py`
(Registry in diesem Repo neu gebaut — das Lexis-Tool
`build_lexis_kb.py` lebt im Schwesterprojekt), eingefrorene Kataloge
`tools/catalogs/*.json` (nur Metadaten, versioniert). IDs:
`kv-kvt-<nnn>` (ein Cluster `kollektivvertraege`, Branche als Tag),
`ris-<cluster-prefix>-<nn>` auf der bestehenden Cluster-Map + 7 neue
Cluster; `LAW_MAP` in `tools/kb_common.py` (59 Gesetze).
- **D10 (Retrieval-Kalibrierung, 2026-09-15):** nach KV/RIS-Erweiterung
(3.005 → 14 984 Chunks) dense_weight=2.0 (Dense relativ zu BM25
gewichtet — BM25 durch KV-§-Titel-Matches inflationiert), rrf_k=20,
candidate_pool=150 → Recall@8 0,851 → 0,923 (>0,9 ✓), Hit-Rate
0,973, MRR 0,667. ENV: PV_DENSE_WEIGHT / PV_RRF_K /
PV_CANDIDATE_POOL. Entry-RRF-Variante getestet: kein Mehrwert.
- **D11 (Prompt-Budget + Kontext-Abdeckung, 2026-09-15):** lange KV-Chunks
ueberlieferten num_ctx=16384 (q-022: 62,7 KB Prompt ≈ 18k Tokens) —
Ollama trunciert den Systemprompt vorn, das Modell verliert die
Zitierregeln („Block 8“-Zitate statt IDs → Regenerierung → Verweigerung).
Fix: num_ctx 32 768, `trim_results` (max_context_chars=90 000, Tail-
Bloecke ganz weg statt trunciert, Mindestbestand 6) und
cross_ref_expand 3 → 6 (die Top-3 sind oft Branchen-KV-Bloecke mit
leeren cross_refs — kuratierte Nachbarn kamen sonst nie nach).
Ergebnis: alle 4 Fehlverweigerungs-Faelle (q-001/q-019/q-022/q-029)
geheilt, 10/10 Bestaetigungslaeufe OK. Eval: Zitier-Praezision 97,6 %,
Verweigerung 97,6 % (> 94,3 %-Gate ✓), erwartete Quelle 91,9 %
(vorher 83,8 %), Retrieval Recall@8 **0,946** (cross_ref-Extras
bringen Expected-IDs nach), MRR 0,671. Latenz mean 33 s.
Report `data/eval-qwen38-kvris-tuned.json`. Restrisiko: q-024
flaky (1/3 Laeufe — transienter leerer Draft, Think-Ghost-Verdacht);
q-015 Branchen-Noise bleibt offen.
- **D12 (Komplexe-Fragen-Stufe 1 / M6, 2026-09-15):** Query-Planer vor dem
Retrieval: Heuristik-Gate (Jahreszahl, Vergleichs-/Aggregationsmarker,
Laenge) entscheidet, ob ein kleiner LLM-Call die Frage in 1-3 Sub-Queries
zerlegt (JSON, temp 0, num_predict 220; Fehler -> Original als Einzel-
Query). Multi-Query-Retrieval: je Sub-Query BM25+Dense, Beitraege
summieren; **Per-Query-Slots** (2 je Sub-Query) sichern jeden Frage-
aspekt im Kontext — ohne sie dominieren Eintraege, die in mehreren
Sub-Queries mittelgut matchen (q-113: 5 KV-Urlaubs-SS schlugen
lb-url-05 (Rang 6) und ris-url-01 (>Top-12) ueber beide Sub-Queries).
**Scope-Filter** je Sub-Query: Planer markiert "gesetz" (nur Lexis/WIKU/
RIS-Chunks) bzw. "kv" (nur Branchen-KV) — q-113 geheilt (ris-url-01/
lb-url-05 + KV-Ss im selben Kontext). Scope-Fallback: gefilterte Suche
leer -> unscoped. Temporal-Intent: stand_year je Sub-Query, kv-Eintraege
im Geltungsjahr erhalten temporal_boost (default 0 — FTS-Tag-Signal
`jahr-YYYY` reichte in der Messung). Grounding unveraendert: ein
Kontext aus der Union, Post-Validierung ueber die gesamte Retrieved-
Menge, Verweigerungspflicht unveraendert.
Eval (46 Fragen): Zitier-Praezision 97,8 %, Verweigerung 97,8 %
(Gate > 94,3 % erfuellt), erwartete Quelle 90,2 %, Latenz mean 33,5 s.
Temporal-Fragen laufen sogar ohne Planer gut (Jahr-Toknen matchen
`jahr-YYYY`-Tags). Neue komplexe Fragen im Goldset: q-110 (Temporal 2023,
nach Korrektur — eine 2024er-Friseur-Lohnordnung existiert im Korpus
NICHT: kv-kvt-161 ist der Mantelvertrag ohne Lohntabelle; korrekt
verweigert), q-111 (Temporal 2025), q-112 (Abfertigung Vergleich),
q-113 (Gesetz+KV Multi-Source). Tests 50 -> 57.
Offen: q-029 Survey (Stufe-2-Hebel: Map-Reduce), q-113 Planer-
Scope flaky (1/2 Laeufe ohne gesetz-Marker).
- **D13 (Antworttyp-Routing / Stufe 2, 2026-09-15):** (a) Planer liefert
jetzt `type: survey|specific`; Survey-Fragen („Welche Neuerungen …“)
laufen ueber Map-Reduce: breiteres Retrieval (`survey_blocks`=16,
PV_SURVEY_BLOCKS), ein Map-Call destilliert JE Block als Stichpunkte
mit seiner KB-ID (MAP_SYSTEM_PROMPT), ein Reduce-Call synthetisiert
daraus die Antwort mit dem normalen Grounding-Prompt; Zitier-
Validierung weiterhin strikt ueber die Retrieved-Union, leerer
Map-Output -> Fallback Einzelantwort. (b) Systemprompt-Regel 9: bei
wesentlicher Kontextabhaengigkeit (Branche, Bundesland, Zeitraum)
belegte allgemeine Aussage + EINE Rueckfrage statt Verweigerung
(API-first; Odoo-Chat kann die Rueckfrage als Follow-up nutzen).
Ergebnis: **q-029 geheilt** (vorher jahrelange Fehlverweigerung;
jetzt Teilantwort mit 5 belegten Heften, 95 s — Map-Reduce-Latenz
nur bei Survey-Fragen), **q-015** antwortet mit expliziter
KV-Abhaengigkeit + Rueckfrage statt Branchen-Noise. Eval (46 Fragen):
Zitier-Praezision 97,8 %, Verweigerung 97,8 % (Gate erfuellt),
erwartete Quelle 90,2 %, Latenz mean 34,2 s. Tests 57 -> 59.
Report `data/eval-qwen38-stage2.json`. Verbleibend: q-024 transiente
Flakiness (Think-Ghost-Verdacht, 2/3 Laeufe sauber).
- **D14 (Output-Budget + length-Retry, 2026-09-15):** q-024-Flakiness
Ursache gefunden — NICHT Thinking (Hypothese widerlegt: thinking-Feld
leer, keine Tags), sondern `num_predict=1024`: lange belegte Antworten
wurden bei `done_reason=length` abgschnitten (q-024: 3/3 Sondenlaeufe)
→ unvollstaendige Zitationen → CITE_RE matcht partielle IDs →
Verletzung → Regen-Eskalation → UNCERTAIN. Fix: (a) num_predict
1024 → 2048; (b) `OllamaClient.chat_full()` liefert (content,
done_reason); (c) `chat_with_length_retry`: ein technischer Retry
mit 2× num_predict bei length (zaehlt nicht als Regel-Regenerierung,
laeuft auch im Map- und im Regenerierungspfad).
**Voll-Eval: Zitier-Praezision 100 %, Verweigerung korrekt 100 %**
(46/46 — alle M3-Gates erfuellt, erstmals ueber Basislinie),
erwartete Quelle 92,7 %, Latenz mean 39,6 s / p95 78 s (+5 s:
vollstaendige statt abgeschnittener Antworten). q-024: 4/4 stabil.
Tests 59 → 60. Report `data/eval-qwen38-lengthfix.json`.
- **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 + Rechtsprechungs-Provenance.
- `tools/ingest_sources.py` / `tools/catalogs/rj_catalog.json` — rj-Intake und gefrorene IDs.
- `agent/eval/goldset.yaml` — q-120123; als Nächstes Antwortmodus-Eval.