Skip to main content

Documentation Index

Fetch the complete documentation index at: https://docs.praison.ai/llms.txt

Use this file to discover all available pages before exploring further.

Agent Structured Output

PraisonAI supports generating structured JSON output with type safety using AI SDK’s generateObject capability. This ensures agents return data in a predictable format.

Quick Start

import { Agent } from 'praisonai';
import { z } from 'zod';

const agent = new Agent({
  instructions: 'You extract structured data from text',
  llm: 'openai/gpt-4o-mini'
});

// Define output schema
const PersonSchema = z.object({
  name: z.string(),
  age: z.number(),
  email: z.string().email().optional()
});

// Get structured output
const result = await agent.generateObject({
  prompt: 'Extract person info: John Doe is 30 years old, email john@example.com',
  schema: PersonSchema
});

console.log(result.object);
// { name: "John Doe", age: 30, email: "john@example.com" }

Using AI SDK Backend Directly

For more control, use the AI SDK backend directly:
import { resolveBackend } from 'praisonai';
import { z } from 'zod';

const { provider } = await resolveBackend('openai/gpt-4o-mini');

const WeatherSchema = z.object({
  location: z.string(),
  temperature: z.number(),
  unit: z.enum(['celsius', 'fahrenheit']),
  conditions: z.string()
});

const result = await provider.generateObject({
  messages: [
    { role: 'user', content: 'What is the weather in Paris?' }
  ],
  schema: WeatherSchema
});

console.log(result.object);
// { location: "Paris", temperature: 18, unit: "celsius", conditions: "partly cloudy" }

Schema Types

Using Zod Schemas

Zod is the recommended way to define schemas:
import { z } from 'zod';

// Simple object
const SimpleSchema = z.object({
  title: z.string(),
  count: z.number()
});

// Nested objects
const NestedSchema = z.object({
  user: z.object({
    name: z.string(),
    profile: z.object({
      bio: z.string(),
      links: z.array(z.string())
    })
  })
});

// Arrays
const ListSchema = z.object({
  items: z.array(z.object({
    id: z.number(),
    name: z.string(),
    active: z.boolean()
  }))
});

// Enums
const StatusSchema = z.object({
  status: z.enum(['pending', 'active', 'completed']),
  priority: z.enum(['low', 'medium', 'high'])
});

// Optional fields
const OptionalSchema = z.object({
  required: z.string(),
  optional: z.string().optional(),
  withDefault: z.string().default('default value')
});

Using JSON Schema

You can also use JSON Schema directly:
const jsonSchema = {
  type: 'object',
  properties: {
    name: { type: 'string' },
    age: { type: 'number' },
    tags: { 
      type: 'array',
      items: { type: 'string' }
    }
  },
  required: ['name', 'age']
};

const result = await provider.generateObject({
  messages: [{ role: 'user', content: 'Extract data...' }],
  schema: jsonSchema
});

Common Use Cases

Data Extraction

const ExtractedDataSchema = z.object({
  entities: z.array(z.object({
    name: z.string(),
    type: z.enum(['person', 'organization', 'location']),
    confidence: z.number().min(0).max(1)
  })),
  summary: z.string()
});

const agent = new Agent({
  instructions: 'Extract named entities from text',
  llm: 'openai/gpt-4o-mini'
});

const result = await agent.generateObject({
  prompt: 'Apple Inc. announced that Tim Cook will visit Tokyo next week.',
  schema: ExtractedDataSchema
});

Classification

const ClassificationSchema = z.object({
  category: z.enum(['spam', 'ham', 'uncertain']),
  confidence: z.number(),
  reasoning: z.string()
});

const result = await agent.generateObject({
  prompt: 'Classify this email: "You won $1,000,000! Click here!"',
  schema: ClassificationSchema
});
// { category: "spam", confidence: 0.95, reasoning: "..." }

Sentiment Analysis

const SentimentSchema = z.object({
  sentiment: z.enum(['positive', 'negative', 'neutral']),
  score: z.number().min(-1).max(1),
  aspects: z.array(z.object({
    aspect: z.string(),
    sentiment: z.enum(['positive', 'negative', 'neutral'])
  }))
});

API Response Generation

const APIResponseSchema = z.object({
  success: z.boolean(),
  data: z.object({
    id: z.string(),
    createdAt: z.string(),
    attributes: z.record(z.string())
  }),
  meta: z.object({
    version: z.string(),
    requestId: z.string()
  })
});

Error Handling

try {
  const result = await agent.generateObject({
    prompt: 'Extract data...',
    schema: MySchema
  });
  console.log(result.object);
} catch (error) {
  if (error.code === 'VALIDATION_ERROR') {
    console.error('Schema validation failed:', error.message);
  } else if (error.code === 'RATE_LIMIT') {
    console.error('Rate limited, retry later');
  } else {
    console.error('Generation failed:', error.message);
  }
}

Options

const result = await provider.generateObject({
  messages: [...],
  schema: MySchema,
  
  // Generation options
  maxTokens: 1000,
  temperature: 0.1,  // Lower for more deterministic output
  
  // Retry options
  maxRetries: 3,
  
  // Timeout
  timeout: 30000
});

TypeScript Integration

Full type safety with inferred types:
import { z } from 'zod';

const UserSchema = z.object({
  id: z.number(),
  name: z.string(),
  email: z.string().email()
});

// Type is inferred from schema
type User = z.infer<typeof UserSchema>;

const result = await agent.generateObject({
  prompt: 'Create a user',
  schema: UserSchema
});

// result.object is typed as User
const user: User = result.object;
console.log(user.name); // TypeScript knows this is string

Best Practices

  1. Use specific schemas: More specific schemas produce better results
  2. Add descriptions: Use .describe() to help the model understand fields
  3. Lower temperature: Use temperature: 0.1 for consistent output
  4. Validate output: Always validate the returned object matches expectations
  5. Handle errors: Implement proper error handling for validation failures
const DetailedSchema = z.object({
  title: z.string().describe('A concise title for the item'),
  description: z.string().describe('Detailed description, 2-3 sentences'),
  tags: z.array(z.string()).describe('Relevant tags, max 5'),
  priority: z.number().min(1).max(5).describe('Priority from 1 (low) to 5 (high)')
});

Multi-Agent Structured Output

Use structured output in multi-agent workflows:
import { Agent, AgentTeam } from 'praisonai';

const analyzer = new Agent({
  instructions: 'Analyze text and extract key points',
  llm: 'openai/gpt-4o-mini'
});

const summarizer = new Agent({
  instructions: 'Create structured summaries',
  llm: 'openai/gpt-4o-mini'
});

const SummarySchema = z.object({
  title: z.string(),
  keyPoints: z.array(z.string()),
  sentiment: z.enum(['positive', 'negative', 'neutral']),
  wordCount: z.number()
});

// Chain agents with structured output at the end
const agents = new AgentTeam([analyzer, summarizer]);
const result = await agents.start();

// Get structured output from final agent
const structured = await summarizer.generateObject({
  prompt: result,
  schema: SummarySchema
});