Ollama-URL korrigiert (100.103.83.12:11435) und M1/M2 gegen Echt-System validiert
Der Host betreibt zwei Ollama-Instanzen: 11434 (fast leer, 0.16.2) und 11435 (Ziel-Instanz, 0.32.13, Modell-Zoo) — Port nicht mehr auf 11434 'korrigieren' (Dokumentation + Skill + Config-Default angepasst). Validierung gegen das echte System: bge-m3 per API gepullt, Hybrid-Index (3005 Chunks, 100 % eingebettet, 144 s), M1-Akzeptanz erreicht (Recall@8 0,952 > 0,9; Hit-Rate 0,968). Antwortmodus-Eval mit qwen3.8:27b (Thinking verifiziert aus): Zitier-Präzision 100 % (4 Regenerierungen), Verweigerung korrekt 94,3 %, Latenz mean 32 s. ATZ-Konfliktfall korrekt beide Werte mit Warnung. generate.py: sources enthaelt jetzt nur zitierte Quellen; Systemprompt ohne redundante Quellenzeile. Bake-off-Feld (M3) bereits installiert: qwen3.6:27B, gemma4:26b, mistral-small3.1:24b, gemma4:12B.
This commit is contained in:
+38
-34
@@ -5,46 +5,50 @@ Rollender Übergabe-Log für agent-Threads. Workflow: `.agents/SKILL.md`
|
||||
|
||||
## Current focus
|
||||
|
||||
M1 (Index + Retrieval) und M2 (Ollama-Generierung + Grounding + API) sind
|
||||
implementiert. Ausstehend: Host-Validierung mit Ollama (Dense-Index,
|
||||
Antwortmodus-Eval) und Modell-Bake-off (M3). Odoo-Integration (M4) ist
|
||||
separat zu planen.
|
||||
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
|
||||
(Bake-off: qwen3.8:27b primär, qwen3:32b, gemma3:27b, mistral-small3.2:24b,
|
||||
qwen3:14b als Latenz-Untergrenze), Meilensteine M1–M4.
|
||||
- **Skill** `.agents/skills/pv-rag-agent/SKILL.md`: verbindliche Regeln für
|
||||
die Implementierung (Grounding, Architektur-Entscheidungen, Gates,
|
||||
Modellwechsel-Protokoll).
|
||||
- **Commits**: `25eb285` (Wissensbasis-Import 601 Layer-2-Einträge +
|
||||
.gitignore), `bf8191b` (Planung + Skills). Noch nicht gepusht — Remote
|
||||
`http://localhost:3003/fegger/pv-agent.git` ist aus der Zed-Sandbox nicht
|
||||
erreichbar; User muss vom Host pushen.
|
||||
- **Implementierung M1+M2** (`agent/`-Paket): kb.py (Parsing + kb.json-Gate),
|
||||
ingest.py (3005 Chunks aus 601 Einträgen, FTS5 + Vektoren-Cache),
|
||||
retrieve.py (Hybrid BM25+Dense/RRF, Stand-Boost, cross_ref-Erweiterung),
|
||||
generate.py (Systemprompt, Post-Validierung, 1× Regenerierung, dann
|
||||
Verweigerung), ollama_client.py (embed/chat, think-Flag-Fallback),
|
||||
api.py (/ask /health /reindex), cli.py, eval/ (Goldset 31 Fragen,
|
||||
evaluate.py), web/index.html, 41 offline Tests (grün).
|
||||
- **Baseline BM25-only**: Hit-Rate 0,871 · Recall@8 0,855 · MRR 0,476
|
||||
(31 Fragen). 4 Fehltreffer: Komposita/Stamm-Schwächen (aliquotiert↔
|
||||
Aliquotierung, Mindestlohngesetz) — Dense-Suche soll diese beheben.
|
||||
- **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.
|
||||
|
||||
## Open issues / blockers
|
||||
|
||||
- **Ollama aus Zed-Sandbox nicht erreichbar** (100.183.83.12:11435 und
|
||||
localhost:3003 beide geblockt): Dense-Index, Antwortmodus-Eval und
|
||||
Bake-off müssen auf dem Host laufen. Kommandos: `agent/README.md`
|
||||
Abschnitt „Deployment auf dem Host".
|
||||
- **Modelle noch nicht gepullt**: auf dem Host `ollama pull qwen3.8:27b`,
|
||||
`ollama pull bge-m3` (plus Bake-off-Kandidaten).
|
||||
- **Reranker** (bge-reranker-v2-m3): API-Unterstützung der installierten
|
||||
Ollama-Version prüfen — Design funktioniert ohne.
|
||||
- **qwen3.8-Think-Parameter**: `think: false` wird im Request gesendet
|
||||
(Auto-Fallback ohne Flag bei 400/404); exaktes Verhalten am Host testen.
|
||||
- **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**: Kandidaten sind bereits installiert — `qwen3.8:27B`,
|
||||
`qwen3.6:27B`, `gemma4:26b`, `mistral-small3.1:24b`, `gemma4:12B`
|
||||
(Latenz-Untergrenze). Achtung: Plan nennt mistral-small3.**2**:24b —
|
||||
installiert ist 3.1; 3.2 ggf. noch pullen oder 3.1 als Proxy.
|
||||
Pro Kandidat: `PV_ANSWER_MODEL=<tag> python -m agent.cli eval --answers`.
|
||||
- **M4 Odoo**: native LLM-Module des konkreten Odoo-19-Stands verifizieren
|
||||
(keine API-Annahmen); Option A (dünnes Custom-Modul + Service-API) ist
|
||||
Default.
|
||||
|
||||
@@ -39,11 +39,11 @@ touches Odoo code, also apply `.agents/odoo19-development/SKILL.md`.
|
||||
|
||||
## System context (fixed facts)
|
||||
|
||||
- **Ollama server:** `http://100.183.83.12:11435` (custom port — do
|
||||
not "correct" it to 11434). Verify reachability and installed models
|
||||
with `curl http://100.183.83.12:11435/api/tags`. Note: agent sandboxes
|
||||
may not reach this host — run such checks from the user's shell, not
|
||||
the sandbox.
|
||||
- **Ollama server:** `http://100.103.83.12:11435` — the target instance
|
||||
(custom port, holds the model zoo: qwen3.8:27b, bge-m3, bake-off
|
||||
candidates). The same host also runs a near-empty instance on port
|
||||
11434 — do **not** "correct" the port to 11434. Verify with
|
||||
`curl http://100.103.83.12:11435/api/tags`.
|
||||
- **GPU:** AMD Radeon AI Pro R9700, 32 GB — keep the total resident
|
||||
budget (answer model + embeddings + KV cache) under ~28 GB.
|
||||
- **Models (provisional until bake-off, see protocol below):**
|
||||
|
||||
+21
-14
@@ -49,7 +49,7 @@ python -m agent.cli serve # http://127.0.0.1:8080 (/ask, /health, /r
|
||||
|
||||
| Variable | Default | Bedeutung |
|
||||
|---|---|---|
|
||||
| `OLLAMA_URL` | `http://100.183.83.12:11435` | Ollama-Server (Custom-Port!) |
|
||||
| `OLLAMA_URL` | `http://100.103.83.12:11435` | Ollama-Server (Ziel-Instanz; der Host betreibt zusätzlich eine fast leere Instanz auf 11434 — nicht "korrigieren") |
|
||||
| `PV_ANSWER_MODEL` | `qwen3.8:27b` | Antwortmodell (provisorisch bis Bake-off M3) |
|
||||
| `PV_EMBED_MODEL` | `bge-m3` | Embedding-Modell |
|
||||
| `PV_DB_PATH` | `data/index.db` | SQLite-Index |
|
||||
@@ -62,25 +62,32 @@ python -m agent.cli serve # http://127.0.0.1:8080 (/ask, /health, /r
|
||||
## Deployment auf dem Host (Ollama-Maschine)
|
||||
|
||||
```bash
|
||||
# Modelle einmalig pullen
|
||||
ollama pull qwen3.8:27b
|
||||
ollama pull bge-m3
|
||||
curl http://100.183.83.12:11435/api/tags # Erreichbarkeit + Modelle
|
||||
# Ollama-Ziel-Instanz prüfen (Custom-Port! Achtung: auf dem Host läuft
|
||||
# zusätzlich eine fast leere Instanz auf 11434 — nicht verwexseln)
|
||||
curl http://100.103.83.12:11435/api/tags # qwen3.8:27b, bge-m3, Bake-off-Feld installiert
|
||||
|
||||
# Vollständiger Index (BM25 + Dense) — danach eval, Ziel: Recall@8 > 0,9
|
||||
# Vollständiger Index (BM25 + Dense)
|
||||
python -m agent.cli ingest
|
||||
python -m agent.cli eval
|
||||
python -m agent.cli eval --answers # Zitier-Präzision, Verweigerungen, Latenz
|
||||
python -m agent.cli eval --answers --json-out data/eval-report.json # Zitier-Präzision, Verweigerungen, Latenz
|
||||
```
|
||||
|
||||
## Baseline (2026-09-14, BM25-only, ohne Dense)
|
||||
## Baseline (2026-09-14, Hybrid BM25 + bge-m3, Ollama :11435)
|
||||
|
||||
Goldset (31 Fragen, `agent/eval/goldset.yaml`): Hit-Rate 0,871 ·
|
||||
Recall@8 0,855 · MRR 0,476. Die vier Fehltreffer sind klassische
|
||||
BM25-Schwächen (Komposita: „aliquotiert"↔„Aliquotierung";
|
||||
„Mindestlohngesetz") — genau die Fälle, die die Dense-Suche abdecken soll.
|
||||
Hybrid-Messung auf dem Host aussteht (Ollama aus der Zed-Sandbox nicht
|
||||
erreichbar).
|
||||
**Retrieval** (Goldset, 31 Fragen): Hit-Rate 0,968 · **Recall@8 0,952** ·
|
||||
MRR 0,690 — M1-Ziel >0,9 erreicht (BM25-only war 0,855; die vier
|
||||
BM25-Fehltreffer behebt die Dense-Suche alle).
|
||||
|
||||
**Antworten** (qwen3.8:27b, Thinking aus, Temperatur 0,1): **Zitier-Präzision
|
||||
100 %** (4 Zitierverletzungen wurden von der Post-Validierung abgefangen und
|
||||
regeneriert) · Verweigerung korrekt 94,3 % · erwartete Quelle zitiert 80,6 %
|
||||
· Latenz mean 32 s / p95 53 s.
|
||||
|
||||
Bekannte Fehlverweigerungen: q-008 (Abfertigung Verfügungsmöglichkeiten),
|
||||
q-031 (Mindestlohngesetz) — breite Fragen, Retrieval erfolgreich, Modell
|
||||
verweigert trotzdem (sicheres Versagensmuster; M3-Prompt-Tuning-Kandidat).
|
||||
Latenz-Hebel für M3: weniger Kontextblöcke, schnellere Kandidaten
|
||||
(gemma4:12B, MoE).
|
||||
|
||||
## Dateien
|
||||
|
||||
|
||||
+4
-2
@@ -37,8 +37,10 @@ class Config:
|
||||
kb_dir: str = "wissensbasis"
|
||||
db_path: str = "data/index.db"
|
||||
|
||||
# Ollama (Custom-Port 11435 — nicht "korrigieren", s. Skill)
|
||||
ollama_url: str = "http://100.183.83.12:11435"
|
||||
# Ollama — Ziel-Instanz ist Port 11435 (Custom-Port, mit Modell-Zoo).
|
||||
# Auf demselben Host läuft auch eine Instanz auf 11434 (fast leer) —
|
||||
# NICHT auf 11434 "korrigieren", s. Skill.
|
||||
ollama_url: str = "http://100.103.83.12:11435"
|
||||
embed_model: str = "bge-m3"
|
||||
answer_model: str = "qwen3.8:27b" # provisorisch bis Bake-off (M3)
|
||||
|
||||
|
||||
+6
-5
@@ -38,8 +38,7 @@ Verbindliche Regeln:
|
||||
5. Widersprechen sich Kontextblöcke, nenne beide Werte mit ihren IDs und
|
||||
kennzeichne den Widerspruch mit ⚠. Löse Widersprüche niemals stillschweigend auf.
|
||||
6. Nenne Paragraphen und Gesetze nur, wenn ein Kontextblock sie nennt.
|
||||
7. Antworte auf Deutsch, prägnant (Stichpunkte, wo sinnvoll), und füge am
|
||||
Ende eine Zeile „Quellen:“ mit den verwendeten IDs (ID — Titel, Stand) an.
|
||||
7. Antworte auf Deutsch und prägnant (Stichpunkte, wo sinnvoll).
|
||||
|
||||
Verletze Regel 2 oder Regel 4 niemals — im Zweifel verweigere die Antwort."""
|
||||
|
||||
@@ -123,14 +122,15 @@ def answer_question(
|
||||
if own_retriever:
|
||||
retriever.close()
|
||||
|
||||
def finish(answer, refused, verified, citations, regenerations=0, draft=None):
|
||||
def finish(answer, refused, verified, citations, regenerations=0,
|
||||
draft=None, sources=None):
|
||||
return {
|
||||
"question": question,
|
||||
"answer": answer,
|
||||
"refused": refused,
|
||||
"verified": verified,
|
||||
"citations": citations,
|
||||
"sources": _source_rows(results),
|
||||
"sources": sources if sources is not None else _source_rows(results),
|
||||
"n_context": len(results),
|
||||
"model": cfg.answer_model,
|
||||
"regenerations": regenerations,
|
||||
@@ -197,6 +197,7 @@ def answer_question(
|
||||
citations=[],
|
||||
regenerations=regenerations,
|
||||
draft=retry,
|
||||
sources=[],
|
||||
)
|
||||
|
||||
citations = sorted(set(CITE_RE.findall(final)))
|
||||
@@ -214,5 +215,5 @@ def answer_question(
|
||||
]
|
||||
return finish(
|
||||
final, refused=refused, verified=not violations,
|
||||
citations=citations, regenerations=regenerations,
|
||||
citations=citations, regenerations=regenerations, sources=sources,
|
||||
)
|
||||
+26
-19
@@ -33,9 +33,10 @@ in weiterer Folge soll der Agent in Odoo-Enterprise verwendet werden.
|
||||
- **Layer-1-Volltexte:** `.lexis360/md/` (572 Dateien) lokal vorhanden,
|
||||
lizenzbeschränkt + unversioniert. `.wiku/` fehlt in diesem Checkout —
|
||||
für Phase A irrelevant (Retrieval läuft auf Layer 2).
|
||||
- **Ollama-Server** `http://100.183.83.12:11435` (Custom-Port): aus der
|
||||
Zed-Sandbox **nicht erreichbar** (Netzwerkrestriktion, Timeout) — ist
|
||||
vom Host aus zu verifizieren (`curl http://100.183.83.12:11435/api/tags`).
|
||||
- **Ollama-Server** `http://100.103.83.12:11435` (Ziel-Instanz mit Modell-Zoo,
|
||||
Custom-Port; der Host betreibt zusätzlich eine fast leere Instanz auf 11434):
|
||||
aus der Zed-Sandbox erreichbar (2026-09-14, nach URL-Korrektur) —
|
||||
`bge-m3` wurde per API gepullt, `qwen3.8:27b` war bereits installiert.
|
||||
- **GPU:** Radeon AI Pro R9700, 32 GB (Strix Halo / RDNA 5) — budgetiert
|
||||
Modellwahl auf ~26–28 GB nutzbar.
|
||||
|
||||
@@ -198,9 +199,10 @@ tests/ # pytest: Ingest-, Retrieval-, Grounding-Unit-Tests
|
||||
|
||||
## 10. Risiken & offene Punkte
|
||||
|
||||
1. **Ollama-Erreichbarkeit** aus der Zed-Sandbox nicht gegeben —
|
||||
Verifikation vom Host: `curl http://100.183.83.12:11435/api/tags`;
|
||||
Modelle ggf. erst pullen (`qwen3:32b`, `bge-m3`, …).
|
||||
1. **Ollama-Erreichbarkeit** gegeben (Ziel-Instanz 11435; Sandbox kann
|
||||
verbinden). Achtung Doppel-Instanz auf 11434 — URL nicht "korrigieren".
|
||||
Cloud-Modelle (`*:cloud`) nicht für Antworten verwenden (Anforderung:
|
||||
lokal).
|
||||
2. **Ollama-Version:** `/api/embed` + allfällige Rerank-Unterstützung
|
||||
prüfen; Fallback ohne Reranker ist unkritisch.
|
||||
3. **Strix Halo (gfx-1151):** Ollama/ROCm muss die Karte unterstützen
|
||||
@@ -233,16 +235,21 @@ tests/ # pytest: Ingest-, Retrieval-, Grounding-Unit-Tests
|
||||
|
||||
## 13. Umsetzungsstand (2026-09-14)
|
||||
|
||||
- **M1 erledigt (offline):** Ingest + Index (601 Einträge → 3.005 Chunks,
|
||||
FTS5-BM25) + Hybrid-Retrieval (Dense-Code vorhanden, am Host zu messen).
|
||||
Goldset 31 Fragen (IDs gegen kb.json verifiziert, inkl. ATZ-Konfliktfall
|
||||
und 4 Verweigerungsfälle). Baseline BM25-only: Hit-Rate 0,871 ·
|
||||
Recall@8 0,855 · MRR 0,476 — 4 Fehltreffer sind Komposita-/Stamm-
|
||||
Muster, die die Dense-Suche abdecken soll. 41 Unit-Tests grün.
|
||||
- **M2 implementiert:** Ollama-Client (embed/chat, think-Fallback),
|
||||
Systemprompt mit Zitierpflicht, Post-Validierung (1× Regenerierung, dann
|
||||
Verweigerung), `/ask`-API + CLI + Test-Chat. **Host-Validierung mit
|
||||
echtem Ollama noch offen** (aus der Zed-Sandbox nicht erreichbar).
|
||||
- **M3 offen:** Bake-off auf dem Host (qwen3.8:27b vs. qwen3:32b vs.
|
||||
gemma3:27b vs. mistral-small3.2:24b; qwen3:14b als Latenz-Untergrenze).
|
||||
- Betrieb/Host-Schritte: `agent/README.md`.
|
||||
- **M1 erledigt und akzeptiert:** Hybrid-Index (601 Einträge → 3.005 Chunks,
|
||||
FTS5-BM25 + bge-m3-Dense, Ollama :11435), Goldset 31 Fragen. **Recall@8
|
||||
0,952 > 0,9** (Hit-Rate 0,968, MRR 0,690; BM25-only-Vergleich:
|
||||
0,855 — die vier Komposita-Fehltreffer behebt die Dense-Suche alle).
|
||||
41 Unit-Tests grün.
|
||||
- **M2 erledigt und gegen das echte Modell validiert** (qwen3.8:27b,
|
||||
Thinking aus): Zitier-Präzision **100 %** (4 Verletzungen → Post-
|
||||
Validierung → Regenerierung, alle geheilt), Verweigerung korrekt 94,3 %,
|
||||
Latenz mean 32 s / p95 53 s. ATZ-Konfliktfall wird korrekt beidseitig
|
||||
mit ⚠ beantwortet; harte Verweigerungsfälle (UStVA) funktionieren.
|
||||
- **M3 teilweise:** qwen3.8:27b-Baseline gemessen (`data/eval-qwen38.json`).
|
||||
Bake-off-Kandidaten sind bereits installiert: qwen3.6:27B, gemma4:26b,
|
||||
mistral-small3.1:24b, gemma4:12B (Latenz-Untergrenze). Bekannte
|
||||
Fehlverweigerungen (q-008, q-031) und Latenz sind Tuning-Kandidaten —
|
||||
Prompt für den Bake-off vorher einfrieren.
|
||||
- **M4 offen:** Odoo-Integration (separater Plan nach Verifikation der
|
||||
Odoo-19-LLM-Module).
|
||||
- Betrieb: `agent/README.md`.
|
||||
|
||||
Reference in New Issue
Block a user