How PersonalityProvider Manages Agent Personality and System Prompts in Heurist Agent Framework
The PersonalityProvider class assembles dynamic system prompts by combining a base configuration with randomly sampled personality traits from a YAML file, ensuring each LLM interaction receives consistent instructions with varied character flavor.
The PersonalityProvider in the heurist-network/heurist-agent-framework serves as the central component for defining how AI agents behave and respond. By managing both static system instructions and dynamic personality attributes, this class enables developers to create agents with consistent core behaviors while maintaining variety in individual interactions.
Understanding the PersonalityProvider Architecture
Configuration Loading via PromptConfig Singleton
The PersonalityProvider initializes by creating a PromptConfig singleton instance defined in core/config.py. This singleton reads the default prompts.yaml file located at agents/config/ and parses sections including system.base, character.basic_settings, character.interaction_styles, and character.name.
When instantiated with an optional config_path parameter, the provider attempts to load a custom YAML file and merge its contents into the singleton's dictionary. This merge capability allows projects to override default personalities without modifying core framework files, as implemented in lines 25-33 of core/components/personality_provider.py.
Core Methods for Personality Retrieval
The class exposes several getter methods that interface directly with the PromptConfig singleton:
get_system_prompt()forwards toPromptConfig.get_system_prompt(), returning thesystem.basevalue from the configurationget_name()retrieves the character identifier fromcharacter.nameget_basic_settings()andget_interaction_styles()return the raw lists defined under their respective configuration keys
These methods provide direct access to personality components while maintaining abstraction from the underlying YAML structure.
How PersonalityProvider Builds System Prompts
Sampling Random Personality Traits
The get_formatted_personality() method (lines 53-65 in core/components/personality_provider.py) implements the core personality randomization logic. This method:
- Retrieves the base system prompt as the foundation
- Randomly samples up to two items from the
basic_settingslist - Randomly samples up to two items from the
interaction_styleslist - Concatenates these sampled traits into a "settings" clause
This sampling approach ensures that each conversation initialization receives a unique combination of personality attributes while maintaining the core behavioral constraints defined in the base prompt.
Formatting the Final Prompt String
The method appends the sampled traits to the base system prompt using a structured format. The final output combines:
- The stable
system.baseinstructions (defining task constraints and capabilities) - The dynamic personality clause (providing behavioral flavor and interaction style)
This concatenated string serves as the complete system prompt transmitted to the LLM during chat.completions.create or equivalent API calls.
Practical Implementation Examples
Creating a standard provider instance uses the default configuration:
from core.components.personality_provider import PersonalityProvider
# Initialize with default prompts.yaml
provider = PersonalityProvider()
# Retrieve base system prompt
system_prompt = provider.get_system_prompt()
print("System prompt:", system_prompt)
# Get agent name
agent_name = provider.get_name()
print("Agent name:", agent_name)
To generate a dynamic personality prompt for LLM integration:
# Get formatted personality with random traits
formatted_prompt = provider.get_formatted_personality()
print("\nFull prompt sent to LLM:\n", formatted_prompt)
For custom personality configurations:
custom_path = "/my/project/custom_prompts.yaml"
provider = PersonalityProvider(config_path=custom_path)
# Custom YAML merges with defaults
print(provider.get_formatted_personality())
Integration with an LLM client:
from openai import AsyncOpenAI
client = AsyncOpenAI()
async def chat(message: str):
prompt = provider.get_formatted_personality()
response = await client.chat.completions.create(
model="gpt-4o-mini",
messages=[
{"role": "system", "content": prompt},
{"role": "user", "content": message}
]
)
return response.choices[0].message.content
Summary
- The
PersonalityProviderclass incore/components/personality_provider.pycentralizes agent personality management and system prompt generation. - It utilizes a
PromptConfigsingleton to load YAML configurations fromagents/config/prompts.yaml, supporting custom config paths for project-specific overrides. - The
get_formatted_personality()method constructs dynamic prompts by combining a stable base system prompt with randomly sampled traits frombasic_settingsandinteraction_styles. - This architecture ensures consistent core behavior while providing variety in agent personality across different conversations.
Frequently Asked Questions
What file format does PersonalityProvider use for configuration?
The PersonalityProvider uses YAML files for configuration, specifically expecting a prompts.yaml structure. By default, it loads from agents/config/prompts.yaml, which contains nested sections like system.base, character.name, character.basic_settings, and character.interaction_styles. The provider can also accept custom YAML paths via the config_path parameter during initialization.
How does PersonalityProvider ensure variety in agent responses?
Variety is achieved through the get_formatted_personality() method, which randomly samples up to two items from the basic_settings list and up to two items from the interaction_styles list each time it is called. These sampled traits are appended to the base system prompt, creating a unique personality flavor for every conversation initialization while maintaining the core behavioral constraints defined in the stable system.base configuration.
Can I override the default personality configuration?
Yes, the PersonalityProvider supports configuration overrides through the optional config_path parameter in its constructor. When provided, the provider attempts to load the specified YAML file and merge its contents into the PromptConfig singleton's dictionary. This merge capability allows projects to customize personality traits, interaction styles, or system prompts without modifying the core framework files in agents/config/.
Where is the system prompt base text defined?
The base system prompt text is defined in the system.base section of the prompts.yaml configuration file. The PersonalityProvider retrieves this value through the get_system_prompt() method, which internally calls PromptConfig.get_system_prompt() as implemented in core/config.py (lines 50-52). This base text provides the stable foundation upon which dynamic personality traits are layered.
Have a question about this repo?
These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:
curl -s "https://instagit.com/install.md" Maintain an open-source project? Get it listed too →