Structured Output

Genkit can generate structured output that conforms to a schema that you provide. The data will be available on the output field of both chunks and responses.

Structured output can be streamed to display incremental progress.

Source Code

Image for: Source Code
// api/route.ts

import { genkit, z } from "genkit";
import { googleAI } from "@genkit-ai/googleai";

const ai = genkit({
  plugins: [googleAI()], // set the GOOGLE_API_KEY env variable
  model: googleAI.model('gemini-2.0-flash'),
});

import genkitEndpoint from "@/lib/genkit-endpoint";
import { CharacterSheetSchema } from "../schema";

export const POST = genkitEndpoint(
  { schema: z.object({ prompt: z.string() }) },
  ({ prompt }) =>
    ai.generateStream({
      prompt: `Generate an interesting Dungeons & Dragons character based on the following prompt: ${prompt}`,
      output: {
        schema: CharacterSheetSchema,
      },
    })
);
// schema.ts

import { z } from "genkit";

export const CharacterSheetSchema = z
  .object({
    name: z.string().describe("Character Name (Required, max 100 characters)"),
    race: z.string().describe("Character Race (Required, max 50 characters)"),
    class: z.string().describe("Character Class (Required, max 50 characters)"),
    level: z
      .number()
      .int()
      .describe("Character Level (Required, integer between 1 and 20)"),
    experiencePoints: z
      .number()
      .int()
      .describe("Experience Points (Required, non-negative integer)"),

    abilityScores: z
      .object({
        strength: z
          .number()
          .int()
          .describe("Strength Score (Required, integer between 1 and 30)"),
        dexterity: z
          .number()
          .int()
          .describe("Dexterity Score (Required, integer between 1 and 30)"),
        constitution: z
          .number()
          .int()
          .describe("Constitution Score (Required, integer between 1 and 30)"),
        intelligence: z
          .number()
          .int()
          .describe("Intelligence Score (Required, integer between 1 and 30)"),
        wisdom: z
          .number()
          .int()
          .describe("Wisdom Score (Required, integer between 1 and 30)"),
        charisma: z
          .number()
          .int()
          .describe("Charisma Score (Required, integer between 1 and 30)"),
      })
      .describe("Ability Scores"),

    hitPoints: z
      .number()
      .int()
      .describe("Hit Points (Required, non-negative integer)"),
    armorClass: z
      .number()
      .int()
      .describe("Armor Class (Required, non-negative integer)"),
    speed: z.number().int().describe("Speed (Required, non-negative integer)"),

    alignment: z
      .string()
      .describe(
        "Alignment (Required, one of: Lawful Good, Neutral Good, Chaotic Good, Lawful Neutral, Neutral, Chaotic Neutral, Lawful Evil, Neutral Evil, Chaotic Evil, max 50 characters)"
      ), // Example enum
    background: z.string().describe("Background (Required, max 50 characters)"), // Could also be an enum

    proficiencies: z
      .string()
      .array()
      .describe("Proficiencies (Array of strings)"),
    languages: z.string().array().describe("Languages (Array of strings)"),

    equipment: z.string().array().describe("Equipment (Array of strings)"),
    inventory: z.string().array().describe("Inventory (Array of strings)"),

    personalityTraits: z
      .string()
      .describe("Personality Traits (Optional, max 500 characters)"),
    ideals: z.string().describe("Ideals (Optional, max 500 characters)"),
    bonds: z.string().describe("Bonds (Optional, max 500 characters)"),
    flaws: z.string().describe("Flaws (Optional, max 500 characters)"),

    notes: z
      .string()
      .describe("Additional Notes (Optional, max 1000 characters)"),
  })
  .describe("D&D Character Sheet");

export type CharacterSheet = z.infer<typeof CharacterSheetSchema>;

D&D Character Generator

Genkit by Example uses cookies from Google to deliver and enhance the quality of its services and to analyze traffic.