วิธีควบคุมค่าใช้จ่าย AI Agent บน VPS ไม่ให้งบบานปลาย
ป้องกันค่าใช้จ่ายพุ่งจากการรัน AI Agent บน VPS ตลอด 24 ชั่วโมง ด้วยการจำกัด Token ต่อรอบ การใช้ Prompt Caching และการตั้ง Hard Cap ใน API เพื่อคุมงบประมาณให้แม่นยำ
วิธีควบคุมค่าใช้จ่ายสำหรับ AI agent ที่ทำงานตลอดเวลา
การควบคุมค่าใช้จ่ายของ AI agent บน VPS (virtual private server) คือการกำหนดเพดานค่าใช้จ่ายไว้ก่อนที่ agent จะเริ่มทำงาน เนื่องจากไม่มีใครคอยเฝ้าดูมิเตอร์ในขณะที่ระบบทำงานอยู่ ให้จำกัดจำนวน token ในทุกการตอบกลับด้วย max_tokens, กำหนดขอบเขตจำนวนรอบการทำงาน (loop iterations) ในโค้ดของคุณเอง, ทำแคช (cache) ส่วนของ prompt ที่ไม่มีการเปลี่ยนแปลง และบันทึกจำนวนการใช้งานของทุกการตอบกลับเพื่อตรวจสอบว่างานใดเป็นตัวสร้างค่าใช้จ่าย ค่าเช่าเซิร์ฟเวอร์เป็นราคาคงที่รายเดือน แต่ API ของโมเดลจะคิดค่าใช้จ่ายตามจำนวน token ซึ่งการปล่อยให้ loop ทำงานโดยไม่มีผู้ดูแลนั้นสามารถใช้ token ไปได้อย่างรวดเร็วโดยที่คุณไม่รู้ตัว
เนื้อหานี้ตั้งอยู่บนสมมติฐานว่าคุณมี agent อยู่แล้วและมีการเรียกใช้งาน Messages API จากเซิร์ฟเวอร์ที่คุณเป็นเจ้าของ สำหรับ การสร้าง AI agent ด้วย Claude บน VPS จะครอบคลุมถึงกลไกการทำงานในส่วนนั้น
เหตุใด unattended agent จึงมีโครงสร้างต้นทุนที่แตกต่างออกไป
เซสชันแบบโต้ตอบ (interactive session) มีมนุษย์คอยควบคุม เมื่อโมเดลทำงานผิดพลาดหรือต้องอ่าน log ขนาด 40,000 บรรทัด ผู้ที่เฝ้าดูจะสั่งหยุดการทำงานได้ทันที แต่ unattended agent ไม่มีกลไกหยุดยั้งเช่นนั้น มันจะทำงานไปจนกว่าลูปจะสิ้นสุด จากนั้นตัวตั้งเวลาจะเริ่มการทำงานใหม่อีกครั้ง
ความถี่คือตัวคูณที่หลายคนมองข้าม งานที่ตั้งตารางเวลาไว้ทุก 5 นาทีจะทำงาน 288 ครั้งต่อวัน และประมาณ 8,640 ครั้งต่อเดือน ต้นทุนต่อการรันหนึ่งครั้งคือตัวเลขที่คุณต้องนำไปคูณ เอเจนต์แบบ "always-on" หลายตัวไม่จำเป็นต้องเปิดทิ้งไว้ตลอดเวลา สิ่งที่ต้องการคือการตอบสนองภายในระยะเวลาที่กำหนด ซึ่งสามารถจัดการได้ด้วยการตั้งตารางเวลา
นอกจากนี้ เอเจนต์ยังมีต้นทุนในส่วนที่หน้าต่างแชททั่วไปไม่มี
- คำจำกัดความของเครื่องมือ (Tool definitions) จะถูกส่งไปพร้อมกับทุกคำขอ ระบบ prompt สำหรับการใช้งานเครื่องมือมีต้นทุน 290 tokens บน Claude Opus 4.8 โดยใช้
tool_choiceของautoหรือnoneและ 410 tokens หากใช้anyหรือtoolส่วน bash tool จะเพิ่มเข้าไปอีก 325 tokens ทุก MCP server ที่คุณเชื่อมต่อ จะเพิ่ม schema เข้าไปในน้ำหนักของคำขอนั้น โดย MCP ย่อมาจาก model context protocol - ผลลัพธ์จากเครื่องมือถือเป็น input tokens คำสั่งที่แสดงผลลัพธ์ 8,000 บรรทัด จะนำข้อมูล 8,000 บรรทัดนั้นเข้าสู่คำขอถัดไป และรวมอยู่ในทุกคำขอหลังจากนั้นในรอบการทำงานเดียวกัน
- หน้าเว็บที่ดึงข้อมูลมาถือเป็น input tokens หน้าเว็บขนาดเฉลี่ย 10 kB คิดเป็นประมาณ 2,500 tokens และไฟล์วิจัย PDF ขนาด 500 kB คิดเป็นประมาณ 125,000 tokens โดย
max_content_tokensจะตัดทอนเฉพาะเนื้อหาที่เป็นข้อความเท่านั้น เนื่องจาก "มีผลกับเนื้อหาที่เป็นข้อความ ไม่ใช่เนื้อหาที่เป็นไบนารี เช่น ไฟล์ PDF" ให้จำกัดขอบเขตของ PDF ด้วยmax_usesและallowed_domainsแทน - การค้นหาบนเว็บมีราคาต่อการค้นหา อยู่ที่ $10 ต่อ 1,000 ครั้ง ไม่ว่าจะมีผลลัพธ์กลับมาจำนวนเท่าใดก็ตาม การค้นหาที่เกิดข้อผิดพลาดจะไม่ถูกเรียกเก็บเงิน
ต้นทุนเหล่านี้อาจไม่สูงหากเกิดขึ้นเพียงครั้งเดียว แต่จะกลายเป็นค่าใช้จ่ายมหาศาลเมื่อเกิดขึ้นถึง 8,640 ครั้ง
เพดานแบบแข็งและเพดานแบบอ่อนแก้ปัญหาที่แตกต่างกัน
max_tokens จะถูกบังคับใช้ นี่คือเพดานแบบแข็งสำหรับผลลัพธ์รวมของหนึ่งคำขอ ทั้งส่วนการคิดและข้อความตอบกลับ Claude จะไม่สร้างเนื้อหาเกินจากจุดนี้ และโมเดลจะไม่เห็นตัวเลขดังกล่าว การถึงขีดจำกัดนี้จะทำให้เกิด stop_reason: "max_tokens" และคำตอบที่ถูกตัดทอน สิ่งที่ต้องระวังสำหรับเอเจนต์คือ ทุกคำขอในลูปการใช้เครื่องมือจะมี max_tokens ของตัวเอง ดังนั้นมันจึงจำกัดแค่การตอบกลับหนึ่งครั้ง ไม่ใช่จำกัดทั้งงาน การเรียกใช้เครื่องมือ 10 ครั้งที่ 4,000 โทเค็น จะเท่ากับเพดาน 40,000 โทเค็นต่อรอบการทำงาน
งบประมาณของงานเป็นเพียงคำแนะนำ task_budget จะอยู่ภายใน output_config และบอกโมเดลว่ามีจำนวนโทเค็นเท่าใดสำหรับลูปเอเจนต์ทั้งหมด โดยนับรวมการคิด การเรียกใช้เครื่องมือ ผลลัพธ์จากเครื่องมือ และผลลัพธ์ที่ส่งออก
resp = client.beta.messages.create(
model="claude-opus-4-8",
max_tokens=4096,
betas=["task-budgets-2026-03-13"],
output_config={"task_budget": {"type": "tokens", "total": 64000}},
messages=messages,
)"งบประมาณของงานเป็นเพียงคำแนะนำแบบอ่อน ไม่ใช่เพดานแบบแข็ง" Claude อาจใช้เกินงบกลางคัน และขีดจำกัดที่บังคับใช้จริงสำหรับผลลัพธ์ยังคงเป็น max_tokens "การนับถอยหลังจะมองเห็นได้เฉพาะโมเดลเท่านั้น" และการตอบกลับจะไม่มีฟิลด์แสดงงบประมาณที่เหลืออยู่ task_budget.total ขั้นต่ำที่ยอมรับได้คือ 20,000 โทเค็น หากน้อยกว่านั้นจะส่งคืนข้อผิดพลาด 400 งบประมาณที่น้อยเกินไปสำหรับงานจะทำให้เกิดพฤติกรรมคล้ายการปฏิเสธงาน ดังนั้นโมเดลจะลดขอบเขตของงานลงหรือหยุดทำงานก่อนกำหนด
รายละเอียดหนึ่งที่ทำให้เสียค่าใช้จ่ายเพิ่มแทนที่จะประหยัด หากไคลเอนต์ของคุณลดค่า task_budget.remaining ในทุกคำขอติดตามผล ค่าที่เปลี่ยนไปจะทำให้ prefix ที่แคชไว้ซึ่งมีค่านั้นใช้งานไม่ได้ ให้ตั้งค่าเพียงครั้งเดียวในคำขอแรกเท่านั้น
งบประมาณของงานอยู่ในสถานะเบต้าบน Claude Fable 5, Claude Opus 4.8 และ Claude Opus 4.7 ส่วน Claude Sonnet 5 และ Claude Haiku 4.5 ถูกระบุว่าเป็น Not supported และงบประมาณของงานไม่มีผลกับ Claude Code ดังนั้น เซสชัน Claude Code ที่แยกออกมาใน tmux จึงขึ้นอยู่กับการจัดการเซสชันให้สะอาดแทน
เพดานที่สามอยู่ใน Claude Console: ให้กำหนดพื้นที่ทำงานแยกต่างหากสำหรับเอเจนต์ จากนั้นตั้งค่าขีดจำกัดการใช้จ่ายรายเดือนและขีดจำกัดอัตราต่อนาทีสำหรับพื้นที่นั้น "คุณไม่สามารถตั้งค่าขีดจำกัดบน Default Workspace ได้" และ "ขีดจำกัดระดับองค์กรจะมีผลเสมอ แม้ว่าขีดจำกัดของพื้นที่ทำงานรวมกันแล้วจะมากกว่าก็ตาม" ให้เพิ่มการแจ้งเตือนการใช้จ่ายเพื่อให้ระบบแจ้งเตือนคุณก่อนที่จะถึงขีดจำกัดจริง
การเลือกโมเดลในแต่ละงาน และปัจจัยที่ส่งผลต่อความพยายามจริง
การเลือกโมเดลเป็นการตัดสินใจในแต่ละงาน ณ เดือนกรกฎาคม 2026 ราคาต่อล้านโทเค็นสำหรับ input และ output ตามลำดับคือ Claude Fable 5 อยู่ที่ $10 และ $50, Claude Opus 4.8 และ Opus 4.7 อยู่ที่ $5 และ $25, Claude Sonnet 5 อยู่ที่ $3 และ $15, และ Claude Haiku 4.5 อยู่ที่ $1 และ $5 สำหรับ Sonnet 5 นั้นปัจจุบันมีราคาต่ำกว่าราคาป้ายเนื่องจาก "ราคาแนะนำที่ $2/$10 ต่อล้านโทเค็นสำหรับ input/output มีผลจนถึงวันที่ 31 สิงหาคม 2026" งานที่ทำเพียงแค่จำแนกบรรทัด log ไม่จำเป็นต้องใช้ Opus และไม่มีโควตาฟรีสำหรับรองรับตารางงานที่หนาแน่น เนื่องจาก Claude API ไม่มีระดับการใช้งานฟรี นอกเหนือจากเครดิตจำนวนเล็กน้อยที่ได้รับเมื่อสมัครใช้งาน
ความพยายาม (effort) เป็นปัจจัยที่สอง output_config.effort ยอมรับค่า low, medium, high, xhigh และ max โดยค่าเริ่มต้นคือ high ดังนั้นการตั้งค่า high อย่างชัดเจนจึงให้ผลเช่นเดียวกับการละไว้ การลดระดับความพยายามช่วยลดค่าใช้จ่ายได้มากกว่าแค่ความยาวในการคิด เอกสารระบุว่ามันทำให้ Claude เรียกใช้เครื่องมือน้อยลงและรวมการดำเนินการเข้าเป็นขั้นตอนเดียว สำหรับเอเจนต์แล้วนี่คือการประหยัดที่มากกว่า เพราะการหลีกเลี่ยงการเรียกใช้เครื่องมือหมายถึงการลดจำนวนคำขอทั้งหมดที่ไม่จำเป็นต้องเกิดขึ้น
ข้อควรระวังคือค่าความพยายามจะขัดแย้งกับแคช การเปลี่ยนค่าระหว่างคำขอจะทำให้การทำ prompt caching เป็นโมฆะ ในตัวอย่างที่ระบุไว้ คำขอที่ 2 รายงานค่า cache_read_input_tokens: 3546 ส่วนคำขอที่ 3 ซึ่งเปลี่ยนค่าความพยายามจากสูงเป็นปานกลาง รายงานค่า cache_creation_input_tokens จาก 3546 และ cache_read_input_tokens เป็น 0 ดังนั้นควรปรับระดับความพยายามตามภาระงาน ไม่ควรเปลี่ยนภายในบทสนทนาที่แคชไว้ หากต้องการควบคุมความลึกโดยไม่ทำลายแคช ให้ทำผ่าน prompt แทน เช่น การเพิ่มบรรทัด "ตอบโดยตรงโดยไม่ต้องไตร่ตรอง" ในข้อความล่าสุดของผู้ใช้ จะช่วยให้จุดพัก (breakpoint) ก่อนหน้านี้ยังคงอยู่ครบถ้วน
โทเค็นการคิด (thinking tokens) จะถูกเรียกเก็บเงินในอัตราเดียวกับ output และนับรวมใน max_tokens ซึ่งเป็นเหตุผลว่าทำไมคำตอบที่ถูกตัดทอนมักหมายถึงการที่กระบวนการคิดใช้โควตาไปจนหมด โปรดอ่าน usage.output_tokens_details.thinking_tokens สำหรับตัวเลขดังกล่าว สิ่งที่ประกอบเป็นบิลค่าโทเค็นของ Claude จริงๆ จะอธิบายรายละเอียดการวัดผลไว้อย่างละเอียด
แคช stable prefix และหยุดทำให้มันพังโดยไม่ตั้งใจ
การเขียนแคชมีค่าใช้จ่าย 1.25 เท่าของราคา input พื้นฐานสำหรับแคชระยะเวลา 5 นาที และ 2 เท่าสำหรับแคชระยะเวลา 1 ชั่วโมง การอ่านแคชมีค่าใช้จ่าย 0.1 เท่า ดังนั้น "การใช้แคชจะคุ้มทุนหลังจากการอ่านเพียงครั้งเดียวสำหรับระยะเวลา 5 นาที (เขียน 1.25 เท่า) หรือหลังจากการอ่านสองครั้งสำหรับระยะเวลา 1 ชั่วโมง (เขียน 2 เท่า)"
ประโยคเดียวที่อธิบายว่าทำไมสิ่งนี้จึงเหมาะกับ agent ที่ทำงานตลอดเวลาคือ: "แคชจะถูกรีเฟรชโดยไม่มีค่าใช้จ่ายเพิ่มเติมทุกครั้งที่มีการใช้งานเนื้อหาที่แคชไว้" งานที่ทำงานทุกสองนาทีโดยใช้แคชระยะเวลา 5 นาทีจะช่วยรักษา prefix ให้พร้อมใช้งานได้ตลอดทั้งวันด้วยการเขียนเพียงครั้งเดียว
สามวิธีที่ทำให้เสียแคชไปโดยไม่รู้ตัว
prefix ที่เปลี่ยนแปลงได้ "prefix ของแคชจะถูกสร้างขึ้นตามลำดับดังนี้: tools, system จากนั้น messages" การเปลี่ยนแปลงของไบต์ใดๆ ที่เกิดขึ้นก่อนหน้าในลำดับนั้นจะทำให้ข้อมูลทั้งหมดหลังจากนั้นเป็นโมฆะ และการแก้ไขคำจำกัดความของเครื่องมือ (tool definitions) จะทำให้แคชทั้งหมดเป็นโมฆะ ความผิดพลาดที่พบบ่อยคือการใส่ timestamp หรือ run id ไว้ใน system prompt: ทุกคำขอจะส่งผลให้มี prefix ที่แตกต่างกัน ทำให้ต้องเขียนรายการใหม่ที่ 1.25 เท่า และอ่านข้อมูลเดิมไม่ได้เลย สัญญาณเตือนคือ usage.cache_read_input_tokens ที่เป็น 0 ในขณะที่คำขอมีลักษณะเหมือนกันทุกประการ ให้ย้ายข้อความที่มีการเปลี่ยนแปลงบ่อยไปไว้ในข้อความล่าสุดของผู้ใช้แทน
prefix ที่สั้นเกินไป โมเดลแต่ละตัวมีความยาวขั้นต่ำที่สามารถแคชได้ หากต่ำกว่านั้นคำขอจะถูกประมวลผลโดยไม่มีการแคชและ "ไม่มีการส่งข้อความแสดงข้อผิดพลาดกลับมา" ตัวเลขดังกล่าวรวมถึง 1,024 tokens บน Claude Opus 4.8 และ Claude Sonnet 5 และ 4,096 บน Claude Haiku 4.5 ดังนั้นการย้ายงานจาก Sonnet ไปยัง Haiku อาจทำให้การแคชถูกปิดไปโดยเงียบๆ
บทสนทนาที่ยาวเกินกว่า lookback "หน้าต่าง lookback คือ 20 บล็อก" ระบบจะตรวจสอบตำแหน่งสูงสุด 20 ตำแหน่งต่อจุดพัก (breakpoint) แล้วหยุดทำงาน ในตัวอย่างที่ระบุไว้ การสนทนาที่มี 35 บล็อกโดยมีจุดพักที่บล็อก 35 จะตรวจสอบบล็อกที่ 35 ลงไปถึง 16 และรายการของรอบก่อนหน้าที่บล็อก 15 จะอยู่นอกหน้าต่างการตรวจสอบ ทำให้ไม่มีการพบข้อมูล (no hit) agent ที่เพิ่มบล็อกการใช้เครื่องมือและผลลัพธ์ของเครื่องมือหลายรายการต่อรอบจะเกิน 20 บล็อกภายในสองหรือสามรอบ คุณสามารถใช้จุดพักได้สี่จุดต่อหนึ่งคำขอ ดังนั้นควรแบ่งหนึ่งจุดไว้สำหรับข้อความล่าสุด
ส่งงานที่รอได้ไปยัง Batches API
"การใช้งานทั้งหมดจะถูกคิดค่าบริการที่ 50% ของราคา API มาตรฐาน" ทั้งในส่วนของ input และ output การประมวลผลแบบ batch เป็นแบบอะซิงโครนัส (asynchronous) โดย "batch ส่วนใหญ่จะเสร็จสิ้นภายในเวลาไม่เกิน 1 ชั่วโมง" และจะได้รับผลลัพธ์เมื่อคำขอทั้งหมดประมวลผลเสร็จสิ้น หรือเมื่อครบกำหนด 24 ชั่วโมง แล้วแต่ว่าเหตุการณ์ใดจะเกิดขึ้นก่อน ซึ่งนี่เป็นเพียงค่าเฉลี่ยทั่วไป ไม่ใช่การรับประกัน
ให้ทำการ poll processing_status จนกว่าสถานะจะเปลี่ยนเป็น ended คำขอที่ส่งผลลัพธ์กลับมาเป็น errored, canceled หรือ expired จะไม่มีการคิดค่าบริการ ข้อควรระวังหากคุณมีการตั้งค่าเพดานการใช้จ่าย (spend cap) คือ "batch อาจมีการใช้จ่ายเกินขีดจำกัดที่กำหนดไว้ใน Workspace ของคุณไปบ้างเล็กน้อย"
ส่วนลดต่างๆ สามารถนำมาใช้ร่วมกันได้ และเนื่องจาก batch อาจใช้เวลาประมวลผลนานกว่า 5 นาที เอกสารจึงแนะนำให้ใช้ cache ระยะเวลา 1 ชั่วโมงสำหรับ batch ที่มีการแชร์ context ร่วมกัน ดังนั้นควรแบ่งแยกงานให้ชัดเจน: งานใดที่ผู้ใช้หรือ webhook ต้องรอผลลัพธ์ให้คงไว้ในเส้นทางปกติ (live path) ส่วนงานประเภทสรุปผลรายคืนหรือการจำแนกประเภท log ของเมื่อวาน ให้ส่งเข้าสู่ระบบ batch เพื่อรับส่วนลดครึ่งราคา
บันทึกฟิลด์การใช้งานของทุกการตอบกลับลงในที่จัดเก็บของคุณเอง
คุณไม่สามารถระบุค่าใช้จ่ายที่คุณไม่ได้บันทึกไว้ได้ ทุกการตอบกลับจะแจ้งให้คุณทราบว่ามีค่าใช้จ่ายเท่าใด
u = resp.usage
row = {
"job": job_name,
"model": resp.model,
"uncached_input": u.input_tokens,
"cache_write": u.cache_creation_input_tokens,
"cache_read": u.cache_read_input_tokens,
"output": u.output_tokens,
"stop_reason": resp.stop_reason,
}ให้เพิ่มข้อมูลหนึ่งแถวต่อหนึ่งการเรียก API ลงในไฟล์ JSON-lines โดยระบุแท็กเป็นชื่อของงาน (job name) ของคุณ หนึ่งสัปดาห์ให้หลัง คุณจะสามารถระบุได้ว่างานใดเป็นผู้ใช้จ่ายและงานใดเพียงแค่แสดงสถานะว่าทำงานอยู่ ให้เฝ้าสังเกต cache_read: คอลัมน์ที่เป็นเลขศูนย์คือข้อผิดพลาดด้านค่าใช้จ่ายที่พบบ่อยที่สุดในเอเจนต์ที่โฮสต์ด้วยตนเอง
มีฟิลด์หนึ่งที่เข้าใจผิดได้ง่าย input_tokens จะนับเฉพาะโทเค็นที่อยู่หลังจุดพักแคช (cache breakpoint) ล่าสุดเท่านั้น ดังนั้นขนาดของ prompt ที่แท้จริงคือ total_input_tokens = cache_read_input_tokens + cache_creation_input_tokens + input_tokens เอเจนต์ที่รายงานค่า input_tokens: 400 บน prompt ขนาดใหญ่ไม่ได้หมายความว่ามีราคาถูก เพราะส่วนที่เหลือมาจากแคช
ให้นับจำนวนก่อนส่ง การนับโทเค็นไม่มีค่าใช้จ่ายและมีขีดจำกัดอัตรา (rate limit) แยกต่างหากจากการสร้างข้อความ ดังนั้นให้ใช้ count_tokens เพื่อปฏิเสธไฟล์แนบที่มีขนาดใหญ่เกินไป แทนที่จะต้องเสียค่าใช้จ่ายเพื่อพบว่ามันใหญ่เกินไป ผลลัพธ์ที่ได้เป็นเพียงการประมาณการ ดังนั้นควรวัดผลใหม่ตามโมเดลและห้ามนำค่าการนับจาก tokenizer ของผู้ให้บริการรายอื่นมาใช้ซ้ำ Claude Opus 4.7 และโมเดล Opus รุ่นใหม่กว่า, Claude Fable 5 และ Claude Sonnet 5 ใช้ tokenizer รุ่นใหม่ที่ "สร้างโทเค็นเพิ่มขึ้นประมาณ 30% สำหรับข้อความเดียวกัน" ส่วน Claude Sonnet 4.6 และรุ่นก่อนหน้า รวมถึง Claude Haiku 4.5 ใช้ tokenizer รุ่นก่อน
สำหรับมุมมองที่เป็นทางการ Admin API จะรายงานการใช้งานที่ https://api.anthropic.com/v1/organizations/usage_report/messages และค่าใช้จ่ายที่ https://api.anthropic.com/v1/organizations/cost_report ทั้งสองส่วนต้องใช้คีย์ผู้ดูแลระบบ (sk-ant-admin01-...) ในรูปแบบ x-api-key: $ANTHROPIC_ADMIN_KEY ร่วมกับ anthropic-version: 2023-06-01 และรองรับ bucket_width=1d, group_by[]=model และ api_key_ids[]= ข้อจำกัดประการหนึ่งคือ "Admin API ไม่สามารถใช้งานได้สำหรับบัญชีส่วนบุคคล"
พารามิเตอร์สุดท้ายนั้นเป็นเทคนิคการระบุแหล่งที่มาที่มีต้นทุนต่ำ: ให้แต่ละงานใช้ API key ของตนเอง กรองข้อมูลด้วย api_key_ids[] และแยกรายงานตามคีย์ด้วย group_by[]=api_key_id ตัวกรองสามารถระบุได้หลายรายการ แต่การจัดกลุ่มข้อมูลจะทำได้ทีละมิติเท่านั้น ให้เก็บคีย์ไว้ใน environment แทนที่จะเก็บไว้ในโค้ด ตามวิธีที่ แอป Claude API แรกบน VPS จัดการคีย์เหล่านั้น
จำกัดจำนวนรอบการทำงาน เพราะไม่มีกลไกอื่นจัดการให้
การกำหนดจำนวนรอบการทำงานให้ชัดเจนเป็นสิ่งที่จำเป็นในกรณีนี้ เนื่องจากคุณเป็นผู้ควบคุมลูป คุณจึงต้องเป็นผู้กำหนดตัวนับด้วยตนเอง:
for step in range(MAX_STEPS): # MAX_STEPS = 12, never "while True"
resp = client.messages.create(...)
if resp.stop_reason != "tool_use":
break
else:
log.warning("job %s hit MAX_STEPS=%d, giving up", job_name, MAX_STEPS)ค่าเพดานที่กำหนดไว้ก่อนหน้าไม่สามารถช่วยคุณได้: max_tokens เป็นเพียงการจำกัดการตอบกลับในหนึ่งครั้ง และโมเดลได้รับเพียงคำแนะนำเกี่ยวกับงบประมาณของงานเท่านั้น หากเป็นผลิตภัณฑ์ที่มีการโฮสต์ไว้ ระบบจะหยุดการทำงานของคุณในลักษณะเดียวกับที่ การจำกัดจำนวนการเรียกใช้เครื่องมือของ Claude ภายในเทิร์นเดียว ยุติเซสชันที่เรียกใช้เครื่องมือมากเกินไป แต่ลูปที่คุณเขียนขึ้นเองจะไม่มีกลไกป้องกันเช่นนี้จนกว่าคุณจะเพิ่มเข้าไปเอง
ให้ติดตั้งเบรกชั้นที่สองไว้ภายนอกกระบวนการทำงาน โดยเรียกใช้งานผ่าน systemd timer แทนการใช้กระบวนการที่ทำงานค้างไว้ตลอดเวลา และตั้งค่า RuntimeMaxSec= ไว้ใน service unit ของคุณ ด้วยการใช้ RuntimeMaxSec=600 การทำงานที่ค้างอยู่จะถูกยกเลิกหลังจากผ่านไป 10 นาที แทนที่จะปล่อยให้ทำงานวนไปเรื่อยๆ จนกว่าคุณจะสังเกตเห็น การรันโปรแกรมในรูปแบบ systemd service และ timer อธิบายรายละเอียดเกี่ยวกับไฟล์ unit เหล่านี้ไว้แล้ว คุณสามารถตรวจสอบผลการทำงานได้ด้วย journalctl -u triage-agent.service --since "1 hour ago"
นอกจากนี้ควรจำกัดจำนวนครั้งในการลองใหม่ (retry) เพราะตัวจัดการที่พยายามลองใหม่ตลอดไปจะทำให้เกิดค่าใช้จ่ายในทุกความพยายาม ข้อผิดพลาดระดับ 429 หรือ 500 ควรลองใหม่เพียงไม่กี่ครั้งโดยใช้กลยุทธ์ backoff แต่สำหรับข้อผิดพลาดระดับ 400 ไม่ควรลองใหม่เลย เนื่องจากคำขอเดิมจะล้มเหลวด้วยสาเหตุเดียวกันเสมอ
การควบคุมค่าใช้จ่ายของ AI agent เริ่มต้นจากการอ่านตัวเลขของคุณเอง
ไม่มีใครสามารถบอกคุณได้ว่าค่าใช้จ่ายของ agent ที่ทำงานตลอดเวลาเป็นเท่าใด เนื่องจากต้นทุนคือจำนวน token ต่อการรันคูณด้วยจำนวนครั้งที่รันต่อวัน ซึ่งทั้งสองส่วนนี้เป็นข้อมูลของคุณเอง ให้รัน agent หนึ่งครั้ง อ่านแถวการใช้งานที่คุณบันทึกไว้ แล้วคูณด้วยตารางเวลาของคุณ จากนั้นตรวจสอบรายงานค่าใช้จ่ายในอีกสองวันถัดมาเทียบกับการคำนวณนั้น เมื่อตัวเลขทั้งสองไม่ตรงกัน ช่องว่างที่เกิดขึ้นมักเกิดจาก cache ที่เสียหายหรือลูปที่ทำงานนานกว่าที่คุณคาดการณ์ไว้เกือบทุกครั้ง
ข้อมูลนี้ตั้งอยู่บนสมมติฐานว่าคุณใช้ API key เนื่องจาก agent คือโปรแกรมของคุณเองที่เรียกใช้งาน Messages API สำหรับการทำงานเชิงโต้ตอบของคุณเอง แผนการใช้งาน Claude แบบใดที่เหมาะกับวิธีการทำงานของคุณ จะครอบคลุมในส่วนของค่าสมาชิก ราคาและขีดจำกัดทั้งหมดในที่นี้ได้รับการตรวจสอบกับเอกสารของ Anthropic ในเดือนกรกฎาคม 2026 แล้ว ดังนั้นโปรดอ่านหน้าแสดงราคาซ้ำอีกครั้งก่อนที่คุณจะจัดทำงบประมาณ
FAQ
การรัน AI agent แบบเปิดตลอดเวลาบน VPS มีค่าใช้จ่ายเท่าไร?
มีค่าใช้จ่ายสองส่วนแต่มีเพียงส่วนเดียวที่คาดการณ์ได้ ค่าเช่าเซิร์ฟเวอร์เป็นราคาคงที่รายเดือน ส่วนค่า API ของโมเดลจะคิดตามจำนวน token ดังนั้นค่าใช้จ่ายคือผลคูณระหว่างปริมาณการใช้งานต่อหนึ่งรอบกับการเรียกใช้งานจริง Anthropic ไม่ได้ระบุตัวเลขสำหรับ agent ที่รันตลอดเวลา ดังนั้นตัวเลขใดๆ ที่ได้รับมาถือเป็นการคาดการณ์เท่านั้น ให้บันทึกค่า usage จากการรันจริงหนึ่งครั้งแล้วนำมาคูณกับตารางการทำงานของคุณ
max_tokens กับ task budget ต่างกันอย่างไร?
max_tokens เป็นการบังคับใช้ที่โมเดลมองไม่เห็น มันทำหน้าที่จำกัดผลลัพธ์ของคำขอหนึ่งครั้งรวมถึงกระบวนการคิด หากเกินขีดจำกัดนี้จะได้รับข้อผิดพลาด stop_reason: "max_tokens" ส่วน task budget นั้นตรงกันข้าม คือการระบุตัวเลขให้โมเดลทราบเพื่อให้มันบริหารจัดการลูปการทำงานตามงบประมาณนั้น แต่ "task budget เป็นเพียงคำแนะนำ ไม่ใช่การจำกัดที่เข้มงวด" และขีดจำกัดที่บังคับใช้จริงยังคงเป็น max_tokens
ทำไมค่า cache_read_input_tokens ของ agent ถึงเป็นศูนย์เสมอ?
เพราะส่วนนำ (prefix) มีการเปลี่ยนแปลงระหว่างการเรียกใช้งาน หรือสั้นเกินกว่าที่จะทำแคชได้ สาเหตุที่พบบ่อยคือการแทรก timestamp หรือ run id ลงใน system prompt เนื่องจากแคชจะอ้างอิงจากส่วนนำ ดังนั้นการเปลี่ยนแปลงเพียงหนึ่งไบต์จะทำให้ข้อมูลที่ตามมาทั้งหมดไม่สามารถใช้แคชได้ การเปลี่ยนนิยามของเครื่องมือหรือค่า effort ก็ส่งผลเช่นเดียวกัน นอกจากนี้ยังขึ้นอยู่กับขนาด เพราะ prompt ที่สั้นเกินไปจะไม่ถูกแคชและไม่มีข้อความแจ้งเตือนใดๆ ส่งกลับมา
จะหยุดไม่ให้ AI agent ทำงานวนลูปไม่สิ้นสุดได้อย่างไร?
ให้เขียนโค้ดนับจำนวนรอบการทำงานและหยุดเมื่อถึงจำนวนสูงสุดที่กำหนดไว้ เพราะ max_tokens จำกัดเพียงการตอบกลับหนึ่งครั้ง แต่ agent หนึ่งตัวอาจมีการตอบกลับหลายครั้ง ให้เพิ่มการจำกัดเวลาแบบ wall-clock ไว้ภายนอกกระบวนการทำงาน โดยเริ่มงานผ่าน systemd timer ที่ตั้งค่า RuntimeMaxSec= ไว้ เพื่อให้งานที่ค้างอยู่ถูกยกเลิกตามกำหนดเวลา และควรจำกัดจำนวนครั้งในการลองใหม่ (retry) ด้วย เพราะลูปการลองใหม่จะถูกคิดค่าใช้จ่ายทุกครั้งที่พยายาม
ฉันสามารถตั้งค่าจำกัดการใช้จ่ายสำหรับ Claude API key เพียงคีย์เดียวได้หรือไม่?
ขีดจำกัดการใช้จ่ายที่ระบุไว้ในเอกสารเป็นแบบราย workspace ไม่ใช่รายคีย์ ดังนั้นควรสร้าง workspace แยกต่างหากสำหรับ agent และตั้งค่าจำกัดการใช้จ่ายรายเดือนไว้ที่นั่น "คุณไม่สามารถตั้งค่าจำกัดใน Default Workspace ได้" ให้เพิ่มการแจ้งเตือนการใช้จ่ายเพื่อให้ระบบแจ้งเตือนเมื่อถึงเกณฑ์ที่กำหนด สำหรับการตรวจสอบการใช้งาน ให้สร้างคีย์แยกสำหรับแต่ละงาน แล้วจัดกลุ่มรายงานการใช้งานด้วย group_by[]=api_key_id