Agent Orchestrator ของฉันเผาโทเคน Opus ไปถึง 1-2 ล้านโทเคนต่อหนึ่งงาน
สาเหตุที่ค่าใช้จ่ายพุ่งสูงขึ้นอย่างมหาศาล
ตัว Orchestrator ถูกสร้างขึ้นสำหรับ Claude Code และใช้โครงสร้างลำดับชั้นของ sub-agents โดยที่ sub-agent แต่ละตัวจะรับการตั้งค่ามาจากตัวแม่ (parent) รัน prompt ของตัวเอง และส่งผลลัพธ์กลับเข้าสู่ลูปจนกว่าผู้ตรวจสอบ (reviewer) จะประกาศว่าผลลัพธ์นั้น "สะอาด" (clean) แม้เครื่องมือนี้จะทำงานได้สำเร็จ แต่ราคาที่ต้องจ่ายนั้นสูงจนน่าตกใจ
"ภาษี" แฝง 3 อย่างที่ทำให้จำนวนโทเคนเพิ่มขึ้นทวีคูณ:
- Model tax (ภาษีโมเดล) – sub-agents ไม่เคยระบุโมเดลที่ต้องการใช้ จึงทำให้ระบบเลือกใช้ Opus ซึ่งเป็นระดับที่แพงที่สุดโดยอัตโนมัติ งานเล็กๆ ที่ควรจะใช้โมเดลที่ราคาถูกกว่า (Haiku หรือ Sonnet) กลับถูกคิดเงินในอัตราของ Opus
- Cache tax (ภาษีแคช) – การทำ Prompt caching จะนำกลับมาใช้ใหม่ได้เฉพาะเมื่อข้อมูลตรงกันแบบ byte-for-byte เท่านั้น แต่เนื่องจาก sub-agent แต่ละตัวมีการเพิ่มคำสั่งแบบกำหนดเอง (custom instructions) ทุกการเรียกใช้งานจึงบังคับให้ต้องเขียนแคชใหม่ (cold cache write) ทำให้ไม่สามารถนำแคชของตัวแม่มาใช้ซ้ำได้ ซึ่งเป็นการทิ้งโอกาสในการประหยัดค่าใช้จ่ายที่ปกติควรจะได้จากการใช้แคชร่วมกัน
- Loop tax (ภาษีลูป) – กฎ "ลูปจนกว่าจะสะอาด" ทำให้กระบวนการทำงานดำเนินต่อไปเรื่อยๆ ตราบใดที่ผู้ตรวจสอบยังพบข้อผิดพลาด และเนื่องจากไม่มีการกำหนดเพดานสูงสุด (hard ceiling) ลูปจึงทำงานไปเรื่อยๆ จนกว่าโมเดลจะหยุดทำงานเอง
ตัวคูณเหล่านี้รวมกันเปลี่ยนโค้ดเพียงไม่กี่บรรทัดให้กลายเป็นพายุโทเคนถล่มทลาย
ทำไมกฎงบประมาณใน prompt ถึงล้มเหลว
การออกแบบในตอนแรกพยายามควบคุมการใช้จ่ายโดยการฝังกฎงบประมาณลงใน system prompt โดยตรง ตามทฤษฎีแล้ว การบอกโมเดลว่า "ให้ใช้ไม่เกิน X โทเคน" ควรจะช่วยจำกัดการใช้งานได้ แต่ในทางปฏิบัติ กฎที่อิงตาม prompt เป็นเพียงแค่ "ความต้องการ" (preference) เท่านั้น เมื่อเซสชันยาวขึ้น โมเดลจะทำการบีบอัดบริบท (compress context) และอาจละทิ้งหรือเพิกเฉยต่อคำสั่งเหล่านั้นไปเลย ผลลัพธ์ที่ได้คือ โมเดลทำงานราวกับว่ากฎนั้นไม่เคยมีอยู่จริง
เปลี่ยนการบังคับใช้จาก prompt มาเป็นโค้ด
การออกแบบใหม่ได้ถอดตรรกะด้านงบประมาณออกจาก prompt และนำไปใส่ไว้ในระบบ hook แบบ deterministic ที่โมเดลไม่สามารถสั่งยกเลิก (override) ได้
- การเลือกโมเดลอย่างชัดเจน (Explicit model selection) – การส่งงานให้ sub-agent แต่ละครั้งต้องมีการเลือกโมเดลที่แน่นอน (Haiku, Sonnet หรือ Opus) การสืบทอดค่าแบบเงียบๆ (silent inheritance) ถูกยกเลิกไปแล้ว ดังนั้นงานราคาถูกจึงยังคงราคาถูกอยู่
- การป้องกันขั้นเด็ดขาดผ่าน PreToolUse hook – ก่อนที่เครื่องมือใดๆ จะทำงาน hook จะทำการตรวจสอบ:
- จำนวนครั้งที่มีการส่งงานไปแล้วในเซสชันนั้น
- โมเดลที่เลือกใช้เป็นไปตามระดับขั้นต่ำที่กำหนดไว้หรือไม่ (เพื่อป้องกันการใช้ Opus โดยไม่ตั้งใจ)
- จำนวนรอบสูงสุดของลูป ซึ่งหากเกินกำหนด กระบวนการจะถูกยกเลิกทันที
หากการป้องกันใดๆ ทำงาน โค้ดจะสั่งยกเลิกการทำงานของ sub-agent ทันที โดยที่โมเดลภาษาไม่มีทางที่จะโต้แย้งเพื่อขอทำต่อได้
สิ่งนี้หมายความว่าอย่างไรสำหรับนักพัฒนา
ระบบใดก็ตามที่มีการกำหนดเพดานการใช้จ่าย, นโยบายความปลอดภัย หรือข้อจำกัดในการใช้คำสั่งที่อาจก่อให้เกิดความเสียหาย (destructive commands) ควรปฏิบัติกับข้อจำกัดเหล่านั้นในฐานะ "โค้ด" ไม่ใช่แค่ "คำแนะนำในการสนทนา" เพราะ prompt สามารถถูกเขียนทับ, ถูกเพิกเฉย หรือสูญหายไปในการบีบอัดข้อมูลภายในของโมเดลได้ ในทางกลับกัน โค้ดจะทำงานแบบ deterministic และสามารถตรวจสอบ (audit) ได้อย่างแม่นยำ
