323 lines
20 KiB
Markdown
323 lines
20 KiB
Markdown
# 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-124–126 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 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 — 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-101–106 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-120–123:
|
||
Hit-Rate 0,956 · Recall@8 **0,922** (Gate ✓) · MRR 0,661, alle vier
|
||
neuen Fälle gefunden. Gezielte Antwortläufe q-120–123: 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-124–126
|
||
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-120–123; als Nächstes Antwortmodus-Eval. |