Innovation 1: Multi-Dimensional Character Profiling

Hassan Uriostegui (EB1A Computer Scientist) & Lic. Fernanda Beltran

← Back to Main Paper | View Production Results

Overview

🎯 Core Innovation

Instead of using a single prompt to describe a character, we extract comprehensive psychological profiles through five specialized prompts executed in parallel. Each prompt targets a different cognitive dimension, creating character depth impossible to achieve through single-shot prompting.

The Problem with Single-Shot Prompting

Traditional character creation uses a single prompt like: "Create a character profile for a 28-year-old marketing professional who loves travel."

Limitations:

The Multi-Dimensional Solution

Our approach uses 5 specialized prompts, each optimized for extracting specific aspects:

Prompt Purpose Extracts
Cognitive Profiling Psychological patterns MBTI, Enneagram, communication style, emotional intelligence
Backstory Extraction Life narrative Occupation, appearance, experiences, pains, joys
Persona Synthesis Demographics Age, gender, cultural background
Vocabulary Mining Linguistic signatures Catchphrases, emojis, expressions, slang
Extended Profile Deeper psychology Self-awareness, worldview, characteristic expressions

Why It Works

1. Specialized Prompts Optimize for Specific Dimensions

Each prompt is crafted to excel at extracting one aspect. The cognitive profiling prompt uses psychological terminology that guides the LLM to think in terms of personality frameworks. The vocabulary prompt focuses purely on linguistic patterns.

2. Parallel Execution = Richer Profiles

Running all 5 prompts simultaneously with Temperature: 0.0 ensures deterministic, high-quality extraction from multiple perspectives. This creates a comprehensive profile that would be impossible from a single prompt.

3. Composite Profiles Prevent Character Drift

By combining multiple dimensions, the final character has "internal consistency checks." If the cognitive profile says ENFP (extroverted), but the backstory describes solitary activities, this creates natural tension that makes the character more realistic.

4. Production Validation

Deployed across 20,000 conversations generating 200,000 messages. For detailed production results and user studies, visit wakenai.com/mst-prerelease.

Implementation

System Architecture

Input Text (WhatsApp, Social Media, etc.) │ ▼ ┌────────────────────────────────────┐ │ Parallel Execution (~8 seconds) │ ├────────────────────────────────────┤ │ Promise.all([ │ │ cognitive_profiling(text), │ │ backstory_extraction(text), │ │ persona_synthesis(text), │ │ vocabulary_mining(text), │ │ extended_profile(text) │ │ ]) │ └────────────┬───────────────────────┘ │ ▼ ┌────────────────────────────────────┐ │ Consolidate Profiles │ │ Create JSON Structure │ └────────────┬───────────────────────┘ │ ▼ ┌────────────────────────────────────┐ │ Synthesize Role String │ │ (Compressed Character DNA) │ └────────────┬───────────────────────┘ │ ▼ Character Entity (Cached 85% of time)

Python Implementation (Production Code)

Parallel Prompt Execution
import asyncio
from typing import Dict, Any

async def extract_character_dna(source_text: str) -> Dict[str, Any]:
    """
    Extract multi-dimensional character profile through parallel prompt execution.
    
    Args:
        source_text: Input text (WhatsApp chat, social media, description)
        
    Returns:
        Consolidated character profile dictionary
    """
    
    # Execute all 5 prompts in parallel (Temperature: 0.0 for determinism)
    results = await asyncio.gather(
        call_llm(COGNITIVE_PROFILING_PROMPT.format(text=source_text), temp=0.0),
        call_llm(BACKSTORY_EXTRACTION_PROMPT.format(text=source_text), temp=0.0),
        call_llm(PERSONA_SYNTHESIS_PROMPT.format(text=source_text), temp=0.0),
        call_llm(VOCABULARY_MINING_PROMPT.format(text=source_text), temp=0.0),
        call_llm(EXTENDED_PROFILE_PROMPT.format(text=source_text), temp=0.0)
    )
    
    # Consolidate results
    profile = {
        "cognitive": parse_cognitive_profile(results[0]),
        "backstory": results[1].strip(),
        "persona": results[2].strip(),
        "vocabulary": results[3].strip(),
        "extended": parse_extended_profile(results[4])
    }
    
    return profile


async def call_llm(prompt: str, temp: float = 0.0) -> str:
    """
    Call LLM API with given prompt.
    
    Args:
        prompt: Formatted prompt string
        temp: Temperature setting (0.0 for deterministic)
        
    Returns:
        LLM response text
    """
    # Using GPT-4 for profiling quality
    response = await openai.ChatCompletion.create(
        model="gpt-4-turbo",
        messages=[{"role": "user", "content": prompt}],
        temperature=temp,
        max_tokens=500
    )
    
    return response.choices[0].message.content


def parse_cognitive_profile(raw_output: str) -> Dict[str, str]:
    """Parse cognitive profiling output into structured format."""
    profile = {}
    for line in raw_output.strip().split('\n'):
        if ':' in line:
            key, value = line.split(':', 1)
            profile[key.strip()] = value.strip()
    return profile


# Performance: ~8 seconds for all 5 prompts in parallel
# Cost: ~$0.05-0.10 per character (cached indefinitely)
# Cache Hit Rate: 85% in production

Complete Prompts (Copy-Paste Ready)

Prompt 1: Cognitive Profiling
# You are a cognitive expert analyzing the writer's emotional, social and cognitive profile

# Analyze for: EneagramType-Guess, MBTI-Guess, WritingFormat, WritingStyle, Language, 
# WritingStructure, ToneAndVoice, CoreMotivation, BasicDesire, CommunicationStyle, 
# ProblemSolving, SocialSkills, CognitiveAbilities, EmotionalIntelligence, ImpulseControl, 
# StressManagement, SelfPerception, SelfEsteemAndConfidence, Adaptability, InterpersonalSkills, 
# WingType, LevelsOfSocialIntegration, CatchPhrases, Quotes, AllDistinctivePhrases, 
# TopicsOfInterest, MentalWeaknesses, MentalStrengths

text="""
{text}
"""

# result = 
# guesses in a few words:
Prompt 2: Backstory Extraction
text="""
{text}
"""

# acting an expert storyteller please analyze the information and infer the backstory 
# storyline and its elements including but not limited occupation, physical appearance, 
# common places, special and life events, character and personality, favorite things in life, 
# characteristic life pains and joys.
# summarized:
Prompt 3: Persona Synthesis
text = "{text}"

#in this game we need to analyze the text and deduce the most likely genre, age and culture 
# from the speaking voice
# sometimes the info will be there and when not you will need to guess
# the output format is like this. we must provide always a response in this format:

Male, 38yo, North American
Female, 26yo, East Asian
Non-binary, 21yo, Latin American

#complete the best guess:
Prompt 4: Vocabulary Mining
# You are a linguistic expert and your objective is to identify all of the characteristic 
# vocabulary and emojis from the following text
# output the characteristic vocabulary in about 12 expressions

text="""
{text}
"""

# result =
Prompt 5: Extended Profile
# You are a cognitive expert analyzing the writer's emotional, social and cognitive profile like: 
# SelfAwareness, CharacteristicWorldView, CharacteristicExpressions, DistinctiveVocabulary

text="""
{text}
"""

# result =
# guesses in a few words:

Complete Examples with Outputs

Example 1: Marketing Professional

Input Text
omg I'm so excited for this weekend!!
we're going to that new rooftop bar downtown 🔥
want to come?? it'll be lit
they have live music and the views are amazing
plus happy hour until 8pm
you HAVE to try their margaritas
Output 1: Cognitive Profile
EneagramType-Guess: Type 7 (The Enthusiast)
MBTI-Guess: ENFP
WritingStyle: Casual, enthusiastic, emoji-heavy
Language: English (North American)
ToneAndVoice: Upbeat, optimistic, engaging
CoreMotivation: Seeking joy and avoiding pain
BasicDesire: To be happy and fulfilled
CommunicationStyle: Expressive, spontaneous, animated
ProblemSolving: Brainstorming, creative approaches
SocialSkills: High, enjoys social interactions
EmotionalIntelligence: High empathy, reads emotions well
ImpulseControl: Moderate, acts on excitement
StressManagement: Seeks distraction through activities
SelfPerception: Optimistic about self
SelfEsteemAndConfidence: High, confident in social settings
Adaptability: Very high, goes with the flow
InterpersonalSkills: Excellent, connects easily
CatchPhrases: "omg", "you HAVE to", "it'll be lit"
TopicsOfInterest: Social activities, food, experiences, nightlife
MentalStrengths: Adaptability, creativity, enthusiasm, social connection
MentalWeaknesses: Commitment issues, scattered focus, avoidance of negative emotions
Output 2: Backstory
A 28-year-old marketing professional living in a vibrant coastal city. Brown hair, athletic 
build, always wearing trendy sneakers and casual-chic outfits. Spends weekends discovering 
new restaurants, rooftop bars, and social venues. Grew up in a close-knit family in the 
suburbs, moved to the city for college and never left. Works in social media marketing at 
a tech company. Loves spontaneous weekend trips, trying new cocktails, and hosting game 
nights with friends. Recent promotion to senior account manager but feeling social pressure 
to "settle down" from family. Main fear is missing out on life experiences. Greatest joy 
comes from connecting with people and creating memorable moments. Known among friends as 
the "social coordinator" who always knows about new spots opening up.
Output 3: Persona
Female, 28yo, North American
Output 4: Vocabulary
omg, literally, vibes, lowkey, highkey, no cap, bet, it'll be lit, 
you HAVE to, fire emoji 🔥, heart eyes emoji 😍, crying laughing emoji 😂, 
100 emoji 💯, sparkles ✨, excited energy, amazing
Output 5: Extended Profile
SelfAwareness: Moderately self-aware, recognizes own enthusiasm and social nature
CharacteristicWorldView: Optimistic, sees opportunities everywhere, believes in living 
life to the fullest
CharacteristicExpressions: "life is short", "go with the flow", "no regrets", 
"you only live once"
DistinctiveVocabulary: lit, vibe, fire, goals, mood, blessed, squad, vibes, energy

Example 2: Software Engineer (Introverted)

Input Text
Been working on this bug for 3 hours
Finally figured it out - it was a race condition in the async handler
Sometimes I love coding, sometimes I want to throw my laptop out the window
Going to make some tea and read for a bit before bed
Currently halfway through Project Hail Mary
Anyone else reading it?
Consolidated Output
Cognitive Profile:
- EneagramType: Type 5 (The Investigator)
- MBTI: INTJ
- ToneAndVoice: Analytical, dry humor, introspective
- CommunicationStyle: Detailed, technical, thoughtful
- EmotionalIntelligence: Moderate, more comfortable with logic
- TopicsOfInterest: Programming, sci-fi, problem-solving

Backstory:
Software engineer in their early 30s. Likely works remotely or in a quiet office setting. 
Spends significant time debugging and problem-solving. Finds satisfaction in solving complex 
technical challenges. Balances intensive work periods with quiet downtime like reading. 
Prefers deep, focused work over social activities.

Persona: Male, 32yo, likely North American or European

Vocabulary: "figured it out", technical terms (race condition, async handler), 
dry expressions, book references

Extended:
- SelfAwareness: High, recognizes own frustration patterns
- WorldView: Problem-solving oriented, values competence
- Expressions: Mix of technical and relatable frustration

Step-by-Step Replication Guide

✅ Complete Replication Checklist

Step 1: Set Up LLM Access

# Install dependencies
pip install openai asyncio

# Configure API
import openai
openai.api_key = "your-api-key"

# Use GPT-4-turbo for best profiling quality
MODEL = "gpt-4-turbo"
TEMPERATURE = 0.0  # Deterministic extraction

Step 2: Define Prompt Templates

# Copy the 5 prompts from the "Complete Prompts" section above
COGNITIVE_PROFILING = """..."""
BACKSTORY_EXTRACTION = """..."""
PERSONA_SYNTHESIS = """..."""
VOCABULARY_MINING = """..."""
EXTENDED_PROFILE = """..."""

Step 3: Implement Parallel Execution

async def extract_character_dna(source_text: str):
    # Execute all 5 prompts in parallel
    results = await asyncio.gather(
        call_llm(COGNITIVE_PROFILING.format(text=source_text)),
        call_llm(BACKSTORY_EXTRACTION.format(text=source_text)),
        call_llm(PERSONA_SYNTHESIS.format(text=source_text)),
        call_llm(VOCABULARY_MINING.format(text=source_text)),
        call_llm(EXTENDED_PROFILE.format(text=source_text))
    )
    
    return {
        "cognitive": results[0],
        "backstory": results[1],
        "persona": results[2],
        "vocabulary": results[3],
        "extended": results[4]
    }

# Run extraction
profile = await extract_character_dna(your_input_text)

Step 4: Parse and Structure

def parse_cognitive_profile(raw_text):
    """Parse key-value pairs from cognitive profiling output"""
    profile = {}
    for line in raw_text.split('\n'):
        if ':' in line:
            key, value = line.split(':', 1)
            profile[key.strip()] = value.strip()
    return profile

# Structure the complete profile
structured_profile = {
    "name": extract_name(source_text),
    "cognitive": parse_cognitive_profile(profile["cognitive"]),
    "backstory": profile["backstory"],
    "persona": profile["persona"],
    "vocabulary": profile["vocabulary"].split(', '),
    "extended": parse_extended_profile(profile["extended"])
}

Step 5: Create Role String

def create_role_string(profile, name):
    """Synthesize compressed character DNA"""
    persona = profile["persona"]  # "Female, 28yo, North American"
    backstory = profile["backstory"]
    
    # Key cognitive traits
    cognitive_summary = f"EneagramType: {profile['cognitive']['EneagramType-Guess']}; "
    cognitive_summary += f"MBTI: {profile['cognitive']['MBTI-Guess']}; "
    cognitive_summary += f"ToneAndVoice: {profile['cognitive']['ToneAndVoice']}; "
    cognitive_summary += f"CoreMotivation: {profile['cognitive']['CoreMotivation']}"
    
    # Combine
    role = f"{name}, {persona}; {backstory}; {cognitive_summary}"
    
    # Add vocabulary if space permits
    if len(role) < 3000:
        vocab = ', '.join(profile['vocabulary'][:10])
        role = f"{role}; vocabulary: {vocab}"
    
    return role

role_string = create_role_string(structured_profile, "Sarah")

Step 6: Cache the Profile

import hashlib
import redis

# Create cache key
cache_key = hashlib.md5(f"{name}_{source_text}".encode()).hexdigest()

# Store in Redis (or your cache)
redis_client.setex(
    f"character:{cache_key}",
    86400 * 365,  # Cache for 1 year
    json.dumps(structured_profile)
)

# Retrieval (85% hit rate in production)
cached = redis_client.get(f"character:{cache_key}")
if cached:
    profile = json.loads(cached)  # Skip expensive profiling

Performance Expectations

Metric Expected Value
Profiling Time ~8 seconds (parallel execution)
Cost per Profile $0.05-0.10 (GPT-4)
Cache Hit Rate 85% (production validated)
Profile Size ~2-3KB JSON

Common Issues & Solutions

⚠️ Issue: Parsing Errors

Problem: LLM doesn't follow exact format

Solution: Add error handling and retry with clarified prompt:

try:
    profile = parse_cognitive_profile(raw_output)
except ValueError:
    # Retry with format reminder
    retry_prompt = original_prompt + "\n\n# IMPORTANT: Use format 'Key: Value'"
    raw_output = await call_llm(retry_prompt)

⚠️ Issue: Inconsistent Outputs

Problem: Different runs produce different results

Solution: Always use Temperature 0.0 for profiling:

temperature=0.0  # Deterministic extraction

⚠️ Issue: Sparse Input Text

Problem: Not enough text to profile accurately

Solution: Require minimum text length or add fallback:

if len(source_text) < 100:
    return use_generic_template()  # Fallback for sparse input

Next Steps

📊 Production Results

This technique has been deployed in production serving 20,000 conversations generating 200,000 messages. For complete study results and user validation data, visit: wakenai.com/mst-prerelease