feat: Objekt-Token-Cleanup + schärferer LLM-Prompt (Kopf-Kompositum vs Bestimmungswort)

Der LLM-Fallback hatte Objektwörter auch dann verlinkt, wenn sie nur
Bestimmungswort eines anderen Dings waren (z.B. "jordgubbsfältet"/Erdbeerfeld
als Erdbeere). Regel jetzt explizit:
- behalten: Wort, Beugung/Mehrzahl/bestimmte Form, Kopf-Kompositum
  ("Landschildkröte"=Schildkröte), Synonym ("Stiefel"/"Lederstiefel"=Schuh)
- entfernen: Objektwort nur als Bestimmungswort ("Erdbeerfeld" != Erdbeere)

- locateSurfaceLLM-Prompt um diese Regel + Beispiele geschärft (verhindert
  künftiges Fehl-Tagging).
- Neuer cleanup-Modus: POST /api/pipeline/retag-objects {"cleanup":true}
  prüft bestehende Objekt-Tokens per LLM und entfernt die falschen. Eindeutig
  gute Formen (exakt/Lemma+Endung) werden ohne LLM behalten.
- Helfer in objectTagging.js: objectTokensInSentence, isSimpleObjectForm, untagToken.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
2026-06-13 19:56:13 +02:00
parent 434839e1d4
commit e44d896f9e
3 changed files with 140 additions and 12 deletions

View File

@@ -312,18 +312,21 @@ router.post('/repair-tokens', async (req, res, next) => {
// POST /api/pipeline/retag-objects — Backfill: Objekt-Wörter in bestehenden Sätzen
// nachtokenisieren (deterministisch + optional Hybrid-LLM-Fallback für gebeugte Formen).
// Body: { picture_id?, dry_run?, use_llm? }. Ohne picture_id über ALLE Bilder.
// Body: { picture_id?, dry_run?, use_llm?, cleanup? }. Ohne picture_id über ALLE Bilder.
// cleanup:true ⇒ statt taggen werden falsch getokte Objekt-Wörter (Objektwort nur als
// Bestimmungswort eines anderen Dings, z.B. „Erdbeerfeld") per LLM-Prüfung wieder entfernt.
// Ändert nur die Satz-Textfelder; Audio/Alignment bleiben gültig (Sprechtext unverändert).
router.post('/retag-objects', async (req, res, next) => {
try {
const pictureId = req.body?.picture_id || null;
const dryRun = !!req.body?.dry_run;
const useLLM = !!req.body?.use_llm;
const cleanup = !!req.body?.cleanup;
if (pictureId) {
const pr = await query(`SELECT id FROM pictures WHERE id = $1`, [pictureId]);
if (!pr.rows.length) return res.status(404).json({ error: 'Bild nicht gefunden' });
}
const report = await retagObjects({ pictureId, dryRun, useLLM });
const report = await retagObjects({ pictureId, dryRun, useLLM, cleanup });
res.json(report);
} catch (err) { next(err); }
});