Interfejs API do przetwarzania zbiorczego

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 do 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ów inlineResponse.
  • 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 obiektem GenerateContentResponse lub obiektem stanu.

Żądania wbudowane

W przypadku niewielkiej liczby próśb możesz bezpośrednio osadzić obiekty GenerateContentRequestBatchGenerateContentRequest. 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

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

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-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 osadzania zbiorczego

Aby uzyskać większą przepustowość, możesz użyć wsadowego interfejsu API do interakcji z modelem Embeddings. Aby utworzyć zadanie wsadowe generowania wektorów dystrybucyjnych za pomocą żądań wbudowanych lub plików wejściowych, użyj interfejsu API batches.create_embeddings i określ model wektorów dystrybucyjnych.

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

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

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: {}}]}} ] 

Możesz też określić uporządkowane dane wyjściowe. Przykład poniżej pokazuje, jak określić żądania wsadowe.

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="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',     } }); 

Stan 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

import time from google import genai  client = genai.Client()  # 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 from google import genai  client = genai.Client()  # 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

from google import genai  client = genai.Client()  # 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

from google import genai  client = genai.Client()  # 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 Modeli. 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ątem failedRequestCount. Jeśli używasz danych wyjściowych w postaci pliku, przeanalizuj każdy wiersz, aby sprawdzić, czy jest to obiekt GenerateContentResponse, 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: chociaż docelowy czas realizacji to 24 godziny, 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?