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, 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 )Use the custom schema:
1from kern.learn import LearningMachine, UserProfileConfig23agent = 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 extraction2role: Optional[str] = field(3 default=None,4 metadata={"description": "Job title like 'Data Scientist' or 'Engineering Manager'"}5)67# Less effective: No description8role: Optional[str] = NoneUse Optional Fields
All custom fields should be Optional with defaults:
1# Good2company: Optional[str] = field(default=None, metadata={...})34# Bad: Required field will fail if not extracted5company: strDocument 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@dataclass2class 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@dataclass2class 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 EntityMemory23@dataclass4class 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 LearnedKnowledge23@dataclass4class 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, field2from typing import Optional3from kern.agent import Agent4from kern.db.postgres import PostgresDb5from kern.learn import LearningMachine, UserProfileConfig6from kern.learn.schemas import UserProfile7from kern.models.openai import OpenAIResponses89@dataclass10class 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 )2728agent = 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)3536# Custom fields extracted automatically37agent.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)