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 output | Prefer text |
|---|---|
| Downstream code reads fields | Human-only chat reply |
| Enums drive workflow branching | Exploratory Q&A |
| APIs need predictable JSON | One-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
outputschema - Optional fields that downstream code treats as required
- Deeply nested objects nobody consumes
- Using structured output to paper over unclear instructions
Related#
- Agents
- Examples — structured weather
- Quick Start