Files
maternal-app/docs/maternal-app-ai-context.md
2025-10-01 19:01:52 +00:00

14 KiB

AI Context & Prompting Templates - Maternal Organization App

LangChain Configuration

Core Setup

// services/ai/langchainConfig.ts
import { ChatOpenAI } from 'langchain/chat_models/openai';
import { ConversationSummaryMemory } from 'langchain/memory';
import { PromptTemplate } from 'langchain/prompts';
import { LLMChain } from 'langchain/chains';

export const initializeLangChain = () => {
  const model = new ChatOpenAI({
    modelName: 'gpt-4-turbo-preview',
    temperature: 0.7,
    maxTokens: 1000,
    openAIApiKey: process.env.OPENAI_API_KEY,
    callbacks: [
      {
        handleLLMStart: async (llm, prompts) => {
          logger.info('LLM request started', { promptLength: prompts[0].length });
        },
        handleLLMEnd: async (output) => {
          logger.info('LLM request completed', { tokensUsed: output.llmOutput?.tokenUsage });
        },
      },
    ],
  });

  const memory = new ConversationSummaryMemory({
    memoryKey: 'chat_history',
    llm: model,
    maxTokenLimit: 2000,
  });

  return { model, memory };
};

Context Window Management

class ContextManager {
  private maxContextTokens = 4000;
  private priorityWeights = {
    currentQuery: 1.0,
    recentActivities: 0.8,
    childProfile: 0.7,
    historicalPatterns: 0.6,
    generalGuidelines: 0.4,
  };

  async buildContext(
    query: string,
    childId: string,
    userId: string
  ): Promise<AIContext> {
    const contexts = await Promise.all([
      this.getChildProfile(childId),
      this.getRecentActivities(childId, 48), // Last 48 hours
      this.getPatterns(childId),
      this.getParentPreferences(userId),
      this.getPreviousConversation(userId, childId),
    ]);

    return this.prioritizeContext(contexts, query);
  }

  private prioritizeContext(
    contexts: ContextPart[],
    query: string
  ): AIContext {
    // Token counting
    let currentTokens = this.countTokens(query);
    const prioritizedContexts: ContextPart[] = [];

    // Sort by relevance and priority
    const sorted = contexts
      .map(ctx => ({
        ...ctx,
        score: this.calculateRelevance(ctx, query) * this.priorityWeights[ctx.type],
      }))
      .sort((a, b) => b.score - a.score);

    // Add contexts until token limit
    for (const context of sorted) {
      const tokens = this.countTokens(context.content);
      if (currentTokens + tokens <= this.maxContextTokens) {
        prioritizedContexts.push(context);
        currentTokens += tokens;
      }
    }

    return {
      query,
      contexts: prioritizedContexts,
      totalTokens: currentTokens,
    };
  }
}

System Prompts

Base System Prompt

const BASE_SYSTEM_PROMPT = `You are a knowledgeable, empathetic AI assistant helping parents care for their children aged 0-6 years. 

Core Guidelines:
1. SAFETY FIRST: Never provide medical diagnoses. Always recommend consulting healthcare providers for medical concerns.
2. EVIDENCE-BASED: Provide advice based on pediatric best practices and research.
3. PARENT-SUPPORTIVE: Be encouraging and non-judgmental. Every family is different.
4. PRACTICAL: Give actionable, realistic suggestions that work for busy parents.
5. CULTURALLY AWARE: Respect diverse parenting approaches and cultural practices.

You have access to:
- The child's recent activity data (feeding, sleep, diapers)
- Developmental milestones for their age
- Pattern analysis from their historical data
- Family preferences and routines

Response Guidelines:
- Keep responses concise (under 150 words unless asked for detail)
- Use simple, clear language (avoid medical jargon)
- Provide specific, actionable suggestions
- Acknowledge parent concerns with empathy
- Include relevant safety warnings when appropriate`;

Child-Specific Context Template

const CHILD_CONTEXT_TEMPLATE = `Child Profile:
- Name: {childName}
- Age: {ageInMonths} months ({ageInYears} years)
- Developmental Stage: {developmentalStage}
- Known Conditions: {medicalConditions}
- Allergies: {allergies}

Recent Patterns (last 7 days):
- Average sleep: {avgSleepHours} hours/day
- Feeding frequency: Every {feedingInterval} hours
- Growth trajectory: {growthPercentile} percentile

Current Concerns:
{parentConcerns}

Recent Activities (last 24 hours):
{recentActivities}`;

Prompt Templates by Scenario

const SLEEP_PROMPT = PromptTemplate.fromTemplate(`
${BASE_SYSTEM_PROMPT}

Context:
{childContext}

Sleep-Specific Data:
- Recent bedtimes: {recentBedtimes}
- Wake windows today: {wakeWindows}
- Nap schedule: {napSchedule}
- Sleep regression risk: {regressionRisk}

Parent Question: {question}

Provide practical sleep advice considering:
1. Age-appropriate wake windows
2. Recent sleep patterns
3. Common sleep regressions at this age
4. Environmental factors

Response:
`);

Feeding Queries

const FEEDING_PROMPT = PromptTemplate.fromTemplate(`
${BASE_SYSTEM_PROMPT}

Context:
{childContext}

Feeding-Specific Data:
- Feeding type: {feedingType}
- Recent intake: {recentIntake}
- Growth trend: {growthTrend}
- Solid foods status: {solidsStatus}

Parent Question: {question}

Provide feeding guidance considering:
1. Age-appropriate feeding amounts
2. Growth patterns
3. Feeding milestones
4. Any mentioned concerns

Response:
`);

Developmental Milestones

const MILESTONE_PROMPT = PromptTemplate.fromTemplate(`
${BASE_SYSTEM_PROMPT}

Context:
{childContext}

Developmental Data:
- Expected milestones: {expectedMilestones}
- Achieved milestones: {achievedMilestones}
- Areas of focus: {developmentalFocus}

Parent Question: {question}

Provide developmental guidance:
1. What's typical for this age
2. Activities to encourage development
3. When to consult professionals
4. Celebrate achievements while avoiding comparison

Response:
`);

Behavioral Concerns

const BEHAVIOR_PROMPT = PromptTemplate.fromTemplate(`
${BASE_SYSTEM_PROMPT}

Context:
{childContext}

Behavioral Patterns:
- Recent behaviors: {recentBehaviors}
- Triggers identified: {triggers}
- Sleep/hunger status: {physiologicalState}

Parent Question: {question}

Provide behavioral guidance:
1. Age-appropriate expectations
2. Positive parenting strategies
3. Understanding underlying needs
4. Consistency and routine importance

Response:
`);

Safety Boundaries

Medical Disclaimer Triggers

const MEDICAL_TRIGGERS = [
  'diagnose', 'disease', 'syndrome', 'disorder',
  'medication', 'dosage', 'prescription',
  'emergency', 'urgent', 'bleeding', 'unconscious',
  'seizure', 'fever over 104', 'difficulty breathing',
];

const MEDICAL_DISCLAIMER = `I understand you're concerned about {concern}. This seems like a medical issue that requires professional evaluation. Please contact your pediatrician or healthcare provider immediately. If this is an emergency, call your local emergency number.

For reference, here are signs requiring immediate medical attention:
- Difficulty breathing or bluish skin
- Unresponsiveness or difficulty waking
- High fever (over 104°F/40°C)
- Severe dehydration
- Head injury with vomiting or confusion`;

Mental Health Support

const MENTAL_HEALTH_PROMPT = `I hear that you're going through a difficult time. Your feelings are valid and important. 

Here are some immediate resources:
- Postpartum Support International: 1-800-4-PPD-MOMS
- Crisis Text Line: Text HOME to 741741
- Local support groups: {localResources}

Please consider reaching out to:
- Your healthcare provider
- A mental health professional
- Trusted family or friends

Remember: Seeking help is a sign of strength, not weakness. Your wellbeing matters for both you and your baby.`;

Response Formatting

Structured Response Template

interface AIResponse {
  mainAnswer: string;
  keyPoints?: string[];
  actionItems?: string[];
  safetyNotes?: string[];
  relatedResources?: Resource[];
  confidenceLevel: 'high' | 'medium' | 'low';
  shouldEscalate: boolean;
}

const formatResponse = (raw: string, metadata: ResponseMetadata): AIResponse => {
  return {
    mainAnswer: extractMainAnswer(raw),
    keyPoints: extractBulletPoints(raw),
    actionItems: extractActionItems(raw),
    safetyNotes: extractSafetyWarnings(raw),
    relatedResources: findRelevantResources(metadata),
    confidenceLevel: calculateConfidence(metadata),
    shouldEscalate: checkEscalationTriggers(raw),
  };
};

Localized Response Generation

const LOCALIZED_PROMPTS = {
  'en-US': {
    greeting: "I understand your concern about {topic}.",
    transition: "Based on {childName}'s patterns,",
    closing: "Remember, every baby is different.",
  },
  'es-ES': {
    greeting: "Entiendo tu preocupación sobre {topic}.",
    transition: "Basándome en los patrones de {childName},",
    closing: "Recuerda, cada bebé es diferente.",
  },
  'fr-FR': {
    greeting: "Je comprends votre inquiétude concernant {topic}.",
    transition: "D'après les habitudes de {childName},",
    closing: "Rappelez-vous, chaque bébé est unique.",
  },
};

Personalization Engine

Learning from Feedback

class PersonalizationEngine {
  async updateResponsePreferences(
    userId: string,
    feedback: UserFeedback
  ) {
    const preferences = await this.getUserPreferences(userId);
    
    // Update preference weights
    if (feedback.helpful) {
      preferences.preferredResponseLength = feedback.responseLength;
      preferences.preferredDetailLevel = feedback.detailLevel;
      preferences.preferredTone = feedback.tone;
    }
    
    // Learn from negative feedback
    if (!feedback.helpful && feedback.reason) {
      this.adjustPromptTemplate(preferences, feedback.reason);
    }
    
    await this.saveUserPreferences(userId, preferences);
  }

  private adjustPromptTemplate(
    preferences: UserPreferences,
    reason: string
  ): PromptTemplate {
    const adjustments = {
      'too_technical': { jargonLevel: 'minimal', explanationStyle: 'simple' },
      'too_general': { specificityLevel: 'high', includeExamples: true },
      'too_long': { maxLength: 100, bulletPoints: true },
      'not_actionable': { focusOnActions: true, includeSteps: true },
    };
    
    return this.applyAdjustments(preferences, adjustments[reason]);
  }
}

Chain of Thought for Complex Queries

Multi-Step Reasoning

const COMPLEX_REASONING_PROMPT = `Let me analyze this step-by-step:

Step 1: Understanding the Situation
{situationAnalysis}

Step 2: Identifying Patterns
Looking at {childName}'s recent data:
{patternAnalysis}

Step 3: Considering Age-Appropriate Norms
For a {ageInMonths}-month-old:
{developmentalNorms}

Step 4: Practical Recommendations
Based on the above:
{recommendations}

Step 5: What to Monitor
Keep track of:
{monitoringPoints}`;

Conversation Memory Management

Memory Summarization

class ConversationMemory {
  private maxConversationLength = 10;
  
  async summarizeConversation(
    messages: Message[],
    childId: string
  ): Promise<string> {
    if (messages.length <= 3) {
      return messages.map(m => m.content).join('\n');
    }
    
    const summary = await this.llm.summarize({
      messages,
      focusPoints: [
        'Main concerns discussed',
        'Advice given',
        'Action items suggested',
        'Follow-up needed',
      ],
    });
    
    return summary;
  }
  
  async getRelevantHistory(
    userId: string,
    childId: string,
    currentQuery: string
  ): Promise<string> {
    const history = await this.fetchHistory(userId, childId);
    
    // Semantic search for relevant past conversations
    const relevant = await this.semanticSearch(history, currentQuery);
    
    return this.formatHistory(relevant);
  }
}

Prompt Injection Protection

Security Filters

const INJECTION_PATTERNS = [
  /ignore previous instructions/i,
  /system:/i,
  /admin mode/i,
  /bypass safety/i,
  /pretend you are/i,
];

const sanitizeUserInput = (input: string): string => {
  // Check for injection attempts
  for (const pattern of INJECTION_PATTERNS) {
    if (pattern.test(input)) {
      logger.warn('Potential prompt injection detected', { input });
      return 'Please ask a question about childcare.';
    }
  }
  
  // Escape special characters
  return input
    .replace(/[<>]/g, '')
    .substring(0, 500); // Limit length
};

Testing Prompt Effectiveness

Prompt Evaluation Metrics

interface PromptMetrics {
  relevance: number;      // 0-1: Response answers the question
  safety: number;         // 0-1: Appropriate medical disclaimers
  actionability: number;  // 0-1: Practical suggestions provided
  empathy: number;        // 0-1: Supportive tone
  accuracy: number;       // 0-1: Factually correct
}

const evaluatePromptResponse = async (
  prompt: string,
  response: string,
  expectedQualities: PromptMetrics
): Promise<EvaluationResult> => {
  const evaluation = await this.evaluatorLLM.evaluate({
    prompt,
    response,
    criteria: expectedQualities,
  });
  
  return {
    passed: evaluation.overall > 0.8,
    metrics: evaluation,
    suggestions: evaluation.improvements,
  };
};

Test Cases

const promptTestCases = [
  {
    scenario: 'Sleep regression concern',
    input: 'My 4-month-old suddenly won\'t sleep',
    expectedResponse: {
      containsMention: ['4-month sleep regression', 'normal', 'temporary'],
      includesActions: ['consistent bedtime', 'wake windows'],
      avoidsMedical: true,
    },
  },
  {
    scenario: 'Feeding amount worry',
    input: 'Is 4oz enough for my 2-month-old?',
    expectedResponse: {
      containsMention: ['varies by baby', 'weight gain', 'wet diapers'],
      includesActions: ['track intake', 'consult pediatrician'],
      providesRanges: true,
    },
  },
];