স্ট্রাকচার্ড আউটপুট

আপনি সুনির্দিষ্ট নিষ্কাশন এবং আরও প্রক্রিয়াকরণের জন্য তথ্যের প্রমিতকরণের অনুমতি দিয়ে অসংগঠিত পাঠ্যের পরিবর্তে কাঠামোগত আউটপুটের জন্য মিথুন কনফিগার করতে পারেন। উদাহরণস্বরূপ, আপনি জীবনবৃত্তান্ত থেকে তথ্য বের করতে কাঠামোগত আউটপুট ব্যবহার করতে পারেন, একটি স্ট্রাকচার্ড ডাটাবেস তৈরি করতে তাদের প্রমিতকরণ করতে পারেন।

মিথুন স্ট্রাকচার্ড আউটপুট হিসাবে 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 পাস করতে পারেন। আপনি একটি enum বিকল্প ব্যবহার করতে পারেন যেখানে আপনি responseSchema একটি string ব্যবহার করতে পারেন, কারণ একটি enum হল স্ট্রিংগুলির একটি অ্যারে। একটি JSON স্কিমার মতো, একটি enum আপনাকে আপনার অ্যাপ্লিকেশনের প্রয়োজনীয়তা পূরণের জন্য মডেল আউটপুট সীমাবদ্ধ করতে দেয়।

উদাহরণস্বরূপ, অনুমান করুন যে আপনি বাদ্যযন্ত্রকে পাঁচটি বিভাগের একটিতে শ্রেণীবদ্ধ করার জন্য একটি অ্যাপ্লিকেশন তৈরি করছেন: "Percussion" , "String" , "Woodwind" , "Brass" , বা " "Keyboard" "৷ আপনি এই কাজটিতে সাহায্য করার জন্য একটি enum তৈরি করতে পারেন।

নিম্নলিখিত উদাহরণে, আপনি responseSchema হিসাবে একটি enum পাস করেন, মডেলটিকে সবচেয়ে উপযুক্ত বিকল্পটি বেছে নিতে বাধা দেয়।

পাইথন
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

পাইথন লাইব্রেরি API-এর জন্য টাইপ ঘোষণা অনুবাদ করবে। যাইহোক, API OpenAPI 3.0 স্কিমার একটি উপসেট গ্রহণ করে ( স্কিমা )।

একটি গণনা নির্দিষ্ট করার অন্য দুটি উপায় আছে। আপনি একটি Literal ব্যবহার করতে পারেন:

পাইথন
Literal["Percussion", "String", "Woodwind", "Brass", "Keyboard"]

এবং আপনি JSON হিসাবে স্কিমা পাস করতে পারেন:

পাইথন
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 স্কিমার যেকোনো জায়গায় একটি enum ব্যবহার করতে পারেন। উদাহরণস্বরূপ, আপনি মডেলটিকে রেসিপি শিরোনামের একটি তালিকার জন্য জিজ্ঞাসা করতে পারেন এবং প্রতিটি শিরোনামকে একটি জনপ্রিয়তা গ্রেড দিতে একটি Grade এনাম ব্যবহার করতে পারেন:

পাইথন
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-এ ব্যবহৃত হয়, স্কিমা রেফারেন্স দেখুন।

সম্পত্তি আদেশ

আপনি যখন জেমিনি API-তে JSON স্কিমাগুলির সাথে কাজ করছেন, তখন বৈশিষ্ট্যের ক্রম গুরুত্বপূর্ণ। ডিফল্টরূপে, API বৈশিষ্ট্যগুলিকে বর্ণানুক্রমিকভাবে অর্ডার করে এবং যে ক্রমে বৈশিষ্ট্যগুলিকে সংজ্ঞায়িত করা হয়েছে তা সংরক্ষণ করে না (যদিও Google Gen AI SDKগুলি এই ক্রমটি সংরক্ষণ করতে পারে)৷ আপনি যদি একটি স্কিমা কনফিগার করা মডেলের সাথে উদাহরণ প্রদান করেন এবং উদাহরণগুলির সম্পত্তির ক্রম স্কিমার সম্পত্তি ক্রমানুসারের সাথে সামঞ্জস্যপূর্ণ না হয়, তাহলে আউটপুট র‍্যাম্বলিং বা অপ্রত্যাশিত হতে পারে।

বৈশিষ্ট্যগুলির একটি সামঞ্জস্যপূর্ণ, অনুমানযোগ্য ক্রম নিশ্চিত করতে, আপনি ঐচ্ছিক propertyOrdering[] ক্ষেত্রটি ব্যবহার করতে পারেন।

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

propertyOrdering[] - OpenAPI স্পেসিফিকেশনে একটি আদর্শ ক্ষেত্র নয় - প্রতিক্রিয়ায় বৈশিষ্ট্যের ক্রম নির্ধারণ করতে ব্যবহৃত স্ট্রিংগুলির একটি অ্যারে। বৈশিষ্ট্যের ক্রম নির্দিষ্ট করে এবং তারপর একই ক্রমে বৈশিষ্ট্য সহ উদাহরণ প্রদান করে, আপনি সম্ভাব্য ফলাফলের গুণমান উন্নত করতে পারেন। propertyOrdering তখনই সমর্থিত হয় যখন আপনি ম্যানুয়ালি types.Schema তৈরি করেন। স্কিমা।

পাইথনে স্কিমা

আপনি যখন পাইথন লাইব্রেরি ব্যবহার করছেন, তখন response_schema মান অবশ্যই নিম্নলিখিতগুলির মধ্যে একটি হতে হবে:

  • একটি প্রকার, যেমন আপনি একটি টাইপ টীকা ব্যবহার করবেন (পাইথন typing মডিউল দেখুন)
  • genai.types.Schema এর একটি উদাহরণ
  • genai.types.Schema এর dict সমতুল্য

একটি স্কিমা সংজ্ঞায়িত করার সবচেয়ে সহজ উপায় হল একটি Pydantic প্রকার (আগের উদাহরণে দেখানো হয়েছে):

পাইথন
config={'response_mime_type': 'application/json',
        'response_schema': list[Recipe]}

আপনি যখন একটি Pydantic প্রকার ব্যবহার করেন, তখন পাইথন লাইব্রেরি আপনার জন্য একটি JSON স্কিমা তৈরি করে এবং এটি API-তে পাঠায়। অতিরিক্ত উদাহরণের জন্য, পাইথন লাইব্রেরি ডক্স দেখুন।

পাইথন লাইব্রেরি নিম্নলিখিত প্রকারের সাথে সংজ্ঞায়িত স্কিমাগুলিকে সমর্থন করে (যেখানে AllowedType যে কোনও অনুমোদিত প্রকার):

  • int
  • float
  • bool
  • str
  • list[AllowedType]
  • AllowedType|AllowedType|...
  • কাঠামোগত প্রকারের জন্য:
    • dict[str, AllowedType] । এই টীকাটি সমস্ত dict মানকে একই ধরণের বলে ঘোষণা করে, কিন্তু কী কী অন্তর্ভুক্ত করা উচিত তা নির্দিষ্ট করে না।
    • ব্যবহারকারী-সংজ্ঞায়িত Pydantic মডেল । এই পদ্ধতিটি আপনাকে মূল নামগুলি নির্দিষ্ট করতে এবং নেস্টেড কাঠামো সহ প্রতিটি কীগুলির সাথে যুক্ত মানগুলির জন্য বিভিন্ন প্রকার সংজ্ঞায়িত করতে দেয়।

সর্বোত্তম অনুশীলন

আপনি যখন প্রতিক্রিয়া স্কিমা ব্যবহার করছেন তখন নিম্নলিখিত বিবেচনা এবং সর্বোত্তম অনুশীলনগুলি মনে রাখবেন:

  • আপনার প্রতিক্রিয়া স্কিমার আকার ইনপুট টোকেন সীমাতে গণনা করা হয়।
  • ডিফল্টরূপে, ক্ষেত্রগুলি ঐচ্ছিক, যার অর্থ মডেলটি ক্ষেত্রগুলি পূরণ করতে পারে বা সেগুলি এড়িয়ে যেতে পারে৷ মডেলটিকে একটি মান প্রদান করতে বাধ্য করার জন্য আপনি প্রয়োজনীয় ক্ষেত্রগুলি সেট করতে পারেন। যদি সংশ্লিষ্ট ইনপুট প্রম্পটে অপর্যাপ্ত প্রসঙ্গ না থাকে, মডেলটি প্রধানত যে ডেটাতে প্রশিক্ষণ দেওয়া হয়েছিল তার উপর ভিত্তি করে প্রতিক্রিয়া তৈরি করে।
  • একটি জটিল স্কিমার একটি InvalidArgument: 400 ত্রুটি হতে পারে। জটিলতা দীর্ঘ সম্পত্তির নাম, দীর্ঘ অ্যারের দৈর্ঘ্যের সীমা, অনেকগুলি মান সহ এনাম, প্রচুর ঐচ্ছিক বৈশিষ্ট্যযুক্ত বস্তু বা এই কারণগুলির সংমিশ্রণ থেকে আসতে পারে।

    আপনি যদি একটি বৈধ স্কিমার সাথে এই ত্রুটিটি পান, তাহলে ত্রুটিটি সমাধান করতে নিম্নলিখিত এক বা একাধিক পরিবর্তন করুন:

    • সম্পত্তি নাম বা enum নাম ছোট করুন.
    • নেস্টেড অ্যারে সমতল করুন।
    • সীমাবদ্ধতা সহ বৈশিষ্ট্যের সংখ্যা হ্রাস করুন, যেমন ন্যূনতম এবং সর্বোচ্চ সীমা সহ সংখ্যা।
    • জটিল সীমাবদ্ধতা সহ বৈশিষ্ট্যের সংখ্যা হ্রাস করুন, যেমন date-time মতো জটিল বিন্যাস সহ বৈশিষ্ট্যগুলি।
    • ঐচ্ছিক বৈশিষ্ট্যের সংখ্যা হ্রাস করুন।
    • enums-এর জন্য বৈধ মানের সংখ্যা হ্রাস করুন।
  • আপনি যদি আপনার প্রত্যাশিত ফলাফলগুলি দেখতে না পান তবে আপনার ইনপুট প্রম্পটে আরও প্রসঙ্গ যোগ করুন বা আপনার প্রতিক্রিয়া স্কিমা সংশোধন করুন। উদাহরণ স্বরূপ, মডেলটি কীভাবে সাড়া দেয় তা দেখতে কাঠামোগত আউটপুট ছাড়াই মডেলের প্রতিক্রিয়া পর্যালোচনা করুন। তারপরে আপনি আপনার প্রতিক্রিয়া স্কিমা আপডেট করতে পারেন যাতে এটি মডেলের আউটপুটের সাথে আরও ভালভাবে ফিট করে।

এরপর কি

এখন যেহেতু আপনি স্ট্রাকচার্ড আউটপুট তৈরি করতে শিখেছেন, আপনি জেমিনি API টুল ব্যবহার করে দেখতে চাইতে পারেন: