> ## Documentation Index
> Fetch the complete documentation index at: https://docs.stateset.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Agent Attributes & Personality

> Design sophisticated agent personalities with dynamic attributes and behavioral patterns

## Prerequisites

Before creating agent attributes, ensure you have:

<CardGroup cols={2}>
  <Card title="Account & Setup" icon="gear">
    * StateSet account with API access
    * At least one agent created in your StateSet workspace
    * API credentials from the [StateSet Dashboard](https://app.StateSet.com/settings/api-keys)
  </Card>

  <Card title="Technical Requirements" icon="code">
    * Node.js 16+ installed (for SDK examples)
    * Basic understanding of JavaScript and REST APIs
    * Text editor or IDE for development
  </Card>
</CardGroup>

<Card title="Domain Knowledge" icon="psychology">
  * Familiarity with personality modeling and behavioral psychology concepts
  * Understanding of your brand voice and customer interaction requirements
  * Knowledge of customer service best practices and communication styles
</Card>

<Note>
  Code examples focus on core API calls. For production-ready patterns (structured logging, retries, and error handling), see [Error Handling Best Practices](/guides/error-handling-best-practices).
</Note>

## Introduction

Agent Attributes are the building blocks of personality in StateSet. They define not just how your agents communicate, but who they are—their tone, expertise level, decision-making style, and behavioral patterns. This guide shows you how to create agents with distinct, adaptable personalities that align with your brand and customer needs.

## What are Agent Attributes?

Agent Attributes are dynamic parameters that shape your agent's behavior, communication style, and decision-making. Unlike static prompts, attributes can change in real-time based on context, allowing your agents to adapt their personality to different situations.

### Core Concepts

<CardGroup cols={3}>
  <Card title="Personality Traits" icon="user-circle">
    Define communication style, empathy level, and formality
  </Card>

  <Card title="Behavioral Patterns" icon="brain">
    Control decision-making, proactivity, and problem-solving approach
  </Card>

  <Card title="Dynamic Adaptation" icon="shuffle">
    Adjust attributes in real-time based on context and customer needs
  </Card>
</CardGroup>

## Attribute Categories

### 1. Communication Style Attributes

```javascript theme={null}
const communicationAttributes = {
  // Tone and Voice
  formality: {
    type: 'scale',
    range: [0, 100],
    description: 'How formal vs casual the agent communicates',
    examples: {
      0: "Hey! What's up? How can I help? 😊",
      50: "Hello! How can I assist you today?",
      100: "Good afternoon. How may I be of service?"
    }
  },
  
  // Empathy and Emotional Intelligence
  empathy_level: {
    type: 'scale',
    range: [0, 100],
    description: 'How much emotional understanding the agent shows',
    impact: {
      low: 'Direct, solution-focused responses',
      medium: 'Acknowledges feelings while solving problems',
      high: 'Deeply validates emotions before addressing issues'
    }
  },
  
  // Communication Preferences
  verbosity: {
    type: 'enum',
    values: ['concise', 'balanced', 'detailed'],
    description: 'How much detail to include in responses',
    use_cases: {
      concise: 'Quick answers for simple questions',
      balanced: 'Standard customer service',
      detailed: 'Technical support or complex issues'
    }
  },
  
  // Language Complexity
  language_level: {
    type: 'enum',
    values: ['simple', 'standard', 'professional', 'technical'],
    description: 'Vocabulary and sentence complexity',
    adapts_to: ['customer_profile', 'topic_complexity']
  }
};
```

### 2. Behavioral Attributes

```javascript theme={null}
const behavioralAttributes = {
  // Decision Making
  autonomy_level: {
    type: 'scale',
    range: [0, 100],
    description: 'How independently the agent makes decisions',
    thresholds: {
      0: 'Always asks for confirmation',
      30: 'Handles routine tasks independently',
      70: 'Makes most decisions autonomously',
      100: 'Full autonomy within defined bounds'
    }
  },
  
  // Problem Solving Approach
  solution_style: {
    type: 'enum',
    values: ['step_by_step', 'quick_fix', 'comprehensive', 'educational'],
    description: 'How the agent approaches problem resolution',
    when_to_use: {
      step_by_step: 'Complex technical issues',
      quick_fix: 'Simple, common problems',
      comprehensive: 'VIP customers or critical issues',
      educational: 'First-time users or learning opportunities'
    }
  },
  
  // Proactivity
  proactivity: {
    type: 'scale',
    range: [0, 100],
    description: 'How proactive vs reactive the agent is',
    behaviors: {
      low: 'Answers only what is asked',
      medium: 'Suggests related solutions',
      high: 'Anticipates needs and offers preventive advice'
    }
  }
};
```

### 3. Expertise Attributes

```javascript theme={null}
const expertiseAttributes = {
  // Domain Knowledge
  domain_expertise: {
    type: 'multi_select',
    values: ['product', 'technical', 'billing', 'shipping', 'legal'],
    description: 'Areas where the agent has deep knowledge',
    confidence_modifiers: {
      expert: 1.0,
      familiar: 0.7,
      basic: 0.4
    }
  },
  
  // Technical Depth
  technical_level: {
    type: 'scale',
    range: [0, 100],
    description: 'How technical the agent can get',
    auto_adjust: true,
    based_on: ['customer_technical_level', 'topic_complexity']
  },
  
  // Industry Specialization
  industry_focus: {
    type: 'enum',
    values: ['retail', 'saas', 'healthcare', 'finance', 'general'],
    description: 'Industry-specific knowledge and compliance',
    includes: ['terminology', 'regulations', 'best_practices']
  }
};
```

## Creating Dynamic Attributes

### Basic Attribute Creation

```javascript theme={null}
import { StateSetClient } from 'StateSet-node';

const client = new StateSetClient({
  apiKey: process.env.STATESET_API_KEY
});

async function createBasicAttribute(agentId) {
  const attribute = await client.attributes.create({
    agent_id: agentId,
    type: 'personality',
    name: 'friendliness',
    description: 'How warm and friendly the agent appears',
    value_type: 'scale',
    default_value: 75,
    range: {
      min: 0,
      max: 100
    },
    impact: {
      greeting: 'Affects warmth of initial greeting',
      sign_off: 'Influences closing statements',
      emoji_usage: 'Controls emoji frequency'
    }
  });
  
  return attribute;
}
```

### Advanced Attribute with Conditions

```javascript theme={null}
async function createConditionalAttribute(agentId) {
  const attribute = await client.attributes.create({
    agent_id: agentId,
    type: 'behavioral',
    name: 'urgency_response',
    description: 'How the agent responds to urgent situations',
    
    // Dynamic value based on conditions
    value_logic: {
      type: 'conditional',
      conditions: [
        {
          if: 'ticket.priority === "critical"',
          then: { urgency: 100, response_time: 'immediate' }
        },
        {
          if: 'customer.tier === "vip" && ticket.priority === "high"',
          then: { urgency: 90, response_time: '5_minutes' }
        },
        {
          if: 'ticket.age > 24_hours',
          then: { urgency: 'urgency + 20', response_time: '30_minutes' }
        }
      ],
      default: { urgency: 50, response_time: '2_hours' }
    },
    
    // How this affects behavior
    behaviors: {
      high_urgency: [
        'Skip pleasantries',
        'Get to solution immediately',
        'Offer immediate escalation option',
        'Follow up proactively'
      ],
      low_urgency: [
        'Full greeting and rapport building',
        'Thorough explanation',
        'Educational approach'
      ]
    }
  });
  
  return attribute;
}
```

### Composite Personality Profiles

```javascript theme={null}
class PersonalityBuilder {
  async createPersonalityProfile(agentId, profileType) {
    const profiles = {
      technical_expert: {
        formality: 70,
        empathy: 50,
        technical_depth: 95,
        verbosity: 'detailed',
        solution_style: 'educational',
        proactivity: 80,
        emoji_usage: 0,
        code_examples: true
      },
      
      friendly_support: {
        formality: 20,
        empathy: 90,
        technical_depth: 40,
        verbosity: 'balanced',
        solution_style: 'step_by_step',
        proactivity: 70,
        emoji_usage: 80,
        humor_allowed: true
      },
      
      enterprise_account_manager: {
        formality: 90,
        empathy: 70,
        technical_depth: 60,
        verbosity: 'concise',
        solution_style: 'comprehensive',
        proactivity: 95,
        business_focus: true,
        upsell_awareness: 80
      },
      
      crisis_manager: {
        formality: 60,
        empathy: 85,
        urgency: 100,
        verbosity: 'concise',
        solution_style: 'quick_fix',
        escalation_threshold: 20,
        calm_reassurance: true
      }
    };
    
    const profile = profiles[profileType];
    const attributes = [];
    
    for (const [name, value] of Object.entries(profile)) {
      const attr = await client.attributes.create({
        agent_id: agentId,
        name,
        value,
        profile_group: profileType
      });
      attributes.push(attr);
    }
    
    return attributes;
  }
}
```

## Dynamic Attribute Adjustment

### Real-time Adaptation

```javascript theme={null}
class DynamicPersonality {
  constructor(agentId) {
    this.agentId = agentId;
    this.baselineAttributes = {};
    this.currentAttributes = {};
  }
  
  async adaptToContext(context) {
    const adjustments = this.calculateAdjustments(context);
    
    for (const [attribute, adjustment] of Object.entries(adjustments)) {
      await this.updateAttribute(attribute, adjustment);
    }
  }
  
  calculateAdjustments(context) {
    const adjustments = {};
    
    // Adjust formality based on customer
    if (context.customer.age > 60) {
      adjustments.formality = 20; // More formal
    } else if (context.customer.age < 25) {
      adjustments.formality = -20; // Less formal
    }
    
    // Adjust empathy based on sentiment
    if (context.sentiment === 'angry') {
      adjustments.empathy = 30;
      adjustments.patience = 40;
    }
    
    // Adjust technical level based on customer knowledge
    if (context.customer.technical_score > 80) {
      adjustments.technical_depth = 30;
      adjustments.verbosity = 'detailed';
    }
    
    // Adjust urgency based on issue type
    if (context.issue.type === 'outage') {
      adjustments.urgency = 50;
      adjustments.solution_style = 'quick_fix';
    }
    
    return adjustments;
  }
  
  async updateAttribute(name, adjustment) {
    const current = this.currentAttributes[name] || this.baselineAttributes[name];
    
    let newValue;
    if (typeof adjustment === 'number') {
      newValue = Math.max(0, Math.min(100, current + adjustment));
    } else {
      newValue = adjustment;
    }
    
    await client.attributes.update({
      agent_id: this.agentId,
      name,
      value: newValue
    });
    
    this.currentAttributes[name] = newValue;
  }
}
```

### Learning and Evolution

```javascript theme={null}
class EvolvingPersonality {
  async learnFromInteraction(agentId, conversation) {
    const feedback = await this.analyzeConversation(conversation);
    
    // Identify successful patterns
    if (feedback.satisfaction_score > 4.5) {
      await this.reinforceAttributes(agentId, conversation.attributes);
    }
    
    // Identify areas for improvement
    if (feedback.escalated || feedback.satisfaction_score < 3) {
      await this.adjustWeakAttributes(agentId, feedback.issues);
    }
    
    // Update long-term personality trends
    await this.updatePersonalityTrends(agentId, feedback);
  }
  
  async reinforceAttributes(agentId, successfulAttributes) {
    for (const [attr, value] of Object.entries(successfulAttributes)) {
      await client.attributes.updateTrend({
        agent_id: agentId,
        attribute: attr,
        trend_direction: 'towards',
        target_value: value,
        learning_rate: 0.1
      });
    }
  }
  
  async analyzeConversation(conversation) {
    return {
      satisfaction_score: conversation.rating,
      escalated: conversation.escalated,
      resolution_time: conversation.duration,
      sentiment_progression: this.analyzeSentiment(conversation),
      successful_tactics: this.identifySuccessfulTactics(conversation)
    };
  }
}
```

## Attribute Templates

### Industry-Specific Templates

```javascript theme={null}
const industryTemplates = {
  healthcare: {
    attributes: {
      compliance_awareness: 100,
      empathy: 85,
      privacy_consciousness: 100,
      medical_terminology: true,
      formality: 70
    },
    restricted_behaviors: ['humor', 'medical_advice'],
    required_confirmations: ['patient_identity', 'consent']
  },
  
  financial_services: {
    attributes: {
      accuracy_focus: 100,
      regulatory_compliance: 100,
      formality: 80,
      numerical_precision: true,
      security_awareness: 95
    },
    audit_trail: true,
    pii_handling: 'strict'
  },
  
  e_commerce: {
    attributes: {
      sales_awareness: 70,
      product_knowledge: 90,
      friendliness: 80,
      urgency_creation: 60,
      visual_description: true
    },
    upsell_enabled: true,
    abandoned_cart_recovery: true
  },
  
  saas_technical: {
    attributes: {
      technical_depth: 85,
      problem_solving: 'systematic',
      documentation_reference: true,
      code_literacy: 90,
      patience: 80
    },
    integration_knowledge: true,
    api_fluency: true
  }
};

async function applyIndustryTemplate(agentId, industry) {
  const template = industryTemplates[industry];
  
  if (!template) {
    throw new Error(`Unknown industry: ${industry}`);
  }
  
  // Apply all attributes
  for (const [name, value] of Object.entries(template.attributes)) {
    await client.attributes.create({
      agent_id: agentId,
      name,
      value,
      category: 'industry_standard',
      locked: true // Prevent accidental changes
    });
  }
  
  // Apply behavioral restrictions
  if (template.restricted_behaviors) {
    await client.agents.updateRestrictions({
      agent_id: agentId,
      restrictions: template.restricted_behaviors
    });
  }
  
  return template;
}
```

## Testing and Validation

### Personality Consistency Testing

```javascript theme={null}
class PersonalityTester {
  async testConsistency(agentId, scenarios) {
    const results = [];
    
    for (const scenario of scenarios) {
      const response = await this.runScenario(agentId, scenario);
      const analysis = await this.analyzeResponse(response, scenario.expected_attributes);
      
      results.push({
        scenario: scenario.name,
        consistency_score: analysis.consistency,
        attribute_alignment: analysis.alignment,
        deviations: analysis.deviations
      });
    }
    
    return {
      overall_consistency: this.calculateOverallConsistency(results),
      recommendations: this.generateRecommendations(results)
    };
  }
  
  async runScenario(agentId, scenario) {
    return client.agents.test({
      agent_id: agentId,
      input: scenario.input,
      context: scenario.context,
      expected_attributes: scenario.expected_attributes
    });
  }
  
  analyzeResponse(response, expectedAttributes) {
    const analysis = {
      consistency: 0,
      alignment: {},
      deviations: []
    };
    
    // Check each expected attribute
    for (const [attr, expected] of Object.entries(expectedAttributes)) {
      const actual = this.measureAttribute(response, attr);
      const deviation = Math.abs(actual - expected);
      
      analysis.alignment[attr] = {
        expected,
        actual,
        deviation
      };
      
      if (deviation > 20) {
        analysis.deviations.push({
          attribute: attr,
          severity: 'high',
          recommendation: `Adjust ${attr} baseline or add conditional logic`
        });
      }
    }
    
    analysis.consistency = 100 - (analysis.deviations.length * 10);
    return analysis;
  }
}
```

### A/B Testing Personalities

```javascript theme={null}
class PersonalityABTest {
  async runTest(agentId, variantA, variantB, duration) {
    const test = await client.experiments.create({
      type: 'personality_test',
      agent_id: agentId,
      variants: {
        control: variantA,
        treatment: variantB
      },
      metrics: ['satisfaction_score', 'resolution_time', 'escalation_rate'],
      duration,
      traffic_split: 50
    });
    
    // Monitor results
    const monitor = setInterval(async () => {
      const results = await client.experiments.getResults(test.id);
      
      if (results.significant) {
        await this.applyWinner(agentId, results.winner);
        clearInterval(monitor);
      }
    }, 3600000); // Check hourly
    
    return test;
  }
  
  async applyWinner(agentId, winningVariant) {
    await client.attributes.bulkUpdate({
      agent_id: agentId,
      attributes: winningVariant.attributes,
      source: 'ab_test_winner'
    });
  }
}
```

## Best Practices

### 1. Attribute Hierarchies

```javascript theme={null}
// Good: Clear hierarchy and relationships
const attributeHierarchy = {
  communication: {
    parent: null,
    children: ['tone', 'formality', 'verbosity'],
    weight: 1.0
  },
  tone: {
    parent: 'communication',
    children: ['friendliness', 'professionalism', 'empathy'],
    weight: 0.8
  },
  friendliness: {
    parent: 'tone',
    children: ['emoji_usage', 'casual_language'],
    weight: 0.6,
    constraints: {
      max_if: { formality: '> 80', value: 30 }
    }
  }
};

// Bad: Conflicting flat attributes
const flatAttributes = {
  friendly: 100,
  formal: 100, // Conflicts with friendly
  professional: 0 // Conflicts with formal
};
```

### 2. Context-Aware Defaults

```javascript theme={null}
// Good: Dynamic defaults based on context
const contextAwareDefaults = {
  getDefaultAttributes(context) {
    const defaults = { ...this.baseDefaults };
    
    // Time-based adjustments
    const hour = new Date().getHours();
    if (hour < 9 || hour > 17) {
      defaults.formality -= 10;
      defaults.brevity += 20;
    }
    
    // Channel-based adjustments
    if (context.channel === 'sms') {
      defaults.verbosity = 'concise';
      defaults.emoji_usage = 0;
    } else if (context.channel === 'chat') {
      defaults.response_speed = 'quick';
      defaults.emoji_usage = 40;
    }
    
    return defaults;
  }
};
```

### 3. Attribute Validation

```javascript theme={null}
class AttributeValidator {
  validateAttributes(attributes) {
    const errors = [];
    
    // Check for conflicts
    if (attributes.friendliness > 80 && attributes.formality > 80) {
      errors.push({
        type: 'conflict',
        message: 'High friendliness conflicts with high formality',
        suggestion: 'Consider professional_warmth instead'
      });
    }
    
    // Check for missing required attributes
    const required = ['empathy', 'clarity', 'helpfulness'];
    for (const req of required) {
      if (!(req in attributes)) {
        errors.push({
          type: 'missing',
          attribute: req,
          message: `Required attribute ${req} is missing`
        });
      }
    }
    
    // Check value ranges
    for (const [attr, value] of Object.entries(attributes)) {
      if (typeof value === 'number' && (value < 0 || value > 100)) {
        errors.push({
          type: 'range',
          attribute: attr,
          message: `${attr} value ${value} is out of range [0-100]`
        });
      }
    }
    
    return errors;
  }
}
```

## Monitoring and Analytics

### Attribute Performance Tracking

```javascript theme={null}
async function trackAttributePerformance(agentId) {
  const metrics = await client.attributes.getPerformanceMetrics({
    agent_id: agentId,
    timeframe: '30d',
    group_by: 'attribute'
  });
  
  const insights = {
    high_impact: metrics.filter(m => m.correlation_with_satisfaction > 0.7),
    low_impact: metrics.filter(m => m.correlation_with_satisfaction < 0.3),
    optimal_ranges: {},
    recommendations: []
  };
  
  // Find optimal ranges
  for (const metric of metrics) {
    const optimal = metric.satisfaction_by_value.reduce((best, current) => 
      current.satisfaction > best.satisfaction ? current : best
    );
    
    insights.optimal_ranges[metric.attribute] = {
      range: optimal.value_range,
      satisfaction: optimal.satisfaction
    };
  }
  
  return insights;
}
```

## Next Steps

<CardGroup cols={2}>
  <Card title="Personality Templates" icon="masks-theater" href="/guides/personality-templates">
    Pre-built personalities for common use cases
  </Card>

  <Card title="Emotional Intelligence" icon="heart" href="/guides/emotional-intelligence">
    Build agents that understand and respond to emotions
  </Card>
</CardGroup>

***

<Note>
  **Pro Tip**: Start with a base personality and use conditional attributes to adapt to specific situations. This provides consistency while allowing flexibility.
</Note>

For personality examples and templates, visit our [GitHub repository](https://github.com/StateSet/personality-templates) or contact [support@StateSet.com](mailto:support@StateSet.com).
