วิธีใช้ Batch API กับ Gemini ประมวลผลงานจำนวนมาก

Gemini Batch API เหมาะสำหรับการประมวลผลงานจำนวนมากที่ ไม่จำเป็นต้องได้รับคำตอบทันที เช่น วิเคราะห์ข้อมูลหลายหมื่นรายการ จัดหมวดหมู่สินค้า สรุปเอกสารจำนวนมาก สร้างคำอธิบายสินค้า ทำ Evaluation หรือสร้าง Embedding เป็นชุด

ข้อดีสำคัญคือ Batch API มีต้นทุนต่ำกว่า Standard Processing โดย Google กำหนดราคา Batch ไว้ประมาณ 50% ของ Standard Cost สำหรับงานที่รองรับ

ตัวอย่างงาน

100,000 Reviews
↓
Gemini Batch API
↓
วิเคราะห์ Sentiment
↓
Positive / Neutral / Negative

แทนการยิง API แบบปกติ

Request 1
Request 2
Request 3
...
Request 100,000

พร้อมกัน

สามารถรวม Request เป็น Batch Job แล้วให้ Gemini ประมวลผลเบื้องหลัง

สิ่งสำคัญ ณ ปัจจุบันคือ Batch API ใช้งานกับ generateContent API เท่านั้น ยังไม่ใช่ส่วนหนึ่งของ Interactions API

ดังนั้นแม้ Project ใหม่ทั่วไป Google จะแนะนำ Interactions API แต่หากต้องการ Batch Processing ต้องใช้ Batch API ตาม generateContent Workflow โดยเฉพาะ

❶ 📦 Gemini Batch API คืออะไร

Batch API คือระบบสำหรับส่ง Request จำนวนมากเข้า Gemini เป็น Job เดียว

Workflow พื้นฐานคือ

เตรียม Requests
↓
สร้าง Batch Job
↓
Gemini รับ Job
↓
ประมวลผล
↓
Job Completed
↓
ดาวน์โหลด Results

Application ไม่ต้องเปิด Connection รอ Response ของแต่ละ Prompt

แตกต่างจาก Standard Request

Request
↓
รอ
↓
Response

Batch จะเป็น

Submit Job
↓
รับ Job ID
↓
ตรวจสถานะภายหลัง
↓
อ่าน Results

❷ 🎯 Batch API เหมาะกับงานแบบไหน

เหมาะกับงานที่

  • มี Request จำนวนมาก
  • ไม่ต้องตอบ User แบบ Real-time
  • สามารถรอผลได้
  • ต้องการลดต้นทุน
  • ต้องประมวลผล Dataset
  • ทำงาน Background
  • ทำ Evaluation

ตัวอย่างที่เหมาะมาก ได้แก่

วิเคราะห์ Review

500,000 Reviews
↓
Sentiment Analysis

จัดหมวดหมู่สินค้า

Product Catalog
↓
Category Classification

สร้าง Product Description

50,000 Products
↓
Generate Description

สรุปเอกสาร

10,000 Documents
↓
Summary

Data Enrichment

Raw Data
↓
Gemini
↓
Structured Data

Evaluation

ทดสอบ Prompt หรือ Model กับ Dataset จำนวนมาก

❸ 🚫 งานแบบไหนไม่ควรใช้ Batch

ไม่เหมาะกับงานที่ User ต้องรอคำตอบทันที

เช่น

Chatbot
Customer Support Chat
Real-time Assistant
Live Search
Voice Assistant

งานเหล่านี้ควรใช้ Standard, Streaming, Interactions หรือ Live API ตาม Use Case

จำง่าย ๆ

ต้องตอบทันที
→ Standard / Interactions

รอได้
→ Batch

❹ ⏱️ Batch API ใช้เวลานานแค่ไหน

Google ระบุ Target Turnaround Time ของ Batch API ไว้ประมาณ

24 ชั่วโมง

แต่ในกรณีส่วนใหญ่ Job สามารถเสร็จเร็วกว่านั้นมาก

อย่างไรก็ตามไม่ควรสร้าง UX ที่รับประกันว่า

เสร็จใน 5 นาทีแน่นอน

เพราะเวลาจริงขึ้นกับ

  • ขนาด Batch
  • จำนวน Tokens
  • Model
  • System Load
  • Processing Capacity

ถ้า Application ต้องมี SLA ระดับวินาทีหรือนาที Batch ไม่ใช่ API ที่เหมาะ

❺ 💰 Batch API ถูกกว่า Standard เท่าไร

Google ออกแบบ Batch API ให้มีต้นทุนประมาณ

50% ของ Standard Cost

สำหรับ Model และ Processing Mode ที่รองรับ

ตัวอย่าง gemini-3.7-flash ณ วันที่ 2 กันยายน 2026

Standard

Input
$0.75 / 1M tokens

Output
$3.75 / 1M tokens

Batch

Input
$0.375 / 1M tokens

Output
$1.875 / 1M tokens

จนถึงวันที่ 31 ธันวาคม 2026

จึงเหมาะมากกับงาน Volume สูงที่ไม่ต้อง Real-time

❻ 🧮 ตัวอย่างประหยัดค่าใช้จ่าย

สมมติงานหนึ่งเดือนใช้

Input
100M tokens

Output
20M tokens

Standard Input

100 × $0.75
=
$75

Standard Output

20 × $3.75
=
$75

รวมประมาณ

$150

ถ้าใช้ Batch Pricing

Input

100 × $0.375
=
$37.50

Output

20 × $1.875
=
$37.50

รวม

$75

ประหยัดประมาณ

$75

ในตัวอย่างนี้

เมื่อ Scale เป็นหลายพันล้าน Tokens ความต่างจะมากขึ้นอีก

❼ ⚠️ Batch API ปัจจุบันใช้ generateContent

นี่เป็นจุดที่ต้องจำให้ชัด

Batch API ปัจจุบันรองรับเฉพาะ

generateContent API

ไม่ใช่

Interactions API

ดังนั้น Code จะใช้

client.batches.create()

โดยภายใน Batch แต่ละ Request จะเป็น

GenerateContentRequest

อย่านำ Structure ของ

client.interactions.create()

จากบทความก่อนหน้ามาใช้ตรง ๆ

❽ 📤 ส่ง Batch ได้กี่วิธี

ปัจจุบันมี 2 วิธีหลัก

Inline Requests

ใส่ Request List เข้า Batch Creation โดยตรง

เหมาะกับ Batch ขนาดเล็ก

Input File

สร้าง JSONL File แล้ว Upload

เหมาะกับ Batch ใหญ่

Decision ง่าย ๆ คือ

Batch เล็ก
→ Inline

Batch ใหญ่
→ JSONL File

❾ 📋 Inline Requests คืออะไร

Inline Requests คือใส่ Request ทั้งหมดไว้ใน Code

ตัวอย่าง

inline_requests = [
    {
        "contents": [
            {
                "parts": [
                    {
                        "text":
                        "สรุปข้อความที่ 1"
                    }
                ],
                "role": "user",
            }
        ]
    },
    {
        "contents": [
            {
                "parts": [
                    {
                        "text":
                        "สรุปข้อความที่ 2"
                    }
                ],
                "role": "user",
            }
        ]
    },
]

จากนั้นส่ง List เข้า Batch Job

เหมาะกับ Request จำนวนไม่มาก

❿ 📏 Inline Batch จำกัดขนาดเท่าไร

Google แนะนำ Inline Requests สำหรับ Batch ที่ Request Payload รวมมีขนาดต่ำกว่า

20 MB

ถ้าเริ่มเข้าใกล้หรือเกินระดับนี้ควรใช้

JSONL Input File

แทน

สำหรับงานใหญ่ File Input จัดการง่ายกว่าและลดความเสี่ยงชนขนาด Batch Creation Request

⓫ 🐍 สร้าง Batch แบบ Inline ด้วย Python

ติดตั้ง SDK ปัจจุบัน

pip install -U google-genai

ตัวอย่าง

from google import genai

client = genai.Client()

inline_requests = [
    {
        "contents": [
            {
                "parts": [
                    {
                        "text":
                        "สรุปข้อดีของ Wi-Fi 7 "
                        "ไม่เกิน 3 ข้อ"
                    }
                ],
                "role": "user",
            }
        ]
    },
    {
        "contents": [
            {
                "parts": [
                    {
                        "text":
                        "อธิบาย Mesh Wi-Fi "
                        "สำหรับมือใหม่"
                    }
                ],
                "role": "user",
            }
        ]
    },
]

batch_job = client.batches.create(
    model="gemini-3.7-flash",
    src=inline_requests,
    config={
        "display_name":
            "network-content-batch"
    },
)

print(batch_job.name)

เมื่อสำเร็จจะได้ Job Name เช่น

batches/123456789

ต้องเก็บชื่อนี้ไว้

⓬ 🔍 client.batches.create() ทำอะไร

ส่วนนี้

client.batches.create(

สร้าง Batch Job ใหม่

กำหนด Model

model="gemini-3.7-flash"

และ Request Source

src=inline_requests

ส่วน

display_name

เป็นชื่อช่วยให้ Developer แยก Job ได้ง่ายขึ้น

⓭ ⚠️ การสร้าง Batch Job ไม่ใช่ Idempotent

Google ระบุชัดว่า Batch Job Creation

ไม่เป็น Idempotent

หมายความว่า ถ้าส่ง

Create Job A

สองครั้ง

ไม่ได้หมายความว่าระบบจะรวมเป็น Job เดิม

แต่สามารถกลายเป็น

Batch Job A
Batch Job B

และทั้งสอง Job สามารถถูกประมวลผล

ดังนั้นต้องระวัง Retry ของคำสั่ง Create Batch

⓮ 🚫 อย่า Retry Create Batch แบบไม่ตรวจ

ไม่ควรทำ

Create Batch
↓
Timeout
↓
Create Batch อีกครั้งทันที

โดยไม่ตรวจว่า Job แรกถูกสร้างหรือยัง

เพราะอาจเกิด

Duplicate Processing
+
Duplicate Cost

Application ควรเก็บ

  • Internal Job ID
  • Batch Name
  • Submission Status

เพื่อป้องกันการ Submit Dataset เดิมซ้ำโดยไม่ตั้งใจ

⓯ 🟨 Inline Batch ด้วย JavaScript

ติดตั้ง

npm install @google/genai

ตัวอย่าง

import {
  GoogleGenAI
} from "@google/genai";

const ai = new GoogleGenAI({});

const requests = [
  {
    contents: [
      {
        parts: [
          {
            text:
              "สรุป Wi-Fi 7 เป็น 3 ข้อ"
          }
        ],
        role: "user",
      },
    ],
  },
  {
    contents: [
      {
        parts: [
          {
            text:
              "อธิบาย Mesh Wi-Fi"
          }
        ],
        role: "user",
      },
    ],
  },
];

const batchJob =
  await ai.batches.create({
    model: "gemini-3.7-flash",
    src: requests,
    config: {
      displayName:
        "network-content-batch",
    },
  });

console.log(batchJob.name);

หลักการเหมือน Python

⓰ 📁 JSONL คืออะไร

สำหรับ Batch ขนาดใหญ่ Google แนะนำใช้

JSON Lines
หรือ
JSONL

JSONL แตกต่างจาก JSON Array

JSON ปกติอาจเป็น

[
  {
    "id": 1
  },
  {
    "id": 2
  }
]

แต่ JSONL คือ

{"id":1}
{"id":2}

หนึ่งบรรทัดต่อหนึ่ง JSON Object

เหมาะกับ Dataset ขนาดใหญ่และ Streaming Processing

⓱ 🔑 แต่ละ JSONL Request ควรมี key

Batch Input File รุ่นปัจจุบันใช้ Structure เช่น

{
  "key": "request-1",
  "request": {
    "contents": [
      {
        "parts": [
          {
            "text":
              "สรุปข้อความนี้"
          }
        ]
      }
    ]
  }
}

key เป็น ID ที่ Developer กำหนดเอง

มีประโยชน์มากเพราะ Result จะถูกผูกกลับด้วย Key เดียวกัน

⓲ 🎯 ทำไม key สำคัญ

สมมติมี Product

product-1001
product-1002
product-1003

ใช้ Key

{"key":"product-1001", ...}

เมื่อผลกลับมา Application สามารถรู้ทันทีว่า

Response นี้
=
Product 1001

ไม่ต้องอาศัยตำแหน่งของ Record อย่างเดียว

สำหรับ Production ควรใช้ Stable ID ของข้อมูลจริง

⓳ 📄 ตัวอย่าง JSONL

ไฟล์

products-batch.jsonl

อาจเป็น

{"key":"product-1001","request":{"contents":[{"parts":[{"text":"จัดหมวดหมู่สินค้า: Wireless Router Wi-Fi 7"}]}]}}
{"key":"product-1002","request":{"contents":[{"parts":[{"text":"จัดหมวดหมู่สินค้า: 24-Port Gigabit Switch"}]}]}}
{"key":"product-1003","request":{"contents":[{"parts":[{"text":"จัดหมวดหมู่สินค้า: Wireless Access Point"}]}]}}

ทุกบรรทัดเป็น Request แยกกัน

⓴ 🐍 สร้าง JSONL ด้วย Python

ตัวอย่าง

import json

requests = [
    {
        "key": "product-1001",
        "request": {
            "contents": [
                {
                    "parts": [
                        {
                            "text":
                            "จัดหมวดหมู่สินค้า: "
                            "Wireless Router Wi-Fi 7"
                        }
                    ]
                }
            ]
        },
    },
    {
        "key": "product-1002",
        "request": {
            "contents": [
                {
                    "parts": [
                        {
                            "text":
                            "จัดหมวดหมู่สินค้า: "
                            "24-Port Gigabit Switch"
                        }
                    ]
                }
            ]
        },
    },
]

with open(
    "products-batch.jsonl",
    "w",
    encoding="utf-8",
) as file:
    for request in requests:
        file.write(
            json.dumps(
                request,
                ensure_ascii=False,
            )
            + "\n"
        )

ไฟล์นี้พร้อม Upload เข้า Gemini Files API

📤 Upload JSONL เข้า Files API

ตัวอย่าง Python ปัจจุบัน

from google import genai
from google.genai import types

client = genai.Client()

uploaded_file = client.files.upload(
    file="products-batch.jsonl",
    config=types.UploadFileConfig(
        display_name=
            "products-batch-input",
        mime_type="jsonl",
    ),
)

print(uploaded_file.name)

จะได้ File Resource เช่น

files/xxxxxxxx

จากนั้นนำ File Name นี้ไปสร้าง Batch Job

🚀 สร้าง Batch จาก JSONL File

batch_job = client.batches.create(
    model="gemini-3.7-flash",
    src=uploaded_file.name,
    config={
        "display_name":
            "products-classification"
    },
)

print(
    "Batch:",
    batch_job.name,
)

Workflow ตอนนี้คือ

JSONL
↓
Files API
↓
File Resource
↓
Batch Job

📏 JSONL Input File ใหญ่ได้แค่ไหน

Google กำหนด Maximum Input File สำหรับ Batch ที่

2 GB ต่อไฟล์

ดังนั้น Dataset ใหญ่ระดับหลาย GB ควรแบ่ง

batch-001.jsonl
batch-002.jsonl
batch-003.jsonl

แทนรวมทุกอย่างเป็น File เดียว

🧱 ทำไมควรแบ่ง Batch ใหญ่

Google แนะนำให้แบ่ง Batch ขนาดใหญ่มากออกเป็นหลาย Job หากต้องการผลบางส่วนเร็วขึ้น

ข้อดีคือ

  • Retry เฉพาะส่วนได้
  • Download ผลบางส่วนได้
  • Debug ง่าย
  • Progress Tracking ง่าย
  • ลดผลกระทบเมื่อ Job ล้ม

ตัวอย่าง

แทน

1 Job
10,000,000 Records

อาจเป็น

Job 1
100,000

Job 2
100,000

Job 3
100,000
...

ขนาดที่เหมาะต้อง Benchmark ตาม Workload

🗂️ ตั้ง Batch Key อย่างไรดี

ควรใช้ ID ที่มีอยู่ใน Database

เช่น

review-100234
product-49930
document-723

ไม่ควรใช้เพียง

1
2
3
4

ถ้า Dataset ถูก Split หรือ Retry

เพราะ Mapping จะสับสนง่าย

⚙️ ตั้ง Configuration ต่อ Request ได้

Batch ไม่ได้จำกัดเพียง Text Prompt ง่าย ๆ

แต่ละ GenerateContentRequest สามารถมี Configuration เช่น

  • System Instruction
  • Temperature
  • Tools
  • Structured Output
  • Multimodal Input

ได้ตาม Feature ที่ Model/API รองรับ

ดังนั้น Requests ใน Batch เดียวไม่จำเป็นต้องมี Prompt เหมือนกันทุกตัว

🧠 ใส่ System Instruction ได้ไหม

ได้

ตัวอย่าง

request = {
    "contents": [
        {
            "parts": [
                {
                    "text":
                    "Wireless Router Wi-Fi 7"
                }
            ]
        }
    ],
    "config": {
        "system_instruction": {
            "parts": [
                {
                    "text":
                    "คุณเป็นระบบ"
                    "จัดหมวดหมู่สินค้าไอที"
                }
            ]
        }
    },
}

ช่วยให้แต่ละ Request มี Behavior ที่กำหนดไว้

📦 Structured Output ใช้กับ Batch ได้ไหม

ได้

นี่เป็น Feature ที่มีประโยชน์มากกับ Bulk Processing

สมมติต้องการ Output

{
  "category": "router",
  "confidence": 0.95
}

สามารถกำหนด

response_mime_type
=
application/json

และ

response_schema

ใน GenerateContentRequest

🐍 ตัวอย่าง Batch + Structured Output

from typing import Literal

from google import genai
from pydantic import BaseModel


class ProductResult(BaseModel):
    category: Literal[
        "router",
        "switch",
        "access_point",
        "other",
    ]
    summary: str


client = genai.Client()

requests = [
    {
        "contents": [
            {
                "parts": [
                    {
                        "text":
                        "Wireless Router Wi-Fi 7"
                    }
                ],
                "role": "user",
            }
        ],
        "config": {
            "response_mime_type":
                "application/json",
            "response_schema":
                ProductResult,
        },
    }
]

job = client.batches.create(
    model="gemini-3.7-flash",
    src=requests,
    config={
        "display_name":
            "product-json-batch"
    },
)

print(job.name)

เหมาะกับการนำ Result เข้า Database หรือ Data Pipeline ต่อ

⚠️ ทำไม Structured Output ของ Batch ใช้ Parameter ต่างจาก Interactions

เพราะ Batch API ปัจจุบันใช้

generateContent

ดังนั้น Structured Output จะใช้ Configuration ของ GenerateContent เช่น

response_mime_type
response_schema

ไม่ใช่ Interactions API แบบบทความ 402 ที่ใช้

response_format

อย่านำ Parameter ของสอง API มาปะปนกัน

🔎 Google Search ใช้กับ Batch ได้ไหม

ได้ตาม Model และ Configuration ที่รองรับ

แต่ละ Request สามารถกำหนด Tool เช่น Google Search ได้

แนวคิด

Batch Request
↓
Google Search
↓
Gemini
↓
Result

เหมาะกับ Bulk Research ที่ไม่ต้องตอบทันที

แต่ Search Tool มี Pricing ของตัวเอง

ดังนั้น Batch Model Pricing ที่ถูกลงไม่ได้หมายความว่า Search Calls ฟรี

📄 Multimodal Batch ทำได้ไหม

ได้

Batch API รองรับ File Input Method ของ Gemini API

จึงสามารถสร้างงาน เช่น

1,000 Images
↓
Gemini Batch
↓
Classification

หรือ

PDF Collection
↓
Batch
↓
Extraction

หรือ

Video Dataset
↓
Batch
↓
Analysis

ตาม Model และ Input Method ที่รองรับ

🧠 Batch Embedding ทำได้ไหม

ได้

Gemini Batch API รองรับ Embedding Batch แยก

Python ใช้

client.batches.create_embeddings()

ตัวอย่าง

from google import genai

client = genai.Client()

embedding_job = (
    client.batches.create_embeddings(
        model="gemini-embedding-2",
        src={
            "inlined_requests":
                embedding_requests
        },
        config={
            "display_name":
                "document-embeddings"
        },
    )
)

print(embedding_job.name)

เหมาะกับการสร้าง Vector สำหรับ Dataset ขนาดใหญ่

📈 Batch Embedding เหมาะกับอะไร

เช่นสร้าง Embedding สำหรับ

100,000 Products

หรือ

1,000,000 Documents

เพื่อนำไปสร้าง

  • Semantic Search
  • RAG
  • Recommendation
  • Similarity Search

ไม่จำเป็นต้องเรียก Embedding API ทีละ Record แบบ Interactive

⏳ Batch Job มีสถานะอะไรบ้าง

Batch Job ปัจจุบันมีสถานะสำคัญ

JOB_STATE_PENDING

Job ถูกสร้างแล้ว รอประมวลผล

JOB_STATE_RUNNING

กำลังทำงาน

JOB_STATE_SUCCEEDED

สำเร็จและสามารถอ่านผลได้

JOB_STATE_FAILED

Job ล้มเหลว

JOB_STATE_CANCELLED

ถูกยกเลิก

JOB_STATE_EXPIRED

Job หมดอายุ

Application ต้องรองรับทุก Final State

⚠️ Batch Job Expire เมื่อไร

Google ระบุว่า Job จะเป็น

JOB_STATE_EXPIRED

หากยังอยู่ในสถานะ Running หรือ Pending นานเกินประมาณ

48 ชั่วโมง

Job ที่ Expire จะไม่มี Result ให้ดาวน์โหลด

ทางแก้คือ

  • Submit ใหม่
  • ลดขนาด Batch
  • แบ่ง Job ออกเป็นชุดเล็กลง

🔍 เช็กสถานะ Batch ด้วย Python

from google import genai

client = genai.Client()

job = client.batches.get(
    name="batches/YOUR_JOB_ID"
)

print(job.state.name)

ไม่ต้องสร้าง Job ใหม่เพียงเพื่อดูสถานะ

ใช้ Job Name เดิม

🔄 Polling จน Job เสร็จ

ตัวอย่าง

import time

from google import genai

client = genai.Client()

job_name = "batches/YOUR_JOB_ID"

final_states = {
    "JOB_STATE_SUCCEEDED",
    "JOB_STATE_FAILED",
    "JOB_STATE_CANCELLED",
    "JOB_STATE_EXPIRED",
}

while True:
    job = client.batches.get(
        name=job_name
    )

    print(job.state.name)

    if job.state.name in final_states:
        break

    time.sleep(30)

อย่า Poll ทุก 10 Milliseconds

เพราะไม่มีประโยชน์และเพิ่ม API Traffic

🔔 ไม่อยาก Poll ใช้ Webhook ได้

Gemini API ปัจจุบันรองรับ Webhooks สำหรับ Async Completion

สามารถ Subscribe Event เช่น

batch.succeeded
batch.failed

เมื่อ Batch เสร็จ Gemini ส่ง Notification ไปยัง Backend ของเรา

Flow

Create Batch
↓
ทำงานอื่นต่อ
↓
Gemini ประมวลผล
↓
Webhook
↓
Backend รับ Notification
↓
ดึง Results

เหมาะกับ Production มากกว่า Poll ต่อเนื่องในหลายกรณี

🐍 ตัวอย่างสร้าง Batch Webhook

from google import genai

client = genai.Client()

webhook = client.webhooks.create(
    name="BatchWebhook",
    subscribed_events=[
        "batch.succeeded",
        "batch.failed",
    ],
    uri=(
        "https://example.com/"
        "gemini-batch-callback"
    ),
)

print(webhook.name)

Production Endpoint ต้องมี Security และ Verification ตาม Webhook Documentation

🧩 Polling หรือ Webhook เลือกอะไร

Polling

เหมาะกับ

  • Prototype
  • Script เล็ก
  • Local Development

Webhook

เหมาะกับ

  • Production
  • Job จำนวนมาก
  • Background Processing
  • Event-driven Architecture

ถ้ามี Batch หลายพัน Job การ Poll ทุก Job ทุก 30 วินาทีอาจไม่ใช่ Architecture ที่เหมาะ

📥 วิธีอ่านผล Inline Batch

หาก Batch ถูกสร้างจาก Inline Requests

Result จะอยู่ใน

dest.inlined_responses

ตัวอย่าง

job = client.batches.get(
    name=job_name
)

if (
    job.state.name
    == "JOB_STATE_SUCCEEDED"
):
    for item in (
        job.dest.inlined_responses
    ):
        if item.response:
            print(
                item.response.text
            )

        elif item.error:
            print(
                "Error:",
                item.error,
            )

ต้องตรวจ Error ต่อ Record ด้วย

📁 วิธีอ่านผล File Batch

หาก Batch ใช้ JSONL Input File

Output จะถูกเก็บเป็น File

ตรวจ

job.dest.file_name

จากนั้น Download

result_file = (
    job.dest.file_name
)

content = client.files.download(
    file=result_file
)

print(
    content.decode("utf-8")
)

Output File เป็น JSONL

แต่ละบรรทัดคือ Response หรือ Error ของ Request นั้น

🧾 Result File เก็บไว้นานแค่ไหน

เมื่อ Batch Job สำเร็จ Google ระบุว่า Result จะถูกเก็บไว้ให้ Download ประมาณ

6 สัปดาห์

หลังจากนั้นจะถูกลบถาวร

ดังนั้น Production Application ควร

Batch Succeeded
↓
Download Results
↓
Validate
↓
Save ใน Storage/Database ของเรา

ไม่ควรใช้ Gemini Result File เป็น Permanent Storage

🗄️ Result ควรเก็บไว้ที่ไหน

เช่น

  • Database
  • Google Cloud Storage
  • S3
  • Data Warehouse
  • Internal Storage

ตามระบบ

Batch API คือ Processing Service

ไม่ใช่ Long-term Data Storage

⚠️ Batch สำเร็จไม่ได้แปลว่าทุก Request สำเร็จ

นี่เป็นจุดสำคัญมาก

Batch Job อาจจบ แต่ Request บางรายการภายใน Batch อาจ Error ได้

จึงต้องตรวจ

batchStats

โดยเฉพาะ

failedRequestCount

และตรวจ Output แต่ละ Record

อย่าตรวจเพียง

JOB_STATE_SUCCEEDED

แล้วถือว่าข้อมูลทั้งหมดเสร็จสมบูรณ์

📊 Batch Stats ควรตรวจอะไร

ควรติดตามอย่างน้อย

Total Requests
Successful Requests
Failed Requests

จากนั้นคำนวณ

Success Rate
=
Successful
÷
Total

ถ้ามี

100,000 Requests

และ Fail

2,000

Success Rate คือ

98%

ต้องตัดสินว่าจะ Retry 2,000 รายการหรือไม่

🔁 Retry เฉพาะ Record ที่ล้ม

ไม่ควร Submit Batch 100,000 รายการทั้งหมดใหม่เพราะ Fail 200 รายการ

ควร

Parse Results
↓
หา Failed Keys
↓
สร้าง Retry Batch
↓
ส่งเฉพาะ Failed Requests

ช่วยลด

  • Cost
  • Duplicate Processing
  • เวลา

นี่เป็น Workflow ที่เหมาะกับ Production

🗂️ เก็บ Original Request ตาม Key

Database สามารถมี

batch_id
record_key
request_payload
status
attempt_count
result
error

เมื่อ Batch เสร็จ

Application Update ตาม

record_key

ถ้า Fail สามารถหา Request เดิมมา Retry ได้ทันที

🔁 จำกัดจำนวน Retry

อย่าทำ

Failed
↓
Retry
↓
Failed
↓
Retry
↓
...

ไม่มีที่สิ้นสุด

ควรกำหนด

MAX_ATTEMPTS = 3

หรือจำนวนตาม Use Case

หลังเกิน Limit ให้

  • Manual Review
  • Dead-letter Queue
  • Error Report

🚨 แยก Error ที่ Retry ได้กับ Error ที่ต้องแก้ Data

ตัวอย่าง

Retry ได้

บาง Temporary Service Error

ไม่ควร Retry Payload เดิมทันที

Invalid Request
Unsupported Format
Invalid Schema

ถ้า Request ผิด Retry 100 ครั้งก็ยังผิด

ต้องแก้ข้อมูลก่อน

📏 Batch API Rate Limit แยกจาก Standard API

ข้อดีสำคัญคือ Batch API มี Rate Limits แยกจาก Non-batch Calls

จึงช่วยแยก

User-facing Traffic

ออกจาก

Background Work

ได้ดีขึ้น

ตัวอย่าง

Interactive API
→ Chat Users

Batch API
→ Nightly Processing

ทำให้งาน Background ไม่ต้องยิง Interactive API จำนวนมหาศาล

📊 Batch Limit สำคัญปัจจุบัน

Google ระบุข้อจำกัดพื้นฐาน ได้แก่

Concurrent Batch Requests
=
100
Input File Size
=
2 GB
File Storage Limit
=
20 GB

นอกจากนี้ยังมี

Enqueued Tokens Per Model

ซึ่งขึ้นกับ Model และ Usage Tier

ควรตรวจ Active Limits ก่อนส่ง Dataset ขนาดใหญ่มาก

🧮 Enqueued Tokens คืออะไร

คือจำนวน Token รวมที่กำลังรออยู่ใน Batch Jobs ของ Model นั้น

ตัวอย่างสมมติ

Job A
100M tokens

Job B
200M tokens

Job C
150M tokens

รวม

450M Enqueued Tokens

หาก Model/Tier รองรับต่ำกว่าปริมาณนี้ Job ใหม่อาจชน Limit

ดังนั้น Batch Capacity Planning ต้องดู Tokens ไม่ใช่เพียงจำนวน Jobs

⚠️ Concurrent Batch 100 ไม่ได้หมายถึง 100 Requests

หมายถึง

Batch Jobs ที่ Active พร้อมกัน

ไม่ใช่

Prompt สูงสุด 100 Prompt

หนึ่ง Job สามารถมี Request จำนวนมากภายในได้ตามข้อจำกัดอื่น

อย่าสับสนสองตัวเลขนี้

📦 File Storage 20 GB ต้องจัดการอย่างไร

หาก Upload JSONL หรือ Media จำนวนมากเข้า Files API

ต้องคำนึงถึง

20 GB Project Storage Limit

ควรมี Cleanup Strategy

ไม่ควร Upload Batch Input ต่อเนื่องโดยไม่ตรวจ File Lifecycle

🧹 Cleanup หลังงานเสร็จ

เมื่อ

Results Saved

และ Input File ไม่ต้องใช้อีก

ควรพิจารณาลบ File Resource ตาม Workflow ที่เหมาะสม

ช่วยลด

  • Storage Usage
  • File Clutter
  • Risk จากข้อมูลเก่า

Source Data จริงควรอยู่ Storage ของ Application เอง

🎯 Batch API สำหรับ Content Generation

ตัวอย่างมีหัวข้อบทความ

10,000 Topics

ต้องสร้าง

  • Meta Description
  • Summary
  • FAQ
  • Category

สามารถสร้างหนึ่ง Request ต่อ Topic

แล้ว Batch Processing เป็นชุด

แต่ควรมี Human/Quality Review ก่อน Publish หาก Content มีผลต่อเว็บไซต์จริง

Batch ทำให้ Scale ง่ายขึ้น แต่ไม่ได้รับประกัน Quality ของทุก Record

📊 Batch API สำหรับ Classification

นี่เป็น Use Case ที่เหมาะมาก

Input

Customer Message

Output

{
  "category": "technical",
  "priority": "high"
}

ใช้

Batch
+
Structured Output

จากนั้น Parse JSON เข้า Database

มีความเสถียรกว่าการให้ AI ตอบ Free-form Text

🛍️ Batch API สำหรับ E-commerce

ตัวอย่าง

100,000 Products

สามารถทำ

  • Category
  • Attribute Extraction
  • Description
  • Keyword
  • Translation
  • Data Cleaning

แต่ Product ID ควรถูกใช้เป็น Batch Key

เช่น

sku-12345

เพื่อ Mapping Result กลับสินค้าได้ถูกต้อง

💬 Batch API สำหรับ Review Analysis

ตัวอย่าง

1,000,000 Reviews
↓
Gemini

Output

{
  "sentiment": "negative",
  "topic": "shipping",
  "summary": "จัดส่งล่าช้า"
}

จากนั้นนำไปสร้าง Dashboard

  • Sentiment Trend
  • Complaint Category
  • Product Issues

นี่เป็น Batch Workload ที่เหมาะมาก

📚 Batch API สำหรับ Evaluation

สมมติต้องเปรียบเทียบ Prompt A และ Prompt B

มี Test Dataset

10,000 Questions

สร้าง

Batch A
→ Prompt A

Batch B
→ Prompt B

จากนั้นเปรียบเทียบ

  • Accuracy
  • Token Usage
  • Cost
  • Failure Rate

ช่วยเลือก Prompt ก่อน Production

🤖 Batch API สำหรับ AI Agent เหมาะไหม

ขึ้นกับ Task

ถ้า Agent ต้อง

User
↔
AI
↔
Tools

แบบ Interactive ไม่เหมาะ

แต่ถ้าเป็น

Nightly Agent Evaluation

หรือ

Offline Agent Simulation

Batch สามารถเหมาะมาก

ต้องแยก Real-time Agent กับ Offline Processing

⏰ Schedule Batch ตอนกลางคืนดีไหม

สำหรับ Application ที่มีงานรายวัน เช่น

23:00
รวบรวมข้อมูล

00:00
สร้าง Batch

เมื่อเสร็จ
Download

เช้า
Report พร้อม

เป็น Architecture ที่เหมาะกับ Batch

แต่เวลาที่ Job เสร็จจริงไม่ได้รับประกันว่าจะเหมือนกันทุกวัน

ระบบต้องรองรับ Delayed Completion

🔔 Webhook เหมาะกับ Scheduled Batch

Flow

Scheduler
↓
Create Batch
↓
Store Job ID
↓
Gemini Processing
↓
Webhook
↓
Download Results
↓
Save Database

ดีกว่าเปิด Worker รอหลายชั่วโมง

🧱 Production Architecture ที่แนะนำ

Database
↓
Batch Builder
↓
JSONL
↓
Gemini Files API
↓
Batch API
↓
Webhook / Poller
↓
Result Processor
↓
Validation
↓
Database

แยกแต่ละ Layer ชัดเจน

ทำให้ Retry และ Debug ง่าย

🔐 อย่าใส่ข้อมูลเกินจำเป็น

ถ้าต้อง Classification Product

ไม่จำเป็นต้องส่ง

  • Customer Password
  • Admin Notes
  • Billing Data

ที่ไม่เกี่ยว

ใช้หลัก

Data Minimization

Batch Dataset มักมีข้อมูลจำนวนมาก หากเกิด Misconfiguration ผลกระทบจะกว้างกว่าการส่ง Request เดียว

🛡️ API Key ต้องอยู่ Server-side

Batch Jobs ควรถูกสร้างจาก

  • Backend
  • Worker
  • Server
  • CI/CD Job

ไม่ใช่ Browser ที่ฝัง Gemini API Key

Architecture

Backend
↓
GEMINI_API_KEY
↓
Batch API

Key ต้องจัดการตาม Security Best Practice เช่นเดียวกับ Gemini API ปกติ

🧪 ทดสอบ Batch เล็กก่อน

ก่อน Submit

1,000,000 Records

ควร Test

10 Records

จากนั้น

100

แล้ว

1,000

ตรวจ

  • Output Format
  • Accuracy
  • Errors
  • Cost
  • Key Mapping

ก่อน Scale

🚫 อย่าเริ่มจาก Dataset ใหญ่ที่สุด

หาก Schema ผิด

แล้ว Submit

500,000 Requests

อาจเสียทั้งเวลาและ Cost

Batch Processing ทำให้ Scale ได้ง่าย จึงยิ่งต้อง Test Prompt และ Schema ให้ดีก่อน

📐 คำนวณ Cost ก่อน Submit

ตัวอย่างมี

500,000 Records

เฉลี่ย

Input 1,000 tokens
Output 200 tokens

Total Input

500M tokens

Total Output

100M tokens

นำไปคูณ Batch Pricing ของ Model

ก่อน Submit Job

ควรมี Cost Estimator ใน Production Pipeline

🧮 Estimate Tokens ก่อน Batch

สามารถสุ่ม Dataset เช่น

1,000 Records

หา Average Tokens

แล้วประมาณ

Average Tokens
×
Total Records

ไม่แม่น 100% แต่ช่วยป้องกัน Budget Surprise ได้มาก

💸 Batch ถูกกว่าแต่ยังสร้างค่าใช้จ่ายสูงได้

คำว่า 50% Discount ไม่ได้หมายความว่า Cheap เสมอไป

ถ้าส่ง

10 Billion Tokens

ค่าใช้จ่ายยังสูง

ควรมี

  • Budget
  • Cost Estimate
  • Record Limit
  • Approval Threshold

ก่อน Submit Job ขนาดใหญ่

🚦 สร้าง Internal Batch Limit

ตัวอย่าง

Job > 1M records
→ ต้องได้รับ Approval

หรือ

Estimated Cost > $100
→ ต้องได้รับ Approval

ตามองค์กร

ช่วยป้องกัน Script Bug สร้าง Batch ขนาดมหาศาลโดยไม่ตั้งใจ

📦 แบ่ง Batch ตาม Business Unit

แทนรวมทุกอย่าง

all-products.jsonl

อาจแยก

routers.jsonl
switches.jsonl
access-points.jsonl

ช่วย

  • ตรวจ Quality
  • Retry
  • Cost Allocation

ได้ง่ายกว่า

🔍 ใช้ Display Name ให้มีความหมาย

ไม่ควรตั้ง

batch1
batch2

ใน Production

อาจใช้

product-classification-2026-09-02

หรือ

review-sentiment-th-2026-09

ช่วย Debug และค้น Job ภายหลัง

📋 List Batch Jobs ได้

Python

for job in client.batches.list():
    print(
        job.name,
        job.state.name,
    )

สามารถกำหนด Page Size ได้ตาม SDK

เหมาะกับ Admin Dashboard

📊 Dashboard Batch ควรมีอะไร

อย่างน้อย

Job ID
Display Name
Model
Created At
State
Total Requests
Failed Requests
Estimated Cost
Actual Usage

และ

Result Imported?

ช่วยรู้ว่า Job สำเร็จแต่ Pipeline ยังไม่ได้นำ Result เข้า Databaseหรือไม่

🔄 State Machine ที่ควรใช้

Database Job Status อาจมี

CREATED
↓
SUBMITTED
↓
RUNNING
↓
SUCCEEDED
↓
RESULT_DOWNLOADED
↓
VALIDATED
↓
IMPORTED

และ Error Path

FAILED
CANCELLED
EXPIRED

ดีกว่าเก็บ Boolean เพียง

done = true/false

เพราะ Batch Workflow มีหลายขั้น

🧪 ตรวจ Result ก่อน Import

ไม่ควร

Download
↓
INSERT ทุกอย่างทันที

ควร

Download
↓
Parse
↓
Schema Validation
↓
Business Validation
↓
Import

โดยเฉพาะ Structured Output

JSON ถูกไม่ได้หมายความว่าข้อมูลถูกเสมอไป

🛡️ Human Review สำหรับงานสำคัญ

เช่น

  • Medical
  • Legal
  • Financial
  • Content Publication
  • Account Action

ไม่ควรถือว่า Bulk AI Output ถูก 100%

สามารถ Review แบบ Sampling

สุ่ม 1–5%

หรือ Rule-based Flagging

ตาม Risk

📈 Quality Sampling

สมมติ Batch 100,000 Records

สุ่มตรวจ

1,000 Records

วัด

  • Accuracy
  • Missing Fields
  • Hallucination
  • Invalid Classification

ถ้า Quality ต่ำกว่า Threshold ให้หยุด Import หรือ Review Prompt

🔄 Version Prompt

Batch Output ควรบันทึก

prompt_version

เช่น

product-classifier-v3

ถ้าภายหลังพบ Error จะรู้ว่า Records ใดถูกสร้างด้วย Prompt Version ไหน

เช่นเดียวกับ

model

และ

schema_version

📦 Metadata ที่ควรเก็บต่อ Record

key
batch_job
model
prompt_version
schema_version
attempt
status
result
error

ช่วย Audit และ Reprocess

สำหรับระบบของ comsiam หากใช้ Batch API สร้าง Metadata หรือวิเคราะห์บทความจำนวนมาก ควรเก็บเลขบทความหรือ Internal Content ID เป็น key เพื่อให้ผลลัพธ์กลับไปตรงกับบทความต้นฉบับโดยไม่ต้องพึ่งลำดับของ Output

⚡ Batch กับ Standard ใช้ร่วมกันได้

ระบบไม่จำเป็นต้องเลือกอย่างใดอย่างหนึ่ง

ตัวอย่าง

User Chat
→ Standard / Interactions

Daily Content Analysis
→ Batch

Large Embeddings
→ Batch

Real-time Search
→ Standard

นี่เป็น Architecture ที่สมดุลกว่า

🧠 Batch กับ Context Caching

Batch Request สามารถใช้ Configuration ที่รองรับของ GenerateContent

แต่ต้องพิจารณา Cost และ Feature Compatibility ของ Model/API

อย่าคิดว่าเพียงเป็น Batch แล้ว Context ซ้ำทุก Recordจะถูกลดต้นทุนแบบเดียวกับ Caching โดยอัตโนมัติ

ต้องดู Caching Configuration และ Pricing ของ Model นั้นโดยตรง

🔍 Batch กับ Google Search ต้องคิด Cost เพิ่ม

แม้ Batch Model Price จะลด 50%

แต่ถ้าแต่ละ Request ใช้

Google Search

Search Tool Pricing ยังคงมีผลตามปัจจุบัน

หนึ่ง Prompt อาจสร้างหลาย Search Queries

ดังนั้น Bulk Research ควร Estimate

Model Tokens
+
Search Queries

พร้อมกัน

⚠️ Result Order ไม่ควรใช้เป็น Identity

โดยเฉพาะ File Batch

ควรใช้

key

เพื่อ Mapping

ไม่ควรสมมติว่า

Output line 100
=
Input row 100

โดยไม่มี Key

Stable Identifier ปลอดภัยกว่า

🧹 JSONL ต้องเป็นหนึ่ง JSON ต่อหนึ่งบรรทัด

ข้อผิดพลาดที่พบบ่อย

{
  "key": "1",
  "request": {
    ...
  }
}

ถูก Pretty Print หลายบรรทัด

JSONL ที่ถูกต้องควรเป็น Object หนึ่งบรรทัด

{"key":"1","request":{...}}
{"key":"2","request":{...}}

แต่ละ Record ต้องจบด้วย Newline ตาม Workflow ของไฟล์

🚨 JSONL Error ควรตรวจอะไร

  • ทุกบรรทัดเป็น Valid JSON
  • มี key
  • มี request
  • contents ถูก Structure
  • Encoding เป็น UTF-8
  • ไม่มี Trailing Text
  • Request Configuration ถูกต้อง

สามารถ Validate Local ก่อน Upload

🧪 Validate JSONL ด้วย Python

import json

with open(
    "batch.jsonl",
    "r",
    encoding="utf-8",
) as file:
    for line_number, line in enumerate(
        file,
        start=1,
    ):
        try:
            json.loads(line)

        except json.JSONDecodeError as exc:
            print(
                "Invalid line:",
                line_number,
                exc,
            )

ช่วยจับ Syntax Error ก่อนเสียเวลาส่ง Batch

🚫 15 ข้อผิดพลาดเมื่อใช้ Gemini Batch API

❶ ใช้ Batch กับ Chat Real-time

ไม่ตรง Use Case

❷ ใช้ Interactions Request Format

Batch ปัจจุบันใช้ GenerateContent

❸ Inline Batch ใหญ่เกิน 20 MB

ควรใช้ JSONL

❹ JSONL ไม่มี Key

Mapping Result ยาก

❺ ใช้ Index เป็น Identity อย่างเดียว

Retry แล้วสับสน

❻ Submit Job เดิมซ้ำ

Batch Create ไม่ Idempotent

❼ Poll ถี่เกินไป

เพิ่ม Traffic โดยไม่จำเป็น

❽ ไม่รองรับ EXPIRED

Job เกิน 48 ชั่วโมงอาจ Expire

❾ ดูเพียง Job Success

บาง Record อาจ Fail

❿ Retry ทั้ง Batch

ควร Retry เฉพาะ Failed Records

⓫ ไม่ Validate Structured Output

ข้อมูลอาจผิด Business Rule

⓬ ไม่ Download Result

Result เก็บประมาณ 6 สัปดาห์

⓭ Upload Files จน Storage เต็ม

File Storage มี Limit

⓮ ไม่ Estimate Tokens ก่อน Submit

เสี่ยง Cost สูง

⓯ ใช้ API Key ใน Client

ควร Submit จาก Backend

🪜 วิธีใช้ Gemini Batch API แบบ Step by Step

❶ เลือกงาน

ต้องเป็น Non-real-time

❷ เลือก Model

ตรวจ Batch Support

❸ สร้าง Prompt

ทดสอบกับ Standard Request ก่อน

❹ Test 10 Records

ตรวจ Quality

❺ เลือก Input Mode

< 20 MB
→ Inline

งานใหญ่
→ JSONL

❻ สร้าง Stable Key

ใช้ ID จาก Database

❼ Validate Input

ก่อน Submit

❽ สร้าง Batch Job

client.batches.create()

❾ เก็บ Job Name

ลง Database

❿ Monitor

Polling หรือ Webhook

⓫ รอ Final State

Succeeded/Failed/Cancelled/Expired

⓬ Download Results

หรืออ่าน Inline Response

⓭ ตรวจ Batch Stats

หา Failed Requests

⓮ Validate Output

Schema + Business Logic

⓯ Import Results

เข้า Database

⓰ Retry เฉพาะ Failed

ไม่ Submit ทั้งหมดใหม่

⓱ เก็บ Metrics

Cost/Quality/Latency

⓲ Cleanup

จัดการ Temporary Files

Workflow นี้เหมาะกว่าการเขียน Loop ยิง Standard API หลายแสนครั้ง

✅ Checklist ก่อน Submit Batch ขนาดใหญ่

Prompt ผ่าน Test แล้ว

Model รองรับ Batch

Pricing ตรวจแล้ว

Cost Estimate แล้ว

Input เป็น Valid JSONL

Key ไม่ซ้ำ

Payload ไม่เกิน Limit

File ไม่เกิน 2 GB

Storage ยังพอ

Enqueued Tokens ยังพอ

Duplicate Submission Protection มี

Job ID ถูกเก็บ

Poll/Webhook มี

Result Parser พร้อม

Error Parser พร้อม

Structured Output Validate ได้

Retry Policy มี

Budget Limit มี

Security Review แล้ว

ถ้ายังไม่มี Result Processing Pipeline ไม่ควรรีบ Submit Batch ใหญ่

📊 Batch Metrics ที่ควรเก็บ

batch_jobs_created
batch_jobs_succeeded
batch_jobs_failed
batch_jobs_expired

ต่อ Record

requests_total
requests_success
requests_failed
retry_count

ด้านประสิทธิภาพ

job_turnaround_time
tokens
cost
cost_per_record

ด้านคุณภาพ

validation_failure
accuracy_sample
manual_review_rate

นี่ช่วยให้รู้ว่า Batch API คุ้มจริงหรือไม่

💡 ตัวอย่างระบบประมวลผล 100,000 รายการ

สมมติมี Product 100,000 ชิ้น

ขั้นที่ 1

Query Database

100,000 Products

ขั้นที่ 2

Split เป็น

10 Batch Files
×
10,000 Products

ขั้นที่ 3

สร้าง Key

product-{id}

ขั้นที่ 4

สร้าง JSONL

ขั้นที่ 5

Upload Files

ขั้นที่ 6

Create Batch Jobs

ขั้นที่ 7

Webhook แจ้ง Job เสร็จ

ขั้นที่ 8

Download Results

ขั้นที่ 9

Validate JSON

ขั้นที่ 10

Update Products

ขั้นที่ 11

Retry Failed Keys

Architecture นี้ Scale ได้ดีกว่าการ Run Request 100,000 ตัวพร้อมกันจาก Web Server

💡 Batch Size ควรเท่าไร

ไม่มีตัวเลขเดียวที่ดีที่สุด

ขึ้นกับ

  • Average Tokens
  • Record Size
  • Model
  • Failure Tolerance
  • Result Urgency

ควรเริ่มจาก Batch ที่ Manage ได้ง่าย

แล้ว Benchmark

ไม่จำเป็นต้องใช้ Maximum 2 GB เพียงเพราะ API อนุญาต

📉 Batch เล็กเกินไปก็มีข้อเสีย

ถ้ามี

1,000,000 Records

แต่สร้าง

1 Record / Batch

ก็เกิด Batch Jobs จำนวนมากโดยไม่จำเป็น

ควรหา Balance ระหว่าง

Manageability
+
Throughput
+
Failure Isolation

📈 Batch ใหญ่เกินไปก็มีข้อเสีย

ถ้า Job ใหญ่มาก

  • รอผลนานขึ้น
  • Retry ยาก
  • Failure กระทบ Dataset ใหญ่
  • Intermediate Result ช้า

Google จึงแนะนำให้แบ่ง Batch ใหญ่มากหากต้องการผลบางส่วนเร็วขึ้น

🔄 Batch Result Pipeline ต้อง Idempotent

แม้ Batch Creation ไม่ Idempotent แต่ Result Import ของเราเองควรออกแบบให้ Safe

เช่น

product-1001

ถูก Process Result ซ้ำ

ไม่ควรสร้าง Duplicate Record

อาจใช้

UPSERT

หรือ Unique Key ตาม Database

ช่วยให้ Webhook Delivery หรือ Worker Retry ปลอดภัยขึ้น

🛡️ Webhook Handler ต้องระวัง Duplicate Delivery

Event-driven System โดยทั่วไปควรถือว่า Notification อาจถูกส่งหรือ Process ซ้ำได้

Handler ควรตรวจ

job_id
+
event_type
+
already_processed

ก่อน Import Result

ไม่ควร Update Database แบบไม่มี Deduplication

📅 Result Retention 6 สัปดาห์ไม่ได้หมายความว่าควรรอ

แม้ Google เก็บ Results ไว้ประมาณ 6 สัปดาห์

Production ควร Download ทันทีหลัง Job สำเร็จ

เพราะ Data Pipeline ของเราไม่ควรพึ่ง Temporary API Storage เป็น Backup

หลัง Download ควรตรวจ

checksum / record count

ตาม Requirement

❓ คำถามที่พบบ่อย

Gemini Batch API คืออะไร

เป็น API สำหรับส่ง Request จำนวนมากไปประมวลผลแบบ Asynchronous เหมาะกับงานที่ไม่ต้องตอบทันที เช่น Classification, Data Processing, Evaluation และ Bulk Content Generation

Batch API ถูกกว่า Gemini API ปกติไหม

สำหรับงานที่รองรับ Google ออกแบบ Batch Pricing ไว้ประมาณ 50% ของ Standard Processing Cost ตัวอย่าง Gemini 3.7 Flash ปัจจุบัน Batch Input อยู่ที่ $0.375 และ Output $1.875 ต่อ 1 ล้าน Tokens จนถึง 31 ธันวาคม 2026

Batch API ใช้กับ Interactions API ได้ไหม

ปัจจุบันยังไม่ได้ Google ระบุว่า Batch API รองรับเฉพาะ generateContent API

Inline Batch กับ JSONL ต่างกันอย่างไร

Inline เหมาะกับ Batch ขนาดเล็กที่ Payload รวมต่ำกว่า 20 MB ส่วน JSONL เหมาะกับ Dataset ใหญ่และรองรับ Input File สูงสุด 2 GB

Batch Job ใช้เวลานานแค่ไหน

Google ตั้ง Target Turnaround Time ประมาณ 24 ชั่วโมง แต่ส่วนใหญ่มักเสร็จเร็วกว่านั้น อย่างไรก็ตามเวลาจริงขึ้นกับขนาดงานและ System Load

ถ้า Batch Job สำเร็จ ทุก Request สำเร็จด้วยไหม

ไม่จำเป็น ต้องตรวจ Batch Stats และ Error ของแต่ละ Response เพราะบาง Request ภายใน Job อาจ Fail ได้ แม้ Job โดยรวมจบแล้ว

🎯 สรุป

Gemini Batch API เป็นตัวเลือกที่เหมาะสำหรับงาน AI ปริมาณมากที่ ไม่ต้องการ Response แบบ Real-time เช่น Classification, Translation, Data Extraction, Product Processing, Review Analysis, Evaluation และ Bulk Embeddings

จุดเด่นสำคัญคือ Batch Pricing อยู่ประมาณครึ่งหนึ่งของ Standard Processing Cost ใน Model ที่รองรับ จึงช่วยลดค่าใช้จ่ายได้มากเมื่องานมี Token จำนวนมหาศาล

Batch API ปัจจุบันรองรับเฉพาะ generateContent ไม่ใช่ Interactions API และสามารถส่ง Request ได้ 2 วิธี คือ Inline Requests สำหรับ Payload ต่ำกว่า 20 MB และ JSONL Input File สำหรับงานขนาดใหญ่ โดย Input File มี Limit สูงสุด 2 GB

สำหรับงาน Production ควรใช้ key ที่เชื่อมกับ ID ใน Database เพื่อ Mapping Results, เก็บ Batch Job Name, Monitor State และตรวจทุก Record หลัง Job เสร็จ เพราะ Batch Success ไม่ได้หมายความว่าทุก Request ภายในสำเร็จ

Job มีสถานะตั้งแต่ Pending, Running, Succeeded, Failed, Cancelled จนถึง Expired โดย Job ที่ Pending หรือ Running เกินประมาณ 48 ชั่วโมงสามารถ Expire ได้ ส่วน Result ของ Job ที่สำเร็จจะถูกเก็บให้ดาวน์โหลดประมาณ 6 สัปดาห์

Google ยังรองรับ Webhook สำหรับ Event เช่น batch.succeeded และ batch.failed ทำให้ Production System ไม่จำเป็นต้อง Poll Job ตลอดเวลา

Batch API รองรับ Configuration สำคัญของ GenerateContent เช่น System Instructions, Structured Output, Tools, Google Search และ Multimodal Input รวมถึงมี Batch Embedding สำหรับสร้าง Vector ปริมาณมาก

สำหรับ comsiam แนวทางที่เหมาะคือทดสอบ Prompt และ Schema กับข้อมูลเล็กก่อน จากนั้นสร้าง JSONL โดยใช้ Internal Content ID เป็น key, แบ่ง Dataset เป็น Batch ที่จัดการได้ และ Retry เฉพาะ Record ที่ล้มเหลว วิธีนี้ควบคุม Cost และ Quality ได้ดีกว่าการยิง Standard API จำนวนมหาศาลพร้อมกัน

หากใช้ Batch API เป็น Pipeline ระยะยาว comsiam ควรเก็บ Model Version, Prompt Version, Schema Version, Batch ID และผล Validation ของแต่ละ Record เพื่อให้สามารถตรวจสอบและประมวลผลใหม่ได้เมื่อ Model หรือ Prompt เปลี่ยนในอนาคต