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 oggettiinlineResponse
. - 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 è unGenerateContentResponse
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
perfailedRequestCount
al termine di un job. Se utilizzi l'output del file, analizza ogni riga per verificare se si tratta di unGenerateContentResponse
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.