feat: Unify AI prompts for Gemini and Mistral

This commit is contained in:
2025-12-19 22:01:29 +01:00
parent 2601a8f12f
commit e0436987a1
5 changed files with 53 additions and 60 deletions

View File

@@ -1,6 +1,7 @@
'use server';
import { Mistral } from '@mistralai/mistralai';
import { getSystemPrompt } from '@/lib/ai-prompts';
import { BottleMetadataSchema, AnalysisResponse, BottleMetadata } from '@/types/whisky';
import { createClient } from '@/lib/supabase/server';
import { createHash } from 'crypto';
@@ -49,21 +50,7 @@ export async function analyzeBottleMistral(base64Image: string, tags?: string[],
const client = new Mistral({ apiKey: process.env.MISTRAL_API_KEY });
const dataUrl = `data:image/jpeg;base64,${base64Data}`;
const prompt = `Du bist ein Whisky-Experte und OCR-Spezialist.
Analysiere dieses Etikett präzise.
Sprache für Beschreibungen: ${locale === 'en' ? 'Englisch' : 'Deutsch'}.
Verfügbare Tags zur Einordnung: ${tags ? tags.join(', ') : 'Keine Tags verfügbar'}.
Antworte AUSSCHLIESSLICH mit gültigem JSON (kein Markdown, kein Text davor/danach):
{
"distillery": "Name der Brennerei (z.B. Lagavulin)",
"name": "Exakter Name/Edition (z.B. 16 Year Old)",
"vintage": "Jahrgang als Zahl oder null",
"age": "Alter als Zahl oder null (z.B. 16)",
"abv": "Alkoholgehalt als Zahl ohne % (z.B. 43)",
"category": "Kategorie (z.B. Single Malt Scotch Whisky)",
"search_string": "site:whiskybase.com [Brennerei] [Name] [Alter]"
}`;
const prompt = getSystemPrompt(tags ? tags.join(', ') : 'Keine Tags verfügbar', locale);
const chatResponse = await client.chat.complete({
model: 'mistral-large-latest',

View File

@@ -1,6 +1,7 @@
'use server';
import { geminiModel, SYSTEM_INSTRUCTION } from '@/lib/gemini';
import { geminiModel } from '@/lib/gemini';
import { getSystemPrompt } from '@/lib/ai-prompts';
import { BottleMetadataSchema, AnalysisResponse } from '@/types/whisky';
import { createClient } from '@/lib/supabase/server';
import { createHash } from 'crypto';
@@ -50,9 +51,7 @@ export async function analyzeBottle(base64Image: string, tags?: string[], locale
};
}
const instruction = SYSTEM_INSTRUCTION
.replace('{AVAILABLE_TAGS}', tags ? tags.join(', ') : 'No tags available')
.replace('{LANGUAGE}', locale === 'en' ? 'English' : 'German');
const instruction = getSystemPrompt(tags ? tags.join(', ') : 'No tags available', locale);
const result = await geminiModel.generateContent([
{
@@ -71,6 +70,10 @@ export async function analyzeBottle(base64Image: string, tags?: string[], locale
jsonData = jsonData[0];
}
// Extract search_string if present
const searchString = jsonData.search_string;
delete jsonData.search_string;
if (!jsonData) {
throw new Error('Keine Daten in der KI-Antwort gefunden.');
}
@@ -106,7 +109,8 @@ export async function analyzeBottle(base64Image: string, tags?: string[], locale
return {
success: true,
data: validatedData,
};
search_string: searchString
} as any;
} catch (error) {
console.error('Gemini Analysis Error:', error);