diff --git a/server/src/analyze/prompt.rs b/server/src/analyze/prompt.rs index bfb5ab6..99080bc 100644 --- a/server/src/analyze/prompt.rs +++ b/server/src/analyze/prompt.rs @@ -3,44 +3,42 @@ use super::AnalysisInput; /// System prompt for the consolidation LLM. /// Temperature 0 is set on the request; the prompt enforces "no interpretation". /// -/// Sandbox-validated against case c414cf52 (3 runs each): -/// - active correction of known drug names (Inoxaparin→Enoxaparin etc.) -/// without curve-fitting examples -/// - explicit fidelity clause for anatomical locations, values+units, -/// recording order -/// - explicit conflict-resolution: take the chronologically latest -/// statement, never fabricate a "course of events" narrative -/// - explicit format clause: flowing prose, no inline section markers, -/// no markdown headings +/// Sandbox-validated against case c414cf52 (3 runs each, fair pipeline with +/// pre- and post-LLM gazetteer pass against the current vocab): +/// - eliminates two hallucination classes the previous prompt produced — +/// unmarked "Hypotonie" when the dictation said "Hypertonie" (0/3 vs 2/3), +/// and inventing a unit ("35 ng/l") for a dictated value without unit +/// (0/3 vs 2/3) +/// - keeps Latin terms intact ("Punctum Maximum", "Apex Cordis", "Axilla" +/// in 3/3 vs 2/3) +/// - relies on the gazetteer for drug-name correction (Enoxaparin etc.) — +/// the prompt no longer needs a separate "AKTIVE KORREKTUR" hammer-block +/// because the gazetteer's pre-LLM pass repairs the typical typos before +/// the LLM ever sees them +/// - block layout: AUFGABE / QUELLE / KORREKTUR-POLITIK / TREUE / CHRONOLOGIE +/// / DOSIERUNGSSCHEMA / MARKIERUNGEN — each rule appears exactly once pub const SYSTEM_PROMPT: &str = r#"Du bist ein medizinischer Assistent. -Fasse die folgenden diktierten Abschnitte zu einem zusammenhängenden Fließtext zusammen. Bereinigen und strukturieren, nichts hinzufügen, keine medizinische Interpretation, keine Diagnose, keine Arztbrief-Struktur. Entferne Redundanzen. Antworte auf Deutsch. Nur der zusammengefasste Text, keine Einleitung, kein Abschlusssatz. +AUFGABE: Fasse die folgenden diktierten Abschnitte zu einem zusammenhängenden, deutschen Fließtext zusammen — bereinigen und strukturieren, keine Diagnose, keine Arztbrief-Struktur, keine Einleitung, kein Abschlusssatz, nur der konsolidierte Text. Mehrere Absätze erlaubt. KEINE Inline-Sektionsmarker (kein "Status:", "Diagnostik:", "Therapie:", "Plan:"), KEINE Markdown-Headings, KEINE Aufzählungspunkte. -FORMAT: Ein einziger zusammenhängender Fließtext, mehrere Absätze erlaubt. KEINE Inline-Sektionsmarker (kein "Status:", "Diagnostik:", "Therapie:", "Plan:"), KEINE Markdown-Headings, KEINE Aufzählungspunkte. - - -WICHTIG: Das Diktat wurde automatisch transkribiert und enthält typische ASR-Fehler wie phonetisch ähnliche Verwechslungen und zerschnittene Komposita (z.B. "Spolade" statt "Schokolade", "posbrandial" statt "postprandial", "in Faust" statt "infaust"). Korrigiere diese Fehler AKTIV. Bei Unsicherheit, wie die Korrektur lauten müsste: behalte das Original bei und markiere es. - -AKTIVE KORREKTUR (nicht durchreichen): Bekannte Wirkstoffnamen, etablierte medizinische Akronyme und Standard-Termini sind aktiv zu korrigieren, wenn der ASR-Fehler eindeutig ist. Wenn die korrigierte Form ein bekannter Wirkstoff oder Standard-Begriff ist und keine andere medizinische Lesart Sinn ergibt: Korrektur ohne Markierung übernehmen. +QUELLE: Das Diktat wurde automatisch transkribiert und enthält typische ASR-Fehler — phonetisch ähnliche Verwechslungen und zerschnittene Komposita (z.B. "Spolade" statt "Schokolade", "posbrandial" statt "postprandial", "in Faust" statt "infaust"). +KORREKTUR-POLITIK: +- Bekannte Wirkstoffnamen, etablierte medizinische Akronyme und Standard-Termini bei eindeutigem ASR-Fehler aktiv und unmarkiert korrigieren. +- Bei Unsicherheit: Original behalten und mit ==...== markieren statt zu raten. KEINE medizinisch klingenden Komposita aus phonetischer Nähe konstruieren. TREUE ZUM DIKTAT (höchste Priorität — vor allen anderen Regeln): - Anatomische Lokalisationen, Werte mit Einheiten, Wirkstoffnamen, Dosierungen und genannte Befunde NIEMALS umformulieren, eindampfen oder weglassen. Wörtlich übernehmen. -- KEINE medizinisch klingenden Komposita aus phonetischer Nähe konstruieren. Wenn ein Token kein klares Wort ergibt: markiere es mit ==...== und lass den Rohinhalt stehen, statt zu raten. -- KEINE neuen Tatsachen hinzufügen, auch nicht naheliegende medizinische Interpretationen. -- Werte mit Einheiten zusammenhalten ("35 ng/l", nicht nur "35"). Wenn die Einheit im Diktat fehlt: markiere die Zahl. +- KEINE neuen Tatsachen oder medizinischen Interpretationen hinzufügen, auch nicht naheliegende. +- Werte mit Einheiten zusammenhalten ("35 ng/l", nicht nur "35"). Fehlt die Einheit im Diktat: Zahl markieren. + +CHRONOLOGIE: - Diktat-Reihenfolge erhalten — Befunde aus späteren Aufnahmen nicht in die Anamnese verschieben, auch wenn sie thematisch verwandt wirken. - -WIDERSPRÜCHE ZWISCHEN AUFNAHMEN: Bei widersprüchlichen Aussagen über mehrere Aufnahmen die chronologisch letzte Aussage übernehmen, die frühere weglassen oder als ==text== markieren. KEINE Verlaufsgeschichte konstruieren (NICHT "die im weiteren Verlauf als X beurteilt wird"). Wenn eine frühere Aufnahme einen offensichtlichen ASR-Fehler enthält und alle späteren Aufnahmen die korrigierte Form zeigen: die spätere als korrekt nehmen, früheren Fehler nicht erwähnen. - +- Bei widersprüchlichen Aussagen über mehrere Aufnahmen die chronologisch letzte übernehmen, die frühere weglassen oder als ==text== markieren. KEINE Verlaufsgeschichte konstruieren (NICHT "die im weiteren Verlauf als X beurteilt wird"). Wenn eine frühere Aufnahme einen offensichtlichen ASR-Fehler enthält und alle späteren die korrigierte Form zeigen: die spätere als korrekt nehmen, früheren Fehler nicht erwähnen. DOSIERUNGSSCHEMA: 3–4 kleine Zahlen im Medikationskontext sind morgens-mittags-abends(-nachts). Schreibe kompakt: "eins null zwei" → "1-0-2", "eins null zwei null" → "1-0-2-0". Nur bei klarem Medikationskontext anwenden, sonst Original behalten und markieren. -MARKIERUNGEN IM FORMAT "==text==" signalisieren dem Arzt "bitte prüfen". -Markiere jede zweifelhafte Stelle, bei der die Korrektur nicht eindeutig ist. -Markiere zusätzlich: Zahlen ohne klaren Kontext oder Einheit. -Markiere sparsam — eindeutig korrigierte Wirkstoffe und geläufige, klar gesprochene Fachbegriffe bleiben unmarkiert. -WICHTIG: Es sind keine anderen Arten von Annotationen erlaubt (z.B. "(unsicher)", "[TODO]")."#; +MARKIERUNGEN: ==text== signalisiert dem Arzt "bitte prüfen". Sparsam einsetzen — eindeutig korrigierte Wirkstoffe und klar gesprochene Fachbegriffe bleiben unmarkiert. Keine anderen Annotations-Formen ("(unsicher)", "[TODO]" o.ä.) verwenden."#; /// Render the user-content portion of the chat request from the persisted /// JSON input. Recordings with blank text are skipped — they carry no signal diff --git a/server/vocab/medical_terms.txt b/server/vocab/medical_terms.txt new file mode 100644 index 0000000..88dcb57 --- /dev/null +++ b/server/vocab/medical_terms.txt @@ -0,0 +1,9 @@ +# Medical domain terms (anatomy, findings, technical compound nouns). +# Single-token entries only — multi-word terms ("Punctum maximum") cannot +# be represented because the tokenizer splits on whitespace. +# Same conventions as vocabulary.txt: ≥5 chars, alphabetical, one per line, +# phonetically distinctive (DL≤2 must not collide with everyday German). +Holosystolikum +Klappenvitien +Koronarbaum +Pumpfunktion diff --git a/server/vocab/vocabulary.txt b/server/vocab/vocabulary.txt index d9174cd..10b7e30 100644 --- a/server/vocab/vocabulary.txt +++ b/server/vocab/vocabulary.txt @@ -48,6 +48,7 @@ Duloxetin Edoxaban Eliquis Enalapril +Enoxaparin Erythromycin Escitalopram Esomeprazol