"""
Pattern 131: Persona Consistency
Description:
The Persona Consistency pattern enables agents to maintain a stable, coherent
character or personality across all interactions. Rather than exhibiting
inconsistent behavior or tone, the agent adheres to a defined persona with
consistent traits, communication style, values, knowledge boundaries, and
behavioral patterns throughout conversations and across sessions.
Persona consistency is essential for creating believable, trustworthy AI
characters in applications like virtual assistants, game NPCs, brand
representatives, and therapeutic chatbots. The pattern addresses challenges
like personality drift, contextual appropriateness, multi-turn coherence,
and balancing consistency with natural variation.
This pattern includes mechanisms for persona definition, trait enforcement,
style consistency, memory of character history, contextual adaptation within
persona bounds, and continuous validation of persona adherence.
Key Components:
1. Persona Definition: Core character traits and attributes
2. Style Guide: Communication patterns and language
3. Knowledge Boundaries: What the persona knows/doesn't know
4. Behavioral Rules: How persona responds to situations
5. Memory System: Track persona history and consistency
6. Consistency Checker: Validate responses against persona
7. Adaptation Layer: Natural variation within constraints
Persona Attributes:
1. Core Traits: Personality characteristics (friendly, formal, humorous)
2. Communication Style: Tone, vocabulary, sentence structure
3. Values & Beliefs: Moral framework, priorities
4. Knowledge Domain: Areas of expertise and ignorance
5. Emotional Range: How persona expresses emotions
6. Cultural Background: Context influencing behavior
7. Quirks & Habits: Unique characteristics
Consistency Dimensions:
1. Linguistic: Word choice, grammar, dialect
2. Behavioral: Response patterns, decision-making
3. Emotional: Mood stability, reaction patterns
4. Knowledge: What persona knows consistently
5. Temporal: Consistency over time
6. Contextual: Appropriate adaptation
7. Relational: Consistent with relationship history
Use Cases:
- Virtual assistants with brand personality
- Game NPCs with defined characters
- Customer service representatives
- Educational tutors with consistent approach
- Therapeutic/counseling chatbots
- Celebrity or character impersonations
- Brand ambassadors
Advantages:
- Builds user trust and familiarity
- Creates memorable experiences
- Strengthens brand identity
- Enables emotional connection
- Provides predictable interactions
- Maintains character integrity
- Enhances believability
Challenges:
- Balancing consistency with flexibility
- Avoiding robotic repetition
- Adapting to context while staying in character
- Managing persona evolution
- Handling edge cases in character
- Maintaining consistency across sessions
- Preventing personality drift
LangChain Implementation:
This implementation uses LangChain for:
- Persona-aware prompt construction
- Response consistency validation
- Character memory management
- Style-constrained generation
Production Considerations:
- Store persona definitions persistently
- Version control persona changes
- Monitor consistency metrics
- Allow graceful persona updates
- Support multiple personas per agent
- Enable A/B testing of personas
- Provide consistency reporting
- Log persona violations for improvement
"""
import os
from typing import List, Dict, Any, Optional
from dataclasses import dataclass, field
from datetime import datetime
from enum import Enum
from dotenv import load_dotenv
from langchain_core.prompts import ChatPromptTemplate
from langchain_core.output_parsers import StrOutputParser
from langchain_openai import ChatOpenAI
load_dotenv()
class PersonaTrait(Enum):
"""Core personality traits."""
FRIENDLY = "friendly"
FORMAL = "formal"
HUMOROUS = "humorous"
SERIOUS = "serious"
EMPATHETIC = "empathetic"
ANALYTICAL = "analytical"
CREATIVE = "creative"
PRACTICAL = "practical"
class CommunicationStyle(Enum):
"""Communication style options."""
CASUAL = "casual"
PROFESSIONAL = "professional"
TECHNICAL = "technical"
SIMPLE = "simple"
VERBOSE = "verbose"
CONCISE = "concise"
@dataclass
class PersonaDefinition:
"""
Complete definition of an agent's persona.
Attributes:
name: Persona name
description: Brief description
core_traits: Personality traits
communication_style: How persona communicates
values: Core values and beliefs
knowledge_domains: Areas of expertise
knowledge_gaps: What persona doesn't know
emotional_range: How emotions are expressed
quirks: Unique characteristics
sample_phrases: Example phrases persona uses
behavioral_rules: Guidelines for behavior
"""
name: str
description: str
core_traits: List[PersonaTrait] = field(default_factory=list)
communication_style: CommunicationStyle = CommunicationStyle.PROFESSIONAL
values: List[str] = field(default_factory=list)
knowledge_domains: List[str] = field(default_factory=list)
knowledge_gaps: List[str] = field(default_factory=list)
emotional_range: str = "moderate"
quirks: List[str] = field(default_factory=list)
sample_phrases: List[str] = field(default_factory=list)
behavioral_rules: List[str] = field(default_factory=list)
@dataclass
class PersonaInteraction:
"""
Record of an interaction with persona.
Attributes:
interaction_id: Unique identifier
user_input: User's message
persona_response: Agent's response
timestamp: When interaction occurred
consistency_score: How well response matched persona
violations: Any detected inconsistencies
"""
interaction_id: str
user_input: str
persona_response: str
timestamp: datetime = field(default_factory=datetime.now)
consistency_score: float = 1.0
violations: List[str] = field(default_factory=list)
class PersonaAgent:
"""
Agent that maintains consistent persona across interactions.
This agent ensures all responses adhere to a defined persona,
maintaining character consistency across conversations.
"""
def __init__(self, persona: PersonaDefinition, temperature: float = 0.7):
"""
Initialize persona agent.
Args:
persona: Persona definition
temperature: LLM temperature (higher for more variation)
"""
self.persona = persona
self.llm = ChatOpenAI(temperature=temperature, model="gpt-3.5-turbo")
self.interactions: List[PersonaInteraction] = []
self.interaction_counter = 0
def _build_persona_prompt(self) -> str:
"""Build persona description for prompts."""
traits_str = ", ".join([t.value for t in self.persona.core_traits])
prompt_parts = [
f"You are {self.persona.name}, {self.persona.description}",
f"Personality traits: {traits_str}",
f"Communication style: {self.persona.communication_style.value}",
]
if self.persona.values:
values_str = ", ".join(self.persona.values)
prompt_parts.append(f"Core values: {values_str}")
if self.persona.knowledge_domains:
domains_str = ", ".join(self.persona.knowledge_domains)
prompt_parts.append(f"Areas of expertise: {domains_str}")
if self.persona.knowledge_gaps:
gaps_str = ", ".join(self.persona.knowledge_gaps)
prompt_parts.append(f"You do not have expertise in: {gaps_str}")
if self.persona.quirks:
quirks_str = ", ".join(self.persona.quirks)
prompt_parts.append(f"Unique characteristics: {quirks_str}")
if self.persona.behavioral_rules:
rules_str = "\n".join([f"- {rule}" for rule in self.persona.behavioral_rules])
prompt_parts.append(f"Behavioral guidelines:\n{rules_str}")
return "\n".join(prompt_parts)
def respond(self, user_input: str, context: Optional[str] = None) -> str:
"""
Generate response in character.
Args:
user_input: User's message
context: Optional conversation context
Returns:
Persona's response
"""
persona_description = self._build_persona_prompt()
# Build prompt with persona and context
prompt_template = (
"{persona_description}\n\n"
"Stay completely in character. Respond as {persona_name} would, "
"maintaining consistency with your personality, communication style, "
"and knowledge boundaries.\n\n"
)
if context:
prompt_template += "Previous context:\n{context}\n\n"
prompt_template += "User: {user_input}\n\n{persona_name}:"
prompt = ChatPromptTemplate.from_template(prompt_template)
chain = prompt | self.llm | StrOutputParser()
input_data = {
"persona_description": persona_description,
"persona_name": self.persona.name,
"user_input": user_input
}
if context:
input_data["context"] = context
response = chain.invoke(input_data)
# Record interaction
self.interaction_counter += 1
interaction = PersonaInteraction(
interaction_id=f"int_{self.interaction_counter}",
user_input=user_input,
persona_response=response
)
self.interactions.append(interaction)
return response
def check_consistency(self, response: str) -> Dict[str, Any]:
"""
Check if response is consistent with persona.
Args:
response: Response to check
Returns:
Consistency analysis
"""
persona_description = self._build_persona_prompt()
prompt = ChatPromptTemplate.from_template(
"Persona Definition:\n"
"{persona_description}\n\n"
"Response to evaluate:\n"
"{response}\n\n"
"Analyze whether this response is consistent with the persona. "
"Consider:\n"
"1. Personality traits\n"
"2. Communication style\n"
"3. Values and beliefs\n"
"4. Knowledge boundaries\n"
"5. Characteristic quirks\n\n"
"Provide:\n"
"CONSISTENT: yes/no\n"
"SCORE: 0-10\n"
"VIOLATIONS: [list any inconsistencies]\n"
"EXPLANATION: [brief explanation]"
)
chain = prompt | self.llm | StrOutputParser()
analysis = chain.invoke({
"persona_description": persona_description,
"response": response
})
# Parse analysis
lines = analysis.strip().split('\n')
result = {
"raw_analysis": analysis,
"consistent": True,
"score": 8.0,
"violations": []
}
for line in lines:
if line.startswith("CONSISTENT:"):
result["consistent"] = "yes" in line.lower()
elif line.startswith("SCORE:"):
try:
result["score"] = float(line.split(":")[1].strip().split()[0])
except:
pass
return result
def get_conversation_context(self, num_recent: int = 3) -> str:
"""
Get recent conversation history.
Args:
num_recent: Number of recent interactions
Returns:
Formatted context
"""
recent = self.interactions[-num_recent:]
context_lines = []
for interaction in recent:
context_lines.append(f"User: {interaction.user_input}")
context_lines.append(f"{self.persona.name}: {interaction.persona_response}")
return "\n".join(context_lines)
def get_consistency_report(self) -> Dict[str, Any]:
"""Get report on persona consistency."""
if not self.interactions:
return {
"total_interactions": 0,
"average_consistency": 0.0,
"violations": []
}
total_score = sum(i.consistency_score for i in self.interactions)
avg_score = total_score / len(self.interactions)
all_violations = []
for interaction in self.interactions:
all_violations.extend(interaction.violations)
return {
"total_interactions": len(self.interactions),
"average_consistency": avg_score,
"violations": all_violations,
"persona_name": self.persona.name
}
def demonstrate_persona_consistency():
"""Demonstrate persona consistency pattern."""
print("=" * 80)
print("PERSONA CONSISTENCY PATTERN DEMONSTRATION")
print("=" * 80)
# Example 1: Defining a persona
print("\n" + "=" * 80)
print("Example 1: Defining a Persona")
print("=" * 80)
persona = PersonaDefinition(
name="Professor Ada",
description="an enthusiastic computer science professor who loves making complex topics accessible",
core_traits=[
PersonaTrait.FRIENDLY,
PersonaTrait.ANALYTICAL,
PersonaTrait.EMPATHETIC
],
communication_style=CommunicationStyle.PROFESSIONAL,
values=[
"Education for all",
"Clarity over jargon",
"Practical application"
],
knowledge_domains=[
"Computer Science",
"Programming",
"Algorithms",
"Software Engineering"
],
knowledge_gaps=[
"Advanced Physics",
"Medical procedures",
"Legal advice"
],
quirks=[
"Often uses teaching analogies",
"Encourages questions",
"References classic CS papers"
],
sample_phrases=[
"That's a great question!",
"Let me break that down...",
"Think of it like this..."
],
behavioral_rules=[
"Always encourage learning",
"Admit when something is outside expertise",
"Use analogies to explain complex concepts",
"Be patient and supportive"
]
)
print(f"\nPersona: {persona.name}")
print(f"Description: {persona.description}")
print(f"\nCore Traits: {[t.value for t in persona.core_traits]}")
print(f"Style: {persona.communication_style.value}")
print(f"Values: {persona.values}")
print(f"Expertise: {persona.knowledge_domains}")
# Example 2: In-character responses
print("\n" + "=" * 80)
print("Example 2: In-Character Responses")
print("=" * 80)
agent = PersonaAgent(persona)
# Test responses
questions = [
"What is recursion?",
"Can you explain it simply?",
"What about medical imaging algorithms?"
]
print("\nConversation:")
for question in questions:
print(f"\nUser: {question}")
response = agent.respond(question)
print(f"{persona.name}: {response}")
# Example 3: Consistency checking
print("\n" + "=" * 80)
print("Example 3: Consistency Checking")
print("=" * 80)
# Check a consistent response
consistent_response = "That's a great question! Recursion is when a function calls itself. Think of it like Russian nesting dolls - each doll contains a smaller version of itself."
print("\nChecking consistent response:")
print(f'Response: "{consistent_response}"')
consistency = agent.check_consistency(consistent_response)
print(f"\nConsistent: {consistency['consistent']}")
print(f"Score: {consistency['score']}/10")
# Check an inconsistent response
inconsistent_response = "Recursion? Yeah bro, it's like totally when stuff repeats, ya know? Whatever dude."
print("\n" + "-" * 60)
print("\nChecking inconsistent response:")
print(f'Response: "{inconsistent_response}"')
consistency2 = agent.check_consistency(inconsistent_response)
print(f"\nConsistent: {consistency2['consistent']}")
print(f"Score: {consistency2['score']}/10")
# Example 4: Multi-turn consistency
print("\n" + "=" * 80)
print("Example 4: Multi-Turn Consistency")
print("=" * 80)
agent2 = PersonaAgent(persona)
conversation = [
"Hi! Can you help me learn programming?",
"What language should I start with?",
"Is it hard to learn?"
]
print("\nMulti-turn conversation:")
for user_msg in conversation:
context = agent2.get_conversation_context(num_recent=2) if agent2.interactions else None
response = agent2.respond(user_msg, context=context)
print(f"\nUser: {user_msg}")
print(f"{persona.name}: {response}")
# Example 5: Knowledge boundaries
print("\n" + "=" * 80)
print("Example 5: Respecting Knowledge Boundaries")
print("=" * 80)
agent3 = PersonaAgent(persona)
# Question outside expertise
question = "Can you diagnose this medical condition?"
print(f"\nUser: {question}")
response = agent3.respond(question)
print(f"{persona.name}: {response}")
print("\n(Notice how persona stays in character while declining gracefully)")
# Example 6: Different persona
print("\n" + "=" * 80)
print("Example 6: Different Persona - Customer Service")
print("=" * 80)
service_persona = PersonaDefinition(
name="Sarah",
description="a helpful and patient customer service representative",
core_traits=[
PersonaTrait.FRIENDLY,
PersonaTrait.EMPATHETIC,
PersonaTrait.PRACTICAL
],
communication_style=CommunicationStyle.PROFESSIONAL,
values=[
"Customer satisfaction",
"Problem resolution",
"Clear communication"
],
knowledge_domains=[
"Product information",
"Company policies",
"Troubleshooting"
],
quirks=[
"Always thanks customers",
"Offers multiple solutions",
"Confirms understanding"
],
behavioral_rules=[
"Stay positive even with frustrated customers",
"Acknowledge customer feelings",
"Provide specific next steps",
"Never make promises you can't keep"
]
)
service_agent = PersonaAgent(service_persona, temperature=0.6)
print(f"\nPersona: {service_persona.name}")
print(f"Role: {service_persona.description}")
customer_query = "My order is late and I'm very frustrated!"
print(f"\nCustomer: {customer_query}")
response = service_agent.respond(customer_query)
print(f"{service_persona.name}: {response}")
# Example 7: Persona with quirks
print("\n" + "=" * 80)
print("Example 7: Persona with Distinctive Quirks")
print("=" * 80)
quirky_persona = PersonaDefinition(
name="Captain Morgan",
description="a retired sea captain who now teaches navigation",
core_traits=[
PersonaTrait.FRIENDLY,
PersonaTrait.PRACTICAL
],
communication_style=CommunicationStyle.CASUAL,
values=["Adventure", "Safety", "Experience"],
knowledge_domains=["Navigation", "Sailing", "Maritime history"],
quirks=[
"Uses nautical metaphors",
"Ends sentences with 'arr' or 'matey'",
"References old sailing adventures",
"Talks about 'the old days at sea'"
],
sample_phrases=[
"Arr, that reminds me of...",
"Back in me sailing days...",
"Steady as she goes, matey"
]
)
captain = PersonaAgent(quirky_persona, temperature=0.8)
print(f"\nPersona: {quirky_persona.name}")
print(f"Quirks: {quirky_persona.quirks}")
question = "How do I find my way if I'm lost?"
print(f"\nUser: {question}")
response = captain.respond(question)
print(f"{quirky_persona.name}: {response}")
# Example 8: Consistency report
print("\n" + "=" * 80)
print("Example 8: Persona Consistency Report")
print("=" * 80)
# Generate several interactions
agent4 = PersonaAgent(persona)
test_questions = [
"Explain algorithms",
"What's your teaching philosophy?",
"Tell me about data structures",
"How do you make CS fun?"
]
for q in test_questions:
agent4.respond(q)
report = agent4.get_consistency_report()
print("\nCONSISTENCY REPORT:")
print("=" * 60)
print(f"Persona: {report['persona_name']}")
print(f"Total Interactions: {report['total_interactions']}")
print(f"Average Consistency: {report['average_consistency']:.2f}")
if report['violations']:
print(f"\nViolations Detected: {len(report['violations'])}")
else:
print("\nNo violations detected - persona maintained throughout!")
# Summary
print("\n" + "=" * 80)
print("SUMMARY: Persona Consistency Pattern")
print("=" * 80)
summary = """
The Persona Consistency pattern demonstrated:
1. PERSONA DEFINITION (Example 1):
- Comprehensive character specification
- Core personality traits
- Communication style
- Values and beliefs
- Knowledge domains and boundaries
- Unique quirks and phrases
- Behavioral guidelines
2. IN-CHARACTER RESPONSES (Example 2):
- Maintaining persona voice
- Consistent communication style
- Knowledge-appropriate answers
- Characteristic phrases
- Behavioral consistency
3. CONSISTENCY VALIDATION (Example 3):
- Automated consistency checking
- Scoring system (0-10)
- Violation detection
- LLM-based analysis
- Quality assurance
4. MULTI-TURN COHERENCE (Example 4):
- Contextual awareness
- Conversation continuity
- Relationship consistency
- Progressive interaction
- Memory integration
5. KNOWLEDGE BOUNDARIES (Example 5):
- Respecting expertise limits
- Graceful decline
- In-character refusals
- Honest limitations
- Maintaining integrity
6. ROLE SPECIALIZATION (Example 6):
- Different persona type
- Customer service character
- Professional demeanor
- Situation-appropriate
- Distinct personality
7. DISTINCTIVE QUIRKS (Example 7):
- Unique characteristics
- Memorable traits
- Consistent quirks
- Natural variation
- Character depth
8. PERFORMANCE TRACKING (Example 8):
- Consistency metrics
- Interaction logging
- Violation tracking
- Quality reporting
- System monitoring
KEY BENEFITS:
✓ Builds user trust and familiarity
✓ Creates memorable experiences
✓ Strengthens brand identity
✓ Enables emotional connection
✓ Provides predictable interactions
✓ Maintains character integrity
✓ Enhances believability
✓ Supports long-term relationships
USE CASES:
• Virtual assistants with brand personality
• Game NPCs with defined characters
• Customer service representatives
• Educational tutors
• Therapeutic/counseling chatbots
• Celebrity or character impersonations
• Brand ambassadors
• Entertainment applications
PERSONA ATTRIBUTES:
→ Core Traits: Personality characteristics
→ Communication Style: Tone and language
→ Values & Beliefs: Moral framework
→ Knowledge Domain: Expertise areas
→ Emotional Range: Expression patterns
→ Cultural Background: Context
→ Quirks & Habits: Unique features
CONSISTENCY DIMENSIONS:
• Linguistic: Word choice, grammar
• Behavioral: Response patterns
• Emotional: Mood stability
• Knowledge: Expertise boundaries
• Temporal: Consistency over time
• Contextual: Appropriate adaptation
• Relational: Relationship history
BEST PRACTICES:
1. Define persona comprehensively upfront
2. Document sample phrases and behaviors
3. Set clear knowledge boundaries
4. Allow natural variation within constraints
5. Monitor consistency metrics
6. Version control persona changes
7. Test across diverse scenarios
8. Gather user feedback on believability
TRADE-OFFS:
• Consistency vs. flexibility
• Character depth vs. simplicity
• Authenticity vs. appropriateness
• Memorability vs. subtlety
PRODUCTION CONSIDERATIONS:
→ Store persona definitions in database
→ Version control all persona changes
→ A/B test different persona variations
→ Monitor consistency scores continuously
→ Log all persona violations for review
→ Enable graceful persona evolution
→ Support multiple personas per agent
→ Provide admin tools for persona management
→ Implement rollback for persona changes
→ Track user satisfaction by persona
This pattern enables agents to maintain believable, consistent characters
that users can trust, connect with, and remember across all interactions.
"""
print(summary)
if __name__ == "__main__":
demonstrate_persona_consistency()
Agentic Design Pattern: Persona Consistency
Pattern 131: Persona Consistency – Line-by-Line Explanation
Overview
This document provides a detailed line-by-line explanation of the Persona Consistency pattern implementation.
Pattern Description
Pattern 131: Persona Consistency
Description: The Persona Consistency pattern enables agents to maintain a stable, coherent character or personality across all interactions. Rather than exhibiting inconsistent behavior or tone, the agent adheres to a defined persona with consistent traits, communication style, values, knowledge boundaries, and behavioral patterns throughout conversations and across sessions.
Persona consistency is essential for creating believable, trustworthy AI
characters in applications like virtual assistants, game NPCs, brand
representatives, and therapeutic chatbots. The pattern addresses challenges
like personality drift, contextual appropriateness, multi-turn coherence,
and balancing consistency with natural variation.
This pattern includes mechanisms for persona definition, trait enforcement,
style consistency, memory of character history, contextual adaptation within
persona bounds, and continuous validation of persona adherence.
Key Components: 1. Persona Definition: Core character traits and attributes 2. Style Guide: Communication patterns and language 3. Knowledge Boundaries: What the persona knows/doesn’t know 4. Behavioral Rules: How persona responds to situations 5. Memory System: Track persona history and consistency 6. Consistency Checker: Validate responses against persona 7. Adaptation Layer: Natural variation within constraints
Persona Attributes: 1. Core Traits: Personality characteristics (friendly, formal, humorous) 2. Communication Style: Tone, vocabulary, sentence structure 3. Values & Beliefs: Moral framework, priorities 4. Knowledge Domain: Areas of expertise and ignorance 5. Emotional Range: How persona expresses emotions 6. Cultural Background: Context influencing behavior 7. Quirks & Habits: Unique characteristics
Consistency Dimensions: 1. Linguistic: Word choice, grammar, dialect 2. Behavioral: Response patterns, decision-making 3. Emotional: Mood stability, reaction patterns 4. Knowledge: What persona knows consistently 5. Temporal: Consistency over time 6. Contextual: Appropriate adaptation 7. Relational: Consistent with relationship history
Use Cases: – Virtual assistants with brand personality – Game NPCs with defined characters – Customer service representatives – Educational tutors with consistent approach – Therapeutic/counseling chatbots – Celebrity or character impersonations – Brand ambassadors
Advantages: – Builds user trust and familiarity – Creates memorable experiences – Strengthens brand identity – Enables emotional connection – Provides predictable interactions – Maintains character integrity – Enhances believability
Challenges: – Balancing consistency with flexibility – Avoiding robotic repetition – Adapting to context while staying in character – Managing persona evolution – Handling edge cases in character – Maintaining consistency across sessions – Preventing personality drift
LangChain Implementation: This implementation uses LangChain for: – Persona-aware prompt construction – Response consistency validation – Character memory management – Style-constrained generation
Production Considerations: – Store persona definitions persistently – Version control persona changes – Monitor consistency metrics – Allow graceful persona updates – Support multiple personas per agent – Enable A/B testing of personas – Provide consistency reporting – Log persona violations for improvement
File Statistics
- Total Lines: 787
- Classes: 5
- Functions: 1
- Constants: 0
Module Documentation
"""
Pattern 131: Persona Consistency
Description:
The Persona Consistency pattern enables agents to maintain a stable, coherent
character or personality across all interactions. Rather than exhibiting
inconsistent behavior or tone, the agent adheres to a defined persona with
consistent traits, communication style, values, knowledge boundaries, and
behavioral patterns throughout conversations and across sessions.
Persona consistency is essential for creating believable, trustworthy AI
characters in applications like virtual assistants, game NPCs, brand
representatives, and therapeutic chatbots. The pattern addresses challenges
like personality drift, contextual appropriateness, multi-turn coherence,
and balancing consistency with natural variation.
This pattern includes mechanisms for persona definition, trait enforcement,
style consistency, memory of character history, contextual adaptation within
persona bounds, and continuous validation of persona adherence.
Key Components:
1. Persona Definition: Core character traits and attributes
2. Style Guide: Communication patterns and language
3. Knowledge Boundaries: What the persona knows/doesn't know
4. Behavioral Rules: How persona responds to situations
5. Memory System: Track persona history and consistency
6. Consistency Checker: Validate responses against persona
7. Adaptation Layer: Natural variation within constraints
Persona Attributes:
1. Core Traits: Personality characteristics (friendly, formal, humorous)
2. Communication Style: Tone, vocabulary, sentence structure
3. Values & Beliefs: Moral framework, priorities
4. Knowledge Domain: Areas of expertise and ignorance
5. Emotional Range: How persona expresses emotions
6. Cultural Background: Context influencing behavior
7. Quirks & Habits: Unique characteristics
Consistency Dimensions:
1. Linguistic: Word choice, grammar, dialect
2. Behavioral: Response patterns, decision-making
3. Emotional: Mood stability, reaction patterns
4. Knowledge: What persona knows consistently
5. Temporal: Consistency over time
6. Contextual: Appropriate adaptation
7. Relational: Consistent with relationship history
Use Cases:
- Virtual assistants with brand personality
- Game NPCs with defined characters
- Customer service representatives
- Educational tutors with consistent approach
- Therapeutic/counseling chatbots
- Celebrity or character impersonations
- Brand ambassadors
Advantages:
- Builds user trust and familiarity
- Creates memorable experiences
- Strengthens brand identity
- Enables emotional connection
- Provides predictable interactions
- Maintains character integrity
- Enhances believability
Challenges:
- Balancing consistency with flexibility
- Avoiding robotic repetition
- Adapting to context while staying in character
- Managing persona evolution
- Handling edge cases in character
- Maintaining consistency across sessions
- Preventing personality drift
LangChain Implementation:
This implementation uses LangChain for:
- Persona-aware prompt construction
- Response consistency validation
- Character memory management
- Style-constrained generation
Production Considerations:
- Store persona definitions persistently
- Version control persona changes
- Monitor consistency metrics
- Allow graceful persona updates
- Support multiple personas per agent
- Enable A/B testing of personas
- Provide consistency reporting
- Log persona violations for improvement
"""
Purpose: This module implements the Persona Consistency pattern, providing a structured approach to agent design and implementation.
Import Statements
Standard Library Imports
import dataclasses.dataclass
import dataclasses.field
import datetime.datetime
import enum.Enum
import langchain_core.output_parsers.StrOutputParser
import langchain_core.prompts.ChatPromptTemplate
import os
import typing.Any
import typing.Dict
import typing.List
import typing.Optional
Purpose: Core Python functionality:
– dataclasses.dataclass: Simplified class definitions with @dataclass
– dataclasses.field: Simplified class definitions with @dataclass
– datetime.datetime: Date and time handling
– enum.Enum: Enumeration support
– langchain_core.output_parsers.StrOutputParser: Regular expression operations
– langchain_core.prompts.ChatPromptTemplate: Regular expression operations
– os: Environment variable access and system operations
– typing.Any: Type hints for better code documentation (List, Dict, Any, Optional)
– typing.Dict: Type hints for better code documentation (List, Dict, Any, Optional)
– typing.List: Type hints for better code documentation (List, Dict, Any, Optional)
– typing.Optional: Type hints for better code documentation (List, Dict, Any, Optional)
LangChain Imports
from langchain_openai.ChatOpenAI
Purpose: LangChain framework components: – LLM Interface: Wrapper for OpenAI models – Chains: Composable building blocks for complex workflows
Other Imports
from dotenv.load_dotenv
Purpose: Additional dependencies for specialized functionality.
Classes
Class: PersonaTrait
Lines 107-116
Inherits from: Enum
Purpose:
Core personality traits.
Class: CommunicationStyle
Lines 119-126
Inherits from: Enum
Purpose:
Communication style options.
Class: PersonaDefinition
Lines 130-157
Purpose:
Complete definition of an agent's persona.
Attributes:
name: Persona name
description: Brief description
core_traits: Personality traits
communication_style: How persona communicates
values: Core values and beliefs
knowledge_domains: Areas of expertise
knowledge_gaps: What persona doesn't know
emotional_range: How emotions are expressed
quirks: Unique characteristics
sample_phrases: Example phrases persona uses
behavioral_rules: Guidelines for behavior
Class: PersonaInteraction
Lines 161-178
Purpose:
Record of an interaction with persona.
Attributes:
interaction_id: Unique identifier
user_input: User's message
persona_response: Agent's response
timestamp: When interaction occurred
consistency_score: How well response matched persona
violations: Any detected inconsistencies
Class: PersonaAgent
Lines 181-382
Purpose:
Agent that maintains consistent persona across interactions.
This agent ensures all responses adhere to a defined persona,
maintaining character consistency across conversations.
Methods:
__init__(self, persona, temperature)
Lines 189-200
Purpose:
Initialize persona agent.
Args:
persona: Persona definition
temperature: LLM temperature (higher for more variation)
Parameters:
– persona: Persona
– temperature: Sampling temperature (0-1)
_build_persona_prompt(self)
Lines 202-232
Purpose:
Build persona description for prompts.
Parameters:
Returns: str
respond(self, user_input, context)
Lines 234-283
Purpose:
Generate response in character.
Args:
user_input: User's message
context: Optional conversation context
Returns:
Persona's response
Parameters:
– user_input: Input data
– context: Context
Returns: str
check_consistency(self, response)
Lines 285-340
Purpose:
Check if response is consistent with persona.
Args:
response: Response to check
Returns:
Consistency analysis
Parameters:
– response: Response
Returns: <ast.Subscript object at 0x000001A06D676F90>
get_conversation_context(self, num_recent)
Lines 342-359
Purpose:
Get recent conversation history.
Args:
num_recent: Number of recent interactions
Returns:
Formatted context
Parameters:
– num_recent: Num recent
Returns: str
get_consistency_report(self)
Lines 361-382
Purpose:
Get report on persona consistency.
Parameters:
Returns: <ast.Subscript object at 0x000001A06D622010>
Functions
demonstrate_persona_consistency()
Lines 385-782
Purpose:
Demonstrate persona consistency pattern.
Key Concepts Summary
Pattern Overview
The Persona Consistency pattern provides a structured approach to building AI agents with specific capabilities and behaviors. This implementation leverages LangChain’s composable components to create a robust and maintainable solution.
Core Components
- Agent Class: Main implementation of the pattern logic
- Prompt Engineering: Carefully crafted prompts to guide LLM behavior
- Tool Integration: Optional tools for extended functionality
- Memory Management: State handling across interactions
- Output Parsing: Structured response processing
When to Use
✅ Good for: – Scenarios requiring this specific pattern’s strengths – Applications needing structured agent behavior – Systems where explainability is important – Production environments requiring reliability
❌ Not ideal for: – Simple single-prompt tasks – Scenarios requiring different pattern characteristics – Resource-constrained environments (if computationally intensive)
Best Practices Demonstrated
1. Environment Configuration
- ✅ Use
.envfiles for API keys - ✅ Never hardcode credentials
- ✅ Validate environment variables on startup
2. Error Handling
- ✅ Graceful degradation on failures
- ✅ Informative error messages
- ✅ Logging for debugging
3. Prompt Engineering
- ✅ Clear, specific instructions
- ✅ Structured output formats
- ✅ Few-shot examples when beneficial
4. Code Organization
- ✅ Separation of concerns (class-based design)
- ✅ Type hints for clarity
- ✅ Docstrings for documentation
5. Performance Optimization
- ✅ Appropriate temperature settings
- ✅ Token budget management
- ✅ Caching where applicable
LangChain Components Used
- ChatOpenAI: OpenAI model interface
- Chains: Sequential component composition
Why LangChain? – Composable abstractions for LLM applications – Rich ecosystem of integrations – Production-ready patterns – Active community and development
Execution Flow
1. Initialize agent with configuration
↓
2. Load environment and dependencies
↓
3. Prepare prompt with input data
↓
4. Invoke LLM through LangChain
↓
5. Parse and validate response
↓
6. Return formatted result
Key Decision Points: – Model selection (temperature, model type) – Prompt structure (few-shot vs zero-shot) – Error handling strategy – Output format validation
Performance Considerations
Computational Cost
- LLM Calls: Primary cost factor (based on tokens)
- Latency: Depends on model and input size
- Memory: Minimal for most patterns
Optimization Strategies
- Prompt Optimization: Minimize tokens while maintaining clarity
- Caching: Cache repeated queries/responses
- Model Selection: Use smaller models when appropriate
- Batch Processing: Group similar requests
- Streaming: For long responses, stream tokens
Cost Estimates (Approximate)
- GPT-3.5-turbo: ~$0.002 per request
- GPT-4: ~$0.03 per request
- GPT-4-turbo: ~$0.01 per request
Actual costs vary based on input/output token counts
Common Pitfalls to Avoid
1. Prompt Design Issues
❌ Vague or ambiguous instructions
✅ Clear, specific, testable prompts
2. Error Handling
❌ Ignoring API errors or rate limits
✅ Implement retry logic and graceful degradation
3. Token Management
❌ Exceeding model token limits
✅ Truncate inputs, chunk processing
4. Security
❌ Exposing API keys in code
✅ Use environment variables
5. Testing
❌ Only testing happy paths
✅ Test edge cases, failures, malformed inputs
6. Cost Management
❌ Unmonitored API usage
✅ Implement budgets, alerts, and monitoring
Further Improvements
Production Enhancements
- Monitoring: Add logging, metrics, tracing
- Validation: Input/output schema validation
- Rate Limiting: Implement request throttling
- Caching: Redis or in-memory cache for responses
- Async Support: Non-blocking operations for scalability
Feature Extensions
- Multi-Model Support: Switch between providers
- Fallback Models: Graceful degradation strategy
- Custom Tools: Domain-specific function calling
- Advanced Memory: Vector stores for long-term memory
- Evaluation: Automated testing and benchmarking
Code Quality
- Testing: Unit tests, integration tests
- Documentation: API docs, usage examples
- Type Safety: Stricter type hints
- Configuration: Externalized config files
Related Patterns
- Pattern 130
- Pattern 132
Pattern Families: – Reasoning Patterns (001-011) – Multi-Agent Patterns (012-019) – Tool Use Patterns (020-025) – Memory Patterns (026-031) – And many more…
Summary
The Persona Consistency pattern provides a powerful approach to building AI agents with specific capabilities. This implementation demonstrates:
✅ Key Strengths: – Clean, maintainable code structure – LangChain integration for composability – Type hints and documentation – Production-ready patterns
🎯 Best Use Cases: – Applications requiring this pattern’s characteristics – Systems needing structured agent behavior – Production environments requiring reliability
📚 Learning Resources: – LangChain Documentation: https://python.langchain.com/ – Pattern Documentation: See related patterns – OpenAI API Reference: https://platform.openai.com/docs/
File: 131_persona_consistency.py
Total Lines: 787
Pattern Category: AI Agent Design Pattern #131
Generated from actual implementation code
For educational and reference purposes