Structured Output

Enforce exact response formats using schemas like Zod, ensuring predictable and validated data every time.

Overview

Structured output allows you to define the exact shape of the data you expect from the AI. This is essential for building reliable applications where you need to process AI responses programmatically.

Note

Mozaik uses Zod for schema validation. Make sure to install it:yarn add zod

Basic Example

Define a schema and pass it to your command:

structured-basic.ts
1import { z } from 'zod'
2import { MozaikAgent, MozaikRequest } from '@mozaik-ai/core'
3
4// Define your output schema
5const mealPlanSchema = z.object({
6 calories: z.number(),
7 meals: z.array(z.object({
8 name: z.string(),
9 description: z.string(),
10 ingredients: z.array(z.string()).min(3)
11 })).length(3),
12 shoppingList: z.array(z.string())
13})
14
15// Create command with structured output
16const request: MozaikRequest = {
17 model: 'gpt-5-mini',
18 task: 'Create a 1-day vegetarian meal plan with breakfast, lunch, and dinner.',
19 structuredOutput: mealPlanSchema
20}
21
22const agent = new MozaikAgent(request)
23const mealPlan = await agent.act()
24
25// mealPlan is fully typed!
26console.log(mealPlan.meals[0].name)
27console.log(mealPlan.shoppingList)

Complex Schemas

You can create complex, nested schemas for sophisticated use cases:

structured-complex.ts
1import { z } from 'zod'
2import { MozaikAgent, MozaikRequest } from '@mozaik-ai/core'
3
4// Define a code review schema
5const codeReviewSchema = z.object({
6 summary: z.string(),
7 score: z.number().min(0).max(100),
8 issues: z.array(z.object({
9 severity: z.enum(['critical', 'warning', 'info']),
10 line: z.number().optional(),
11 message: z.string(),
12 suggestion: z.string()
13 })),
14 suggestions: z.array(z.string()),
15 approved: z.boolean()
16})
17
18const request: MozaikRequest = {
19 model: 'claude-sonnet-4.5',
20 task: 'Review this TypeScript code for best practices and potential bugs.',
21 structuredOutput: codeReviewSchema,
22 messages: [
23 { role: 'user', content: 'const data = fetch(url); console.log(data)' }
24 ]
25}
26
27const agent = new MozaikAgent(request)
28const review = await agent.act()
29
30if (!review.approved) {
31 console.log('Issues found:', review.issues)
32}

Type Inference

Zod schemas automatically infer TypeScript types:

type-inference.ts
1import { z } from 'zod'
2
3const userSchema = z.object({
4 name: z.string(),
5 email: z.string().email(),
6 age: z.number().optional(),
7 role: z.enum(['admin', 'user', 'guest'])
8})
9
10// Infer the TypeScript type from the schema
11type User = z.infer<typeof userSchema>
12
13// Now you have full type safety
14const processUser = (user: User) => {
15 console.log(user.name) // string
16 console.log(user.role) // 'admin' | 'user' | 'guest'
17}

Best Practices

  • Be specific: The more detailed your schema, the more accurate the AI's response will be.
  • Use enums: When you have a fixed set of options, use z.enum() instead of strings.
  • Add constraints: Use .min(), .max(), .length() to enforce data quality.
  • Keep schemas reusable: Define schemas in separate files and reuse them across agents.

Next Steps