Structured Outputs

Validate final answers before another system consumes them.

Structured Outputs

Structured output gives a run a final contract. Instead of trusting free text, Shiro validates the model response with a schema that exposes .parse() before returning result.output.

Why it exists#

Agents feed tickets, workflows, databases, and APIs. Those consumers need fields, enums, and types — not a paragraph that usually contains a JSON blob.

import { Agent } from "@shiro-sdk/core";
import { z } from "zod";

const weatherOutput = z.object({
  city: z.string(),
  condition: z.string(),
  temperature: z.number(),
});

const agent = new Agent({
  name: "weather",
  instructions: "Return weather as structured data only.",
  provider: "openai",
  output: weatherOutput,
});

const result = await engine.execute(agent, "Sample weather for Pune: 24C, cloudy.");

// result.output is typed / parsed
console.log(result.output.city, result.output.temperature);

This matches the repo’s examples/basic-agent pattern.

When to use it#

Use structured outputPrefer text
Downstream code reads fieldsHuman-only chat reply
Enums drive workflow branchingExploratory Q&A
APIs need predictable JSONOne-off summaries

Validation and repair#

Validation failures are runtime events. Core includes output managers and repair strategies so a failed parse can be retried under policy instead of crashing silently. Always inspect traces when structured output flaps — see Tracing and Error Handling.

Best practices#

  • Keep schemas small and flat when possible
  • Prefer enums for decisions (priority, nextStep)
  • Validate before firing side effects that depend on the shape
  • Trace validation failures with the run id

Common mistakes#

  • Asking for JSON in the prompt without an output schema
  • Optional fields that downstream code treats as required
  • Deeply nested objects nobody consumes
  • Using structured output to paper over unclear instructions