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) ได้

  1. การเลือกโมเดลอย่างชัดเจน (Explicit model selection) – การส่งงานให้ sub-agent แต่ละครั้งต้องมีการเลือกโมเดลที่แน่นอน (Haiku, Sonnet หรือ Opus) การสืบทอดค่าแบบเงียบๆ (silent inheritance) ถูกยกเลิกไปแล้ว ดังนั้นงานราคาถูกจึงยังคงราคาถูกอยู่
  2. การป้องกันขั้นเด็ดขาดผ่าน PreToolUse hook – ก่อนที่เครื่องมือใดๆ จะทำงาน hook จะทำการตรวจสอบ:
    • จำนวนครั้งที่มีการส่งงานไปแล้วในเซสชันนั้น
    • โมเดลที่เลือกใช้เป็นไปตามระดับขั้นต่ำที่กำหนดไว้หรือไม่ (เพื่อป้องกันการใช้ Opus โดยไม่ตั้งใจ)
    • จำนวนรอบสูงสุดของลูป ซึ่งหากเกินกำหนด กระบวนการจะถูกยกเลิกทันที

หากการป้องกันใดๆ ทำงาน โค้ดจะสั่งยกเลิกการทำงานของ sub-agent ทันที โดยที่โมเดลภาษาไม่มีทางที่จะโต้แย้งเพื่อขอทำต่อได้

สิ่งนี้หมายความว่าอย่างไรสำหรับนักพัฒนา

ระบบใดก็ตามที่มีการกำหนดเพดานการใช้จ่าย, นโยบายความปลอดภัย หรือข้อจำกัดในการใช้คำสั่งที่อาจก่อให้เกิดความเสียหาย (destructive commands) ควรปฏิบัติกับข้อจำกัดเหล่านั้นในฐานะ "โค้ด" ไม่ใช่แค่ "คำแนะนำในการสนทนา" เพราะ prompt สามารถถูกเขียนทับ, ถูกเพิกเฉย หรือสูญหายไปในการบีบอัดข้อมูลภายในของโมเดลได้ ในทางกลับกัน โค้ดจะทำงานแบบ deterministic และสามารถตรวจสอบ (audit) ได้อย่างแม่นยำ