mirror of
https://github.com/Jeuners/Logpy-AgentOne.git
synced 2026-09-19 11:44:10 +02:00
feat: Bewertungssystem (👍/👎) als Trainingsdaten-Export
Jede Karte im Leitstand bekommt Daumen hoch/runter fuer die Kategorisierung. Bei 👎 optional Korrektur (richtige Kategorie/Dringlichkeit). Gespeichert als bewertung.json pro Anruf-Ordner (gleiches Muster wie stapel.json, pipe/bewertung.py). Export als JSONL (pipe/export.py, neuer "📤 Bewertungen exportieren"-Knopf + automatisch beim "Tag archivieren"): ein Datensatz pro bewertetem Anruf mit Transkript, Modell-Ausgabe, Backend/Modell, Bewertung und Korrektur - fuer externe Auswertung (z.B. um Kategorisierungs-Fehler systematisch statt zufaellig zu finden, wie das Notfall-Sicherheitsnetz vom letzten Fund). Export-Knopf verlangt Bestaetigung ("Transkripte und Namen verlassen den Rechner") - bewusst kein automatischer Export ohne Hinweis, das steht sonst im Widerspruch zum On-Prem-Versprechen. training/ ist neu gitignored (volle Transkripte/Namen drin, siehe README-Hinweis zu Testdaten). Nebenbei: process_call.py legt jetzt auch backend/modell/dauer_s der Kategorisierung dauerhaft in meta.json ab (vorher nur im fluechtigen Log) - noetig, damit der Export nachvollziehbar ist, welches Modell lief. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_015vtvcyNkapuDh583643hNs
This commit is contained in:
parent
7e4505d9b7
commit
90548944a2
5 changed files with 219 additions and 7 deletions
69
pipe/export.py
Normal file
69
pipe/export.py
Normal file
|
|
@ -0,0 +1,69 @@
|
|||
"""Exportiert bewertete Anrufe als JSONL-Trainingsdaten (Transkript + Modell-
|
||||
Ausgabe + Bewertung + ggf. Korrektur) - fuer externe Auswertung, z.B. um
|
||||
Kategorisierungs-Fehler systematisch statt zufaellig zu finden.
|
||||
|
||||
python3 -m pipe.export
|
||||
|
||||
Nimmt jeden Anruf mit bewertung.json (unabhaengig vom Datum - kein
|
||||
inkrementeller Export, einfach alle aktuell vorhandenen Bewertungen). Legt
|
||||
unter training/ ab, das wie ablage/ nicht ins Git gehoert (siehe .gitignore) -
|
||||
volle Transkripte + Namen sind bewusst drin (Testphase, siehe README-Hinweis
|
||||
zu erfundenen Daten), fuer den Produktivbetrieb muss das neu entschieden
|
||||
werden, siehe Warnhinweis beim Export-Knopf im Leitstand.
|
||||
"""
|
||||
from __future__ import annotations
|
||||
|
||||
import json
|
||||
from datetime import datetime
|
||||
from pathlib import Path
|
||||
|
||||
from . import bewertung, config
|
||||
|
||||
EXPORT_ORDNER = config.WURZEL / "training"
|
||||
|
||||
|
||||
def sammle() -> list[dict]:
|
||||
"""Alle aktuell bewerteten Anrufe, als flache Trainingsdatensaetze."""
|
||||
eintraege = []
|
||||
if not config.ABLAGE_LOKAL.is_dir():
|
||||
return eintraege
|
||||
for meta_pfad in sorted(config.ABLAGE_LOKAL.glob("*/*/meta.json")):
|
||||
ordner = meta_pfad.parent
|
||||
b = bewertung.lies(ordner)
|
||||
if b is None:
|
||||
continue
|
||||
try:
|
||||
daten = json.loads(meta_pfad.read_text(encoding="utf-8"))
|
||||
except Exception:
|
||||
continue
|
||||
eintraege.append({
|
||||
"anruf_id": str(ordner.relative_to(config.ABLAGE_LOKAL)),
|
||||
"empfangen": daten.get("empfangen"),
|
||||
"transkript": daten.get("transkript"),
|
||||
"modell_ausgabe": daten.get("auswertung"),
|
||||
"kategorisierung": daten.get("kategorisierung"),
|
||||
"bewertung": b["bewertung"],
|
||||
"korrektur": b.get("korrektur"),
|
||||
"bewertet_am": b.get("zeitpunkt"),
|
||||
})
|
||||
return eintraege
|
||||
|
||||
|
||||
def exportiere() -> tuple[Path, int]:
|
||||
"""Schreibt eine neue JSONL-Datei. Gibt (Pfad, Anzahl) zurueck."""
|
||||
eintraege = sammle()
|
||||
EXPORT_ORDNER.mkdir(parents=True, exist_ok=True)
|
||||
ziel = EXPORT_ORDNER / f"export_{datetime.now():%Y%m%d-%H%M%S}.jsonl"
|
||||
with ziel.open("w", encoding="utf-8") as f:
|
||||
for e in eintraege:
|
||||
f.write(json.dumps(e, ensure_ascii=False) + "\n")
|
||||
return ziel, len(eintraege)
|
||||
|
||||
|
||||
def main() -> None:
|
||||
ziel, anzahl = exportiere()
|
||||
print(f"{anzahl} bewertete Anrufe exportiert nach {ziel}")
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
Loading…
Add table
Add a link
Reference in a new issue