Message Batches API: 50% ถูกกว่า, ถึง 24 ชม., custom_id
แนวคิด
Message Batches API คือวิธีประมวลผลคำขอ Messages จำนวนมากแบบ asynchronous เอกสารระบุคุณสมบัติหลักสามข้อ คือ ลดต้นทุนลง 50%, ประมวลผลได้นานถึง 24 ชั่วโมง โดย batch ที่ยังไม่เสร็จภายใน 24 ชั่วโมงจะหมดอายุ (expire) และไม่มีการรับประกันความเร็ว คือไม่มี latency SLA แม้เอกสารระบุว่าส่วนใหญ่เสร็จภายในหนึ่งชั่วโมง แต่ก็ไม่รับประกัน
แต่ละคำขอใน batch มี custom_id เป็นตัวจับคู่ระหว่างคำขอกับผลลัพธ์ จุดนี้จำเป็นเพราะผลลัพธ์ของ batch กลับมาในลำดับใดก็ได้ ไม่จำเป็นต้องตรงลำดับที่ส่งไป เอกสารย้ำว่าให้จับคู่ด้วย custom_id เสมอ อย่าอิงตำแหน่ง
ทำไมสำคัญ
การเลือกระหว่าง batch กับ realtime ขึ้นกับว่างานนั้นบล็อกคนอยู่หรือไม่ batch เหมาะกับงานที่ไม่บล็อกและทนหน่วงเวลาได้ เช่น รายงานยามค่ำคืน การตรวจสอบรายสัปดาห์ หรือการสร้าง test ตอนกลางคืน งานพวกนี้ไม่มีใครนั่งรอผล จึงแลกความเร็วกับต้นทุนที่ถูกลงครึ่งหนึ่งได้คุ้ม ในทางกลับกัน batch ไม่เหมาะกับ workflow ที่บล็อกคน เช่น pre-merge check ที่ developer ต้องรอผลก่อน merge ได้ เพราะหน้าต่างที่นานถึง 24 ชั่วโมงและไม่มี SLA จะทำให้คนติดค้าง
ตัวอย่างที่ตรงกับ Sample Question ของ exam คือ ทีมมีสอง workflow หนึ่งคือ pre-merge check ที่บล็อกและต้องเสร็จก่อน merge อีกอันคือ technical debt report ที่รันข้ามคืนไว้อ่านเช้าวันรุ่งขึ้น คำตอบที่ถูกคือใช้ batch เฉพาะ technical debt report และคง realtime ไว้สำหรับ pre-merge check การสลับทั้งคู่ไปเป็น batch ผิด เพราะ pre-merge เป็นงานบล็อก การหวังว่า batch จะเสร็จเร็วไม่ใช่สิ่งที่ยอมรับได้กับงานที่คนรออยู่ และการคง realtime ทั้งคู่ก็เสียโอกาสประหยัดครึ่งราคาของงานข้ามคืนไปเปล่า ๆ
ข้อจำกัดสำคัญที่ต้องรู้ตามกรอบ exam guide คือ batch ไม่รองรับการรันวง agentic loop ของ client-side tool ให้จบภายในคำขอเดียว คือเรียก tool กลางคัน รันเอง แล้วป้อนผลกลับเข้าไปในคำขอเดิมไม่ได้ ต้องส่งคำขอตามไปอีกรอบ ส่วน server-side tool เช่น web search หรือ code execution วิ่งวง agentic loop จบได้ภายในคำขอ batch เดียวด้วยกลไก pause_turn ต่อเนื่องฝั่งเซิร์ฟเวอร์ ตรงนี้เอกสารมีมุมที่ต้องเข้าใจให้ถูก เอกสารระบุว่า batch รองรับ multi-turn conversation ในความหมายว่าคุณ "แนบ" ประวัติสนทนาหลายเทิร์นเป็น input ได้ แต่แต่ละคำขอใน batch ยังเป็นคำขอเดียวจบเดียว มันไม่รันวง agentic loop ที่เรียก client-side tool แล้วรับผลกลับให้ นี่คือส่วนที่ถ้อยคำใน exam guide เจาะจงกว่า ผู้เรียนควรแยกให้ออกว่า "แนบประวัติหลายเทิร์นได้" กับ "รันลูปเรียก tool ให้ไม่ได้" เป็นคนละเรื่อง
เมื่อ batch มีคำขอบางส่วนล้มเหลว ให้ส่งซ้ำเฉพาะคำขอที่ล้มเหลวโดยระบุด้วย custom_id พร้อมปรับแก้ตามเหตุ เช่น chunk เอกสารที่ยาวเกิน context ผลลัพธ์แต่ละอันมี type เป็น succeeded, errored, canceled หรือ expired ให้จัดการตามชนิด
ตัวอย่าง
batch = client.messages.batches.create(requests=[
{"custom_id": "doc-1", "params": {"model": "claude-opus-4-8", ...}},
{"custom_id": "doc-2", "params": {"model": "claude-opus-4-8", ...}},
])
# poll จน processing_status == "ended"
for r in client.messages.batches.results(batch.id):
# จับคู่ด้วย custom_id เท่านั้น ผลกลับมาไม่เรียงลำดับ
if r.result.type == "succeeded": ...
elif r.result.type == "expired": ... # ส่งซ้ำเฉพาะตัวนี้ด้วย custom_id เดิม
เลื่อนปรับเงื่อนไขในซิมด้านล่างเพื่อดูว่างานแบบไหนควรใช้ batch และแบบไหนควรอยู่กับ realtime
recommendation: realtime
เป็นงานที่ block อยู่ (เช่น เช็กก่อน merge) หรือ caller รอ window แบบไม่เกิน 24 ชม./ไม่มี SLA ของ batch ไม่ได้ — อยู่กับ realtime ต่อ
เช็คความเข้าใจ
ทำไม pre-merge check ที่บล็อก developer จึงไม่ควรใช้ Message Batches API แต่ technical debt report ข้ามคืนควรใช้
ข้อความว่า batch รองรับ multi-turn conversation กับข้อจำกัดว่า batch ไม่รองรับ multi-turn tool calling ขัดกันหรือไม่