Interfejs Gemini Batch API został zaprojektowany do asynchronicznego przetwarzania dużych ilości żądań za 50% standardowej ceny. Docelowy czas realizacji to 24 godziny, ale w większości przypadków jest on znacznie krótszy.
Używaj interfejsu Batch API w przypadku zadań na dużą skalę, które nie wymagają natychmiastowej odpowiedzi, takich jak wstępne przetwarzanie danych czy przeprowadzanie ocen.
Tworzenie zadania wsadowego
Żądania w interfejsie Batch API możesz przesyłać na 2 sposoby:
- Żądania wbudowane: lista obiektów
GenerateContentRequest
bezpośrednio uwzględnionych w żądaniu tworzenia zbiorczego. Jest to odpowiednie rozwiązanie w przypadku mniejszych partii, w których łączny rozmiar żądania nie przekracza 20 MB. Dane wyjściowe zwracane przez model to lista obiektówinlineResponse
. - Plik wejściowy: plik JSON Lines (JSONL), w którym każdy wiersz zawiera kompletny obiekt
GenerateContentRequest
. Ta metoda jest zalecana w przypadku większych żądań. Dane wyjściowe zwracane przez model to plik JSONL, w którym każdy wiersz jest obiektemGenerateContentResponse
lub obiektem stanu.
Żądania w tekście
W przypadku niewielkiej liczby żądań możesz bezpośrednio osadzić obiekty GenerateContentRequest
w BatchGenerateContentRequest
. W tym przykładzie wywoływana jest metoda BatchGenerateContent
z żądaniami wbudowanymi:
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}")
JavaScript
import {GoogleGenAI} from '@google/genai';
const GEMINI_API_KEY = process.env.GEMINI_API_KEY;
const ai = new GoogleGenAI({apiKey: GEMINI_API_KEY});
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-2.5-flash',
src: inlinedRequests,
config: {
displayName: 'inlined-requests-job-1',
}
});
console.log(response);
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"
}
}
]
}
}
}
}'
Plik wejściowy
W przypadku większych zestawów żądań przygotuj plik JSON Lines (JSONL). Każdy wiersz w tym pliku musi być obiektem JSON zawierającym zdefiniowany przez użytkownika klucz i obiekt żądania, gdzie żądanie jest prawidłowym obiektem GenerateContentRequest
. Klucz zdefiniowany przez użytkownika jest używany w odpowiedzi, aby wskazać, które dane wyjściowe są wynikiem którego żądania. Na przykład żądanie z kluczem zdefiniowanym jako request-1
będzie miało odpowiedź opatrzoną tą samą nazwą klucza.
Ten plik jest przesyłany za pomocą interfejsu File API. Maksymalny rozmiar pliku wejściowego to 2 GB.
Poniżej znajdziesz przykład pliku JSONL. Możesz go zapisać w pliku o nazwie: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?"}]}]}}
Podobnie jak w przypadku żądań wbudowanych, w każdym żądaniu JSON możesz określić inne parametry, takie jak instrukcje systemowe, narzędzia lub inne konfiguracje.
Możesz przesłać ten plik za pomocą interfejsu File API, jak pokazano w tym przykładzie. Jeśli pracujesz z danymi wejściowymi multimodalnymi, możesz odwoływać się do innych przesłanych plików w pliku 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}")
JavaScript
import {GoogleGenAI} from '@google/genai';
import * as fs from "fs";
import * as path from "path";
import { fileURLToPath } from 'url';
const GEMINI_API_KEY = process.env.GEMINI_API_KEY;
const ai = new GoogleGenAI({apiKey: GEMINI_API_KEY});
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)
W tym przykładzie wywoływana jest metoda
BatchGenerateContent
z plikiem wejściowym przesłanym za pomocą interfejsu File API:
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}")
JavaScript
// Assumes `uploadedFile` is the file object from the previous step
const fileBatchJob = await ai.batches.create({
model: 'gemini-2.5-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-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': {
'file_name': '${BATCH_INPUT_FILE}'
}
}
}"
Po utworzeniu zadania zbiorczego otrzymasz jego nazwę. Użyj tej nazwy do monitorowania stanu zadania, a także do pobierania wyników po jego zakończeniu.
Oto przykładowe dane wyjściowe zawierające nazwę zadania:
Created batch job from file: batches/123456789
Obsługa wektorów dystrybucyjnych w pakietach
Aby uzyskać większą przepustowość, możesz użyć wsadowego interfejsu API do interakcji z modelem Embeddings.
Aby utworzyć zadanie wsadowe dotyczące wektorów dystrybucyjnych za pomocą żądań wbudowanych lub plików wejściowych, użyj interfejsu batches.create_embeddings
API i określ model wektorów dystrybucyjnych.
Python
# Creating an embeddings batch job with an input file request:
file_job = client.batches.create_embeddings(
model="gemini-embedding-001",
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-001",
# 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-001',
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-001',
// For a predefined a list of requests `inlinedRequests`
src: {inlinedRequests: inlinedRequests},
config: {displayName: 'Inlined embeddings batch'},
});
console.log(`Created batch job: ${batchJob.name}`);
Więcej przykładów znajdziesz w sekcji Embeddings w książce kucharskiej Batch API.
Konfiguracja żądania
Możesz uwzględnić dowolne konfiguracje żądań, których używasz w standardowym żądaniu niebędącym żądaniem wsadowym. Możesz na przykład określić temperaturę, instrukcje systemowe lub przekazać inne dane. Poniższy przykład pokazuje przykładowe żądanie wbudowane, które zawiera instrukcję systemową dla jednego z żądań:
Python
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.'}]}}
]
JavaScript
inlineRequestsList = [
{contents: [{parts: [{text: 'Write a short poem about a cloud.'}]}]},
{contents: [{parts: [{text: 'Write a short poem about a cat.'}]}], systemInstructions: {parts: [{text: 'You are a cat. Your name is Neko.'}]}}
]
Podobnie możesz określić narzędzia, których chcesz użyć w przypadku żądania. Poniższy przykład przedstawia żądanie, które włącza narzędzie wyszukiwarki Google:
Python
inline_requests_list = [
{'contents': [{'parts': [{'text': 'Who won the euro 1998?'}]}]},
{'contents': [{'parts': [{'text': 'Who won the euro 2025?'}]}], 'tools': [{'google_search ': {}}]}
]
JavaScript
inlineRequestsList = [
{contents: [{parts: [{text: 'Who won the euro 1998?'}]}]},
{contents: [{parts: [{text: 'Who won the euro 2025?'}]}], tools: [{googleSearch: {}}]}
]
Możesz też określić uporządkowane dane wyjściowe. Przykład poniżej pokazuje, jak określić żądania wsadowe.
Python
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', '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 GEMINI_API_KEY = process.env.GEMINI_API_KEY;
const ai = new GoogleGenAI({apiKey: GEMINI_API_KEY});
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-2.5-flash',
src: inlinedRequests,
config: {
displayName: 'inlined-requests-job-1',
}
});
Sprawdzanie stanu zadania monitorowania
Aby sprawdzić stan zadania wsadowego, użyj nazwy operacji uzyskanej podczas jego tworzenia. Pole stanu zadania wsadowego będzie wskazywać jego bieżący stan. Zadanie wsadowe może mieć jeden z tych stanów:
JOB_STATE_PENDING
: zadanie zostało utworzone i oczekuje na przetworzenie przez usługę.JOB_STATE_RUNNING
: praca jest w toku.JOB_STATE_SUCCEEDED
: zadanie zostało wykonane. Możesz teraz pobrać wyniki.JOB_STATE_FAILED
: zadanie nie powiodło się. Więcej informacji znajdziesz w szczegółach błędu.JOB_STATE_CANCELLED
: zadanie zostało anulowane przez użytkownika.JOB_STATE_EXPIRED
: zadanie wygasło, ponieważ było uruchomione lub oczekiwało na wykonanie przez ponad 48 godzin. Zadanie nie będzie miało żadnych wyników do pobrania. Możesz spróbować ponownie przesłać zadanie lub podzielić żądania na mniejsze partie.
Możesz okresowo sprawdzać stan zadania, aby dowiedzieć się, czy zostało ukończone.
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',
'JOB_STATE_EXPIRED',
])
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}")
JavaScript
// Use the name of the job you want to check
// e.g., inlinedBatchJob.name from the previous step
let batchJob;
const completedStates = new Set([
'JOB_STATE_SUCCEEDED',
'JOB_STATE_FAILED',
'JOB_STATE_CANCELLED',
'JOB_STATE_EXPIRED',
]);
try {
batchJob = await ai.batches.get({name: inlinedBatchJob.name});
while (!completedStates.has(batchJob.state)) {
console.log(`Current state: ${batchJob.state}`);
// Wait for 30 seconds before polling again
await new Promise(resolve => setTimeout(resolve, 30000));
batchJob = await client.batches.get({ name: batchJob.name });
}
console.log(`Job finished with state: ${batchJob.state}`);
if (batchJob.state === 'JOB_STATE_FAILED') {
// The exact structure of `error` might vary depending on the SDK
// This assumes `error` is an object with a `message` property.
console.error(`Error: ${batchJob.state}`);
}
} catch (error) {
console.error(`An error occurred while polling job ${batchJob.name}:`, error);
}
Pobieranie wyników
Gdy stan zadania wskazuje, że zadanie wsadowe zostało wykonane, wyniki są dostępne w polu 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
# (for embeddings, use batch_job.dest.inlined_embed_content_responses)
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}")
JavaScript
// Use the name of the job you want to check
// e.g., inlinedBatchJob.name from the previous step
const jobName = "YOUR_BATCH_JOB_NAME";
try {
const batchJob = await ai.batches.get({ name: jobName });
if (batchJob.state === 'JOB_STATE_SUCCEEDED') {
console.log('Found completed batch:', batchJob.displayName);
console.log(batchJob);
// If batch job was created with a file destination
if (batchJob.dest?.fileName) {
const resultFileName = batchJob.dest.fileName;
console.log(`Results are in file: ${resultFileName}`);
console.log("Downloading result file content...");
const fileContentBuffer = await ai.files.download({ file: resultFileName });
// Process fileContentBuffer (Buffer) as needed
console.log(fileContentBuffer.toString('utf-8'));
}
// If batch job was created with inline responses
else if (batchJob.dest?.inlinedResponses) {
console.log("Results are inline:");
for (let i = 0; i < batchJob.dest.inlinedResponses.length; i++) {
const inlineResponse = batchJob.dest.inlinedResponses[i];
console.log(`Response ${i + 1}:`);
if (inlineResponse.response) {
// Accessing response, structure may vary.
if (inlineResponse.response.text !== undefined) {
console.log(inlineResponse.response.text);
} else {
console.log(inlineResponse.response); // Fallback
}
} else if (inlineResponse.error) {
console.error(`Error: ${inlineResponse.error}`);
}
}
}
// If batch job was an embedding batch with inline responses
else if (batchJob.dest?.inlinedEmbedContentResponses) {
console.log("Embedding results found inline:");
for (let i = 0; i < batchJob.dest.inlinedEmbedContentResponses.length; i++) {
const inlineResponse = batchJob.dest.inlinedEmbedContentResponses[i];
console.log(`Response ${i + 1}:`);
if (inlineResponse.response) {
console.log(inlineResponse.response);
} else if (inlineResponse.error) {
console.error(`Error: ${inlineResponse.error}`);
}
}
} else {
console.log("No results found (neither file nor inline).");
}
} else {
console.log(`Job did not succeed. Final state: ${batchJob.state}`);
if (batchJob.error) {
console.error(`Error: ${typeof batchJob.error === 'string' ? batchJob.error : batchJob.error.message || JSON.stringify(batchJob.error)}`);
}
}
} catch (error) {
console.error(`An error occurred while processing job ${jobName}:`, 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"
elif [[ $batch_state == "JOB_STATE_EXPIRED" ]]; then
echo "Batch expired after 48 hours"
fi
Anulowanie zadania wsadowego
Trwające zadanie wsadowe możesz anulować, używając jego nazwy. Gdy zadanie zostanie anulowane, przestanie przetwarzać nowe żądania.
Python
# Cancel a batch job
client.batches.cancel(name=batch_job_to_cancel.name)
JavaScript
await ai.batches.cancel({name: batchJobToCancel.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'
Usuwanie zadania wsadowego
Istniejące zadanie wsadowe możesz usunąć, używając jego nazwy. Gdy zadanie zostanie usunięte, przestanie przetwarzać nowe żądania i zostanie usunięte z listy zadań wsadowych.
Python
# Delete a batch job
client.batches.delete(name=batch_job_to_delete.name)
JavaScript
await ai.batches.delete({name: batchJobToDelete.name});
REST
BATCH_NAME="batches/123456" # Your batch job name
# Delete the batch job
curl https://generativelanguage.googleapis.com/v1beta/$BATCH_NAME:delete \
-H "x-goog-api-key: $GEMINI_API_KEY"
Szczegóły techniczne
- Obsługiwane modele: interfejs Batch API obsługuje różne modele Gemini. Informacje o obsłudze interfejsu Batch API przez poszczególne modele znajdziesz na stronie Modele. Obsługiwane tryby interfejsu Batch API są takie same jak w przypadku interaktywnego interfejsu API (niezbiorczego).
- Ceny: korzystanie z interfejsu Batch API kosztuje 50% standardowej ceny interaktywnego interfejsu API dla odpowiedniego modelu. Szczegółowe informacje znajdziesz na stronie z cennikiem. Szczegółowe informacje o limitach szybkości tej funkcji znajdziesz na tej stronie.
- Docelowy poziom usług: zadania wsadowe są zaprojektowane tak, aby można było je wykonać w ciągu 24 godzin. Wiele zadań może zostać wykonanych znacznie szybciej, w zależności od ich rozmiaru i bieżącego obciążenia systemu.
- Buforowanie: w przypadku żądań zbiorczych włączone jest buforowanie kontekstu. Jeśli żądanie w Twojej grupie spowoduje trafienie w pamięci podręcznej, tokeny w pamięci podręcznej będą kosztować tyle samo co ruch w interfejsie API bez grupowania.
Sprawdzone metody
- W przypadku dużych żądań używaj plików wejściowych: w przypadku dużej liczby żądań zawsze używaj metody wprowadzania plików, aby ułatwić zarządzanie i uniknąć przekroczenia limitów rozmiaru żądań dla samego wywołania
BatchGenerateContent
. Maksymalny rozmiar pliku wejściowego to 2 GB. - Obsługa błędów: po zakończeniu zadania sprawdź
batchStats
pod kątemfailedRequestCount
. Jeśli używasz danych wyjściowych w postaci pliku, przeanalizuj każdy wiersz, aby sprawdzić, czy jest to obiektGenerateContentResponse
, czy obiekt stanu wskazujący błąd w przypadku konkretnego żądania. Pełną listę kodów błędów znajdziesz w przewodniku rozwiązywania problemów. - Przesyłaj zadania tylko raz: tworzenie zadania wsadowego nie jest idempotentne. Jeśli wyślesz to samo żądanie utworzenia 2 razy, utworzone zostaną 2 osobne zadania wsadowe.
- Dziel duże partie: docelowy czas realizacji to 24 godziny, ale rzeczywisty czas przetwarzania może się różnić w zależności od obciążenia systemu i rozmiaru zadania. W przypadku dużych zadań rozważ podzielenie ich na mniejsze partie, jeśli wyniki pośrednie są potrzebne wcześniej.
Co dalej?
- Więcej przykładów znajdziesz w notatniku interfejsu Batch API.
- Warstwa zgodności OpenAI obsługuje interfejs Batch API. Przykłady znajdziesz na stronie Zgodność z OpenAI.