L'API Gemini Batch è 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 l'API 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
Esistono due modi per inviare le richieste nell'API Batch:
- Richieste inline: un elenco di oggetti
GenerateContentRequestinclusi 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
GenerateContentRequestcompleto. Questo metodo è consigliato per le richieste più grandi. L'output restituito dal modello è un file JSONL in cui ogni riga è un oggettoGenerateContentResponseo di stato.
Richieste inline
Per un numero ridotto di richieste, puoi incorporare direttamente gli oggetti
GenerateContentRequest
all'interno del tuo BatchGenerateContentRequest. L'esempio seguente 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="gemini-3.6-flash",
src=inline_requests,
config={
'display_name': "inlined-requests-job-1",
},
)
print(f"Created batch job: {inline_batch_job.name}")
JavaScript
import {GoogleGenAI} from '@google/genai';
const ai = new GoogleGenAI({});
const inlinedRequests = [
{
contents: [{
parts: [{text: 'Tell me a one-sentence joke.'}],
role: 'user'
}]
},
{
contents: [{
parts: [{'text': 'Why is the sky blue?'}],
role: 'user'
}]
}
]
const response = await ai.batches.create({
model: 'gemini-3.6-flash',
src: inlinedRequests,
config: {
displayName: 'inlined-requests-job-1',
}
});
console.log(response);
REST
curl https://generativelanguage.googleapis.com/v1beta/models/gemini-3.6-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?"}]}]}}
Analogamente alle 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
import json
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}")
JavaScript
import {GoogleGenAI} from '@google/genai';
import * as fs from "fs";
import * as path from "path";
import { fileURLToPath } from 'url';
const ai = new GoogleGenAI({});
const fileName = "my-batch-requests.jsonl";
// Define the requests
const 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?" }] }] } }
];
// Construct the full path to file
const __filename = fileURLToPath(import.meta.url);
const __dirname = path.dirname(__filename);
const filePath = path.join(__dirname, fileName); // __dirname is the directory of the current script
async function writeBatchRequestsToFile(requests, filePath) {
try {
// Use a writable stream for efficiency, especially with larger files.
const writeStream = fs.createWriteStream(filePath, { flags: 'w' });
writeStream.on('error', (err) => {
console.error(`Error writing to file ${filePath}:`, err);
});
for (const req of requests) {
writeStream.write(JSON.stringify(req) + '\n');
}
writeStream.end();
console.log(`Successfully wrote batch requests to ${filePath}`);
} catch (error) {
// This catch block is for errors that might occur before stream setup,
// stream errors are handled by the 'error' event.
console.error(`An unexpected error occurred:`, error);
}
}
// Write to a file.
writeBatchRequestsToFile(requests, filePath);
// Upload the file to the File API.
const uploadedFile = await ai.files.upload({file: 'my-batch-requests.jsonl', config: {
mimeType: 'jsonl',
}});
console.log(uploadedFile.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
from google import genai
# Assumes `uploaded_file` is the file object from the previous step
client = genai.Client()
file_batch_job = client.batches.create(
model="gemini-3.6-flash",
src=uploaded_file.name,
config={
'display_name': "file-upload-job-1",
},
)
print(f"Created batch job: {file_batch_job.name}")
JavaScript
// Assumes `uploadedFile` is the file object from the previous step
const fileBatchJob = await ai.batches.create({
model: 'gemini-3.6-flash',
src: uploadedFile.name,
config: {
displayName: 'file-upload-job-1',
}
});
console.log(fileBatchJob);
REST
# Set the File ID taken from the upload response.
BATCH_INPUT_FILE='files/123456'
curl https://generativelanguage.googleapis.com/v1beta/models/gemini-3.6-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': {
'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
Supporto per l'embedding batch
Puoi utilizzare l'API Batch per interagire con il
modello di incorporamento per una velocità effettiva maggiore.
Per creare un job batch di incorporamento con richieste inline
o file di input, utilizza l'API batches.create_embeddings e
specifica il modello di incorporamento.
Python
from google import genai
client = genai.Client()
# Creating an embeddings batch job with an input file request:
file_job = client.batches.create_embeddings(
model="gemini-embedding-2",
src={'file_name': uploaded_batch_requests.name},
config={'display_name': "Input embeddings batch"},
)
# Creating an embeddings batch job with an inline request:
batch_job = client.batches.create_embeddings(
model="gemini-embedding-2",
# For a predefined list of requests `inlined_requests`
src={'inlined_requests': inlined_requests},
config={'display_name': "Inlined embeddings batch"},
)
JavaScript
// Creating an embeddings batch job with an input file request:
let fileJob;
fileJob = await client.batches.createEmbeddings({
model: 'gemini-embedding-2',
src: {fileName: uploadedBatchRequests.name},
config: {displayName: 'Input embeddings batch'},
});
console.log(`Created batch job: ${fileJob.name}`);
// Creating an embeddings batch job with an inline request:
let batchJob;
batchJob = await client.batches.createEmbeddings({
model: 'gemini-embedding-2',
// For a predefined a list of requests `inlinedRequests`
src: {inlinedRequests: inlinedRequests},
config: {displayName: 'Inlined embeddings batch'},
});
console.log(`Created batch job: ${batchJob.name}`);
Per altri esempi, consulta la sezione Incorporamenti del Batch API cookbook.
Richiedi configurazione
Puoi includere qualsiasi configurazione di richiesta che utilizzeresti in una richiesta standard non batch. Ad esempio, puoi specificare la temperatura, le istruzioni del sistema o anche passare in altre modalità. L'esempio seguente mostra una richiesta inline che contiene un'istruzione di sistema per una delle richieste:
Python
inline_requests_list = [
{'contents': [{'parts': [{'text': 'Write a short poem about a cloud.'}]}]},
{'contents': [{
'parts': [{
'text': 'Write a short poem about a cat.'
}]
}],
'config': {
'system_instruction': {'parts': [{'text': 'You are a cat. Your name is Neko.'}]}}
}
]
JavaScript
inlineRequestsList = [
{contents: [{parts: [{text: 'Write a short poem about a cloud.'}]}]},
{contents: [{parts: [{text: 'Write a short poem about a cat.'}]}],
config: {systemInstruction: {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 di ricerca Google:
Python
inlined_requests = [
{'contents': [{'parts': [{'text': 'Who won the euro 1998?'}]}]},
{'contents': [{'parts': [{'text': 'Who won the euro 2025?'}]}],
'config':{'tools': [{'google_search': {}}]}}]
JavaScript
inlineRequestsList = [
{contents: [{parts: [{text: 'Who won the euro 1998?'}]}]},
{contents: [{parts: [{text: 'Who won the euro 2025?'}]}],
config: {tools: [{googleSearch: {}}]}}
]
Puoi anche specificare un output strutturato. L'esempio seguente mostra come specificare le richieste batch.
Python
import time
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="gemini-3.6-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', 'JOB_STATE_EXPIRED'):
break
print(f"Job not finished. Current state: {batch_job_inline.state.name}. Waiting 30 seconds...")
time.sleep(30)
print(f"Job finished with state: {batch_job_inline.state.name}")
# print the response
for i, inline_response in enumerate(batch_job_inline.dest.inlined_responses, start=1):
print(f"\n--- Response {i} ---")
# Check for a successful response
if inline_response.response:
# The .text property is a shortcut to the generated text.
print(inline_response.response.text)
JavaScript
import {GoogleGenAI, Type} from '@google/genai';
const ai = new GoogleGenAI({});
const inlinedRequests = [
{
contents: [{
parts: [{text: 'List a few popular cookie recipes, and include the amounts of ingredients.'}],
role: 'user'
}],
config: {
responseMimeType: 'application/json',
responseSchema: {
type: Type.ARRAY,
items: {
type: Type.OBJECT,
properties: {
'recipeName': {
type: Type.STRING,
description: 'Name of the recipe',
nullable: false,
},
'ingredients': {
type: Type.ARRAY,
items: {
type: Type.STRING,
description: 'Ingredients of the recipe',
nullable: false,
},
},
},
required: ['recipeName'],
},
},
}
},
{
contents: [{
parts: [{text: 'List a few popular gluten free cookie recipes, and include the amounts of ingredients.'}],
role: 'user'
}],
config: {
responseMimeType: 'application/json',
responseSchema: {
type: Type.ARRAY,
items: {
type: Type.OBJECT,
properties: {
'recipeName': {
type: Type.STRING,
description: 'Name of the recipe',
nullable: false,
},
'ingredients': {
type: Type.ARRAY,
items: {
type: Type.STRING,
description: 'Ingredients of the recipe',
nullable: false,
},
},
},
required: ['recipeName'],
},
},
}
}
]
const inlinedBatchJob = await ai.batches.create({
model: 'gemini-3.6-flash',
src: inlinedRequests,
config: {
displayName: 'inlined-requests-job-1',
}
});
Di seguito è riportato un esempio di output di questo job:
--- Response 1 ---
[
{
"recipe_name": "Chocolate Chip Cookies",
"ingredients": [
"1 cup (2 sticks) unsalted butter, softened",
"3/4 cup granulated sugar",
"3/4 cup packed light brown sugar",
"1 large egg",
"1 teaspoon vanilla extract",
"2 1/4 cups all-purpose flour",
"1 teaspoon baking soda",
"1/2 teaspoon salt",
"1 1/2 cups chocolate chips"
]
},
{
"recipe_name": "Oatmeal Raisin Cookies",
"ingredients": [
"1 cup (2 sticks) unsalted butter, softened",
"1 cup packed light brown sugar",
"1/2 cup granulated sugar",
"2 large eggs",
"1 teaspoon vanilla extract",
"1 1/2 cups all-purpose flour",
"1 teaspoon baking soda",
"1 teaspoon ground cinnamon",
"1/2 teaspoon salt",
"3 cups old-fashioned rolled oats",
"1 cup raisins"
]
},
{
"recipe_name": "Sugar Cookies",
"ingredients": [
"1 cup (2 sticks) unsalted butter, softened",
"1 1/2 cups granulated sugar",
"1 large egg",
"1 teaspoon vanilla extract",
"2 3/4 cups all-purpose flour",
"1 teaspoon baking powder",
"1/2 teaspoon salt"
]
}
]
--- Response 2 ---
[
{
"recipe_name": "Gluten-Free Chocolate Chip Cookies",
"ingredients": [
"1 cup (2 sticks) unsalted butter, softened",
"3/4 cup granulated sugar",
"3/4 cup packed light brown sugar",
"2 large eggs",
"1 teaspoon vanilla extract",
"2 1/4 cups gluten-free all-purpose flour blend (with xanthan gum)",
"1 teaspoon baking soda",
"1/2 teaspoon salt",
"1 1/2 cups chocolate chips"
]
},
{
"recipe_name": "Gluten-Free Peanut Butter Cookies",
"ingredients": [
"1 cup (250g) creamy peanut butter",
"1/2 cup (100g) granulated sugar",
"1/2 cup (100g) packed light brown sugar",
"1 large egg",
"1 teaspoon vanilla extract",
"1/2 teaspoon baking soda",
"1/4 teaspoon salt"
]
},
{
"recipe_name": "Gluten-Free Oatmeal Raisin Cookies",
"ingredients": [
"1/2 cup (1 stick) unsalted butter, softened",
"1/2 cup granulated sugar",
"1/2 cup packed light brown sugar",
"1 large egg",