إخراج منظَّم

يمكنك ضبط Gemini لإنتاج بيانات منظَّمة بدلاً من نص غير منظَّم، ما يتيح استخراج المعلومات وتوحيدها بدقة لإجراء المزيد من المعالجة. على سبيل المثال، يمكنك استخدام الناتج المنظَّم لاستخراج المعلومات من السير الذاتية وتوحيدها لإنشاء قاعدة بيانات منظَّمة.

يمكن أن ينشئ Gemini JSON أو قيم تعدادية كناتج منظَّم.

إنشاء JSON

لإجبار النموذج على إنشاء JSON، اضبط responseSchema. بعد ذلك، سيستجيب النموذج لأي طلب باستخدام ناتج منسَّق بتنسيق JSON.

Python

from google import genai
from pydantic import BaseModel

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

client = genai.Client()
response = client.models.generate_content(
    model="gemini-2.5-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

JavaScript

import { GoogleGenAI, Type } from "@google/genai";

const ai = new GoogleGenAI({});

async function main() {
  const response = await ai.models.generateContent({
    model: "gemini-2.5-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();

Go

package main

import (
    "context"
    "fmt"
    "log"

    "google.golang.org/genai"
)

func main() {
    ctx := context.Background()
    client, err := genai.NewClient(ctx, nil)
    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.5-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())
}

REST

curl "https://generativelanguage.googleapis.com/v1beta/models/gemini-2.5-flash:generateContent" \
-H "x-goog-api-key: $GEMINI_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"
    ]
  },
  ...
]

إنشاء قيم التعداد

في بعض الحالات، قد تريد أن يختار النموذج خيارًا واحدًا من قائمة خيارات. لتنفيذ هذا السلوك، يمكنك تمرير تعداد في المخطط. يمكنك استخدام خيار تعداد في أي مكان يمكنك فيه استخدام string في responseSchema، لأنّ التعداد هو مصفوفة من السلاسل. مثل مخطط JSON، يتيح لك enum تقييد ناتج النموذج لتلبية متطلبات تطبيقك.

على سبيل المثال، لنفترض أنّك بصدد تطوير تطبيق لتصنيف الآلات الموسيقية إلى إحدى الفئات الخمس التالية: "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()
response = client.models.generate_content(
    model='gemini-2.5-flash',
    contents='What type of instrument is an oboe?',
    config={
        'response_mime_type': 'text/x.enum',
        'response_schema': Instrument,
    },
)

print(response.text)
# Woodwind

JavaScript

import { GoogleGenAI, Type } from "@google/genai";

const ai = new GoogleGenAI({});

const response = await ai.models.generateContent({
    model: "gemini-2.5-flash",
    contents: "What type of instrument is an oboe?",
    config: {
      responseMimeType: "text/x.enum",
      responseSchema: {
        type: Type.STRING,
        enum: ["Percussion", "String", "Woodwind", "Brass", "Keyboard"],
      },
    },
  });

console.log(response.text);

REST

curl "https://generativelanguage.googleapis.com/v1beta/models/gemini-2.5-flash:generateContent" \
-H "x-goog-api-key: $GEMINI_API_KEY" \
    -H 'Content-Type: application/json' \
    -d '{
          "contents": [{
            "parts":[
              { "text": "What type of instrument is an oboe?" }
            ]
          }],
          "generationConfig": {
            "responseMimeType": "text/x.enum",
            "responseSchema": {
              "type": "STRING",
              "enum": ["Percussion", "String", "Woodwind", "Brass", "Keyboard"]
            }
          }
    }'

ستترجم مكتبة Python تعريفات الأنواع لواجهة برمجة التطبيقات. ومع ذلك، تقبل واجهة برمجة التطبيقات مجموعة فرعية من مخطط OpenAPI 3.0 ‏(المخطط).

هناك طريقتان أخريان لتحديد تعداد. يمكنك استخدام Literal: ```

Python

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

يمكنك أيضًا تمرير المخطط على شكل JSON:

Python

from google import genai

client = genai.Client()
response = client.models.generate_content(
    model='gemini-2.5-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 enum لمنح كل عنوان درجة رواج:

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()
response = client.models.generate_content(
    model='gemini-2.5-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

يعتمد ضبط النموذج لإخراج JSON باستخدام المَعلمة responseSchema على الكائن Schema لتحديد بنيته. يمثّل هذا العنصر مجموعة فرعية محدّدة من عنصر المخطط في OpenAPI 3.0، ويضيف أيضًا الحقل propertyOrdering.

في ما يلي تمثيل زائف بتنسيق JSON لجميع حقول Schema:

{
  "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"]
}

للاطّلاع على المستندات الكاملة الخاصة بحقول Schema كما يتم استخدامها في Gemini API، يُرجى الرجوع إلى مرجع Schema.

ترتيب المواقع

عند استخدام مخططات JSON في Gemini API، يكون ترتيب السمات مهمًا. ترتّب واجهة برمجة التطبيقات الخصائص أبجديًا بشكل تلقائي، ولا تحتفظ بترتيب تحديد الخصائص (مع أنّ حِزم تطوير البرامج من Google للذكاء الاصطناعي التوليدي قد تحتفظ بهذا الترتيب). إذا كنت تقدّم أمثلة إلى النموذج مع إعداد مخطط، ولم يكن ترتيب السمات في الأمثلة متوافقًا مع ترتيب السمات في المخطط، قد يكون الناتج غير متناسق أو غير متوقّع.

لضمان ترتيب ثابت ويمكن توقّعه للخصائص، يمكنك استخدام الحقل الاختياري propertyOrdering[].

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

propertyOrdering[] – ليس حقلاً عاديًا في مواصفات OpenAPI – هو عبارة عن مصفوفة من السلاسل تُستخدَم لتحديد ترتيب السمات في الردّ. من خلال تحديد ترتيب الخصائص ثم تقديم أمثلة بالخصائص بالترتيب نفسه، يمكنك تحسين جودة النتائج. لا تتوفّر السمة propertyOrdering إلا عند إنشاء types.Schema يدويًا.

المخططات في Python

عند استخدام مكتبة Python، يجب أن تكون قيمة response_schema إحدى القيم التالية:

  • نوع، كما هو مستخدَم في تعليق توضيحي للنوع (راجِع وحدة typing في Python)
  • مثال على genai.types.Schema
  • ما يعادل dict من genai.types.Schema

أسهل طريقة لتحديد مخطط هي استخدام نوع 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 التي يحدّدها المستخدم يتيح لك هذا الأسلوب تحديد أسماء المفاتيح وتحديد أنواع مختلفة للقيم المرتبطة بكل مفتاح، بما في ذلك البُنى المتداخلة.

التوافق مع JSON Schema

مخطط JSON هو مواصفات أحدث من مواصفات OpenAPI 3.0 التي يستند إليها عنصر المخطط. تتوفّر ميزة التوافق مع JSON Schema كمعاينة باستخدام الحقل responseJsonSchema الذي يقبل أي JSON Schema مع القيود التالية:

  • لا تعمل هذه الميزة إلا مع Gemini 2.5.
  • يمكن تمرير جميع خصائص JSON Schema، ولكن لا تتوافق جميعها مع هذه الأداة. يمكنك الاطّلاع على المستندات الخاصة بالحقل لمزيد من التفاصيل.
  • لا يمكن استخدام المراجع المتكررة إلا كقيمة لسمة كائن غير مطلوبة.
  • يتم فك المراجع المتكرّرة إلى درجة محدودة، استنادًا إلى حجم المخطط.
  • لا يمكن أن تحتوي المخططات التي تتضمّن $ref على أي خصائص أخرى غير تلك التي تبدأ بـ $.

في ما يلي مثال على إنشاء مخطط JSON باستخدام Pydantic وإرساله إلى النموذج:

curl "https://generativelanguage.googleapis.com/v1alpha/models/\
gemini-2.5-flash:generateContent" \
    -H "x-goog-api-key: $GEMINI_API_KEY"\
    -H 'Content-Type: application/json' \
    -d @- <<EOF
{
  "contents": [{
    "parts":[{
      "text": "Please give a random example following this schema"
    }]
  }],
  "generationConfig": {
    "response_mime_type": "application/json",
    "response_json_schema": $(python3 - << PYEOF
    from enum import Enum
    from typing import List, Optional, Union, Set
    from pydantic import BaseModel, Field, ConfigDict
    import json

    class UserRole(str, Enum):
        ADMIN = "admin"
        VIEWER = "viewer"

    class Address(BaseModel):
        street: str
        city: str

    class UserProfile(BaseModel):
        username: str = Field(description="User's unique name")
        age: Optional[int] = Field(ge=0, le=120)
        roles: Set[UserRole] = Field(min_items=1)
        contact: Union[Address, str]
        model_config = ConfigDict(title="User Schema")

    # Generate and print the JSON Schema
    print(json.dumps(UserProfile.model_json_schema(), indent=2))
    PYEOF
    )
  }
}
EOF

لا يمكن حاليًا تمرير مخطط JSON مباشرةً عند استخدام حزمة تطوير البرامج.

أفضل الممارسات

يُرجى مراعاة الاعتبارات وأفضل الممارسات التالية عند استخدام مخطط استجابة:

  • يتم احتساب حجم مخطط الرد ضمن الحد الأقصى لعدد الرموز المميزة للإدخال.
  • تكون الحقول اختيارية تلقائيًا، ما يعني أنّه يمكن للنموذج ملء الحقول أو تخطّيها. يمكنك ضبط الحقول على أنّها مطلوبة لإجبار النموذج على تقديم قيمة. إذا لم يتوفّر سياق كافٍ في طلب الإدخال المرتبط، ينشئ النموذج الردود بشكل أساسي استنادًا إلى البيانات التي تم تدريبه عليها.
  • يمكن أن يؤدي المخطط المعقّد إلى حدوث خطأ InvalidArgument: 400. قد ينشأ التعقيد من أسماء السمات الطويلة، أو حدود طول المصفوفة الطويلة، أو التعدادات الثابتة التي تتضمّن العديد من القيم، أو الكائنات التي تتضمّن الكثير من السمات الاختيارية، أو مزيج من هذه العوامل.

    إذا ظهرت لك رسالة الخطأ هذه مع مخطط صالح، يمكنك إجراء واحد أو أكثر من التغييرات التالية لحلّ المشكلة:

    • اختصِر أسماء المواقع أو أسماء التعداد.
    • تسوية المصفوفات المتداخلة
    • قلِّل عدد السمات التي تتضمّن قيودًا، مثل الأرقام التي تتضمّن حدًا أدنى وأقصى.
    • قلِّل عدد السمات التي تتضمّن قيودًا معقّدة، مثل السمات التي تتضمّن تنسيقات معقّدة مثل date-time.
    • قلِّل عدد الخصائص الاختيارية.
    • قلِّل عدد القيم الصالحة للتعدادات.
  • إذا لم تظهر لك النتائج التي تتوقّعها، أضِف المزيد من السياق إلى طلبات الإدخال أو راجِع مخطط الرد. على سبيل المثال، راجِع ردّ النموذج بدون ناتج منظَّم لمعرفة طريقة ردّ النموذج. يمكنك بعد ذلك تعديل مخطط الردّ ليتناسب بشكل أفضل مع الناتج الذي يقدّمه النموذج. للحصول على نصائح إضافية حول تحديد المشاكل وحلّها في ما يتعلّق بالناتج المنظَّم، يمكنك الاطّلاع على دليل تحديد المشاكل وحلّها.

الخطوات التالية

بعد أن تعرّفت على كيفية إنشاء نواتج منظَّمة، يمكنك تجربة استخدام أدوات Gemini API: