Emotional Context Tracking

Category: User Experience

Problem

Users interact with AI agents during moments of frustration, excitement, confusion, and urgency. An agent that responds with the same neutral tone regardless of emotional context feels robotic and uncaring. Without memory of emotional states, the agent cannot adapt its communication style or recognize patterns like recurring frustration with a specific feature.

Architecture

This pattern stores detected sentiment alongside interaction context in Dakera. Each memory includes emotional metadata (sentiment label, intensity, trigger). At recall time, the agent retrieves recent emotional history to calibrate its tone and identify users who may need escalation to human support.

Flow

Implementation

from dakera import Dakera
from datetime import datetime

client = Dakera(base_url="http://localhost:3300", api_key="dk-...")

def store_emotional_context(user_id: str, message: str, sentiment: str, intensity: float):
    """Store a user interaction with emotional metadata."""
    client.memory.store(
        content=f"User said: {message}",
        namespace=f"user-{user_id}-emotions",
        metadata={
            "sentiment": sentiment,        # positive, negative, neutral, frustrated
            "intensity": intensity,        # 0.0 to 1.0
            "trigger": message[:100],
            "timestamp": datetime.utcnow().isoformat(),
            "importance": 0.7 if intensity > 0.6 else 0.4
        }
    )

def get_emotional_context(user_id: str, current_message: str) -> dict:
    """Recall recent emotional history to inform response tone."""
    results = client.memory.recall(
        query=current_message,
        namespace=f"user-{user_id}-emotions",
        top_k=10
    )

    if not results["results"]:
        return {"tone": "neutral", "escalate": False}

    # Analyze recent emotional trajectory
    sentiments = [r["metadata"]["sentiment"] for r in results["results"] if "metadata" in r]
    intensities = [r["metadata"]["intensity"] for r in results["results"] if "metadata" in r]

    negative_count = sentiments.count("frustrated") + sentiments.count("negative")
    avg_intensity = sum(intensities) / len(intensities) if intensities else 0

    # Determine appropriate tone
    if negative_count >= 3 and avg_intensity > 0.7:
        return {"tone": "empathetic_urgent", "escalate": True}
    elif negative_count >= 2:
        return {"tone": "empathetic", "escalate": False}
    elif sentiments.count("positive") > negative_count:
        return {"tone": "enthusiastic", "escalate": False}
    else:
        return {"tone": "neutral", "escalate": False}

# Usage: user is frustrated with repeated errors
store_emotional_context("bob", "This is broken AGAIN, I've reported this 3 times!", "frustrated", 0.9)

# Before next response, check emotional context
context = get_emotional_context("bob", "Still having the same issue")
# Returns: {"tone": "empathetic_urgent", "escalate": True}
# Agent adjusts: acknowledges frustration, escalates to human support

When to Use This Pattern

Key Considerations