DEV Community

Shrijith Venkatramana
Shrijith Venkatramana

Posted on

How To Generate Structured Output (JSON, YAML) in Gemini AI

Hi there! I'm Shrijith Venkatrama, the founder of Hexmos. Right now, I’m building LiveAPI, a super-convenient tool that simplifies engineering workflows by generating awesome API docs from your code in minutes.

Step 1: Get a Gemini API Key

Use Google's AI Studio to get a free API Key first.

We will be using the API key to make Gemini requests.

Step 2: Install SDK

Create a project and install dependency:

mkdir structured-gemini
cd structured-gemini
npm install @google/generative-ai
Enter fullscreen mode Exit fullscreen mode

Import the genai library and configure with API key in sg.mjs:

import { GoogleGenerativeAI } from "@google/generative-ai";

// Access your API key as an environment variable
const genAI = new GoogleGenerativeAI(process.env.API_KEY);
Enter fullscreen mode Exit fullscreen mode

Step 3: Generate a valid JSON using SchemaType

In this section, we will try to get gemini to give us the top 10 mystery movies of all time, with some metadata about each movie as an array of JSON objects.

Step 3.1 - Define Schema

import { GoogleGenerativeAI, SchemaType } from "@google/generative-ai";

const schema = {
  description: "Top 10 mystery movies of all time",
  type: SchemaType.ARRAY,
  items: {
    type: SchemaType.OBJECT,
    properties: {
      title: { type: SchemaType.STRING, description: "Title of the movie", nullable: false },
      director: { type: SchemaType.STRING, description: "Director of the movie", nullable: false },
      year: { type: SchemaType.INTEGER, description: "Year of release", nullable: false },
      imdbRating: { type: SchemaType.NUMBER, description: "IMDb rating of the movie", nullable: false },
    },
    required: ["title", "director", "year", "imdbRating"],
  },
};
Enter fullscreen mode Exit fullscreen mode

You can see that we are requesting an array of objects with highly specific requirements.

3.2 - Define Model

In the next step, we define a model, where we explicitly request a json response:

const model = genAI.getGenerativeModel({
  model: "gemini-1.5-pro",
  generationConfig: {
    responseMimeType: "application/json",
    responseSchema: schema,
  },
});
Enter fullscreen mode Exit fullscreen mode

3.3 Generate JSON and Pretty Print the Result

async function fetchMovies() {
  const result = await model.generateContent(
    "List the top 10 mystery movies of all time with their title, director, year of release, and IMDb rating."
  );
  let movies = JSON.parse(result.response.text())
  console.log(JSON.stringify(movies, null, 2));
}

fetchMovies().catch(console.error);
Enter fullscreen mode Exit fullscreen mode

When I run the above with node sg.mjs, I get the following output (pretty cool!):

[
  {
    "director": "Alfred Hitchcock",
    "imdbRating": 8.3,
    "title": "Vertigo",
    "year": 1958
  },
  {
    "director": "Orson Welles",
    "imdbRating": 8.3,
    "title": "Citizen Kane",
    "year": 1941
  },
  {
    "director": "Billy Wilder",
    "imdbRating": 8.3,
    "title": "Double Indemnity",
    "year": 1944
  },
  {
    "director": "Akira Kurosawa",
    "imdbRating": 8.2,
    "title": "Rashomon",
    "year": 1950
  },
  {
    "director": "John Huston",
    "imdbRating": 8.1,
    "title": "The Maltese Falcon",
    "year": 1941
  },
  {
    "director": "Carol Reed",
    "imdbRating": 8.1,
    "title": "The Third Man",
    "year": 1949
  },
  {
    "director": "Stanley Kubrick",
    "imdbRating": 8.3,
    "title": "2001: A Space Odyssey",
    "year": 1968
  },
  {
    "director": "David Fincher",
    "imdbRating": 8.2,
    "title": "Seven",
    "year": 1995
  },
  {
    "director": "Christopher Nolan",
    "imdbRating": 8.4,
    "title": "The Prestige",
    "year": 2006
  },
  {
    "director": "Rian Johnson",
    "imdbRating": 7.9,
    "title": "Knives Out",
    "year": 2019
  }
]
Enter fullscreen mode Exit fullscreen mode

Step 4: Getting a YAML version of the same output

Guess how difficult it'd be to get a YAML version of the same output?

I tried changing application/json to text/yaml in the mime field.

Turns out that doesn't work:

YAML Generation Failure

So, a workaround is to convert JSON to YAML, since JSON can easily be represented in YAML.

Get JSON to YAML converter

npm i @catalystic/json-to-yaml
Enter fullscreen mode Exit fullscreen mode

Import and use the converter

import { convert } from "@catalystic/json-to-yaml";

async function fetchMovies() {
  const result = await model.generateContent(
    "List the top 10 mystery movies of all time with their title, director, year of release, and IMDb rating."
  );
  let movies = JSON.parse(result.response.text())
  console.log(JSON.stringify(movies, null, 2));

  const yaml = convert(movies);
  console.log("\n==============\n")
  console.log(yaml)
}
Enter fullscreen mode Exit fullscreen mode

When I run this, I get the YAML output as expected:


  - director: "Alfred Hitchcock"
    imdbRating: 8.3
    title: "Vertigo"
    year: 1958
  - director: "Orson Welles"
    imdbRating: 8.3
    title: "Citizen Kane"
    year: 1941
  - director: "Billy Wilder"
    imdbRating: 8.3
    title: "Double Indemnity"
    year: 1944
  - director: "Akira Kurosawa"
    imdbRating: 8.2
    title: "Rashomon"
    year: 1950
  - director: "Carol Reed"
    imdbRating: 8.1
    title: "The Third Man"
    year: 1949
  - director: "John Huston"
    imdbRating: 8.1
    title: "The Maltese Falcon"
    year: 1941
  - director: "Stanley Kubrick"
    imdbRating: 8
    title: "2001: A Space Odyssey"
    year: 1968
  - director: "Roman Polanski"
    imdbRating: 8
    title: "Chinatown"
    year: 1974
  - director: "David Fincher"
    imdbRating: 8
    title: "Seven"
    year: 1995
  - director: "Christopher Nolan"
    imdbRating: 8
    title: "Memento"
    year: 2000
Enter fullscreen mode Exit fullscreen mode

Top comments (0)