Custom Schemas

Extend stores with custom fields for your domain.

Learning stores use predefined schemas by default. Extend them with custom fields to capture domain-specific information.

Extending User Profile

The default UserProfile includes name and preferred_name. Add fields 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 )

Use the custom schema:

1from kern.learn import LearningMachine, UserProfileConfig
2
3agent = Agent(
4 model=OpenAIResponses(id="gpt-5.2"),
5 db=db,
6 learning=LearningMachine(
7 user_profile=UserProfileConfig(schema=CustomerProfile),
8 ),
9)

Field Guidelines

Use Metadata Descriptions

The metadata={"description": ...} tells the LLM what to extract:

1# Good: Clear description guides extraction
2role: Optional[str] = field(
3 default=None,
4 metadata={"description": "Job title like 'Data Scientist' or 'Engineering Manager'"}
5)
6
7# Less effective: No description
8role: Optional[str] = None

Use Optional Fields

All custom fields should be Optional with defaults:

1# Good
2company: Optional[str] = field(default=None, metadata={...})
3
4# Bad: Required field will fail if not extracted
5company: str

Document Constrained Values

For fields with known options, list them in the description:

1plan_tier: Optional[str] = field(
2 default=None,
3 metadata={"description": "Subscription tier: free | pro | enterprise"}
4)

Domain Examples

SaaS Support

1@dataclass
2class SupportProfile(UserProfile):
3 company: Optional[str] = field(
4 default=None,
5 metadata={"description": "Company name"}
6 )
7 plan: Optional[str] = field(
8 default=None,
9 metadata={"description": "Plan: starter | professional | enterprise"}
10 )
11 account_id: Optional[str] = field(
12 default=None,
13 metadata={"description": "Account or customer ID"}
14 )
15 primary_use_case: Optional[str] = field(
16 default=None,
17 metadata={"description": "Main use case or workflow"}
18 )

Developer Tools

1@dataclass
2class DeveloperProfile(UserProfile):
3 primary_language: Optional[str] = field(
4 default=None,
5 metadata={"description": "Primary language: python | javascript | go | rust"}
6 )
7 framework: Optional[str] = field(
8 default=None,
9 metadata={"description": "Primary framework: react | django | fastapi"}
10 )
11 experience_years: Optional[int] = field(
12 default=None,
13 metadata={"description": "Years of programming experience"}
14 )
15 editor: Optional[str] = field(
16 default=None,
17 metadata={"description": "Editor: vscode | neovim | intellij"}
18 )

Extending Other Schemas

Entity Memory

1from kern.learn.schemas import EntityMemory
2
3@dataclass
4class CompanyEntity(EntityMemory):
5 industry: Optional[str] = field(
6 default=None,
7 metadata={"description": "Industry: fintech | healthcare | saas"}
8 )
9 funding_stage: Optional[str] = field(
10 default=None,
11 metadata={"description": "Stage: seed | series_a | series_b | public"}
12 )
13 employee_count: Optional[int] = field(
14 default=None,
15 metadata={"description": "Number of employees"}
16 )

Learned Knowledge

1from kern.learn.schemas import LearnedKnowledge
2
3@dataclass
4class TechnicalInsight(LearnedKnowledge):
5 applicable_languages: Optional[List[str]] = field(
6 default=None,
7 metadata={"description": "Languages this applies to"}
8 )
9 performance_impact: Optional[str] = field(
10 default=None,
11 metadata={"description": "Performance impact: high | medium | low"}
12 )
13 complexity: Optional[str] = field(
14 default=None,
15 metadata={"description": "Complexity: simple | moderate | complex"}
16 )

Full Example

1from dataclasses import dataclass, field
2from typing import Optional
3from kern.agent import Agent
4from kern.db.postgres import PostgresDb
5from kern.learn import LearningMachine, UserProfileConfig
6from kern.learn.schemas import UserProfile
7from kern.models.openai import OpenAIResponses
8
9@dataclass
10class EnterpriseProfile(UserProfile):
11 company: Optional[str] = field(
12 default=None,
13 metadata={"description": "Company name"}
14 )
15 department: Optional[str] = field(
16 default=None,
17 metadata={"description": "Department: engineering | sales | marketing"}
18 )
19 role: Optional[str] = field(
20 default=None,
21 metadata={"description": "Job title"}
22 )
23 region: Optional[str] = field(
24 default=None,
25 metadata={"description": "Region: NA | EMEA | APAC"}
26 )
27
28agent = Agent(
29 model=OpenAIResponses(id="gpt-5.2"),
30 db=PostgresDb(db_url="postgresql+psycopg://ai:ai@localhost:5532/ai"),
31 learning=LearningMachine(
32 user_profile=UserProfileConfig(schema=EnterpriseProfile),
33 ),
34)
35
36# Custom fields extracted automatically
37agent.print_response(
38 "Hi, I'm Sarah Chen, VP of Engineering at Acme Corp. We're the EMEA team.",
39 user_id="sarah@acme.com",
40)