حالت دسته ای

حالت دسته ای Gemini API برای پردازش حجم زیادی از درخواست ها به صورت ناهمزمان با 50 درصد هزینه استاندارد طراحی شده است. زمان چرخش هدف 24 ساعت است، اما در اکثر موارد، بسیار سریعتر است.

از حالت دسته ای برای کارهای بزرگ مقیاس و غیر فوری مانند پیش پردازش داده ها یا ارزیابی های در حال اجرا که نیازی به پاسخ فوری نیست استفاده کنید.

ایجاد یک کار دسته ای

شما دو راه برای ارسال درخواست های خود در حالت دسته ای دارید:

  • درخواست های درون خطی : لیستی از اشیاء GenerateContentRequest که مستقیماً در درخواست ایجاد دسته شما گنجانده شده است. این برای دسته های کوچکتر که حجم کل درخواست را زیر 20 مگابایت نگه می دارند مناسب است. خروجی برگردانده شده از مدل لیستی از اشیاء inlineResponse است.
  • فایل ورودی : یک فایل JSON Lines (JSONL) که در آن هر خط حاوی یک شیء GenerateContentRequest کامل است. این روش برای درخواست های بزرگتر توصیه می شود. خروجی برگردانده شده از مدل یک فایل JSONL است که در آن هر خط یک GenerateContentResponse یا یک شی وضعیت است.

درخواست های درون خطی

برای تعداد کمی از درخواست‌ها، می‌توانید مستقیماً اشیاء GenerateContentRequest را در BatchGenerateContentRequest خود جاسازی کنید. مثال زیر متد BatchGenerateContent را با درخواست های درون خطی فراخوانی می کند:

پایتون


from google import genai
from google.genai import types

client = genai.Client()

# A list of dictionaries, where each is a GenerateContentRequest
inline_requests = [
    {
        'contents': [{
            'parts': [{'text': 'Tell me a one-sentence joke.'}],
            'role': 'user'
        }]
    },
    {
        'contents': [{
            'parts': [{'text': 'Why is the sky blue?'}],
            'role': 'user'
        }]
    }
]

inline_batch_job = client.batches.create(
    model="models/gemini-2.5-flash",
    src=inline_requests,
    config={
        'display_name': "inlined-requests-job-1",
    },
)

print(f"Created batch job: {inline_batch_job.name}")

استراحت

curl https://generativelanguage.googleapis.com/v1beta/models/gemini-2.5-flash:batchGenerateContent \
-H "x-goog-api-key: $GEMINI_API_KEY" \
-X POST \
-H "Content-Type:application/json" \
-d '{
    "batch": {
        "display_name": "my-batch-requests",
        "input_config": {
            "requests": {
                "requests": [
                    {
                        "request": {"contents": [{"parts": [{"text": "Describe the process of photosynthesis."}]}]},
                        "metadata": {
                            "key": "request-1"
                        }
                    },
                    {
                        "request": {"contents": [{"parts": [{"text": "Describe the process of photosynthesis."}]}]},
                        "metadata": {
                            "key": "request-2"
                        }
                    }
                ]
            }
        }
    }
}'

فایل ورودی

برای مجموعه های بزرگتر از درخواست ها، یک فایل JSON Lines (JSONL) آماده کنید. هر خط در این فایل باید یک شی JSON حاوی یک کلید تعریف شده توسط کاربر و یک شی درخواست باشد که در آن درخواست یک شی GenerateContentRequest معتبر است. کلید تعریف شده توسط کاربر در پاسخ استفاده می شود تا نشان دهد کدام خروجی نتیجه کدام درخواست است. به عنوان مثال، درخواست با کلید تعریف شده به عنوان request-1 پاسخ آن با همان نام کلید مشروح می شود.

این فایل با استفاده از File API آپلود می شود. حداکثر اندازه مجاز فایل برای یک فایل ورودی 2 گیگابایت است.

نمونه زیر نمونه ای از فایل JSONL است. می توانید آن را در فایلی به نام my-batch-requests.json ذخیره کنید:

{"key": "request-1", "request": {"contents": [{"parts": [{"text": "Describe the process of photosynthesis."}]}], "generation_config": {"temperature": 0.7}}}
{"key": "request-2", "request": {"contents": [{"parts": [{"text": "What are the main ingredients in a Margherita pizza?"}]}]}}

مشابه درخواست‌های درون خطی، می‌توانید پارامترهای دیگری مانند دستورالعمل‌های سیستم، ابزارها یا سایر تنظیمات را در هر درخواست JSON تعیین کنید.

همانطور که در مثال زیر نشان داده شده است می توانید این فایل را با استفاده از File API آپلود کنید. اگر با ورودی چند وجهی کار می‌کنید، می‌توانید به سایر فایل‌های آپلود شده در فایل JSONL خود مراجعه کنید.

پایتون


from google import genai
from google.genai import types

client = genai.Client()

# Create a sample JSONL file
with open("my-batch-requests.jsonl", "w") as f:
    requests = [
        {"key": "request-1", "request": {"contents": [{"parts": [{"text": "Describe the process of photosynthesis."}]}]}},
        {"key": "request-2", "request": {"contents": [{"parts": [{"text": "What are the main ingredients in a Margherita pizza?"}]}]}}
    ]
    for req in requests:
        f.write(json.dumps(req) + "\n")

# Upload the file to the File API
uploaded_file = client.files.upload(
    file='my-batch-requests.jsonl',
    config=types.UploadFileConfig(display_name='my-batch-requests', mime_type='jsonl')
)

print(f"Uploaded file: {uploaded_file.name}")

استراحت

tmp_batch_input_file=batch_input.tmp
echo -e '{"contents": [{"parts": [{"text": "Describe the process of photosynthesis."}]}], "generationConfig": {"temperature": 0.7}}\n{"contents": [{"parts": [{"text": "What are the main ingredients in a Margherita pizza?"}]}]}' > batch_input.tmp
MIME_TYPE=$(file -b --mime-type "${tmp_batch_input_file}")
NUM_BYTES=$(wc -c < "${tmp_batch_input_file}")
DISPLAY_NAME=BatchInput

tmp_header_file=upload-header.tmp

# Initial resumable request defining metadata.
# The upload url is in the response headers dump them to a file.
curl "https://generativelanguage.googleapis.com/upload/v1beta/files \
-D "${tmp_header_file}" \
-H "x-goog-api-key: $GEMINI_API_KEY" \
-H "X-Goog-Upload-Protocol: resumable" \
-H "X-Goog-Upload-Command: start" \
-H "X-Goog-Upload-Header-Content-Length: ${NUM_BYTES}" \
-H "X-Goog-Upload-Header-Content-Type: ${MIME_TYPE}" \
-H "Content-Type: application/jsonl" \
-d "{'file': {'display_name': '${DISPLAY_NAME}'}}" 2> /dev/null

upload_url=$(grep -i "x-goog-upload-url: " "${tmp_header_file}" | cut -d" " -f2 | tr -d "\r")
rm "${tmp_header_file}"

# Upload the actual bytes.
curl "${upload_url}" \
-H "Content-Length: ${NUM_BYTES}" \
-H "X-Goog-Upload-Offset: 0" \
-H "X-Goog-Upload-Command: upload, finalize" \
--data-binary "@${tmp_batch_input_file}" 2> /dev/null > file_info.json

file_uri=$(jq ".file.uri" file_info.json)

مثال زیر متد BatchGenerateContent را با فایل ورودی آپلود شده با استفاده از File API فراخوانی می کند:

پایتون


# Assumes `uploaded_file` is the file object from the previous step
file_batch_job = client.batches.create(
    model="gemini-2.5-flash",
    src=uploaded_file.name,
    config={
        'display_name': "file-upload-job-1",
    },
)

print(f"Created batch job: {file_batch_job.name}")

استراحت

BATCH_INPUT_FILE='files/123456' # File ID
curl https://generativelanguage.googleapis.com/v1beta/models/gemini-2.5-flash:batchGenerateContent \
-X POST \
-H "x-goog-api-key: $GEMINI_API_KEY" \
-H "Content-Type:application/json" \
-d "{
    'batch': {
        'display_name': 'my-batch-requests',
        'input_config': {
            'requests': {
                'file_name': ${BATCH_INPUT_FILE}
            }
        }
    }
}"

وقتی یک کار دسته‌ای ایجاد می‌کنید، نام شغلی به شما برگردانده می‌شود. از این نام برای نظارت بر وضعیت شغل و همچنین بازیابی نتایج پس از اتمام کار استفاده کنید.

در زیر یک نمونه خروجی است که حاوی نام شغل است:


Created batch job from file: batches/123456789

درخواست پیکربندی

شما می توانید هر پیکربندی درخواستی را که در یک درخواست استاندارد غیر دسته ای استفاده می کنید، اضافه کنید. برای مثال، می‌توانید دما، دستورالعمل‌های سیستم را مشخص کنید یا حتی در روش‌های دیگر عبور کنید. مثال زیر یک نمونه درخواست درون خطی را نشان می دهد که حاوی یک دستورالعمل سیستم برای یکی از درخواست ها است:

inline_requests_list = [
    {'contents': [{'parts': [{'text': 'Write a short poem about a cloud.'}]}]},
    {'contents': [{'parts': [{'text': 'Write a short poem about a cat.'}]}], 'system_instructions': {'parts': [{'text': 'You are a cat. Your name is Neko.'}]}}
]

به طور مشابه می توان ابزارهایی را برای استفاده برای یک درخواست مشخص کرد. مثال زیر درخواستی را نشان می دهد که ابزار جستجوی Google را فعال می کند:

inline_requests_list = [
    {'contents': [{'parts': [{'text': 'Who won the euro 1998?'}]}]},
    {'contents': [{'parts': [{'text': 'Who won the euro 2025?'}]}], 'tools': [{'google_search ': {}}]}
]

می توانید خروجی ساختاریافته را نیز مشخص کنید. مثال زیر نحوه تعیین درخواست های دسته ای خود را نشان می دهد.

from google import genai
from pydantic import BaseModel, TypeAdapter

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

client = genai.Client()

# A list of dictionaries, where each is a GenerateContentRequest
inline_requests = [
    {
        'contents': [{
            'parts': [{'text': 'List a few popular cookie recipes, and include the amounts of ingredients.'}],
            'role': 'user'
        }],
        'config': {
            'response_mime_type': 'application/json',
            'response_schema': list[Recipe]
        }
    },
    {
        'contents': [{
            'parts': [{'text': 'List a few popular gluten free cookie recipes, and include the amounts of ingredients.'}],
            'role': 'user'
        }],
        'config': {
            'response_mime_type': 'application/json',
            'response_schema': list[Recipe]
        }
    }
]

inline_batch_job = client.batches.create(
    model="models/gemini-2.5-flash",
    src=inline_requests,
    config={
        'display_name': "structured-output-job-1"
    },
)

# wait for the job to finish
job_name = inline_batch_job.name
print(f"Polling status for job: {job_name}")

while True:
    batch_job_inline = client.batches.get(name=job_name)
    if batch_job_inline.state.name in ('JOB_STATE_SUCCEEDED', 'JOB_STATE_FAILED', 'JOB_STATE_CANCELLED'):
        break
    print(f"Job not finished. Current state: {batch_job.state.name}. Waiting 30 seconds...")
    time.sleep(30)

print(f"Job finished with state: {batch_job.state.name}")

# print the response
for i, inline_response in enumerate(batch_job_inline.dest.inlined_responses):
    print(f"\n--- Response {i+1} ---")

    # Check for a successful response
    if inline_response.response:
        # The .text property is a shortcut to the generated text.
        print(inline_response.response.text)

نظارت بر وضعیت شغلی

از نام عملیاتی که هنگام ایجاد کار دسته ای به دست می آید برای نظرسنجی وضعیت آن استفاده کنید. فیلد وضعیت کار دسته ای وضعیت فعلی آن را نشان می دهد. یک کار دسته ای می تواند در یکی از حالت های زیر باشد:

  • JOB_STATE_PENDING : کار ایجاد شده است و در انتظار پردازش توسط سرویس است.
  • JOB_STATE_SUCCEEDED : کار با موفقیت انجام شد. اکنون می توانید نتایج را بازیابی کنید.
  • JOB_STATE_FAILED : کار ناموفق بود. برای اطلاعات بیشتر جزئیات خطا را بررسی کنید.
  • JOB_STATE_CANCELLED : کار توسط کاربر لغو شد.

می توانید وضعیت شغل را به صورت دوره ای نظرسنجی کنید تا تکمیل شدن آن را بررسی کنید.

پایتون


# Use the name of the job you want to check
# e.g., inline_batch_job.name from the previous step
job_name = "YOUR_BATCH_JOB_NAME"  # (e.g. 'batches/your-batch-id')
batch_job = client.batches.get(name=job_name)

completed_states = set([
    'JOB_STATE_SUCCEEDED',
    'JOB_STATE_FAILED',
    'JOB_STATE_CANCELLED',
])

print(f"Polling status for job: {job_name}")
batch_job = client.batches.get(name=job_name) # Initial get
while batch_job.state.name not in completed_states:
  print(f"Current state: {batch_job.state.name}")
  time.sleep(30) # Wait for 30 seconds before polling again
  batch_job = client.batches.get(name=job_name)

print(f"Job finished with state: {batch_job.state.name}")
if batch_job.state.name == 'JOB_STATE_FAILED':
    print(f"Error: {batch_job.error}")

در حال بازیابی نتایج

هنگامی که وضعیت شغل نشان می دهد که کار دسته ای شما موفق شده است، نتایج در قسمت response در دسترس هستند.

پایتون

import json

# Use the name of the job you want to check
# e.g., inline_batch_job.name from the previous step
job_name = "YOUR_BATCH_JOB_NAME"
batch_job = client.batches.get(name=job_name)

if batch_job.state.name == 'JOB_STATE_SUCCEEDED':

    # If batch job was created with a file
    if batch_job.dest and batch_job.dest.file_name:
        # Results are in a file
        result_file_name = batch_job.dest.file_name
        print(f"Results are in file: {result_file_name}")

        print("Downloading result file content...")
        file_content = client.files.download(file=result_file_name)
        # Process file_content (bytes) as needed
        print(file_content.decode('utf-8'))

    # If batch job was created with inline request
    elif batch_job.dest and batch_job.dest.inlined_responses:
        # Results are inline
        print("Results are inline:")
        for i, inline_response in enumerate(batch_job.dest.inlined_responses):
            print(f"Response {i+1}:")
            if inline_response.response:
                # Accessing response, structure may vary.
                try:
                    print(inline_response.response.text)
                except AttributeError:
                    print(inline_response.response) # Fallback
            elif inline_response.error:
                print(f"Error: {inline_response.error}")
    else:
        print("No results found (neither file nor inline).")
else:
    print(f"Job did not succeed. Final state: {batch_job.state.name}")
    if batch_job.error:
        print(f"Error: {batch_job.error}")

استراحت

BATCH_NAME="batches/123456" # Your batch job name

curl https://generativelanguage.googleapis.com/v1beta/$BATCH_NAME \
-H "x-goog-api-key: $GEMINI_API_KEY" \
-H "Content-Type:application/json" 2> /dev/null > batch_status.json

if jq -r '.done' batch_status.json | grep -q "false"; then
    echo "Batch has not finished processing"
fi

batch_state=$(jq -r '.metadata.state' batch_status.json)
if [[ $batch_state = "JOB_STATE_SUCCEEDED" ]]; then
    if [[ $(jq '.response | has("inlinedResponses")' batch_status.json) = "true" ]]; then
        jq -r '.response.inlinedResponses' batch_status.json
        exit
    fi
    responses_file_name=$(jq -r '.response.responsesFile' batch_status.json)
    curl https://generativelanguage.googleapis.com/download/v1beta/$responses_file_name:download?alt=media \
    -H "x-goog-api-key: $GEMINI_API_KEY" 2> /dev/null
elif [[ $batch_state = "JOB_STATE_FAILED" ]]; then
    jq '.error' batch_status.json
elif [[ $batch_state == "JOB_STATE_CANCELLED" ]]; then
    echo "Batch was cancelled by the user"
fi

لغو یک کار دسته جمعی

می‌توانید یک کار دسته‌ای در حال انجام را با استفاده از نام آن لغو کنید. هنگامی که یک کار لغو می شود، پردازش درخواست های جدید متوقف می شود.

پایتون

# Cancel a batch job
client.batches.cancel(name=batch_job_to_cancel.name)

استراحت

BATCH_NAME="batches/123456" # Your batch job name

# Cancel the batch
curl https://generativelanguage.googleapis.com/v1beta/$BATCH_NAME:cancel \
-H "x-goog-api-key: $GEMINI_API_KEY" \

# Confirm that the status of the batch after cancellation is JOB_STATE_CANCELLED
curl https://generativelanguage.googleapis.com/v1beta/$BATCH_NAME \
-H "x-goog-api-key: $GEMINI_API_KEY" \
-H "Content-Type:application/json" 2> /dev/null | jq -r '.metadata.state'

حذف یک کار دسته ای

می‌توانید یک کار دسته‌ای موجود را با استفاده از نام آن حذف کنید. هنگامی که یک کار حذف می شود، پردازش درخواست های جدید را متوقف می کند و از لیست کارهای دسته ای حذف می شود.

پایتون

# Delete a batch job
client.batches.delete(name=batch_job_to_delete.name)

استراحت

BATCH_NAME="batches/123456" # Your batch job name

# Cancel the batch
curl https://generativelanguage.googleapis.com/v1beta/$BATCH_NAME:delete \
-H "x-goog-api-key: $GEMINI_API_KEY" \

جزئیات فنی

  • مدل های پشتیبانی شده: حالت دسته ای طیفی از مدل های Gemini را پشتیبانی می کند. برای پشتیبانی هر مدل از حالت دسته ای به صفحه مدل ها مراجعه کنید. حالت‌های پشتیبانی شده برای حالت دسته‌ای، همان چیزی است که در API تعاملی (یا حالت غیر دسته‌ای) پشتیبانی می‌شود.
  • قیمت گذاری: استفاده از حالت دسته ای 50 درصد از هزینه API تعاملی استاندارد برای مدل معادل قیمت گذاری شده است. برای جزئیات بیشتر به صفحه قیمت مراجعه کنید. برای جزئیات بیشتر در مورد محدودیت نرخ برای این ویژگی به صفحه محدودیت نرخ مراجعه کنید.
  • هدف سطح خدمات (SLO): کارهای دسته ای طوری طراحی شده اند که در یک زمان 24 ساعته تکمیل شوند. بسیاری از کارها بسته به اندازه و بار فعلی سیستم ممکن است بسیار سریعتر انجام شوند.
  • ذخیره سازی: ذخیره متن برای درخواست های دسته ای فعال است. اگر درخواستی در دسته شما منجر به ضربه حافظه پنهان شود، قیمت توکن های ذخیره شده مانند ترافیک حالت غیر دسته ای است.

بهترین شیوه ها

  • استفاده از فایل‌های ورودی برای درخواست‌های بزرگ: برای تعداد زیادی درخواست، همیشه از روش ورودی فایل برای مدیریت بهتر و جلوگیری از وارد کردن محدودیت‌های اندازه درخواست برای خود تماس BatchGenerateContent استفاده کنید. توجه داشته باشید که محدودیت اندازه فایل 2 گیگابایتی برای هر فایل ورودی وجود دارد.
  • رسیدگی به خطا: پس از اتمام کار، batchStats برای failedRequestCount بررسی کنید. اگر از خروجی فایل استفاده می کنید، هر خط را تجزیه کنید تا بررسی کنید که GenerateContentResponse یا یک شی وضعیت است که نشان دهنده خطای آن درخواست خاص است. برای مجموعه کاملی از کدهای خطا به راهنمای عیب یابی مراجعه کنید.
  • یک بار کارها را ارسال کنید: ایجاد یک شغل دسته‌ای بی‌توان نیست. اگر یک درخواست ایجاد یکسان را دو بار ارسال کنید، دو کار دسته ای جداگانه ایجاد می شود.
  • جدا کردن دسته های بسیار بزرگ: در حالی که زمان چرخش هدف 24 ساعت است، زمان پردازش واقعی می تواند بر اساس بار سیستم و اندازه کار متفاوت باشد. برای کارهای بزرگ، اگر زودتر به نتایج متوسط نیاز دارید، آنها را به دسته های کوچکتر تقسیم کنید.

بعدش چی

برای نمونه های بیشتر، نوت بوک حالت دسته ای را بررسی کنید.