From d314a964786572a58b974cb39b67b25799f15f8d Mon Sep 17 00:00:00 2001 From: root Date: Mon, 30 Jun 2025 12:59:23 +0200 Subject: [PATCH] =?UTF-8?q?=F0=9F=A7=A0=20Improve=20answer=20analysis=20to?= =?UTF-8?q?=20handle=20mixed=20responses?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - Enhanced detection logic to distinguish between pure 'I don't know' and thoughtful hypotheses - When child says 'I don't know but maybe it's temperature', now treats as substantial thinking, not ignorance - Added detection for substantive content: hypotheses, questions, specific topics (temperature, weather) - Updated server to provide Socratic follow-up questions for thoughtful answers instead of just validation - Improved fallback responses to be contextually aware of specific topics mentioned - Better handling of answers that show reasoning even when prefixed with 'I don't know' Now 'das weis ich nicht. hat es etwas mit der temperatur zu tun?' gets proper Socratic questioning about temperature instead of generic encouragement. --- html/kidsai/script-new.js | 58 ++++++++++++++++++++++++++++----------- html/kidsai/server.js | 54 +++++++++++++++++++++--------------- 2 files changed, 74 insertions(+), 38 deletions(-) diff --git a/html/kidsai/script-new.js b/html/kidsai/script-new.js index 8c4bb76..0fa31e5 100644 --- a/html/kidsai/script-new.js +++ b/html/kidsai/script-new.js @@ -418,16 +418,29 @@ class KidsAIExplorer { // Analyze the answer to determine the appropriate response type const answerLower = answer.toLowerCase().trim(); const isNegative = answerLower === 'no' || answerLower === 'nein' || answerLower === 'nope' || answerLower === 'nei'; - const isDontKnow = answerLower.includes("don't know") || answerLower.includes('weiß nicht') || answerLower.includes('keine ahnung') || - answerLower.includes('ich weiß es nicht') || answerLower.includes('weis es nicht') || answerLower.includes('weiss es nicht') || - answerLower.includes('i dont know') || answerLower.includes("i don't know") || - answerLower === 'warum' || answerLower === 'why' || answerLower === 'warum?' || answerLower === 'why?' || - (answer.trim().length < 5 && (answerLower.includes('weiß') || answerLower.includes('know'))); + + // Check for pure "don't know" responses (without additional thinking) + const hasDontKnowPhrase = answerLower.includes("don't know") || answerLower.includes('weiß nicht') || answerLower.includes('keine ahnung') || + answerLower.includes('ich weiß es nicht') || answerLower.includes('weis es nicht') || answerLower.includes('weiss es nicht') || + answerLower.includes('i dont know') || answerLower.includes("i don't know"); + + const isOnlyWhyQuestion = answerLower === 'warum' || answerLower === 'why' || answerLower === 'warum?' || answerLower === 'why?'; + + // Check if it's a substantial answer (has thinking beyond just "don't know") + const hasSubstantialThinking = answer.length > 15 && ( + answerLower.includes('vielleicht') || answerLower.includes('maybe') || answerLower.includes('könnte') || answerLower.includes('could') || + answerLower.includes('hat es') || answerLower.includes('does it') || answerLower.includes('is it') || answerLower.includes('liegt es') || + answerLower.includes('temperatur') || answerLower.includes('temperature') || answerLower.includes('wetter') || answerLower.includes('weather') || + answer.includes('?') // Contains a question showing thinking + ); + + // Pure "don't know" without additional thinking + const isPureDontKnow = (hasDontKnowPhrase || isOnlyWhyQuestion || answer.trim().length < 5) && !hasSubstantialThinking; let response; - if (isNegative || isDontKnow) { - // For "no" or "don't know" answers, get Socratic guidance questions + if (isNegative || isPureDontKnow) { + // For pure "no" or "don't know" answers without thinking, get Socratic guidance questions console.log('📤 Sending guidance request to /api/ask for Socratic questioning'); const guidancePrompt = this.currentLanguage === 'de' @@ -561,16 +574,29 @@ class KidsAIExplorer { // Analyze the answer to determine the appropriate response type const answerLower = answer.toLowerCase().trim(); const isNegative = answerLower === 'no' || answerLower === 'nein' || answerLower === 'nope' || answerLower === 'nei'; - const isDontKnow = answerLower.includes("don't know") || answerLower.includes('weiß nicht') || answerLower.includes('keine ahnung') || - answerLower.includes('ich weiß es nicht') || answerLower.includes('weis es nicht') || answerLower.includes('weiss es nicht') || - answerLower.includes('i dont know') || answerLower.includes("i don't know") || - answerLower === 'warum' || answerLower === 'why' || answerLower === 'warum?' || answerLower === 'why?' || - (answer.trim().length < 5 && (answerLower.includes('weiß') || answerLower.includes('know'))); + + // Check for pure "don't know" responses (without additional thinking) + const hasDontKnowPhrase = answerLower.includes("don't know") || answerLower.includes('weiß nicht') || answerLower.includes('keine ahnung') || + answerLower.includes('ich weiß es nicht') || answerLower.includes('weis es nicht') || answerLower.includes('weiss es nicht') || + answerLower.includes('i dont know') || answerLower.includes("i don't know"); + + const isOnlyWhyQuestion = answerLower === 'warum' || answerLower === 'why' || answerLower === 'warum?' || answerLower === 'why?'; + + // Check if it's a substantial answer (has thinking beyond just "don't know") + const hasSubstantialThinking = answer.length > 15 && ( + answerLower.includes('vielleicht') || answerLower.includes('maybe') || answerLower.includes('könnte') || answerLower.includes('could') || + answerLower.includes('hat es') || answerLower.includes('does it') || answerLower.includes('is it') || answerLower.includes('liegt es') || + answerLower.includes('temperatur') || answerLower.includes('temperature') || answerLower.includes('wetter') || answerLower.includes('weather') || + answer.includes('?') // Contains a question showing thinking + ); + + // Pure "don't know" without additional thinking + const isPureDontKnow = (hasDontKnowPhrase || isOnlyWhyQuestion || answer.trim().length < 5) && !hasSubstantialThinking; let response; - if (isNegative || isDontKnow) { - // For "no" or "don't know" answers, get Socratic guidance questions + if (isNegative || isPureDontKnow) { + // For pure "no" or "don't know" answers without thinking, get Socratic guidance questions console.log('📤 Sending guidance request to /api/ask for Socratic questioning'); const guidancePrompt = this.currentLanguage === 'de' @@ -657,8 +683,8 @@ class KidsAIExplorer { // Determine next action based on response type setTimeout(() => { - if (data.guidance && data.guidance.steps && (isNegative || isDontKnow)) { - // For "don't know" responses with Socratic guidance, continue to next question immediately + if (data.guidance && data.guidance.steps && (isNegative || isPureDontKnow)) { + // For pure "don't know" responses with Socratic guidance, continue to next question immediately this.continueToNextQuestion(); } else { // For substantial answers, show choice buttons diff --git a/html/kidsai/server.js b/html/kidsai/server.js index 9546e16..1dc8edc 100755 --- a/html/kidsai/server.js +++ b/html/kidsai/server.js @@ -561,36 +561,38 @@ app.post('/api/respond-to-answer', async (req, res) => { const isGerman = language === 'de'; const contextualPrompt = isGerman ? - `Du bist ein unterstützender Lernbegleiter für Kinder. Ein Kind hat gerade auf eine Frage geantwortet. + `Du bist ein Socratic Lernbegleiter für Kinder. Ein Kind hat gerade auf eine Frage geantwortet. FRAGE: "${question}" ANTWORT DES KINDES: "${answer}" -Deine Aufgabe ist es, eine rein ermutigende Antwort zu geben, die: -1. Das Kind für seinen Mut zu antworten lobt -2. Die spezifische Antwort wertschätzt -3. Das Nachdenken des Kindes würdigt +Das Kind zeigt eigenes Denken. Deine Aufgabe ist es, eine Socratic Folgefrage zu stellen, die: +1. Auf der spezifischen Antwort des Kindes aufbaut +2. Das Kind dazu ermutigt, tiefer zu denken +3. Eine konkrete Folgefrage stellt, die zur Entdeckung führt WICHTIG: -- Gib KEINE Erklärungen oder Fakten -- Stelle KEINE Folgefragen -- Verrate NICHT die richtige Antwort -- Antworte nur mit Ermutigung und Anerkennung in 1-2 kurzen Sätzen` : - `You are a supportive learning companion for children. A child just answered a question. +- Stelle EINE durchdachte Folgefrage +- Gib KEINE Erklärungen oder Antworten +- Baue direkt auf der Antwort des Kindes auf +- Verwende "Was denkst du..." oder "Hast du schon mal bemerkt..." +- Nur 1-2 Sätze` : + `You are a Socratic learning companion for children. A child just answered a question. QUESTION: "${question}" CHILD'S ANSWER: "${answer}" -Your task is to provide a purely encouraging response that: -1. Praises the child for having the courage to answer -2. Appreciates their specific answer -3. Acknowledges the child's thinking +The child is showing their own thinking. Your task is to ask a Socratic follow-up question that: +1. Builds directly on the child's specific answer +2. Encourages the child to think deeper +3. Asks one concrete follow-up question that leads to discovery IMPORTANT: -- Give NO explanations or facts -- Ask NO follow-up questions -- Do NOT reveal the correct answer -- Only respond with encouragement and recognition in 1-2 short sentences`; +- Ask ONE thoughtful follow-up question +- Give NO explanations or answers +- Build directly on the child's answer +- Use "What do you think..." or "Have you ever noticed..." +- Only 1-2 sentences`; // Try OpenAI first if (process.env.OPENAI_API_KEY) { @@ -631,14 +633,22 @@ IMPORTANT: fallbackResponse = isGerman ? "🌟 Perfekt! Lass uns das gemeinsam herausfinden." : "🌟 Perfect! Let's figure this out together."; + } else if (answerLower.includes('temperatur') || answerLower.includes('temperature')) { + fallbackResponse = isGerman ? + `🤔 Interessante Überlegung zur Temperatur! Was denkst du, wie Temperatur dabei eine Rolle spielen könnte?` : + `🤔 Interesting thinking about temperature! What do you think - how might temperature play a role in this?`; + } else if (answerLower.includes('wetter') || answerLower.includes('weather') || answerLower.includes('regen') || answerLower.includes('rain')) { + fallbackResponse = isGerman ? + `�️ Gute Beobachtung zum Wetter! Hast du schon mal genau beobachtet, was nach einem Regenschauer passiert?` : + `🌦️ Good observation about weather! Have you ever closely watched what happens after a rain shower?`; } else if (answer.length < 15) { fallbackResponse = isGerman ? - `💡 Guter Gedanke! Du bist auf dem richtigen Weg.` : - `💡 Good thinking! You're on the right track.`; + `💡 Guter Gedanke! Was denkst du, könnte als nächstes passieren?` : + `💡 Good thinking! What do you think might happen next?`; } else { fallbackResponse = isGerman ? - `🎯 Ausgezeichnet! Du denkst wirklich wissenschaftlich.` : - `🎯 Excellent! You're thinking like a real scientist.`; + `🎯 Das ist eine durchdachte Antwort! Was würdest du beobachten, um das herauszufinden?` : + `🎯 That's thoughtful reasoning! What would you observe to find that out?`; } res.json({