From a5fae8cf5572ed33a470ad5d44560ccc356979a6 Mon Sep 17 00:00:00 2001 From: Marcus van Elst Date: Mon, 27 Apr 2026 16:11:42 +0200 Subject: [PATCH] Fix #42: KI-Prompt weist explizit zur Kuerzung bei Zeichenlimit an Wenn die KI einen Titel nahe am Zeichenlimit erzeugt, kam es regelmaessig zur Limit-Ueberschreitung um wenige Zeichen, was den Lauf in FAILED_RETRYABLE und nach Wiederholung in FAILED_FINAL trieb. Der Default-Prompt enthaelt jetzt eine explizite Kuerzungsanweisung (Abkuerzungen, kompaktere Datumsformate, Weglassen unwichtiger Details) mit dynamisch eingesetztem Zeichenlimit. Die bestehende Validierung in AiResponseValidator bleibt als Sicherheitsnetz unveraendert. Co-Authored-By: Claude Opus 4.7 (1M context) --- .../technicaltest/DefaultPromptTemplate.java | 10 ++++++++++ .../technicaltest/DefaultPromptTemplateTest.java | 14 ++++++++++++++ 2 files changed, 24 insertions(+) diff --git a/pdf-umbenenner-application/src/main/java/de/gecheckt/pdf/umbenenner/application/validation/technicaltest/DefaultPromptTemplate.java b/pdf-umbenenner-application/src/main/java/de/gecheckt/pdf/umbenenner/application/validation/technicaltest/DefaultPromptTemplate.java index e57e5d4..5e68d2a 100644 --- a/pdf-umbenenner-application/src/main/java/de/gecheckt/pdf/umbenenner/application/validation/technicaltest/DefaultPromptTemplate.java +++ b/pdf-umbenenner-application/src/main/java/de/gecheckt/pdf/umbenenner/application/validation/technicaltest/DefaultPromptTemplate.java @@ -36,6 +36,8 @@ public final class DefaultPromptTemplate { *
  • Eine Rollenanweisung an die KI (deutsches Dokumentenverwaltungssystem)
  • *
  • Das erwartete JSON-Ausgabeformat mit den Feldern {@code date}, {@code title} und {@code reasoning}
  • *
  • Benennungsregeln für Titel (maximal {@code maxTitleLength} Zeichen, deutsch, keine Sonderzeichen)
  • + *
  • Eine explizite Kürzungsanweisung: die KI muss Titel, die das Zeichenlimit überschreiten würden, + * eigenständig kürzen (Abkürzungen, kompaktere Formate, Weglassen unwichtiger Details)
  • *
  • Hinweis auf das Datumsformat ({@code YYYY-MM-DD})
  • * *

    @@ -75,6 +77,14 @@ public final class DefaultPromptTemplate { - Das Datumsformat ist YYYY-MM-DD (z.B. 2026-03-15). - Der Titel ist auf Deutsch, verständlich und eindeutig für den Dokumentinhalt. - Der Titel hat maximal {MAX_TITLE_LENGTH} Zeichen (Basistitel ohne Suffix). + - Wenn der ideale Titel das Zeichenlimit überschreiten würde, kürze den Titel + eigenständig auf maximal {MAX_TITLE_LENGTH} Zeichen, ohne dass der Inhalt + unverständlich wird. Erlaubte Mittel: Abkürzungen (z. B. "Nov." statt + "November", "Int." statt "Internationale"), kompaktere Datumsformate + (z. B. "11-2022" statt "November 2022"), Weglassen unwichtiger Details und + Kürzen von Adressen oder Absenderfloskeln. + - Das Zeichenlimit von {MAX_TITLE_LENGTH} Zeichen ist verbindlich und MUSS + eingehalten werden. - Keine generischen Bezeichner wie "Dokument", "Scan", "Datei", "PDF". - Keine Sonderzeichen außer Leerzeichen im Titel. - Eigennamen bleiben unverändert. diff --git a/pdf-umbenenner-application/src/test/java/de/gecheckt/pdf/umbenenner/application/validation/technicaltest/DefaultPromptTemplateTest.java b/pdf-umbenenner-application/src/test/java/de/gecheckt/pdf/umbenenner/application/validation/technicaltest/DefaultPromptTemplateTest.java index 6b61eb7..93e1e45 100644 --- a/pdf-umbenenner-application/src/test/java/de/gecheckt/pdf/umbenenner/application/validation/technicaltest/DefaultPromptTemplateTest.java +++ b/pdf-umbenenner-application/src/test/java/de/gecheckt/pdf/umbenenner/application/validation/technicaltest/DefaultPromptTemplateTest.java @@ -72,4 +72,18 @@ class DefaultPromptTemplateTest { .isThrownBy(() -> DefaultPromptTemplate.defaultContent(0)) .withMessageContaining("maxTitleLength must be >= 1"); } + + @Test + void defaultContent_containsTruncationInstruction() { + String content = DefaultPromptTemplate.defaultContent(TEST_MAX_TITLE_LENGTH); + // Die Kürzungsanweisung muss explizit vorhanden sein + assertThat(content).contains("kürze"); + assertThat(content).contains("Abkürzungen"); + // Der Platzhalter wurde ersetzt, daher muss der numerische Wert mindestens zweimal erscheinen: + // einmal in der Längenregel und einmal in der Kürzungsanweisung + assertThat(content.split(String.valueOf(TEST_MAX_TITLE_LENGTH), -1).length - 1) + .as("Die konfigurierte Titellänge (%d) muss mindestens zweimal im Prompt vorkommen", + TEST_MAX_TITLE_LENGTH) + .isGreaterThanOrEqualTo(2); + } }