Structured Input for Teams

Validate input data for teams with Pydantic models.

Pass structured data to teams using Pydantic models. You can either pass a model instance directly or set input_schema to validate dictionaries automatically.

Input Format Types

Use CaseInput Format
You're building the input in codeUse Pydantic Model instance
Input comes from external sources (APIs, files, user input)Use input_schema

Using Pydantic Models

Pass a Pydantic model instance to input:

1from pydantic import BaseModel, Field
2from kern.agent import Agent
3from kern.models.openai import OpenAIResponses
4from kern.team import Team
5from kern.tools.hackernews import HackerNewsTools
6from kern.tools.yfinance import YFinanceTools
7
8class ResearchProject(BaseModel):
9 topic: str
10 focus_areas: list[str] = Field(min_length=1)
11 max_sources: int = Field(ge=1, le=20, default=10)
12
13news_agent = Agent(
14 name="News Researcher",
15 role="Research tech news and trends",
16 tools=[HackerNewsTools()]
17)
18
19finance_agent = Agent(
20 name="Finance Researcher",
21 role="Research financial data",
22 tools=[YFinanceTools()]
23)
24
25team = Team(
26 name="Research Team",
27 model=OpenAIResponses(id="gpt-5.2"),
28 members=[news_agent, finance_agent],
29)
30
31# Pass the model instance directly
32project = ResearchProject(
33 topic="AI Agents",
34 focus_areas=["multi-agent systems", "tool use"],
35 max_sources=15
36)
37
38response = team.run(input=project)

Validation happens when you create the model instance. Invalid data raises a Pydantic ValidationError before the team runs.

Using input_schema

Set input_schema on the team to validate dictionaries automatically:

1from pydantic import BaseModel, Field
2from kern.agent import Agent
3from kern.models.openai import OpenAIResponses
4from kern.team import Team
5from kern.tools.hackernews import HackerNewsTools
6from kern.tools.yfinance import YFinanceTools
7
8class ResearchProject(BaseModel):
9 topic: str
10 focus_areas: list[str] = Field(min_length=1)
11 max_sources: int = Field(ge=1, le=20, default=10)
12
13news_agent = Agent(
14 name="News Researcher",
15 role="Research tech news and trends",
16 tools=[HackerNewsTools()]
17)
18
19finance_agent = Agent(
20 name="Finance Researcher",
21 role="Research financial data",
22 tools=[YFinanceTools()]
23)
24
25team = Team(
26 name="Research Team",
27 model=OpenAIResponses(id="gpt-5.2"),
28 members=[news_agent, finance_agent],
29 input_schema=ResearchProject,
30)
31
32# Pass a dict - validated against ResearchProject
33response = team.run(
34 input={
35 "topic": "AI Agents",
36 "focus_areas": ["multi-agent systems", "tool use"],
37 "max_sources": 15
38 }
39)

This is useful when input comes from external sources like API requests or configuration files.

Handling Input ValidationError

Invalid input raises a Pydantic ValidationError:

1from pydantic import BaseModel, Field, ValidationError
2
3class ResearchProject(BaseModel):
4 topic: str
5 focus_areas: list[str] = Field(min_length=1)
6
7team = Team(
8 model=OpenAIResponses(id="gpt-5.2"),
9 members=[news_agent, finance_agent],
10 input_schema=ResearchProject,
11)
12
13try:
14 team.run(input={"topic": "AI", "focus_areas": []}) # Empty list
15except ValidationError as e:
16 print(e)
17 # focus_areas: List should have at least 1 item

Common Patterns

Multi-Topic Research

1from pydantic import BaseModel, Field
2
3class ComparisonProject(BaseModel):
4 title: str
5 items_to_compare: list[str] = Field(min_length=2, max_length=5)
6 comparison_criteria: list[str]
7 output_format: str = Field(default="table")
8
9team = Team(
10 model=OpenAIResponses(id="gpt-5.2"),
11 members=[news_agent, finance_agent],
12 input_schema=ComparisonProject,
13)
14
15response = team.run(
16 input={
17 "title": "AI Framework Comparison",
18 "items_to_compare": ["Kern", "LangChain", "CrewAI"],
19 "comparison_criteria": ["performance", "ease of use", "documentation"],
20 "output_format": "table"
21 }
22)

Scoped Analysis

1from pydantic import BaseModel, Field
2from datetime import date
3
4class AnalysisScope(BaseModel):
5 company: str
6 analysis_type: str = Field(description="financial, competitive, or market")
7 start_date: date | None = None
8 end_date: date | None = None
9 include_competitors: bool = True
10
11team = Team(
12 model=OpenAIResponses(id="gpt-5.2"),
13 members=[news_agent, finance_agent],
14 input_schema=AnalysisScope,
15)
16
17response = team.run(
18 input={
19 "company": "NVIDIA",
20 "analysis_type": "competitive",
21 "include_competitors": True
22 }
23)

Nested Configuration

1from pydantic import BaseModel, Field
2
3class Source(BaseModel):
4 name: str
5 priority: int = Field(ge=1, le=3, default=2)
6
7class ResearchConfig(BaseModel):
8 topic: str
9 sources: list[Source]
10 depth: int = Field(ge=1, le=10, default=5)
11
12team = Team(
13 model=OpenAIResponses(id="gpt-5.2"),
14 members=[news_agent, finance_agent],
15 input_schema=ResearchConfig,
16)
17
18response = team.run(
19 input={
20 "topic": "Quantum Computing",
21 "sources": [
22 {"name": "HackerNews", "priority": 1},
23 {"name": "Financial Reports", "priority": 2}
24 ],
25 "depth": 7
26 }
27)

Related