fix: make label suggestions content-specific, not generic
All checks were successful
Deploy to Production / Build and Deploy (push) Successful in 42s
All checks were successful
Deploy to Production / Build and Deploy (push) Successful in 42s
Rewrote prompts to be strict about content relevance — only suggest labels directly related to THIS note's content. Raised confidence threshold to 0.5 in code, 0.7 in prompt. Limited to max 2 suggestions from existing labels. Prevents same labels being suggested for every note. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
This commit is contained in:
@@ -133,11 +133,11 @@ export class ContextualAutoTagService {
|
|||||||
return []
|
return []
|
||||||
}
|
}
|
||||||
|
|
||||||
// Filter and map suggestions (case-insensitive)
|
// Filter and map suggestions (case-insensitive, strict threshold)
|
||||||
const lowerAvailable = availableLabels.map((l: string) => l.toLowerCase())
|
const lowerAvailable = availableLabels.map((l: string) => l.toLowerCase())
|
||||||
const suggestions = suggestionsArray
|
const suggestions = suggestionsArray
|
||||||
.filter((s: any) => {
|
.filter((s: any) => {
|
||||||
return s.label && lowerAvailable.includes(s.label.toLowerCase()) && (s.confidence || 0) > 0.3
|
return s.label && lowerAvailable.includes(s.label.toLowerCase()) && (s.confidence || 0) > 0.5
|
||||||
})
|
})
|
||||||
.map((s: any) => {
|
.map((s: any) => {
|
||||||
const originalLabel = availableLabels.find((l: string) => l.toLowerCase() === s.label.toLowerCase()) || s.label
|
const originalLabel = availableLabels.find((l: string) => l.toLowerCase() === s.label.toLowerCase()) || s.label
|
||||||
@@ -149,7 +149,7 @@ export class ContextualAutoTagService {
|
|||||||
}
|
}
|
||||||
})
|
})
|
||||||
.sort((a: any, b: any) => b.confidence - a.confidence)
|
.sort((a: any, b: any) => b.confidence - a.confidence)
|
||||||
.slice(0, 5)
|
.slice(0, 3)
|
||||||
|
|
||||||
console.log('[ContextualAutoTag] filtered existing suggestions:', suggestions.length, suggestions.map((s: any) => `${s.label}(${s.confidence})`))
|
console.log('[ContextualAutoTag] filtered existing suggestions:', suggestions.length, suggestions.map((s: any) => `${s.label}(${s.confidence})`))
|
||||||
return suggestions as LabelSuggestion[]
|
return suggestions as LabelSuggestion[]
|
||||||
@@ -252,172 +252,119 @@ export class ContextualAutoTagService {
|
|||||||
|
|
||||||
const instructions: Record<string, string> = {
|
const instructions: Record<string, string> = {
|
||||||
fr: `
|
fr: `
|
||||||
Tu es un assistant qui suggère les labels les plus appropriés pour une note.
|
Tu es un assistant qui suggère des labels PERTINENTS pour une note.
|
||||||
|
|
||||||
CONTENU DE LA NOTE :
|
CONTENU DE LA NOTE :
|
||||||
${noteContent.substring(0, 1000)}
|
${noteContent.substring(0, 1000)}
|
||||||
|
|
||||||
NOTEBOOK ACTUEL :
|
CARNET : ${notebookName}
|
||||||
${notebookName}
|
|
||||||
|
|
||||||
LABELS DISPONIBLES DANS CE NOTEBOOK :
|
LABELS DISPONIBLES :
|
||||||
${labelList}
|
${labelList}
|
||||||
|
|
||||||
TÂCHE :
|
RÈGLES STRICTES :
|
||||||
Analyse le contenu de la note et suggère les labels les PLUS appropriés parmi les labels disponibles ci-dessus.
|
- Ne suggère un label QUE s'il est DIRECTEMENT en rapport avec le contenu de cette note précise
|
||||||
Considère :
|
- Un label "voyage" n'est pertinent QUE si la note parle de voyage
|
||||||
1. La pertinence du label pour le contenu
|
- Un label "projet" n'est pertinent QUE si la note parle d'un projet spécifique
|
||||||
2. Le nombre de labels (maximum 3 suggestions)
|
- Ne suggère PAS un label juste parce qu'il existe dans le carnet
|
||||||
3. La confiance (seuil minimum : 0.6)
|
- Maximum 2 suggestions
|
||||||
|
- Confiance < 0.7 = ne pas suggérer
|
||||||
|
- Si AUCUN label n'est clairement pertinent, retourne un tableau VIDE
|
||||||
|
|
||||||
RÈGLES :
|
Réponds en JSON :
|
||||||
- Suggère SEULEMENT des labels qui sont dans la liste des labels disponibles
|
{"suggestions":[{"label":"nom","confidence":0.85,"reasoning":"pourquoi"}]}
|
||||||
- Retourne au maximum 3 suggestions
|
|
||||||
- Chaque suggestion doit avoir une confiance > 0.6
|
|
||||||
- Si aucun label n'est pertinent, retourne un tableau vide
|
|
||||||
|
|
||||||
FORMAT DE RÉPONSE (JSON uniquement) :
|
|
||||||
{
|
|
||||||
"suggestions": [
|
|
||||||
{ "label": "nom_du_label", "confidence": 0.85, "reasoning": "Pourquoi ce label est pertinent" }
|
|
||||||
]
|
|
||||||
}
|
|
||||||
|
|
||||||
Ta réponse :
|
Ta réponse :
|
||||||
`.trim(),
|
`.trim(),
|
||||||
en: `
|
en: `
|
||||||
You are an assistant that suggests the most appropriate labels for a note.
|
You are an assistant that suggests RELEVANT labels for a note.
|
||||||
|
|
||||||
NOTE CONTENT:
|
NOTE CONTENT:
|
||||||
${noteContent.substring(0, 1000)}
|
${noteContent.substring(0, 1000)}
|
||||||
|
|
||||||
CURRENT NOTEBOOK:
|
NOTEBOOK: ${notebookName}
|
||||||
${notebookName}
|
|
||||||
|
|
||||||
AVAILABLE LABELS IN THIS NOTEBOOK:
|
AVAILABLE LABELS:
|
||||||
${labelList}
|
${labelList}
|
||||||
|
|
||||||
TASK:
|
STRICT RULES:
|
||||||
Analyze the note content and suggest the MOST appropriate labels from the available labels above.
|
- Only suggest a label if it is DIRECTLY related to the content of THIS specific note
|
||||||
Consider:
|
- A "travel" label is relevant ONLY if the note is about travel
|
||||||
1. Label relevance to content
|
- A "project" label is relevant ONLY if the note discusses a specific project
|
||||||
2. Number of labels (maximum 3 suggestions)
|
- Do NOT suggest a label just because it exists in the notebook
|
||||||
3. Confidence (minimum threshold: 0.6)
|
- Maximum 2 suggestions
|
||||||
|
- Confidence < 0.7 = do not suggest
|
||||||
|
- If NO label is clearly relevant, return an EMPTY array
|
||||||
|
|
||||||
RULES:
|
Respond in JSON:
|
||||||
- Suggest ONLY labels that are in the available labels list
|
{"suggestions":[{"label":"name","confidence":0.85,"reasoning":"why"}]}
|
||||||
- Return maximum 3 suggestions
|
|
||||||
- Each suggestion must have confidence > 0.6
|
|
||||||
- If no label is relevant, return an empty array
|
|
||||||
|
|
||||||
RESPONSE FORMAT (JSON only):
|
|
||||||
{
|
|
||||||
"suggestions": [
|
|
||||||
{ "label": "label_name", "confidence": 0.85, "reasoning": "Why this label is relevant" }
|
|
||||||
]
|
|
||||||
}
|
|
||||||
|
|
||||||
Your response:
|
Your response:
|
||||||
`.trim(),
|
`.trim(),
|
||||||
fa: `
|
fa: `
|
||||||
شما یک دستیار هستید که مناسبترین برچسبها را برای یک یادداشت پیشنهاد میدهید.
|
تو دستیاری هستی که برچسبهای مرتبط برای یادداشت پیشنهاد میدهی.
|
||||||
|
|
||||||
محتوای یادداشت:
|
محتوای یادداشت:
|
||||||
${noteContent.substring(0, 1000)}
|
${noteContent.substring(0, 1000)}
|
||||||
|
|
||||||
دفترچه فعلی:
|
دفترچه: ${notebookName}
|
||||||
${notebookName}
|
|
||||||
|
|
||||||
برچسبهای موجود در این دفترچه:
|
برچسبهای موجود:
|
||||||
${labelList}
|
${labelList}
|
||||||
|
|
||||||
وظیفه:
|
قوانین سختگیرانه:
|
||||||
محتوای یادداشت را تحلیل کنید و مناسبترین برچسبها را از لیست برچسبهای موجود در بالا پیشنهاد دهید.
|
- فقط برچسبی را پیشنهاد بده که مستقیماً با محتوای همین یادداشت مرتبط باشد
|
||||||
در نظر بگیرید:
|
- برچسب "سفر" فقط وقتی مرتبط است که یادداشت درباره سفر باشد
|
||||||
1. ارتباط برچسب با محتوا
|
- حداکثر ۲ پیشنهاد
|
||||||
2. تعداد برچسبها (حداکثر ۳ پیشنهاد)
|
- اطمینان < 0.7 = پیشنهاد نده
|
||||||
3. اطمینان (حداقل آستانه: 0.6)
|
- اگر هیچ برچسبی مرتبط نیست، آرایه خالی برگردان
|
||||||
|
|
||||||
قوانین:
|
پاسخ JSON:
|
||||||
- فقط برچسبهایی را پیشنهاد دهید که در لیست برچسبهای موجود هستند
|
{"suggestions":[{"label":"نام","confidence":0.85,"reasoning":"چرا"}]}
|
||||||
- حداکثر ۳ پیشنهاد برگردانید
|
|
||||||
- هر پیشنهاد باید دارای اطمینان > 0.6 باشد
|
|
||||||
- اگر هیچ برچسبی مرتبط نیست، یک اینرایه خالی برگردانید
|
|
||||||
|
|
||||||
فرمت پاسخ (فقط JSON):
|
|
||||||
{
|
|
||||||
"suggestions": [
|
|
||||||
{ "label": "نام_برچسب", "confidence": 0.85, "reasoning": "چرا این برچسب مرتبط است" }
|
|
||||||
]
|
|
||||||
}
|
|
||||||
|
|
||||||
پاسخ شما:
|
پاسخ شما:
|
||||||
`.trim(),
|
`.trim(),
|
||||||
es: `
|
es: `
|
||||||
Eres un asistente que sugiere las etiquetas más apropiadas para una nota.
|
Eres un asistente que sugiere etiquetas RELEVANTES para una nota.
|
||||||
|
|
||||||
CONTENIDO DE LA NOTA:
|
CONTENIDO DE LA NOTA:
|
||||||
${noteContent.substring(0, 1000)}
|
${noteContent.substring(0, 1000)}
|
||||||
|
|
||||||
CUADERNO ACTUAL:
|
CUADERNO: ${notebookName}
|
||||||
${notebookName}
|
|
||||||
|
|
||||||
ETIQUETAS DISPONIBLES EN ESTE CUADERNO:
|
ETIQUETAS DISPONIBLES:
|
||||||
${labelList}
|
${labelList}
|
||||||
|
|
||||||
TAREA:
|
REGLAS ESTRICTAS:
|
||||||
Analiza el contenido de la nota y sugiere las etiquetas MÁS apropiadas de las etiquetas disponibles arriba.
|
- Solo sugiere una etiqueta si está DIRECTAMENTE relacionada con el contenido de ESTA nota
|
||||||
Considera:
|
- Máximo 2 sugerencias
|
||||||
1. Relevancia de la etiqueta para el contenido
|
- Confianza < 0.7 = no sugerir
|
||||||
2. Número de etiquetas (máximo 3 sugerencias)
|
- Si NINGUNA etiqueta es relevante, devuelve un array VACÍO
|
||||||
3. Confianza (umbral mínimo: 0.6)
|
|
||||||
|
|
||||||
REGLAS:
|
Responde en JSON:
|
||||||
- Sugiere SOLO etiquetas que estén en la lista de etiquetas disponibles
|
{"suggestions":[{"label":"nombre","confidence":0.85,"reasoning":"por qué"}]}
|
||||||
- Devuelve máximo 3 sugerencias
|
|
||||||
- Cada sugerencia debe tener confianza > 0.6
|
|
||||||
- Si ninguna etiqueta es relevante, devuelve un array vacío
|
|
||||||
|
|
||||||
FORMATO DE RESPUESTA (solo JSON):
|
|
||||||
{
|
|
||||||
"suggestions": [
|
|
||||||
{ "label": "nombre_etiqueta", "confidence": 0.85, "reasoning": "Por qué esta etiqueta es relevante" }
|
|
||||||
]
|
|
||||||
}
|
|
||||||
|
|
||||||
Tu respuesta:
|
Tu respuesta:
|
||||||
`.trim(),
|
`.trim(),
|
||||||
de: `
|
de: `
|
||||||
Du bist ein Assistent, der die passendsten Labels für eine Notiz vorschlägt.
|
Du bist ein Assistent, der RELEVANTE Labels für eine Notiz vorschlägt.
|
||||||
|
|
||||||
NOTIZINHALT:
|
NOTIZINHALT:
|
||||||
${noteContent.substring(0, 1000)}
|
${noteContent.substring(0, 1000)}
|
||||||
|
|
||||||
AKTUELLES NOTIZBUCH:
|
NOTIZBUCH: ${notebookName}
|
||||||
${notebookName}
|
|
||||||
|
|
||||||
VERFÜGBARE LABELS IN DIESEM NOTIZBUCH:
|
VERFÜGBARE LABELS:
|
||||||
${labelList}
|
${labelList}
|
||||||
|
|
||||||
AUFGABE:
|
STRIKTE REGELN:
|
||||||
Analysiere den Notizinhalt und schlage die AM BESTEN geeigneten Labels aus den oben verfügbaren Labels vor.
|
- Schlage ein Label nur vor, wenn es DIREKT mit dem Inhalt DIESER Notiz zusammenhängt
|
||||||
Berücksichtige:
|
- Maximal 2 Vorschläge
|
||||||
1. Relevanz des Labels für den Inhalt
|
- Konfidenz < 0.7 = nicht vorschlagen
|
||||||
2. Anzahl der Labels (maximal 3 Vorschläge)
|
- Wenn KEIN Label relevant ist, gib ein LEERES Array zurück
|
||||||
3. Konfidenz (Mindestschwellenwert: 0.6)
|
|
||||||
|
|
||||||
REGELN:
|
Antworte in JSON:
|
||||||
- Schlage NUR Labels vor, die in der Liste der verfügbaren Labels sind
|
{"suggestions":[{"label":"name","confidence":0.85,"reasoning":"warum"}]}
|
||||||
- Gib maximal 3 Vorschläge zurück
|
|
||||||
- Jeder Vorschlag muss eine Konfidenz > 0.6 haben
|
|
||||||
- Wenn kein Label relevant ist, gib ein leeres Array zurück
|
|
||||||
|
|
||||||
ANTWORTFORMAT (nur JSON):
|
|
||||||
{
|
|
||||||
"suggestions": [
|
|
||||||
{ "label": "label_name", "confidence": 0.85, "reasoning": "Warum dieses Label relevant ist" }
|
|
||||||
]
|
|
||||||
}
|
|
||||||
|
|
||||||
Deine Antwort:
|
Deine Antwort:
|
||||||
`.trim()
|
`.trim()
|
||||||
|
|||||||
Reference in New Issue
Block a user