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) <noreply@anthropic.com>
This commit is contained in:
2026-04-27 16:11:42 +02:00
parent 191d398604
commit a5fae8cf55
2 changed files with 24 additions and 0 deletions
@@ -36,6 +36,8 @@ public final class DefaultPromptTemplate {
* <li>Eine Rollenanweisung an die KI (deutsches Dokumentenverwaltungssystem)</li> * <li>Eine Rollenanweisung an die KI (deutsches Dokumentenverwaltungssystem)</li>
* <li>Das erwartete JSON-Ausgabeformat mit den Feldern {@code date}, {@code title} und {@code reasoning}</li> * <li>Das erwartete JSON-Ausgabeformat mit den Feldern {@code date}, {@code title} und {@code reasoning}</li>
* <li>Benennungsregeln für Titel (maximal {@code maxTitleLength} Zeichen, deutsch, keine Sonderzeichen)</li> * <li>Benennungsregeln für Titel (maximal {@code maxTitleLength} Zeichen, deutsch, keine Sonderzeichen)</li>
* <li>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)</li>
* <li>Hinweis auf das Datumsformat ({@code YYYY-MM-DD})</li> * <li>Hinweis auf das Datumsformat ({@code YYYY-MM-DD})</li>
* </ul> * </ul>
* <p> * <p>
@@ -75,6 +77,14 @@ public final class DefaultPromptTemplate {
- Das Datumsformat ist YYYY-MM-DD (z.B. 2026-03-15). - 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 ist auf Deutsch, verständlich und eindeutig für den Dokumentinhalt.
- Der Titel hat maximal {MAX_TITLE_LENGTH} Zeichen (Basistitel ohne Suffix). - 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 generischen Bezeichner wie "Dokument", "Scan", "Datei", "PDF".
- Keine Sonderzeichen außer Leerzeichen im Titel. - Keine Sonderzeichen außer Leerzeichen im Titel.
- Eigennamen bleiben unverändert. - Eigennamen bleiben unverändert.
@@ -72,4 +72,18 @@ class DefaultPromptTemplateTest {
.isThrownBy(() -> DefaultPromptTemplate.defaultContent(0)) .isThrownBy(() -> DefaultPromptTemplate.defaultContent(0))
.withMessageContaining("maxTitleLength must be >= 1"); .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);
}
} }