स्ट्रक्चर्ड आउटपुट

Gemini को अनस्ट्रक्चर्ड टेक्स्ट के बजाय स्ट्रक्चर्ड आउटपुट के लिए कॉन्फ़िगर किया जा सकता है. इससे, आगे की प्रोसेसिंग के लिए जानकारी को सटीक तरीके से निकाला जा सकता है और उसे स्टैंडर्ड किया जा सकता है. उदाहरण के लिए, स्ट्रक्चर्ड आउटपुट का इस्तेमाल करके, रीज़्यूमे से जानकारी निकाली जा सकती है. साथ ही, स्ट्रक्चर्ड डेटाबेस बनाने के लिए, उन्हें स्टैंडर्ड किया जा सकता है.

Gemini, स्ट्रक्चर्ड आउटपुट के तौर पर JSON या enum वैल्यू जनरेट कर सकता है.

JSON जनरेट करना

Gemini API का इस्तेमाल करके JSON जनरेट करने के दो तरीके हैं:

  • मॉडल पर स्कीमा कॉन्फ़िगर करना
  • टेक्स्ट प्रॉम्प्ट में स्कीमा देना

मॉडल पर स्कीमा कॉन्फ़िगर करना, JSON जनरेट करने का सुझाया गया तरीका है, क्योंकि इससे मॉडल को JSON आउटपुट करने के लिए बाध्य किया जाता है.

स्कीमा कॉन्फ़िगर करना (सुझाया गया)

JSON जनरेट करने के लिए मॉडल को सीमित करने के लिए, responseSchema कॉन्फ़िगर करें. इसके बाद, मॉडल किसी भी प्रॉम्प्ट का जवाब, JSON फ़ॉर्मैट में देगा.

from google import genai
from pydantic import BaseModel

class Recipe(BaseModel):
    recipe_name: str
    ingredients: list[str]

client = genai.Client(api_key="GOOGLE_API_KEY")
response = client.models.generate_content(
    model="gemini-2.0-flash",
    contents="List a few popular cookie recipes, and include the amounts of ingredients.",
    config={
        "response_mime_type": "application/json",
        "response_schema": list[Recipe],
    },
)
# Use the response as a JSON string.
print(response.text)

# Use instantiated objects.
my_recipes: list[Recipe] = response.parsed
import { GoogleGenAI, Type } from "@google/genai";

const ai = new GoogleGenAI({ "GOOGLE_API_KEY" });

async function main() {
  const response = await ai.models.generateContent({
    model: "gemini-2.0-flash",
    contents:
      "List a few popular cookie recipes, and include the amounts of ingredients.",
    config: {
      responseMimeType: "application/json",
      responseSchema: {
        type: Type.ARRAY,
        items: {
          type: Type.OBJECT,
          properties: {
            recipeName: {
              type: Type.STRING,
            },
            ingredients: {
              type: Type.ARRAY,
              items: {
                type: Type.STRING,
              },
            },
          },
          propertyOrdering: ["recipeName", "ingredients"],
        },
      },
    },
  });

  console.log(response.text);
}

main();
package main

import (
    "context"
    "fmt"
    "log"

    "google.golang.org/genai"
)

func main() {
    ctx := context.Background()
    client, err := genai.NewClient(ctx, &genai.ClientConfig{
        APIKey:  "GOOGLE_API_KEY",
        Backend: genai.BackendGeminiAPI,
    })
    if err != nil {
        log.Fatal(err)
    }

    config := &genai.GenerateContentConfig{
        ResponseMIMEType: "application/json",
        ResponseSchema: &genai.Schema{
            Type: genai.TypeArray,
            Items: &genai.Schema{
                Type: genai.TypeObject,
                Properties: map[string]*genai.Schema{
                    "recipeName": {Type: genai.TypeString},
                    "ingredients": {
                        Type:  genai.TypeArray,
                        Items: &genai.Schema{Type: genai.TypeString},
                    },
                },
                PropertyOrdering: []string{"recipeName", "ingredients"},
            },
        },
    }

    result, err := client.Models.GenerateContent(
        ctx,
        "gemini-2.0-flash",
        genai.Text("List a few popular cookie recipes, and include the amounts of ingredients."),
        config,
    )
    if err != nil {
        log.Fatal(err)
    }
    fmt.Println(result.Text())
}
curl "https://generativelanguage.googleapis.com/v1beta/models/gemini-2.0-flash:generateContent?key=$GOOGLE_API_KEY" \
-H 'Content-Type: application/json' \
-d '{
      "contents": [{
        "parts":[
          { "text": "List a few popular cookie recipes, and include the amounts of ingredients." }
        ]
      }],
      "generationConfig": {
        "responseMimeType": "application/json",
        "responseSchema": {
          "type": "ARRAY",
          "items": {
            "type": "OBJECT",
            "properties": {
              "recipeName": { "type": "STRING" },
              "ingredients": {
                "type": "ARRAY",
                "items": { "type": "STRING" }
              }
            },
            "propertyOrdering": ["recipeName", "ingredients"]
          }
        }
      }
}' 2> /dev/null | head

आउटपुट कुछ ऐसा दिख सकता है:

[
  {
    "recipeName": "Chocolate Chip Cookies",
    "ingredients": [
      "1 cup (2 sticks) unsalted butter, softened",
      "3/4 cup granulated sugar",
      "3/4 cup packed brown sugar",
      "1 teaspoon vanilla extract",
      "2 large eggs",
      "2 1/4 cups all-purpose flour",
      "1 teaspoon baking soda",
      "1 teaspoon salt",
      "2 cups chocolate chips"
    ]
  },
  ...
]

टेक्स्ट प्रॉम्प्ट में स्कीमा देना

स्कीमा को कॉन्फ़िगर करने के बजाय, टेक्स्ट प्रॉम्प्ट में स्कीमा को सामान्य भाषा या स्यूडो-कोड के तौर पर दिया जा सकता है. इस तरीके का सुझाव नहीं दिया जाता, क्योंकि इससे खराब क्वालिटी का आउटपुट मिल सकता है. साथ ही, मॉडल को स्कीमा का पालन करने की ज़रूरत नहीं होती.

यहां टेक्स्ट प्रॉम्प्ट में दिए गए स्कीमा का एक सामान्य उदाहरण दिया गया है:

List a few popular cookie recipes, and include the amounts of ingredients.

Produce JSON matching this specification:

Recipe = { "recipeName": string, "ingredients": array<string> }
Return: array<Recipe>

मॉडल को प्रॉम्प्ट में मौजूद टेक्स्ट से स्कीमा मिलता है. इसलिए, स्कीमा को दिखाने के तरीके में आपको कुछ विकल्प मिल सकते हैं. हालांकि, इस तरह स्कीमा को इनलाइन में देने पर, मॉडल को JSON फ़ॉर्मैट में नतीजे दिखाने की ज़रूरत नहीं होती. बेहतर क्वालिटी का और ज़्यादा सटीक जवाब पाने के लिए, मॉडल पर स्कीमा कॉन्फ़िगर करें. साथ ही, टेक्स्ट प्रॉम्प्ट में स्कीमा की डुप्लीकेट कॉपी न बनाएं.

enum वैल्यू जनरेट करना

कुछ मामलों में, हो सकता है कि आप मॉडल को विकल्पों की सूची से कोई एक विकल्प चुनने के लिए कहें. इस तरह के व्यवहार को लागू करने के लिए, अपने स्कीमा में enum पास किया जा सकता है. responseSchema में string का इस्तेमाल करने के लिए, कहीं भी एनम विकल्प का इस्तेमाल किया जा सकता है. ऐसा इसलिए है, क्योंकि एनम स्ट्रिंग का कलेक्शन होता है. JSON स्कीमा की तरह, किसी एलिमेंट के लिए वैल्यू के तौर पर तय की गई वैल्यू की सूची से, अपने ऐप्लिकेशन की ज़रूरतों के हिसाब से मॉडल के आउटपुट को सीमित किया जा सकता है.

उदाहरण के लिए, मान लें कि आपने एक ऐसा ऐप्लिकेशन डेवलप किया है जिसमें संगीत वाले इंस्ट्रूमेंट को इन पांच कैटगरी में से किसी एक में बांटा जाता है: "Percussion", "String", "Woodwind", "Brass" या ""Keyboard"". इस काम में मदद पाने के लिए, एक एनम बनाएं.

नीचे दिए गए उदाहरण में, responseSchema के तौर पर एक एनम पास किया गया है. इससे मॉडल को सबसे सही विकल्प चुनने में मदद मिलती है.

Python
from google import genai
import enum

class Instrument(enum.Enum):
  PERCUSSION = "Percussion"
  STRING = "String"
  WOODWIND = "Woodwind"
  BRASS = "Brass"
  KEYBOARD = "Keyboard"

client = genai.Client(api_key="GEMINI_API_KEY")
response = client.models.generate_content(
    model='gemini-2.0-flash',
    contents='What type of instrument is an oboe?',
    config={
        'response_mime_type': 'text/x.enum',
        'response_schema': Instrument,
    },
)

print(response.text)
# Woodwind

Python लाइब्रेरी, एपीआई के लिए टाइप के एलान का अनुवाद करेगी. हालांकि, एपीआई, OpenAPI 3.0 स्कीमा (स्कीमा) के सबसेट को स्वीकार करता है.

एनोटेशन की वैल्यू तय करने के दो और तरीके हैं. Literal का इस्तेमाल इनके लिए किया जा सकता है:

Python
Literal["Percussion", "String", "Woodwind", "Brass", "Keyboard"]

स्कीमा को JSON के तौर पर भी पास किया जा सकता है:

Python
from google import genai

client = genai.Client(api_key="GEMINI_API_KEY")
response = client.models.generate_content(
    model='gemini-2.0-flash',
    contents='What type of instrument is an oboe?',
    config={
        'response_mime_type': 'text/x.enum',
        'response_schema': {
            "type": "STRING",
            "enum": ["Percussion", "String", "Woodwind", "Brass", "Keyboard"],
        },
    },
)

print(response.text)
# Woodwind

कई विकल्पों वाले बुनियादी सवालों के अलावा, JSON स्कीमा में कहीं भी एनम का इस्तेमाल किया जा सकता है. उदाहरण के लिए, मॉडल से रेसिपी के टाइटल की सूची मांगी जा सकती है. साथ ही, हर टाइटल को लोकप्रियता का ग्रेड देने के लिए, Grade एनम का इस्तेमाल किया जा सकता है:

Python
from google import genai

import enum
from pydantic import BaseModel

class Grade(enum.Enum):
    A_PLUS = "a+"
    A = "a"
    B = "b"
    C = "c"
    D = "d"
    F = "f"

class Recipe(BaseModel):
  recipe_name: str
  rating: Grade

client = genai.Client(api_key="GEMINI_API_KEY")
response = client.models.generate_content(
    model='gemini-2.0-flash',
    contents='List 10 home-baked cookie recipes and give them grades based on tastiness.',
    config={
        'response_mime_type': 'application/json',
        'response_schema': list[Recipe],
    },
)

print(response.text)

जवाब कुछ इस तरह दिख सकता है:

[
  {
    "recipe_name": "Chocolate Chip Cookies",
    "rating": "a+"
  },
  {
    "recipe_name": "Peanut Butter Cookies",
    "rating": "a"
  },
  {
    "recipe_name": "Oatmeal Raisin Cookies",
    "rating": "b"
  },
  ...
]

JSON स्कीमा के बारे में जानकारी

responseSchema पैरामीटर का इस्तेमाल करके, JSON आउटपुट के लिए मॉडल को कॉन्फ़िगर करने के लिए, Schema ऑब्जेक्ट का इस्तेमाल किया जाता है. यह ऑब्जेक्ट, OpenAPI 3.0 स्कीमा ऑब्जेक्ट के चुनिंदा सबसेट को दिखाता है. साथ ही, इसमें propertyOrdering फ़ील्ड भी जोड़ा जाता है.

यहां सभी Schema फ़ील्ड का सूडो-JSON वर्शन दिया गया है:

{
  "type": enum (Type),
  "format": string,
  "description": string,
  "nullable": boolean,
  "enum": [
    string
  ],
  "maxItems": integer,
  "minItems": integer,
  "properties": {
    string: {
      object (Schema)
    },
    ...
  },
  "required": [
    string
  ],
  "propertyOrdering": [
    string
  ],
  "items": {
    object (Schema)
  }
}

स्कीमा का Type, OpenAPI के डेटा टाइप में से कोई एक होना चाहिए या उन टाइप का यूनियन (anyOf का इस्तेमाल करके) होना चाहिए. हर Type के लिए, सिर्फ़ फ़ील्ड का एक सबसेट मान्य है. नीचे दी गई सूची में, हर Type को उस टाइप के लिए मान्य फ़ील्ड के सबसेट पर मैप किया गया है:

  • string -> enum, format, nullable
  • integer -> format, minimum, maximum, enum, nullable
  • number -> format, minimum, maximum, enum, nullable
  • boolean -> nullable
  • array -> minItems, maxItems, items, nullable
  • object -> properties, required, propertyOrdering, nullable

यहां टाइप और फ़ील्ड के मान्य कॉम्बिनेशन दिखाने वाले कुछ स्कीमा के उदाहरण दिए गए हैं:

{ "type": "string", "enum": ["a", "b", "c"] }

{ "type": "string", "format": "date-time" }

{ "type": "integer", "format": "int64" }

{ "type": "number", "format": "double" }

{ "type": "boolean" }

{ "type": "array", "minItems": 3, "maxItems": 3, "items": { "type": ... } }

{ "type": "object",
  "properties": {
    "a": { "type": ... },
    "b": { "type": ... },
    "c": { "type": ... }
  },
  "nullable": true,
  "required": ["c"],
  "propertyOrdering": ["c", "b", "a"]
}

Gemini API में इस्तेमाल किए गए स्कीमा फ़ील्ड का पूरा दस्तावेज़ देखने के लिए, स्कीमा रेफ़रंस देखें.

प्रॉपर्टी ऑर्डर करना

Gemini API में JSON स्कीमा के साथ काम करते समय, प्रॉपर्टी का क्रम ज़रूरी होता है. डिफ़ॉल्ट रूप से, एपीआई प्रॉपर्टी को वर्णमाला के क्रम में लगाता है. साथ ही, वह उस क्रम को सेव नहीं करता जिसमें प्रॉपर्टी तय की गई हैं. हालांकि, Google जनरेटिव एआई SDK टूल इस क्रम को सेव कर सकते हैं. अगर कॉन्फ़िगर किए गए स्कीमा के साथ मॉडल को उदाहरण दिए जा रहे हैं और उदाहरणों की प्रॉपर्टी का क्रम, स्कीमा की प्रॉपर्टी के क्रम से मेल नहीं खाता है, तो आउटपुट गलत या अनचाहा हो सकता है.

प्रॉपर्टी की क्रम से लगाई गई सूची में कोई बदलाव न हो, इसके लिए propertyOrdering[] फ़ील्ड का इस्तेमाल किया जा सकता है. हालांकि, ऐसा करना ज़रूरी नहीं है.

"propertyOrdering": ["recipeName", "ingredients"]

propertyOrdering[] – यह OpenAPI स्पेसिफ़िकेशन में स्टैंडर्ड फ़ील्ड नहीं है. यह एक स्ट्रिंग कलेक्शन है, जिसका इस्तेमाल रिस्पॉन्स में प्रॉपर्टी के क्रम को तय करने के लिए किया जाता है. प्रॉपर्टी का क्रम तय करके, उसी क्रम में प्रॉपर्टी के उदाहरण देने से, नतीजों की क्वालिटी को बेहतर बनाया जा सकता है. propertyOrdering का इस्तेमाल सिर्फ़ तब किया जा सकता है, जब आपने मैन्युअल तरीके से types.Schema बनाया हो.

Python में स्कीमा

Python लाइब्रेरी का इस्तेमाल करते समय, response_schema की वैल्यू इनमें से कोई एक होनी चाहिए:

  • टाइप, जिसका इस्तेमाल टाइप एनोटेशन में किया जाता है (Python का typing मॉड्यूल देखें)
  • genai.types.Schema का एक उदाहरण
  • genai.types.Schema के बराबर dict

स्कीमा तय करने का सबसे आसान तरीका, Pydantic टाइप का इस्तेमाल करना है. जैसा कि पिछले उदाहरण में दिखाया गया है:

Python
config={'response_mime_type': 'application/json',
        'response_schema': list[Recipe]}

Pydantic टाइप का इस्तेमाल करने पर, Python लाइब्रेरी आपके लिए एक JSON स्कीमा बनाती है और उसे एपीआई को भेजती है. ज़्यादा उदाहरणों के लिए, Python लाइब्रेरी के दस्तावेज़ देखें.

Python लाइब्रेरी, इन टाइप के स्कीमा के साथ काम करती है (जहां AllowedType, अनुमति वाला कोई भी टाइप है):

  • int
  • float
  • bool
  • str
  • list[AllowedType]
  • AllowedType|AllowedType|...
  • स्ट्रक्चर्ड टाइप के लिए:
    • dict[str, AllowedType]. यह एनोटेशन, डिक्शनरी की सभी वैल्यू को एक ही टाइप का बताता है. हालांकि, यह नहीं बताता कि किन कुंजियों को शामिल किया जाना चाहिए.
    • उपयोगकर्ता के तय किए गए Pydantic मॉडल. इस तरीके से, आपको पासकोड के नाम तय करने और हर पासकोड से जुड़ी वैल्यू के लिए अलग-अलग टाइप तय करने की सुविधा मिलती है. इनमें नेस्ट किए गए स्ट्रक्चर भी शामिल हैं.

सबसे सही तरीके

रिस्पॉन्स स्कीमा का इस्तेमाल करते समय, इन बातों और सबसे सही तरीकों का ध्यान रखें:

  • आपके रिस्पॉन्स स्कीमा का साइज़, इनपुट टोकन की सीमा में गिना जाता है.
  • डिफ़ॉल्ट रूप से, फ़ील्ड ज़रूरी नहीं होते. इसका मतलब है कि मॉडल, फ़ील्ड में अपने-आप जानकारी भर सकता है या उन्हें छोड़ सकता है. मॉडल को वैल्यू देने के लिए, ज़रूरत के हिसाब से फ़ील्ड सेट किए जा सकते हैं. अगर उससे जुड़े इनपुट प्रॉम्प्ट में ज़रूरत के मुताबिक संदर्भ नहीं है, तो मॉडल मुख्य रूप से उस डेटा के आधार पर जवाब जनरेट करता है जिस पर उसे ट्रेन किया गया था.
  • जटिल स्कीमा की वजह से, InvalidArgument: 400 गड़बड़ी हो सकती है. प्रॉपर्टी के लंबे नाम, लंबी ऐरे की सीमा, कई वैल्यू वाले एन्सम, कई वैकल्पिक प्रॉपर्टी वाले ऑब्जेक्ट या इन फ़ैक्टर के कॉम्बिनेशन की वजह से, कॉन्फ़िगरेशन जटिल हो सकता है.

    अगर आपको मान्य स्कीमा के साथ यह गड़बड़ी दिखती है, तो गड़बड़ी को ठीक करने के लिए इनमें से एक या एक से ज़्यादा बदलाव करें:

    • प्रॉपर्टी के नाम या एनम के नाम छोटे करें.
    • नेस्ट किए गए ऐरे को फ़्लैट करें.
    • सीमाओं वाली प्रॉपर्टी की संख्या कम करें. जैसे, संख्याओं के लिए तय की गई कम से कम और ज़्यादा से ज़्यादा सीमा.
    • जटिल शर्तों वाली प्रॉपर्टी की संख्या कम करें. जैसे, date-time जैसे जटिल फ़ॉर्मैट वाली प्रॉपर्टी.
    • वैकल्पिक प्रॉपर्टी की संख्या कम करें.
    • एन्सम के लिए मान्य वैल्यू की संख्या कम करें.
  • अगर आपको अपनी उम्मीद के मुताबिक नतीजे नहीं दिख रहे हैं, तो अपने इनपुट प्रॉम्प्ट में ज़्यादा जानकारी जोड़ें या जवाब के स्कीमा में बदलाव करें. उदाहरण के लिए, मॉडल के रिस्पॉन्स को स्ट्रक्चर्ड आउटपुट के बिना देखें, ताकि यह पता चल सके कि मॉडल कैसे जवाब देता है. इसके बाद, अपने जवाब के स्कीमा को अपडेट किया जा सकता है, ताकि वह मॉडल के आउटपुट के हिसाब से बेहतर तरीके से काम कर सके.

आगे क्या करना है

स्ट्रक्चर्ड आउटपुट जनरेट करने का तरीका जानने के बाद, Gemini API टूल का इस्तेमाल करें: