Structured Output for Teams
Get validated Pydantic object from team instead of raw text.
Set output_schema on a team to constrain its final response to a Pydantic model. The team leader synthesizes member outputs into a validated object.
Basic Usage
1from pydantic import BaseModel, Field2from kern.agent import Agent3from kern.models.openai import OpenAIResponses4from kern.team import Team5from kern.tools.hackernews import HackerNewsTools6from kern.tools.yfinance import YFinanceTools78class ResearchReport(BaseModel):9 title: str10 summary: str = Field(description="Executive summary of findings")11 key_insights: list[str] = Field(description="Top 3-5 insights")12 recommendation: str1314news_agent = Agent(15 name="News Researcher",16 role="Research tech news and trends",17 tools=[HackerNewsTools()]18)1920finance_agent = Agent(21 name="Finance Analyst",22 role="Analyze financial data and stocks",23 tools=[YFinanceTools()]24)2526team = Team(27 name="Research Team",28 model=OpenAIResponses(id="gpt-5.2"),29 members=[news_agent, finance_agent],30 output_schema=ResearchReport,31)3233response = team.run("Research NVIDIA - analyze stock performance and recent news")3435# response.content is a validated ResearchReport object36report: ResearchReport = response.content37print(report.title)38print(report.summary)39print(report.recommendation)How It Works
When a team has output_schema set:
- The team leader delegates tasks to members
- Members execute and return their results
- The leader synthesizes all member outputs
- The final response is structured according to your schema
Only the team's final output is structured. Individual member responses remain unstructured unless those members have their own output_schema.
Control output_schema Per-Run
Override or set the schema at run time:
1team = Team(2 model=OpenAIResponses(id="gpt-5.2"),3 members=[news_agent, finance_agent],4)56# Different schemas for different requests7report = team.run("Analyze AI market", output_schema=MarketReport)8comparison = team.run("Compare NVDA vs AMD", output_schema=StockComparison)Control output_schema Per Member/Team
You can set output_schema on both individual members and the team:
1from pydantic import BaseModel, Field2from kern.agent import Agent3from kern.models.openai import OpenAIResponses4from kern.team import Team5from kern.tools.hackernews import HackerNewsTools6from kern.tools.yfinance import YFinanceTools78# Member schemas9class NewsInsights(BaseModel):10 headlines: list[str]11 sentiment: str = Field(description="positive, negative, or neutral")1213class FinanceInsights(BaseModel):14 price: float15 change_percent: float16 recommendation: str1718# Team schema19class CombinedReport(BaseModel):20 summary: str21 market_sentiment: str22 stock_outlook: str23 final_recommendation: str2425news_agent = Agent(26 name="News Analyst",27 role="Research news",28 tools=[HackerNewsTools()],29 output_schema=NewsInsights,30)3132finance_agent = Agent(33 name="Finance Analyst",34 role="Analyze stocks",35 tools=[YFinanceTools()],36 output_schema=FinanceInsights,37)3839team = Team(40 model=OpenAIResponses(id="gpt-5.2"),41 members=[news_agent, finance_agent],42 output_schema=CombinedReport,43)4445response = team.run("Full analysis of NVDA")46report: CombinedReport = response.contentMember schemas ensure consistent intermediate outputs. The team schema controls the final synthesized response.
Schema Design Tips
Aggregate Multiple Perspectives
Design schemas that capture synthesized insights:
1class CompetitiveAnalysis(BaseModel):2 company: str3 market_position: str = Field(description="Leader, challenger, or follower")4 technical_strengths: list[str] = Field(description="From technical research")5 financial_strengths: list[str] = Field(description="From financial analysis")6 combined_outlook: strInclude Confidence and Reasoning
1class InvestmentRecommendation(BaseModel):2 ticker: str3 action: str = Field(description="buy, hold, or sell")4 price_target: float | None = None5 reasoning: str = Field(description="Synthesized reasoning from all analysts")6 risk_factors: list[str]7 confidence: float = Field(ge=0, le=1)Structured Comparisons
1class CompanyComparison(BaseModel):2 companies: list[str]3 winner: str4 comparison_criteria: list[str]5 scores: dict[str, dict[str, int]] # company -> criterion -> score6 summary: strFallback with use_json_mode
Enable JSON mode for models that don't support structured output natively:
1team = Team(2 model=SomeModel(),3 members=[...],4 output_schema=MySchema,5 use_json_mode=True,6)JSON mode instructs the model to respond in JSON but doesn't guarantee schema compliance. Prefer models with native structured output support.
Related
- Agent Structured Output: Configure structured output for agents
- Team Structured Input: Validate input for teams
- Output Model: Use a separate model to structure output