From 04b218044e5b2ee093299b3f453c56de35a0e9cc Mon Sep 17 00:00:00 2001 From: root Date: Mon, 16 Mar 2026 09:43:44 +0700 Subject: [PATCH] Dokumentenextraktion: konservativ, feldweise Confidence, kein Raten, Rohtext/Interpretation getrennt --- homelab-ai-bot/llm.py | 96 +++++++++++++++++++++++++++++++++---------- 1 file changed, 74 insertions(+), 22 deletions(-) diff --git a/homelab-ai-bot/llm.py b/homelab-ai-bot/llm.py index 46c5c05d..38ad0f1c 100644 --- a/homelab-ai-bot/llm.py +++ b/homelab-ai-bot/llm.py @@ -64,29 +64,79 @@ SESSION-RUECKBLICK: - Optional kurz erwaehnen was sonst noch Thema war. - session_search nur fuer Stichwort-Suche in ALTEN Sessions (nicht aktuelle). -BILDERKENNUNG: -Wenn der User ein Bild oder PDF schickt: -- Beschreibe STRUKTURIERT was du siehst. -- Bei Flugplaenen/Buchungen: Extrahiere ALLE Daten (Flugnummer, Datum, Abflug/Ankunft Uhrzeit, Airports mit IATA-Codes, Preis, Buchungscode, Airline, Sitzplatz, Gepaeck). +BILDERKENNUNG — ALLGEMEIN: +Wenn der User ein Bild schickt das KEIN kritisches Dokument ist (z.B. Foto, Screenshot, Landschaft): +- Beschreibe strukturiert was du siehst. - Bei Screenshots von Fehlern/Logs: Identifiziere das Problem, ordne es einem Container/Service zu, schlage Loesung vor. -- Bei Rechnungen/Dokumenten: Extrahiere Betrag, Datum, Absender, Faelligkeit. -- WICHTIG: Speichere erkannte Reiseplaene, Termine, Buchungen IMMER via memory_suggest (memory_type="plan", mit expires_at). - Bei Folgefragen zum selben Bild: Beantworte anhand der vorherigen Bildbeschreibung in der Session-History. +- Speichere erkannte Termine/Plaene via memory_suggest. -DATUMSANGABEN AUS BILDERN (KRITISCH — lies EXTREM genau): -- Lies JEDES Datum Zeichen fuer Zeichen vom Bild ab. Verwechsle NICHT 18 mit 19, 13 mit 15 etc. -- Tickets zeigen Daten oft als "18MAR", "15MAR" etc. Lies die ZAHL vor dem Monat praezise. -- PLAUSIBILITAET: Bei Anschlussfluegen muss die Umsteigezeit realistisch sein (mind. 1-3h bei internationalem Umstieg). Wenn Flug A um 23:30 landet und Flug B um 23:35 startet, sind beide am SELBEN Tag — ein Tagessprung waere unlogisch bei 5 Min Differenz. -- Wenn ein Vorgaengerflug am Tag X landet und der naechste Flug wenige Stunden spaeter startet, hat der naechste Flug ebenfalls Datum X (nicht X+1). +DOKUMENTENEXTRAKTION — HARTE REGELN: +Gilt fuer: Flugtickets, Buchungen, Belege, Rechnungen, Formulare, Behoerdendokumente. +Bei diesen Dokumenten ist eine UNVOLLSTAENDIGE aber EHRLICHE Antwort IMMER besser als eine VOLLSTAENDIGE aber ERFUNDENE. -ZEIT- UND DATUMSLOGIK (PFLICHT bei Flugdaten): +1. NIEMALS RATEN: +- Wenn ein Feld nicht sicher lesbar ist: NICHT erfinden. +- Keine plausible Uhrzeit ergaenzen. Keine Codes aus Weltwissen ergaenzen. +- Stattdessen markieren: "nicht sicher lesbar", "unklar", "im Bild nicht eindeutig". + +2. BILDWISSEN VOR WELTWISSEN: +- NUR extrahieren was im Bild steht. KEIN externes Wissen um fehlende Felder zu "reparieren". +- Wenn im Bild "KTI" steht: "KTI" ausgeben, NICHT stillschweigend zu "PNH" aendern. +- Wenn eine Zeit nicht lesbar ist: NICHT eine Standardzeit aus Flugplaenen erfinden. +- Interpretation nur in Klammern und nur wenn wirklich sicher: "KTI (vermutl. Phnom Penh Techo International)". + +3. ROHTEXT UND INTERPRETATION TRENNEN: +- Bei kritischen Feldern zwei Ebenen: was im Bild steht vs. was interpretiert wird. +- Wenn Interpretation unsicher: NUR den Rohwert zeigen oder als unklar markieren. + +4. FELDWEISE CONFIDENCE: +Jedes wichtige Feld bekommt eine Confidence (high/medium/low). +Wichtige Felder: Flugnummer, Datum, Abflugzeit, Ankunftszeit, Flughaefen, Gepaeck, Buchungsnummer, Filekey/CRS, Name, Telefon, Preis. +- Unsichere Felder NIEMALS mit hoher Sicherheit formulieren. +- Low-confidence Felder IMMER kennzeichnen. + +5. TABELLARISCH STATT FREIFORM: +Ausgabeformat fuer Flugtickets: + +Allgemeine Angaben: +- Fluggesellschaft: [Wert] +- Ticketdatum: [Wert] +- Buchungsnummer: [Wert] +- Kunde: [Wert] +- Telefon: [Wert] +- Filekey/CRS: [Wert] + +Flugsegmente: +1. [Von] → [Nach] +- Flugnummer: [Wert] +- Datum: [Wert] +- Abflug: [Wert oder "nicht sicher lesbar"] +- Ankunft: [Wert oder "nicht sicher lesbar"] +- Gepaeck: [Wert] +- Confidence: [high/medium/low] +- Unsichere Felder: [Liste oder "keine"] + +2. ... + +6. ZEICHEN-FUER-ZEICHEN BEI NUMMERN/DATEN: +Lies STRIKT Zeichen fuer Zeichen: Datum, Flugnummer, Buchungsnummer, CRS/Filekey, Telefon, Ticketnummer. +NICHT glaetten, NICHT umdeuten, NICHT kreativ korrigieren. +Tickets zeigen Daten oft als "18MAR", "15MAR" — lies die ZAHL vor dem Monat praezise. Verwechsle NICHT 18 mit 19, 13 mit 15. + +7. PLAUSIBILITAETSPRUEFUNG — NUR ALS KONTROLLE: +- Darf verwendet werden um falsch gelesene Werte zu erkennen. +- Darf NIEMALS fehlende Werte erfinden. +- Bei Anschlussfluegen: Wenn Flug A um 23:30 landet und Flug B um 23:35 startet = SELBER Tag (kein Tagessprung bei 5 Min). +- Langstreckenfluege (Suedostasien→Europa = 10-12h): Ankunft VOR Abflug = Ankunftsdatum ist naechster Tag. +- Zeitzonen: Suedostasien UTC+7, Mitteleuropa CET/UTC+1 = 6h Differenz. - RECHNE IMMER SELBST NACH. Kopiere NIEMALS Zeitberechnungen aus frueheren Antworten. -- Langstreckenfluege (z.B. Suedostasien→Europa = 10-12h): Wenn Ankunft VOR Abflug liegt, ist Ankunftsdatum der NAECHSTE Tag. -- Umsteigezeit = Ankunftszeit Flug 1 bis Abflugzeit Flug 2. BEACHTE das DATUM beider Fluege. -- Zeitzonen: Abflugzeit = lokal am Abflugort, Ankunft = lokal am Zielort. Suedostasien (UTC+7) zu Mitteleuropa (CET/UTC+1) = 6h Differenz. Deshalb dauert ein 12h-Flug auf der Uhr nur ~6h (z.B. 23:25 ab → 06:00 an). -- Gesamtreisezeit = Summe aller Flugzeiten + alle Umsteigezeiten. -- Bei Unstimmigkeiten: KORRIGIERE und weise den User darauf hin. -- Uhrzeiten IMMER mit korrektem Datum (z.B. "18.03. 17:30"). + +8. KONSERVATIV FORMULIEREN: +Bei Reisen, Geld, Behoerden, Rechnungen, Buchungen: +- Lieber unvollstaendig aber ehrlich. +- NIEMALS praezise falsche Angaben machen. +- Speichere nur HIGH-CONFIDENCE Daten via memory_suggest (Reiseplaene, Buchungscodes). TOOLS: Nutze Tools fuer Live-Daten. Wenn alles OK: kurz sagen. Bei Problemen: erklaeren + Loesung.""" @@ -527,10 +577,12 @@ def ask_with_image(image_base64: str, caption: str, tool_handlers: dict, session memory_block = "" default_prompt = ( - "Lies dieses Bild/Dokument VOLLSTAENDIG und GENAU. " - "Extrahiere ALLE sichtbaren Texte, Zahlen, Daten, Namen. " - "Strukturiere die Informationen uebersichtlich. " - "Bei Tickets/Buchungen: JEDE Flugnummer, JEDES Datum, JEDE Uhrzeit, JEDEN Preis, JEDEN Code einzeln auflisten." + "Analysiere dieses Bild. " + "Wenn es ein Dokument ist (Ticket, Rechnung, Beleg, Buchung): " + "Wende die DOKUMENTENEXTRAKTION-Regeln an — feldweise, konservativ, mit Confidence pro Feld. " + "Markiere unsichere Felder explizit. Erfinde NICHTS. " + "Lies Nummern und Daten Zeichen fuer Zeichen. " + "Wenn es ein normales Bild ist: Beschreibe strukturiert was du siehst." ) prompt_text = caption if caption else default_prompt user_content = [