Skip to content

Instantly share code, notes, and snippets.

@tanaikech
Last active May 1, 2024 05:03
Show Gist options
  • Save tanaikech/0a55011d3e8b8fadebb71b624bb9a8af to your computer and use it in GitHub Desktop.
Save tanaikech/0a55011d3e8b8fadebb71b624bb9a8af to your computer and use it in GitHub Desktop.
Taming the Wild Output: Effective Control of Gemini API Response Formats with response_mime_type

Taming the Wild Output: Effective Control of Gemini API Response Formats with response_mime_type

Abstract

This report explores controlling output formats for the Gemini API. Traditionally, prompts dictated the format. A new property, "response_mime_type", allows specifying the format (e.g., JSON) directly. Testing confirms this property improves control over output format, especially for complex JSON schemas. The recommended approach is to combine a detailed JSON schema with "response_mime_type" for clear and consistent outputs.

Introduction

One of the key challenges when working with the Gemini API is ensuring the output data is in the format your application requires. Traditionally, the response format heavily relied on the specific prompt you provided. For example, retrieving data as a JSON object necessitated including a "Return JSON" prompt within your input text. This approach could be cumbersome and introduce potential errors if the desired format wasn't explicitly requested.

To address this limitation, a new property called "response_mime_type" was recently introduced as part of the GenerationConfig configuration. Ref and Ref This property allows you to explicitly specify the desired output format, such as JSON. This enhancement significantly improves the controllability and predictability of the Gemini API's response format.

This report builds upon my previous work on specifying output types for Gemini API using Google Apps Script. Ref Here, we'll delve deeper into testing the controllability of output formats using the "response_mime_type" property. We'll compare and analyze the behavior with and without this property, along with exploring its usage in function calls.

Usage

In order to test this script, please do the following steps.

1. Create an API key

Please access https://makersuite.google.com/app/apikey and create your API key. At that time, please enable Generative Language API at the API console. This API key is used for this sample script.

This official document can also be seen. Ref.

2. Create a Google Apps Script project

In this report, Google Apps Script is used. Of course, the method introducing this report can also be used in other languages.

Please create a standalone Google Apps Script project. Of course, this script can also be used with the container-bound script.

And, please open the script editor of the Google Apps Script project.

3. Base script

The base script is as follows.

  • sample1_: The output type is tried to control by the prompt.
  • sample2_: The output type is tried to control by the function call. This is from this report.
  • sample3_: The output type is tried to control by the property "response_mime_type".

When you use this script, please execute main function. But, in that case, please set your API key. In the following section, the value of prompt is changed and the result values are shown.

function sample1_({ apiKey, model, version, prompt }) {
  const url = `https://generativelanguage.googleapis.com/${version}/${model}:generateContent?key=${apiKey}`;
  const payload = { contents: [{ parts: [{ text: prompt }] }] };
  const options = {
    payload: JSON.stringify(payload),
    contentType: "application/json",
    muteHttpExceptions: true,
  };
  const res = UrlFetchApp.fetch(url, options);
  const obj = JSON.parse(res.getContentText());
  if (obj.candidates.length > 0 && obj.candidates[0].content.parts.length > 0) {
    return obj.candidates[0].content.parts[0].text;
  }
  return "No response.";
}

function sample2_({ apiKey, model, version, prompt }) {
  const functions = {
    customType_array: (e) => e.items,
    customType_object: (e) => e.items,
  };
  const url = `https://generativelanguage.googleapis.com/${version}/${model}:generateContent?key=${apiKey}`;
  const payload = {
    contents: [{ parts: [{ text: prompt }], role: "user" }],
    tools: [
      {
        function_declarations: [
          {
            name: "customType_array",
            description:
              "Output type is array type. When the output type is array type, this is used. No descriptions and explanations.",
            parameters: {
              type: "OBJECT",
              properties: {
                items: {
                  type: "ARRAY",
                  description:
                    "Output type is array type. When the output type is array type, this is used. No descriptions and explanations.",
                },
              },
              required: ["items"],
            },
          },
          {
            name: "customType_object",
            description:
              "Output type is JSON object type. When the output type is object type, this is used. No descriptions and explanations.",
            parameters: {
              type: "OBJECT",
              properties: {
                items: {
                  type: "OBJECT",
                  description:
                    "Output type is JSON object type. When the output type is object type, this is used. No descriptions and explanations.",
                },
              },
              required: ["items"],
            },
          },
        ],
      },
    ],
  };
  const options = {
    payload: JSON.stringify(payload),
    contentType: "application/json",
    muteHttpExceptions: true,
  };
  const res = UrlFetchApp.fetch(url, options);
  const { candidates } = JSON.parse(res.getContentText());
  const parts = (candidates && candidates[0]?.content?.parts) || [];
  const check = parts.find((o) => o.hasOwnProperty("functionCall"));
  if (check) {
    return functions[check.functionCall.name](check.functionCall.args || null);
  }
  return "No response.";
}

function sample3_({ apiKey, model, version, prompt }) {
  const url = `https://generativelanguage.googleapis.com/${version}/${model}:generateContent?key=${apiKey}`;
  const payload = {
    contents: [{ parts: [{ text: prompt }] }],
    generationConfig: { response_mime_type: "application/json" },
  };
  const options = {
    payload: JSON.stringify(payload),
    contentType: "application/json",
    muteHttpExceptions: true,
  };
  const res = UrlFetchApp.fetch(url, options);
  const obj = JSON.parse(res.getContentText());
  if (obj.candidates.length > 0 && obj.candidates[0].content.parts.length > 0) {
    return obj.candidates[0].content.parts[0].text;
  }
  return "No response.";
}

// This is a main function.
function main() {
  const prompt = "###"; // In this report, it tests by changing this value.

  const apiKey = "###"; // Please set your API key.
  const model = "models/gemini-1.5-pro-latest";
  const version = "v1beta";
  const functions = [sample1_, sample2_, sample3_];
  functions.forEach((f) => {
    const res = f({ apiKey, model, version, prompt });
    console.log(res);
  });
}

4. Sample prompts

In order to investigate the output formats from Gemini API, several prompts were tested as follows.

Sample 1

In this sample, the following script is run. The value of this prompt is from this official document.

function main() {
  const prompt =
    'List 5 popular cookie recipes using this JSON schema: { "type": "object", "properties": { "recipe_name": { "type": "string" },}}';

  const apiKey = "###"; // Please set your API key.
  const model = "models/gemini-1.5-pro-latest";
  const version = "v1beta";
  const functions = [sample1_, sample2_, sample3_];
  functions.forEach((f) => {
    const res = f({ apiKey, model, version, prompt });
    console.log(res);
  });
}

When this script is run, the following result is obtained.

From sample1_

```json
{
  "type": "object",
  "properties": {
    "recipe_name": {
      "type": "string",
      "enum": ["Chocolate Chip Cookies", "Peanut Butter Cookies", "Oatmeal Raisin Cookies", "Sugar Cookies", "Snickerdoodle Cookies"]
    }
  }
}
```

From sample2_

[ { recipe_name: 'Chocolate Chip Cookies' },
  { recipe_name: 'Peanut Butter Cookies' },
  { recipe_name: 'Oatmeal Raisin Cookies' },
  { recipe_name: 'Sugar Cookies' },
  { recipe_name: 'Shortbread Cookies' } ]

From sample3_

[
  {
    "recipe_name": "Chocolate Chip Cookies"
  },
  {
    "recipe_name": "Peanut Butter Cookies"
  },
  {
    "recipe_name": "Oatmeal Raisin Cookies"
  },
  {
    "recipe_name": "Sugar Cookies"
  },
  {
    "recipe_name": "Snickerdoodle Cookies"
  }
]

In the case of this prompt, sample1_ returned the updated structure of given JSON schema with the markdown format. The function call and the property "response_mime_type" returned the correct values. For example, when the following prompt is used,

const prompt = [
  `List 5 popular cookie recipes using this an array including JSON schema`,
  `<Format>`,
  `[{"recipe_name": "name"}]`,
  `</Format>`,
  `Return only array including JSON data. No markdown format. No descriptions.`,
].join("\n");

sample1_ returned the following result.

```json
[
  { "recipe_name": "Chocolate Chip Cookies" },
  { "recipe_name": "Peanut Butter Cookies" },
  { "recipe_name": "Oatmeal Raisin Cookies" },
  { "recipe_name": "Sugar Cookies" },
  { "recipe_name": "Snickerdoodles" }
]
```

Sample 2

In this sample, the following script is run. The value of this prompt was updated the prompt of this official document.

function main() {
  const jsonSchema = {
    title: "Recipe names",
    description: "Names of recipe.",
    type: "object",
    properties: {
      recipe_name: {
        description: "Names of recipe.",
        type: "string",
      },
      materials: {
        description: "Requirement materials for running the recipe.",
        type: "array",
        items: {
          description: "Requirement material for running the recipe.",
          type: "string",
        },
      },
    },
  };
  const prompt = [
    `List 5 popular cookie recipes and include the required materials for each recipe as JSON schema.`,
    `<JSONSchema>`,
    JSON.stringify(jsonSchema),
    `</JSONSchema>`,
    `Return only array including JSON data. No markdown format. No descriptions.`,
  ].join("\n");

  const apiKey = "###"; // Please set your API key.
  const model = "models/gemini-1.5-pro-latest";
  const version = "v1beta";
  const functions = [sample1_, sample2_, sample3_];
  functions.forEach((f) => {
    const res = f({ apiKey, model, version, prompt });
    console.log(res);
  });
}

When this script is run, the following result is obtained.

From sample1_

```json
[
  {
    "recipe_name": "Chocolate Chip Cookies",
    "materials": [
      "Flour",
      "Sugar",
      "Brown Sugar",
      "Eggs",
      "Butter",
      "Chocolate Chips",
      "Vanilla Extract",
      "Baking Soda",
      "Salt"
    ]
  },
  {
    "recipe_name": "Peanut Butter Cookies",
    "materials": [
      "Flour",
      "Sugar",
      "Brown Sugar",
      "Eggs",
      "Peanut Butter",
      "Vanilla Extract",
      "Baking Soda",
      "Salt"
    ]
  },
  {
    "recipe_name": "Oatmeal Raisin Cookies",
    "materials": [
      "Flour",
      "Sugar",
      "Brown Sugar",
      "Eggs",
      "Butter",
      "Oats",
      "Raisins",
      "Vanilla Extract",
      "Baking Soda",
      "Salt",
      "Cinnamon"
    ]
  },
  {
    "recipe_name": "Sugar Cookies",
    "materials": [
      "Flour",
      "Sugar",
      "Eggs",
      "Butter",
      "Vanilla Extract",
      "Baking Powder",
      "Salt"
    ]
  },
  {
    "recipe_name": "Snickerdoodle Cookies",
    "materials": [
      "Flour",
      "Sugar",
      "Eggs",
      "Butter",
      "Cream of Tartar",
      "Baking Soda",
      "Salt",
      "Cinnamon"
    ]
  }
]
```

From sample2_

[ { recipe_name: 'Chocolate Chip Cookies',
    materials: [ 'flour', 'sugar', 'chocolate chips', 'eggs', 'butter' ] },
  { recipe_name: 'Peanut Butter Cookies',
    materials: [ 'flour', 'sugar', 'peanut butter', 'eggs', 'butter' ] },
  { materials: [ 'flour', 'sugar', 'oats', 'raisins', 'eggs', 'butter' ],
    recipe_name: 'Oatmeal Raisin Cookies' },
  { materials: [ 'flour', 'sugar', 'eggs', 'butter', 'vanilla extract' ],
    recipe_name: 'Sugar Cookies' },
  { materials:
     [ 'flour',
       'sugar',
       'cinnamon',
       'eggs',
       'butter',
       'cream of tartar' ],
    recipe_name: 'Snickerdoodles' } ]

From sample3_

[
  {
    "recipe_name":"Chocolate Chip Cookies",
    "materials":[
      "flour",
      "sugar",
      "brown sugar",
      "eggs",
      "butter",
      "vanilla extract",
      "chocolate chips"
    ]
  },
  {
    "recipe_name":"Peanut Butter Cookies",
    "materials":[
      "flour",
      "sugar",
      "brown sugar",
      "eggs",
      "peanut butter",
      "vanilla extract",
      "baking soda",
      "salt"
    ]
  },
  {
    "recipe_name":"Oatmeal Raisin Cookies",
    "materials":[
      "flour",
      "sugar",
      "brown sugar",
      "eggs",
      "butter",
      "vanilla extract",
      "oats",
      "raisins",
      "cinnamon",
      "nutmeg"
    ]
  },
  {
    "recipe_name":"Sugar Cookies",
    "materials":[
      "flour",
      "sugar",
      "eggs",
      "butter",
      "vanilla extract",
      "baking powder",
      "salt"
    ]
  },
  {
    "recipe_name":"Snickerdoodles",
    "materials":[
      "flour",
      "sugar",
      "eggs",
      "butter",
      "cream of tartar",
      "baking soda",
      "cinnamon"
    ]
  }
]

From these results, it was found that Gemini API can correctly understand the JSON schema.

Sample 3

In this sample, the following script is run. The value of this prompt was updated more the prompt of this official document. The structure of the output JSON object is more complicated.

function main() {
  const jsonSchema = {
    title: "Recipe names",
    description: "Names of recipe.",
    type: "object",
    properties: {
      recipe_name: {
        description: "Names of recipe.",
        type: "string",
      },
      materials: {
        description: "Requirement materials for running the recipe.",
        type: "array",
        items: {
          type: "object",
          properties: {
            material: {
              description: "Requirement material for running the recipe.",
              type: "string",
            },
            amount: {
              description:
                "Requirement amount of material for running the recipe. Unit is grams.",
              type: "number",
            },
            cost: {
              description:
                "Cost of requirement material for running the recipe. Unit is dollar.",
              type: "number",
            },
          },
          required: ["material", "material", "cost"],
          additionalProperties: false,
        },
      },
    },
  };
  const prompt = [
    `List 5 popular cookie recipes and include the required materials and required amount of materials and costs for each recipe as JSON schema.`,
    `<JSONSchema>`,
    JSON.stringify(jsonSchema),
    `</JSONSchema>`,
    `Return only array including JSON data. No markdown format. No descriptions.`,
  ].join("\n");

  const apiKey = "###"; // Please set your API key.
  const model = "models/gemini-1.5-pro-latest";
  const version = "v1beta";
  const functions = [sample1_, sample2_, sample3_];
  functions.forEach((f) => {
    const res = f({ apiKey, model, version, prompt });
    console.log(res);
  });
}

When this script is run, the following result is obtained.

From sample1_

```json
[
  {
    "recipe_name": "Chocolate Chip Cookies",
    "materials": [
      {
        "material": "All-purpose flour",
        "amount": 225,
        "cost": 0.5
      },
      {
        "material": "Baking soda",
        "amount": 1,
        "cost": 0.1
      },
      {
        "material": "Salt",
        "amount": 0.5,
        "cost": 0.05
      },
      {
        "material": "Unsalted butter",
        "amount": 170,
        "cost": 2
      },
      {
        "material": "Granulated sugar",
        "amount": 100,
        "cost": 0.3
      },
      {
        "material": "Brown sugar",
        "amount": 150,
        "cost": 0.4
      },
      {
        "material": "Eggs",
        "amount": 100,
        "cost": 0.5
      },
      {
        "material": "Vanilla extract",
        "amount": 2,
        "cost": 0.2
      },
      {
        "material": "Chocolate chips",
        "amount": 300,
        "cost": 3
      }
    ]
  },
  {
    "recipe_name": "Peanut Butter Cookies",
    "materials": [
      {
        "material": "All-purpose flour",
        "amount": 150,
        "cost": 0.3
      },
      {
        "material": "Baking soda",
        "amount": 0.5,
        "cost": 0.05
      },
      {
        "material": "Salt",
        "amount": 0.5,
        "cost": 0.05
      },
      {
        "material": "Unsalted butter",
        "amount": 115,
        "cost": 1.38
      },
      {
        "material": "Peanut butter",
        "amount": 120,
        "cost": 1.5
      },
      {
        "material": "Granulated sugar",
        "amount": 75,
        "cost": 0.22
      },
      {
        "material": "Brown sugar",
        "amount": 75,
        "cost": 0.22
      },
      {
        "material": "Eggs",
        "amount": 50,
        "cost": 0.25
      },
      {
        "material": "Vanilla extract",
        "amount": 1,
        "cost": 0.1
      }
    ]
  },
  {
    "recipe_name": "Oatmeal Raisin Cookies",
    "materials": [
      {
        "material": "All-purpose flour",
        "amount": 150,
        "cost": 0.3
      },
      {
        "material": "Baking soda",
        "amount": 0.5,
        "cost": 0.05
      },
      {
        "material": "Salt",
        "amount": 0.25,
        "cost": 0.03
      },
      {
        "material": "Ground cinnamon",
        "amount": 1,
        "cost": 0.1
      },
      {
        "material": "Unsalted butter",
        "amount": 115,
        "cost": 1.38
      },
      {
        "material": "Granulated sugar",
        "amount": 75,
        "cost": 0.22
      },
      {
        "material": "Brown sugar",
        "amount": 75,
        "cost": 0.22
      },
      {
        "material": "Eggs",
        "amount": 50,
        "cost": 0.25
      },
      {
        "material": "Vanilla extract",
        "amount": 1,
        "cost": 0.1
      },
      {
        "material": "Rolled oats",
        "amount": 150,
        "cost": 0.5
      },
      {
        "material": "Raisins",
        "amount": 100,
        "cost": 1
      }
    ]
  },
  {
    "recipe_name": "Sugar Cookies",
    "materials": [
      {
        "material": "All-purpose flour",
        "amount": 300,
        "cost": 0.6
      },
      {
        "material": "Baking powder",
        "amount": 2,
        "cost": 0.15
      },
      {
        "material": "Salt",
        "amount": 1,
        "cost": 0.1
      },
      {
        "material": "Unsalted butter",
        "amount": 225,
        "cost": 2.7
      },
      {
        "material": "Granulated sugar",
        "amount": 150,
        "cost": 0.45
      },
      {
        "material": "Eggs",
        "amount": 50,
        "cost": 0.25
      },
      {
        "material": "Vanilla extract",
        "amount": 2,
        "cost": 0.2
      },
      {
        "material": "Almond extract",
        "amount": 1,
        "cost": 0.15
      }
    ]
  },
  {
    "recipe_name": "Shortbread Cookies",
    "materials": [
      {
        "material": "All-purpose flour",
        "amount": 255,
        "cost": 0.51
      },
      {
        "material": "Salt",
        "amount": 0.5,
        "cost": 0.05
      },
      {
        "material": "Unsalted butter",
        "amount": 225,
        "cost": 2.7
      },
      {
        "material": "Powdered sugar",
        "amount": 60,
        "cost": 0.3
      }
    ]
  }
]
```

From sample2_

No response.

In this case, the following error occurred. Unfortunately, when I tested this several times to sample2_, the following error often occurred.

{
  "error": {
    "code": 500,
    "message": "An internal error has occurred. Please retry or report in https://developers.generativeai.google/guide/troubleshooting",
    "status": "INTERNAL"
  }
}

From sample3_

[
  {
    "recipe_name":"Chocolate Chip Cookies",
    "materials":[
      {
        "material":"Butter",
        "amount":226,
        "cost":2.5
      },
      {
        "material":"White sugar",
        "amount":150,
        "cost":0.5
      },
      {
        "material":"Brown sugar",
        "amount":220,
        "cost":0.7
      },
      {
        "material":"Eggs",
        "amount":100,
        "cost":0.5
      },
      {
        "material":"Vanilla extract",
        "amount":5,
        "cost":0.5
      },
      {
        "material":"All-purpose flour",
        "amount":375,
        "cost":1
      },
      {
        "material":"Baking soda",
        "amount":5,
        "cost":0.2
      },
      {
        "material":"Hot water",
        "amount":2,
        "cost":0
      },
      {
        "material":"Salt",
        "amount":5,
        "cost":0.1
      },
      {
        "material":"Chocolate chips",
        "amount":340,
        "cost":3
      }
    ]
  },
  {
    "recipe_name":"Peanut Butter Cookies",
    "materials":[
      {
        "material":"Butter",
        "amount":115,
        "cost":1.25
      },
      {
        "material":"Peanut butter",
        "amount":115,
        "cost":1.5
      },
      {
        "material":"White sugar",
        "amount":70,
        "cost":0.25
      },
      {
        "material":"Brown sugar",
        "amount":70,
        "cost":0.25
      },
      {
        "material":"Egg",
        "amount":50,
        "cost":0.25
      },
      {
        "material":"Vanilla extract",
        "amount":5,
        "cost":0.5
      },
      {
        "material":"All-purpose flour",
        "amount":160,
        "cost":0.5
      },
      {
        "material":"Baking soda",
        "amount":2,
        "cost":0.05
      },
      {
        "material":"Salt",
        "amount":2,
        "cost":0.05
      }
    ]
  },
  {
    "recipe_name":"Oatmeal Cookies",
    "materials":[
      {
        "material":"Butter",
        "amount":115,
        "cost":1.25
      },
      {
        "material":"White sugar",
        "amount":150,
        "cost":0.5
      },
      {
        "material":"Brown sugar",
        "amount":115,
        "cost":0.5
      },
      {
        "material":"Eggs",
        "amount":100,
        "cost":0.5
      },
      {
        "material":"Vanilla extract",
        "amount":5,
        "cost":0.5
      },
      {
        "material":"All-purpose flour",
        "amount":190,
        "cost":0.6
      },
      {
        "material":"Baking soda",
        "amount":2,
        "cost":0.05
      },
      {
        "material":"Ground cinnamon",
        "amount":2,
        "cost":0.1
      },
      {
        "material":"Salt",
        "amount":2,
        "cost":0.05
      },
      {
        "material":"Oats",
        "amount":230,
        "cost":0.8
      }
    ]
  },
  {
    "recipe_name":"Sugar Cookies",
    "materials":[
      {
        "material":"Butter",
        "amount":226,
        "cost":2.5
      },
      {
        "material":"White sugar",
        "amount":150,
        "cost":0.5
      },
      {
        "material":"Eggs",
        "amount":100,
        "cost":0.5
      },
      {
        "material":"Vanilla extract",
        "amount":5,
        "cost":0.5
      },
      {
        "material":"All-purpose flour",
        "amount":340,
        "cost":1
      },
      {
        "material":"Baking powder",
        "amount":5,
        "cost":0.2
      },
      {
        "material":"Salt",
        "amount":2,
        "cost":0.05
      }
    ]
  },
  {
    "recipe_name":"Snickerdoodle Cookies",
    "materials":[
      {
        "material":"Butter",
        "amount":190,
        "cost":2
      },
      {
        "material":"Shortening",
        "amount":115,
        "cost":1
      },
      {
        "material":"White sugar",
        "amount":150,
        "cost":0.5
      },
      {
        "material":"Brown sugar",
        "amount":200,
        "cost":0.6
      },
      {
        "material":"Eggs",
        "amount":100,
        "cost":0.5
      },
      {
        "material":"Vanilla extract",
        "amount":5,
        "cost":0.5
      },
      {
        "material":"All-purpose flour",
        "amount":290,
        "cost":0.8
      },
      {
        "material":"Cream of tartar",
        "amount":4,
        "cost":0.2
      },
      {
        "material":"Baking soda",
        "amount":2,
        "cost":0.05
      },
      {
        "material":"Salt",
        "amount":2,
        "cost":0.05
      },
      {
        "material":"Ground cinnamon",
        "amount":15,
        "cost":0.5
      },
      {
        "material":"White sugar",
        "amount":40,
        "cost":0.15
      }
    ]
  }
]

From these results, it was found that the function call is not suitable for the complicated JSON schema.

Sample 4

From the above results, it is considered that the output format can be controlled by only the JSON schema with Gemini API as the following image.

So, I tested the following sample script. In this sample, only the function sample3_ is used. Please be careful about this.

function main() {
  const jsonSchema = {
    title: "5 popular cookie recipes",
    description:
      "List 5 popular cookie recipes by including the following properties.",
    type: "object",
    properties: {
      recipe_name: {
        description: "Names of recipe.",
        type: "string",
      },
      materials: {
        description: "Requirement materials for running the recipe.",
        type: "array",
        items: {
          type: "object",
          properties: {
            material: {
              description: "Requirement material for running the recipe.",
              type: "string",
            },
            amount: {
              description:
                "Requirement amount of material for running the recipe. Unit is grams.",
              type: "number",
            },
            cost: {
              description:
                "Cost of requirement material for running the recipe. Unit is dollar.",
              type: "number",
            },
          },
          required: ["material", "material", "cost"],
          additionalProperties: false,
        },
      },
    },
  };
  const prompt = [
    `Follow JSON schema.`,
    `<JSONSchema>`,
    JSON.stringify(jsonSchema),
    `</JSONSchema>`,
  ].join("\n");

  const apiKey = "###"; // Please set your API key.
  const model = "models/gemini-1.5-pro-latest";
  const version = "v1beta";
  const functions = [sample3_];
  functions.forEach((f) => {
    const res = f({ apiKey, model, version, prompt });
    console.log(res);
  });
}

When this script is run, the following result is obtained.

[
  {
    "recipe_name": "Chocolate Chip Cookies",
    "materials": [
      {
        "material": "Flour",
        "amount": 225,
        "cost": 2
      },
      {
        "material": "Baking Soda",
        "amount": 1,
        "cost": 0.5
      },
      {
        "material": "Salt",
        "amount": 0.5,
        "cost": 0.25
      },
      {
        "material": "Butter",
        "amount": 150,
        "cost": 4
      },
      {
        "material": "White Sugar",
        "amount": 100,
        "cost": 1
      },
      {
        "material": "Brown Sugar",
        "amount": 100,
        "cost": 1
      },
      {
        "material": "Eggs",
        "amount": 100,
        "cost": 2
      },
      {
        "material": "Vanilla Extract",
        "amount": 2,
        "cost": 1
      },
      {
        "material": "Chocolate Chips",
        "amount": 200,
        "cost": 3
      }
    ]
  },
  {
    "recipe_name": "Peanut Butter Cookies",
    "materials": [
      {
        "material": "Flour",
        "amount": 150,
        "cost": 1.5
      },
      {
        "material": "Baking Soda",
        "amount": 0.75,
        "cost": 0.37
      },
      {
        "material": "Salt",
        "amount": 0.5,
        "cost": 0.25
      },
      {
        "material": "Butter",
        "amount": 100,
        "cost": 2.5
      },
      {
        "material": "Peanut Butter",
        "amount": 100,
        "cost": 2
      },
      {
        "material": "White Sugar",
        "amount": 75,
        "cost": 0.75
      },
      {
        "material": "Brown Sugar",
        "amount": 75,
        "cost": 0.75
      },
      {
        "material": "Eggs",
        "amount": 50,
        "cost": 1
      },
      {
        "material": "Vanilla Extract",
        "amount": 1,
        "cost": 0.5
      }
    ]
  },
  {
    "recipe_name": "Oatmeal Raisin Cookies",
    "materials": [
      {
        "material": "Flour",
        "amount": 175,
        "cost": 1.75
      },
      {
        "material": "Baking Soda",
        "amount": 0.5,
        "cost": 0.25
      },
      {
        "material": "Salt",
        "amount": 0.5,
        "cost": 0.25
      },
      {
        "material": "Cinnamon",
        "amount": 1,
        "cost": 0.5
      },
      {
        "material": "Butter",
        "amount": 125,
        "cost": 3
      },
      {
        "material": "White Sugar",
        "amount": 75,
        "cost": 0.75
      },
      {
        "material": "Brown Sugar",
        "amount": 75,
        "cost": 0.75
      },
      {
        "material": "Eggs",
        "amount": 50,
        "cost": 1
      },
      {
        "material": "Vanilla Extract",
        "amount": 1,
        "cost": 0.5
      },
      {
        "material": "Oats",
        "amount": 150,
        "cost": 1.5
      },
      {
        "material": "Raisins",
        "amount": 100,
        "cost": 2
      }
    ]
  },
  {
    "recipe_name": "Sugar Cookies",
    "materials": [
      {
        "material": "Flour",
        "amount": 250,
        "cost": 2.5
      },
      {
        "material": "Baking Powder",
        "amount": 2,
        "cost": 1
      },
      {
        "material": "Salt",
        "amount": 0.5,
        "cost": 0.25
      },
      {
        "material": "Butter",
        "amount": 150,
        "cost": 4
      },
      {
        "material": "White Sugar",
        "amount": 125,
        "cost": 1.25
      },
      {
        "material": "Eggs",
        "amount": 50,
        "cost": 1
      },
      {
        "material": "Vanilla Extract",
        "amount": 1,
        "cost": 0.5
      }
    ]
  },
  {
    "recipe_name": "Shortbread Cookies",
    "materials": [
      {
        "material": "Flour",
        "amount": 250,
        "cost": 2.5
      },
      {
        "material": "Salt",
        "amount": 0.25,
        "cost": 0.12
      },
      {
        "material": "Butter",
        "amount": 200,
        "cost": 5
      },
      {
        "material": "White Sugar",
        "amount": 50,
        "cost": 0.5
      }
    ]
  }
]

From this result, it was found that when the detailed JSON schema and the "response_mime_type" property are used, the question can be simply like Follow JSON schema..

Summary

This report investigated the controllability of Gemini API output formats. It compared results with and without the "response_mime_type" property and function calls, while varying JSON schema complexity. The findings are as follows:

  • The Gemini API can correctly interpret JSON schemas.
  • For low-complexity JSON schemas, all tested patterns returned valid values.
  • High-complexity JSON schemas often resulted in a status code 500 error with the function call. Function calls proved ineffective for handling high complexity.
  • Combining a detailed JSON schema with the "response_mime_type" property allows for clear and concise queries. When the detailed JSON schema and the "response_mime_type" property are used, the question can be simply like Follow JSON schema..

Therefore, a detailed JSON schema with the "response_mime_type" property is recommended for controlling Gemini API output formats. Of course, the method introducing this report can also be used in other languages except for Google Apps Script.

Note

  • The top abstract image was created by Gemini.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment