User Profile

Structured facts about users.

The User Profile Store captures structured fields about users: name, preferred name, and custom fields you define.

AspectValue
ScopePer user
PersistenceForever (updated as new info is learned)
Default modeAlways
Supported modesAlways, Agentic

Basic Usage

1from kern.agent import Agent
2from kern.db.postgres import PostgresDb
3from kern.learn import LearningMachine
4from kern.models.openai import OpenAIResponses
5
6agent = 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)
11
12# Session 1: Share information
13agent.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)
18
19# Session 2: Profile is recalled automatically
20agent.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, UserProfileConfig
2
3agent = 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, UserProfileConfig
2
3agent = Agent(
4 model=OpenAIResponses(id="gpt-5.2"),
5 db=db,
6 learning=LearningMachine(
7 user_profile=UserProfileConfig(mode=LearningMode.AGENTIC),
8 ),
9)
10
11agent.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

FieldDescription
nameFull name
preferred_nameName they prefer to be called

Custom Schemas

Extend the base schema for your domain:

1from dataclasses import dataclass, field
2from typing import Optional
3from kern.learn.schemas import UserProfile
4
5@dataclass
6class 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 )
23
24agent = 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()
2
3# Get profile
4profile = lm.user_profile_store.get(user_id="alice@example.com")
5print(profile.name)
6print(profile.preferred_name)
7
8# Debug output
9lm.user_profile_store.print(user_id="alice@example.com")

Context Injection

Profiles are automatically injected into the system prompt:

1<user_profile>
2Name: Alice Chen
3Preferred Name: Ali
4Company: Acme Corp
5Role: Data Scientist
6</user_profile>

No manual context building needed.

User Profile vs User Memory

User ProfileUser Memory
Structured fieldsUnstructured text
Fixed schemaFlexible observations
Updated in placeAppended over time
Exact recallSemantic 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."