Modalità batch

La modalità batch dell'API Gemini è progettata per elaborare grandi volumi di richieste in modo asincrono al 50% del costo standard. Il tempo di risposta target è di 24 ore, ma nella maggior parte dei casi è molto più rapido.

Utilizza la modalità batch per attività su larga scala e non urgenti, come la pre-elaborazione dei dati o l'esecuzione di valutazioni in cui non è richiesta una risposta immediata.

Creazione di un job batch

Hai due modi per inviare le richieste in modalità batch:

  • Richieste inline: un elenco di oggetti GenerateContentRequest inclusi direttamente nella richiesta di creazione batch. Questa opzione è adatta a batch più piccoli che mantengono le dimensioni totali della richiesta al di sotto di 20 MB. L'output restituito dal modello è un elenco di oggetti inlineResponse.
  • File di input: un file JSON Lines (JSONL) in cui ogni riga contiene un oggetto GenerateContentRequest completo. Questo metodo è consigliato per le richieste più grandi. L'output restituito dal modello è un file JSONL in cui ogni riga è un GenerateContentResponse o un oggetto di stato.

Richieste inline

Per un numero ridotto di richieste, puoi incorporare direttamente gli oggetti GenerateContentRequest all'interno di BatchGenerateContentRequest. Il seguente esempio chiama il metodo BatchGenerateContent con richieste inline:

Python


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}")

REST

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

File di input

Per set di richieste più grandi, prepara un file JSON Lines (JSONL). Ogni riga di questo file deve essere un oggetto JSON contenente una chiave definita dall'utente e un oggetto richiesta, dove la richiesta è un oggetto GenerateContentRequest valido. La chiave definita dall'utente viene utilizzata nella risposta per indicare quale output è il risultato di quale richiesta. Ad esempio, la richiesta con la chiave definita come request-1 avrà la risposta annotata con lo stesso nome della chiave.

Questo file viene caricato utilizzando l'API File. La dimensione massima consentita per un file di input è 2 GB.

Di seguito è riportato un esempio di file JSONL. Puoi salvarlo in un file denominato 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?"}]}]}}

Come per le richieste inline, puoi specificare altri parametri come istruzioni di sistema, strumenti o altre configurazioni in ogni JSON della richiesta.

Puoi caricare questo file utilizzando l'API File come mostrato nell'esempio seguente. Se utilizzi l'input multimodale, puoi fare riferimento ad altri file caricati all'interno del file JSONL.

Python


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}")

REST

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)

L'esempio seguente chiama il metodo BatchGenerateContent con il file di input caricato utilizzando l'API File:

Python


# 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}")

REST

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

Quando crei un job batch, viene restituito un nome del job. Utilizza questo nome per monitorare lo stato del job e recuperare i risultati al termine del job.

Di seguito è riportato un output di esempio che contiene il nome di un job:


Created batch job from file: batches/123456789

Richiedi configurazione

Puoi includere tutte le configurazioni delle richieste che utilizzeresti in una richiesta standard non batch. Ad esempio, puoi specificare la temperatura, le istruzioni del sistema o anche passare ad altre modalità. L'esempio seguente mostra una richiesta in linea che contiene un'istruzione di sistema per una delle richieste:

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.'}]}}
]

Allo stesso modo, puoi specificare gli strumenti da utilizzare per una richiesta. L'esempio seguente mostra una richiesta che attiva lo strumento Ricerca Google:

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

Puoi anche specificare l'output strutturato. Il seguente esempio mostra come specificare le richieste batch.

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)

Stato del job di monitoraggio

Utilizza il nome dell'operazione ottenuto durante la creazione del job batch per verificarne lo stato. Il campo Stato del job batch indica lo stato attuale. Un job batch può avere uno dei seguenti stati:

  • JOB_STATE_PENDING: il job è stato creato ed è in attesa di essere elaborato dal servizio.
  • JOB_STATE_SUCCEEDED: il job è stato completato correttamente. Ora puoi recuperare i risultati.
  • JOB_STATE_FAILED: il job non è riuscito. Per maggiori informazioni, controlla i dettagli dell'errore.
  • JOB_STATE_CANCELLED: Il lavoro è stato annullato dall'utente.

Puoi eseguire il polling periodico dello stato del job per verificare il completamento.

Python


# 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}")

Recupero dei risultati

Una volta che lo stato del job indica che il job batch è riuscito, i risultati sono disponibili nel campo response.

Python

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}")

REST

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

Annullamento di un job batch

Puoi annullare un job batch in corso utilizzando il relativo nome. Quando un job viene annullato, smette di elaborare nuove richieste.

Python

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

REST

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'

Eliminazione di un job batch

Puoi eliminare un job batch esistente utilizzando il relativo nome. Quando un job viene eliminato, smette di elaborare nuove richieste e viene rimosso dall'elenco dei job batch.

Python

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

REST

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" \

Dettagli tecnici

  • Modelli supportati:la modalità batch supporta una gamma di modelli Gemini. Consulta la pagina Modelli per verificare il supporto della modalità batch per ciascun modello. Le modalità supportate per la modalità batch sono le stesse di quelle supportate dall'API interattiva (o non batch).
  • Prezzi:l'utilizzo della modalità batch ha un prezzo pari al 50% del costo standard dell'API interattiva per il modello equivalente. Per i dettagli, consulta la pagina dei prezzi. Per informazioni dettagliate sui limiti di frequenza per questa funzionalità, consulta la pagina sui limiti di frequenza.
  • Obiettivo del livello di servizio (SLO): i job batch sono progettati per essere completati entro 24 ore. Molti job potrebbero essere completati molto più rapidamente a seconda delle dimensioni e del carico attuale del sistema.
  • Memorizzazione nella cache: la memorizzazione nella cache del contesto è abilitata per le richieste batch. Se una richiesta nel batch genera un hit della cache, i token memorizzati nella cache hanno lo stesso prezzo del traffico in modalità non batch.

Best practice

  • Utilizza i file di input per le richieste di grandi dimensioni: per un numero elevato di richieste, utilizza sempre il metodo di input dei file per una migliore gestibilità ed evitare di raggiungere i limiti di dimensione delle richieste per la chiamata BatchGenerateContent stessa. Tieni presente che esiste un limite di dimensioni di 2 GB per file di input.
  • Gestione degli errori: controlla batchStats per failedRequestCount al termine di un job. Se utilizzi l'output del file, analizza ogni riga per verificare se si tratta di un GenerateContentResponse o di un oggetto di stato che indica un errore per quella richiesta specifica. Consulta la guida alla risoluzione dei problemi per un elenco completo dei codici di errore.
  • Invia job una sola volta:la creazione di un job batch non è idempotente. Se invii due volte la stessa richiesta di creazione, verranno creati due job batch separati.
  • Dividi batch molto grandi: anche se il tempo di elaborazione target è di 24 ore, il tempo di elaborazione effettivo può variare in base al carico del sistema e alle dimensioni del job. Per i job di grandi dimensioni, valuta la possibilità di suddividerli in batch più piccoli se sono necessari risultati intermedi in tempi più brevi.

Passaggi successivi

Per altri esempi, consulta il notebook in modalità batch.