🧠 Improve answer analysis to handle mixed responses

- 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.
This commit is contained in:
root
2025-06-30 12:59:23 +02:00
parent 589a45e94e
commit d314a96478
2 changed files with 74 additions and 38 deletions

View File

@@ -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

View File

@@ -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 ?
`<EFBFBD> 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({