From 2c50049238d7d0fb3b90da2006e2ab83c15595c5 Mon Sep 17 00:00:00 2001 From: Sascha Wolf Date: Thu, 24 Sep 2026 09:45:34 +0200 Subject: [PATCH] fix(ki): gpt-6 und spaetere Modelle als Reasoning-Modelle erkennen isReasoningModel() kannte nur gpt-5. gpt-6-luna bekam deshalb temperature 0.1 und OpenAI lehnte jeden Aufruf mit 400 ab ("Only the default (1) value is supported"). Jetzt zaehlt jede Generation ab 5. Vergleich gpt-4o-mini gegen gpt-6-luna in docs/14-ki.md. Co-Authored-By: Claude Opus 5.5 --- docs/14-ki.md | 23 +++++++++++++++++++++-- server/src/ai.js | 12 +++++++----- server/test/ai.test.mjs | 2 +- 3 files changed, 29 insertions(+), 8 deletions(-) diff --git a/docs/14-ki.md b/docs/14-ki.md index 345a469..7d304a0 100644 --- a/docs/14-ki.md +++ b/docs/14-ki.md @@ -70,9 +70,9 @@ Die Wahl gilt ab dem nächsten Aufruf - es gibt keinen Zwischenspeicher. Die beiden Modellfamilien nehmen unterschiedliche Parameter. Damit ein Wechsel im Dropdown keinen `400` von OpenAI auslöst, entscheidet `isReasoningModel()` -(Namen `o1…`, `o3…`, `gpt-5…`) je Aufruf: +(Namen `o1…`, `o3…`, `gpt-5…`, `gpt-6…` und jede spätere Generation) je Aufruf: -| | Reasoning (`o*`, `gpt-5*`) | klassisch (`gpt-4o*`, `gpt-4.1*`) | +| | Reasoning (`o*`, `gpt-5*`, `gpt-6*` …) | klassisch (`gpt-4o*`, `gpt-4.1*`) | | --- | --- | --- | | Scanner-Bewertung | `reasoning_effort: low` | `temperature: 0.1` | | Abgleich „bereits beworben" | `reasoning_effort: low` | `temperature: 0` | @@ -81,6 +81,25 @@ im Dropdown keinen `400` von OpenAI auslöst, entscheidet `isReasoningModel()` `max_completion_tokens` verstehen beide Familien, das alte `max_tokens` die Reasoning-Modelle nicht. +Bis zum 24.09.2026 erkannte das Muster nur `gpt-5…`. `gpt-6-luna` galt damit als +klassisch, bekam `temperature: 0.1` und OpenAI lehnte jeden Aufruf ab +(„Only the default (1) value is supported"). Deshalb zählt jetzt jede Generation +ab 5 als Reasoning-Modell. + +**Vergleich Scanner-Bewertung, 24.09.2026** (33 echte Projekte aus Lisa, Ariane +und Tobias, neuer Bewertungsprompt, siehe [03 Scanner](03-scanner.md#bewertungsprompt)): + +| | `gpt-4o-mini` | `gpt-6-luna` (`reasoning_effort: low`) | +| --- | --- | --- | +| Fehler | 0 | 0 | +| Ø Antwortzeit | 1,3 s | 2,8 s | +| Ø Token rein / raus | 5337 / 108 | 5336 / 172 (davon 35 Reasoning) | +| passende Rollen | 85-95 | 82-98 | +| fachfremde Rollen | meist 0 oder 30 | 0-15, feiner abgestuft | + +Luna begründet genauer und bleibt nah am Lebenslauf. Grenzfälle +(übertragbare Erfahrung) bewertet es spürbar großzügiger als `gpt-4o-mini`. + ## Endpunkte Alle unter `/api/ai`, nur für Administratoren. diff --git a/server/src/ai.js b/server/src/ai.js index 7064a50..01f3054 100644 --- a/server/src/ai.js +++ b/server/src/ai.js @@ -52,7 +52,7 @@ export const AI_PURPOSES = { * Auswahl, falls OpenAI die Modellliste nicht liefert (kein Schluessel, * nicht erreichbar). Die aktuell eingestellten Modelle kommen immer dazu. */ -const FALLBACK_MODELS = ['gpt-5.6-luna', 'gpt-5', 'gpt-5-mini', 'gpt-4.1', 'gpt-4.1-mini', 'gpt-4o', 'gpt-4o-mini']; +const FALLBACK_MODELS = ['gpt-6-luna', 'gpt-5.6-luna', 'gpt-5', 'gpt-5-mini', 'gpt-4.1', 'gpt-4.1-mini', 'gpt-4o', 'gpt-4o-mini']; const settingKey = (purpose) => `ai_model_${purpose}`; @@ -147,12 +147,14 @@ export function isValidModel(value) { } /** - * Reasoning-Modelle (o1, o3, o4-mini, gpt-5 ...) nehmen kein `temperature`, - * dafuer `reasoning_effort`. Wer in den Einstellungen umstellt, soll keinen - * 400er von OpenAI bekommen - die Aufrufer fragen deshalb hier nach. + * Reasoning-Modelle (o1, o3, o4-mini, gpt-5 ..., gpt-6 ...) nehmen kein + * `temperature`, dafuer `reasoning_effort`. Wer in den Einstellungen umstellt, + * soll keinen 400er von OpenAI bekommen - die Aufrufer fragen deshalb hier nach. + * Ab gpt-5 zaehlt jede Generation dazu: gpt-6-luna lehnte `temperature: 0.1` + * am 24.09.2026 mit "Only the default (1) value is supported" ab. */ export function isReasoningModel(model) { - return /^(o\d|gpt-5)/i.test(String(model ?? '')); + return /^(o\d|gpt-([5-9]|\d{2,}))/i.test(String(model ?? '')); } /** Eingestelltes Modell je Zweck, sonst die Vorgabe. */ diff --git a/server/test/ai.test.mjs b/server/test/ai.test.mjs index 912d0b3..167677a 100644 --- a/server/test/ai.test.mjs +++ b/server/test/ai.test.mjs @@ -28,7 +28,7 @@ for (const name of ['', ' gpt-4o', 'gpt 4o', 'gpt-4o;drop', 'x'.repeat(101), nul check(`ungueltig: ${JSON.stringify(name)?.slice(0, 20)}`, !isValidModel(name)); } -for (const name of ['o1', 'o3-mini', 'o4-mini', 'gpt-5', 'gpt-5.6-luna']) { +for (const name of ['o1', 'o3-mini', 'o4-mini', 'gpt-5', 'gpt-5.6-luna', 'gpt-6-luna', 'gpt-6-sol', 'gpt-10']) { check(`reasoning: ${name}`, isReasoningModel(name)); } for (const name of ['gpt-4o-mini', 'gpt-4.1', 'chatgpt-4o-latest']) {