Lesson 6 of 8

Output Formatting & Structured Data

Getting consistent JSON, markdown, code, and structured responses

Why Output Formatting Matters

When building applications with LLMs, you often need structured, parseable output rather than free-form text. Proper formatting instructions help you get consistent JSON, code blocks, tables, or any structured format that your application can reliably process.

🎯 Formatting Goals

  • Parseability: Output that code can reliably parse (JSON, XML)
  • Consistency: Same structure every time for the same type of request
  • Completeness: All required fields present
  • Type Safety: Correct data types for each field

JSON Output

// Basic JSON request
"Extract entities from this text and return as JSON.

Text: 'Apple Inc. announced that CEO Tim Cook will visit 
the new Paris office on March 15, 2024.'

Return JSON with: companies, people, locations, dates"

// Better: Specify exact schema
"Extract entities from the text. Return a JSON object 
with this exact structure:

{
  "companies": [{ "name": string, "type": string }],
  "people": [{ "name": string, "role": string }],
  "locations": [{ "city": string, "country": string }],
  "dates": [{ "date": string, "context": string }]
}

Text: 'Apple Inc. announced that CEO Tim Cook will visit 
the new Paris office on March 15, 2024.'

Return ONLY the JSON, no other text."

// Response:
{
  "companies": [{ "name": "Apple Inc.", "type": "technology" }],
  "people": [{ "name": "Tim Cook", "role": "CEO" }],
  "locations": [{ "city": "Paris", "country": "France" }],
  "dates": [{ "date": "2024-03-15", "context": "office visit" }]
}

Ensuring Valid JSON

// Techniques for reliable JSON

// 1. Show complete example
"Generate a product listing in JSON format.

Example output:
{
  "id": "prod_123",
  "name": "Wireless Mouse",
  "price": 29.99,
  "inStock": true,
  "categories": ["electronics", "accessories"]
}

Generate a listing for: 'Bluetooth Keyboard with backlight'

Output the JSON only, with no markdown formatting or explanation."

// 2. Specify constraints
"Return a JSON object. Rules:
- Must be valid JSON (no trailing commas)
- Use double quotes for strings
- Numbers should not be quoted
- Booleans are true/false (not strings)
- Empty arrays are [] not null
- No comments in the JSON"

// 3. Use delimiters for extraction
"Return your response in this format:

```json
{ your json here }
```

This makes it easy to parse the JSON from the response."

// Parsing in code:
const jsonMatch = response.match(/```json\n([\s\S]*?)\n```/);
const data = JSON.parse(jsonMatch[1]);

TypeScript Interfaces from JSON

// Generate types along with data
"Generate TypeScript interfaces and sample data.

Task: Create types for a blog post system.

Return in this format:

INTERFACES:
```typescript
// Your interfaces here
```

SAMPLE DATA:
```json
// Sample data matching the interfaces
```

Include: Post, Author, Comment, Category"

// Response includes both parseable sections:

INTERFACES:
```typescript
interface Author {
  id: string;
  name: string;
  email: string;
  avatarUrl: string;
}

interface Comment {
  id: string;
  authorId: string;
  content: string;
  createdAt: string;
}

interface Post {
  id: string;
  title: string;
  content: string;
  author: Author;
  comments: Comment[];
  categories: string[];
  publishedAt: string | null;
}
```

SAMPLE DATA:
```json
{
  "id": "post_1",
  "title": "Getting Started with TypeScript",
  ...
}
```

Markdown Formatting

// Structured markdown output
"Create documentation for this API endpoint.

Use this exact markdown structure:

# Endpoint Name

## Description
[1-2 sentence description]

## HTTP Request
\`[METHOD] /path\`

## Parameters
| Name | Type | Required | Description |
|------|------|----------|-------------|
| ... | ... | ... | ... |

## Response
\`\`\`json
{example response}
\`\`\`

## Errors
| Code | Description |
|------|-------------|
| ... | ... |

Endpoint:
POST /api/users - Creates a new user with email and password"

Code Block Formatting

// Getting properly formatted code
"Write a React hook for form validation.

Format your response as:

HOOK CODE:
```typescript
// The complete hook implementation
```

USAGE EXAMPLE:
```typescript
// How to use the hook in a component
```

Requirements:
- TypeScript with proper types
- Support for email, required, and minLength validators
- Return errors object and isValid boolean"

// Code-only response
"Write a binary search function in JavaScript.

Return ONLY the code block, no explanations:

```javascript
// your code here
```"

Structured Lists

// Numbered steps with consistent format
"Explain how to set up a Next.js project.

Format as numbered steps:

1. **Step Title**
   - Command: `command here`
   - Explanation: Brief explanation

2. **Step Title**
   ...

Include exactly 5 steps from initialization to running the dev server."

// Checklists
"Create a code review checklist.

Format as a markdown checklist:

## Category Name
- [ ] Item 1
- [ ] Item 2

Include categories: Security, Performance, Code Quality, Testing"

// Comparison format
"Compare React and Vue.

Use this format for each aspect:

### [Aspect Name]
- **React**: [description]
- **Vue**: [description]
- **Winner**: [React/Vue/Tie] - [reason]

Compare: Learning Curve, Performance, Ecosystem, Job Market"

Handling Edge Cases

// Specify what to do when data is missing
"Extract product info as JSON. If a field is not found:
- Use null for missing optional fields
- Use empty array [] for missing lists
- Use 'UNKNOWN' for missing required strings

Schema:
{
  "name": string,         // required
  "price": number | null, // optional
  "description": string,  // required, use 'UNKNOWN' if missing
  "features": string[]    // use [] if missing
}

Text: 'iPhone 15 Pro - Buy now!'

JSON:"

// Validation in response
"Analyze this data and return JSON.

Before returning, validate:
1. All required fields are present
2. Numbers are valid (not NaN)
3. Dates are in ISO format

If validation fails, return:
{
  "success": false,
  "error": "description of the issue"
}

If validation passes, return:
{
  "success": true,
  "data": { ... }
}"

API Integration Patterns

// OpenAI Function Calling / Structured Outputs
const response = await openai.chat.completions.create({
  model: "gpt-4o",
  messages: [{ role: "user", content: "Extract user info from: ..." }],
  response_format: { 
    type: "json_schema",
    json_schema: {
      name: "user_info",
      schema: {
        type: "object",
        properties: {
          name: { type: "string" },
          email: { type: "string" },
          age: { type: "number" }
        },
        required: ["name", "email"]
      }
    }
  }
});

// Anthropic Tool Use for structured output
const response = await anthropic.messages.create({
  model: "claude-sonnet-4-20250514",
  tools: [{
    name: "extract_info",
    description: "Extract structured information",
    input_schema: {
      type: "object",
      properties: {
        name: { type: "string" },
        email: { type: "string" }
      }
    }
  }],
  tool_choice: { type: "tool", name: "extract_info" },
  messages: [{ role: "user", content: "Extract from: ..." }]
});

✅ Formatting Best Practices

  • • Always specify the exact schema/structure you want
  • • Use delimiters (backticks, tags) for parseable sections
  • • Include a complete example of desired output
  • • Specify how to handle missing or invalid data
  • • Use API features (function calling) when available
  • • Validate output in your code before using it