User Profile
Structured facts about users.
The User Profile Store captures structured fields about users: name, preferred name, and custom fields you define.
| Aspect | Value |
|---|---|
| Scope | Per user |
| Persistence | Forever (updated as new info is learned) |
| Default mode | Always |
| Supported modes | Always, Agentic |
Basic Usage
1from kern.agent import Agent2from kern.db.postgres import PostgresDb3from kern.learn import LearningMachine4from kern.models.openai import OpenAIResponses56agent = Agent(7 model=OpenAIResponses(id="gpt-5.2"),8 db=PostgresDb(db_url="postgresql+psycopg://ai:ai@localhost:5532/ai"),9 learning=LearningMachine(user_profile=True),10)1112# Session 1: Share information13agent.print_response(14 "Hi! I'm Alice Chen, but please call me Ali.",15 user_id="alice@example.com",16 session_id="session_1",17)1819# Session 2: Profile is recalled automatically20agent.print_response(21 "What's my name?",22 user_id="alice@example.com",23 session_id="session_2",24)Always Mode
Extraction happens automatically after each response. No tools visible to the agent.
1from kern.learn import LearningMachine, LearningMode, UserProfileConfig23agent = Agent(4 model=OpenAIResponses(id="gpt-5.2"),5 db=db,6 learning=LearningMachine(7 user_profile=UserProfileConfig(mode=LearningMode.ALWAYS),8 ),9)Tradeoff: extra LLM call per interaction.
Agentic Mode
The agent receives an update_profile tool and decides when to update.
1from kern.learn import LearningMachine, LearningMode, UserProfileConfig23agent = Agent(4 model=OpenAIResponses(id="gpt-5.2"),5 db=db,6 learning=LearningMachine(7 user_profile=UserProfileConfig(mode=LearningMode.AGENTIC),8 ),9)1011agent.print_response(12 "Please remember that my name is Bob Smith.",13 user_id="bob@example.com",14)Tradeoff: agent may miss implicit profile info.
Default Fields
| Field | Description |
|---|---|
name | Full name |
preferred_name | Name they prefer to be called |
Custom Schemas
Extend the base schema for your domain:
1from dataclasses import dataclass, field2from typing import Optional3from kern.learn.schemas import UserProfile45@dataclass6class CustomerProfile(UserProfile):7 company: Optional[str] = field(8 default=None,9 metadata={"description": "Company or organization"}10 )11 plan_tier: Optional[str] = field(12 default=None,13 metadata={"description": "Subscription tier: free | pro | enterprise"}14 )15 role: Optional[str] = field(16 default=None,17 metadata={"description": "Job title or role"}18 )19 timezone: Optional[str] = field(20 default=None,21 metadata={"description": "User's timezone"}22 )2324agent = Agent(25 model=OpenAIResponses(id="gpt-5.2"),26 db=db,27 learning=LearningMachine(28 user_profile=UserProfileConfig(schema=CustomerProfile),29 ),30)The metadata["description"] tells the LLM what each field captures.
Accessing Profile Data
1lm = agent.get_learning_machine()23# Get profile4profile = lm.user_profile_store.get(user_id="alice@example.com")5print(profile.name)6print(profile.preferred_name)78# Debug output9lm.user_profile_store.print(user_id="alice@example.com")Context Injection
Profiles are automatically injected into the system prompt:
1<user_profile>2Name: Alice Chen3Preferred Name: Ali4Company: Acme Corp5Role: Data Scientist6</user_profile>No manual context building needed.
User Profile vs User Memory
| User Profile | User Memory |
|---|---|
| Structured fields | Unstructured text |
| Fixed schema | Flexible observations |
| Updated in place | Appended over time |
| Exact recall | Semantic search |
Use User Profile for: name, company, role, preferences with defined values.
Use User Memory for: observations like "prefers detailed explanations" or "works on ML projects."