เป็นที่กล่าวกันบ่อยในวงการวิศวกรรมว่า "Cache Rules Everything Around Me" และกฎเดียวกันนี้ก็ใช้ได้กับเอเจนต์เช่นกัน
ผลิตภัณฑ์เอเจนต์ที่ทำงานยาวนานอย่าง Claude Code เป็นไปได้ด้วย prompt caching ซึ่งช่วยให้เราสามารถนำการคำนวณจากรอบการส่งข้อมูลก่อนหน้ามาใช้ซ้ำได้ และลดความหน่วงเวลาและต้นทุนลงอย่างมาก
prompt caching คืออะไร ทำงานอย่างไร และจะนำไปใช้งานทางเทคนิคได้อย่างไร? อ่านเพิ่มเติมในบทความของ @RLanceMartin เกี่ยวกับ prompt caching และการเปิดตัว auto-caching ใหม่ของเรา
ที่ Claude Code เราสร้างโครงสร้างการทำงานทั้งหมดของเราบน prompt caching อัตราการตี cache ที่สูงจะช่วยลดต้นทุนและช่วยให้เราสร้างขีดจำกัดอัตราการใช้งานที่เอื้อเฟื้อมากขึ้นสำหรับแผนการสมัครสมาชิก ดังนั้นเราจึงตั้งค่าการแจ้งเตือนสำหรับอัตราการตี cache และประกาศ SEV หากอัตราต่ำเกินไป
นี่คือบทเรียน (ที่มักไม่เป็นไปตามสัญชาตญาณ) ที่เราได้เรียนรู้จากการปรับปรุง prompt caching ในระดับใหญ่
วางโครงสร้าง Prompt ของคุณเพื่อการแคช

Prompt caching ทำงานโดยการจับคู่prefix — API จะแคชทุกอย่างตั้งแต่ต้นคำขอไปจนถึงจุดแบ่ง cache_control แต่ละจุด ซึ่งหมายความว่าลำดับที่คุณวางสิ่งต่าง ๆ มีความสำคัญอย่างมาก คุณต้องการให้คำขอของคุณจำนวนมากที่สุดเท่าที่เป็นไปได้มีprefixร่วมกัน
วิธีที่ดีที่สุดคือวางเนื้อหาที่คงที่ก่อน เนื้อหาแบบไดนามิกทีหลัง สำหรับ Claude Code จะเป็นดังนี้:
- System prompt แบบคงที่ & เครื่องมือ (แคชในระดับโลก)
- Claude.MD (แคชภายในโปรเจกต์)
- บริบทเซสชัน (แคชภายในเซสชัน)
- ข้อความสนทนา
ด้วยวิธีนี้เราจะเพิ่มจำนวนเซสชันที่แชร์ cache hits ให้มากที่สุด
แต่วิธีนี้ก็เปราะบางอย่างน่าประหลาดใจ! ตัวอย่างสาเหตุที่เราเคยทำลายลำดับนี้มาก่อน ได้แก่: การใส่ timestamp ที่ละเอียดมากใน system prompt แบบคงที่ การสับเปลี่ยนลำดับคำจำกัดความของเครื่องมือแบบไม่กำหนดตายตัว การอัปเดตพารามิเตอร์ของเครื่องมือ (เช่น เอเจนต์ที่ AgentTool สามารถเรียกใช้ได้) เป็นต้น
ใช้ Messages สำหรับการอัปเดต
อาจมีบางครั้งที่ข้อมูลที่คุณใส่ใน prompt ของคุณล้าสมัย เช่น ถ้าคุณมีเวลาหรือผู้ใช้เปลี่ยนไฟล์ อาจดูน่าดึงดูดที่จะอัปเดต prompt แต่นั่นจะทำให้เกิด cache miss และอาจมีค่าใช้จ่ายสูงสำหรับผู้ใช้
ลองพิจารณาว่าคุณสามารถส่งข้อมูลนี้ผ่าน messages ในรอบถัดไปแทนได้หรือไม่ ใน Claude Code เราเพิ่มแท็ก <system-reminder> ในข้อความผู้ใช้หรือผลลัพธ์ของเครื่องมือในรอบถัดไปพร้อมข้อมูลที่อัปเดตสำหรับโมเดล (เช่น ตอนนี้เป็นวันพุธแล้ว) ซึ่งช่วยรักษา cache ไว้
อย่าเปลี่ยนโมเดลกลางเซสชัน
Prompt caches เป็นเอกลักษณ์เฉพาะของแต่ละโมเดล และสิ่งนี้ทำให้การคำนวณเกี่ยวกับ prompt caching ไม่เป็นไปตามสัญชาตญาณมากนัก
หากคุณสนทนากับ Opus ไปแล้ว 100k tokens และต้องการถามคำถามที่ค่อนข้างง่าย การเปลี่ยนไปใช้ Haiku จะมีค่าใช้จ่ายสูงกว่าการให้ Opus ตอบ เพราะเราจะต้องสร้าง prompt cache สำหรับ Haiku ขึ้นมาใหม่
หากคุณจำเป็นต้องเปลี่ยนโมเดล วิธีที่ดีที่สุดคือใช้ subagents โดย Opus จะเตรียมข้อความ "handoff" ให้กับอีกโมเดลหนึ่งเกี่ยวกับงานที่ต้องทำ เราทำแบบนี้บ่อยครั้งกับ Explore agents ใน Claude Code ซึ่งใช้ Haiku
ห้ามเพิ่มหรือลบเครื่องมือกลางเซสชัน
การเปลี่ยนชุดเครื่องมือกลางการสนทนาเป็นหนึ่งในวิธีที่พบบ่อยที่สุดที่ผู้คนทำลาย prompt caching มันดูเหมือนเข้าใจได้ — คุณควรให้เฉพาะเครื่องมือที่คุณคิดว่าโมเดลต้องการในตอนนั้นเท่านั้น แต่เนื่องจากเครื่องมือเป็นส่วนหนึ่งของ prefix ที่ถูกแคช การเพิ่มหรือลบเครื่องมือจะทำให้ cache สำหรับการสนทนาทั้งหมดใช้ไม่ได้
Plan Mode — ออกแบบโดยคำนึงถึง Cache
Plan mode เป็นตัวอย่างที่ดีของการออกแบบฟีเจอร์โดยคำนึงถึงข้อจำกัดของ caching วิธีการที่เข้าใจได้คือ: เมื่อผู้ใช้เข้าสู่ plan mode ให้สลับชุดเครื่องมือเป็นเฉพาะเครื่องมือแบบอ่านอย่างเดียว แต่นั่นจะทำให้ cache เสียหาย
แทนที่จะทำแบบนั้น เราเก็บเครื่องมือ ทั้งหมด ไว้ในคำขอตลอดเวลา และใช้ EnterPlanMode และ ExitPlanMode เป็นเครื่องมือเอง เมื่อผู้ใช้เปิด plan mode เอเจนต์จะได้รับข้อความจากระบบที่อธิบายว่าอยู่ใน plan mode และคำแนะนำคืออะไร — สำรวจ codebase อย่าแก้ไขไฟล์ เรียก ExitPlanMode เมื่อแผนเสร็จสมบูรณ์ คำจำกัดความของเครื่องมือไม่เคยเปลี่ยนแปลง
สิ่งนี้ให้ประโยชน์เพิ่มเติม: เนื่องจาก EnterPlanMode เป็นเครื่องมือที่โมเดลสามารถเรียกใช้เองได้ มันสามารถเข้าสู่ plan mode ได้อย่างอิสระเมื่อตรวจพบปัญหาที่ยาก โดยไม่ทำลาย cache
Tool Search — เลื่อนการโหลดแทนที่จะลบ
หลักการเดียวกันนี้ใช้กับฟีเจอร์ tool search ของเรา Claude Code สามารถโหลดเครื่องมือ MCP ได้หลายสิบตัว และการรวมทั้งหมดไว้ในทุกคำขอจะมีค่าใช้จ่ายสูง แต่การลบออกกลางการสนทนาจะทำลาย cache
วิธีแก้ของเรา: defer_loading แทนที่จะลบเครื่องมือ เราส่ง stub ที่มีน้ำหนักเบา — แค่ชื่อเครื่องมือ พร้อม defer_loading: true — ที่โมเดลสามารถ "ค้นพบ" ผ่านเครื่องมือ ToolSearch เมื่อจำเป็น โครงร่างเครื่องมือเต็มจะถูกโหลดเมื่อโมเดลเลือกใช้เท่านั้น วิธีนี้ทำให้ prefix ที่ถูกแคชคงที่: stub เดิมจะอยู่ในลำดับเดิมเสมอ
โชคดีที่คุณสามารถใช้เครื่องมือ tool search ผ่าน API ของเราเพื่อทำให้สิ่งนี้ง่ายขึ้น
Forking Context — การบีบอัด

การบีบอัด (compaction) คือสิ่งที่เกิดขึ้นเมื่อคุณใช้ context window หมด เราสรุปการสนทนาที่ผ่านมาและเริ่มเซสชันใหม่ด้วยสรุปนั้น
ที่น่าแปลกใจคือ การบีบอัดมีกรณีขอบหลายกรณีที่เกี่ยวข้องกับ prompt caching ซึ่งอาจไม่เป็นไปตามสัญชาตญาณ
โดยเฉพาะอย่างยิ่ง เมื่อเราบีบอัด เราต้องส่งการสนทนาทั้งหมดให้โมเดลเพื่อสร้างสรุป หากนี่เป็นการเรียก API แยกต่างหากที่มี system prompt ต่างกันและไม่มีเครื่องมือ (ซึ่งเป็นวิธีการที่เรียบง่าย) prefix ที่ถูกแคชจากการสนทนาหลักจะไม่ตรงกันเลย คุณต้องจ่ายเต็มราคาสำหรับ input token เหล่านั้นทั้งหมด ซึ่งเพิ่มต้นทุนให้ผู้ใช้อย่างมาก
วิธีแก้ — Forking ที่ปลอดภัยต่อ Cache
เมื่อเราดำเนินการบีบอัด เราใช้ system prompt, บริบทผู้ใช้, บริบทระบบ และคำจำกัดความเครื่องมือที่ เหมือนกันทุกประการ กับการสนทนาหลัก เราเตรียมข้อความสนทนาของการสนทนาหลักไว้ข้างหน้า จากนั้นต่อท้าย prompt สำหรับการบีบอัดเป็นข้อความผู้ใช้ใหม่ต่อท้าย
จากมุมมองของ API คำขอนี้ดูเกือบจะเหมือนกับคำขอสุดท้ายของการสนทนาหลัก — prefix เดียวกัน เครื่องมือเดียวกัน ประวัติเดียวกัน — ดังนั้น prefix ที่ถูกแคชจึงถูกนำมาใช้ซ้ำ tokens ใหม่มีเพียง prompt สำหรับการบีบอัดเท่านั้น
อย่างไรก็ตาม นั่นหมายความว่าเราต้องบันทึก "บัฟเฟอร์การบีบอัด" เพื่อให้มีพื้นที่เพียงพอใน context window สำหรับรวมข้อความที่ถูกบีบอัดและ tokens ผลลัพธ์สรุป
การบีบอัดเป็นเรื่องยุ่งยาก แต่โชคดีที่คุณไม่จำเป็นต้องเรียนรู้บทเรียนเหล่านี้ด้วยตัวเอง — จากสิ่งที่เราเรียนรู้จาก Claude Code เราได้สร้าง การบีบอัด ลงใน API โดยตรง ดังนั้นคุณจึงสามารถนำรูปแบบเหล่านี้ไปใช้ในแอปพลิเคชันของคุณเองได้
บทเรียนที่ได้เรียนรู้
- Prompt caching คือการจับคู่ prefix การเปลี่ยนแปลงใด ๆ ใน prefix ไม่ว่าส่วนไหนจะทำให้ทุกอย่างหลังจากนั้นใช้ไม่ได้ ออกแบบทั้งระบบของคุณโดยคำนึงถึงข้อจำกัดนี้ จัดลำดับให้ถูกต้อง และการแคชส่วนใหญ่จะทำงานได้โดยอัตโนมัติ
- ใช้ messages แทนการเปลี่ยน system prompt คุณอาจอยากแก้ไข system prompt เพื่อทำสิ่งต่าง ๆ เช่น เข้าสู่ plan mode เปลี่ยนวันที่ ฯลฯ แต่ที่จริงแล้วจะดีกว่าถ้าแทรกสิ่งเหล่านี้ลงใน messages ระหว่างการสนทนา
- อย่าเปลี่ยนเครื่องมือหรือโมเดลกลางการสนทนา ใช้เครื่องมือเพื่อจำลองการเปลี่ยนสถานะ (เช่น plan mode) แทนที่จะเปลี่ยนชุดเครื่องมือ เลื่อนการโหลดเครื่องมือแทนที่จะลบ
- ตรวจสอบอัตราการตี cache ของคุณเหมือนกับที่คุณตรวจสอบ uptime เราแจ้งเตือนเมื่อ cache เสียหายและปฏิบัติต่อมันเป็นเหตุการณ์ที่ต้องดำเนินการ อัตรา cache miss เพียงไม่กี่เปอร์เซ็นต์อาจส่งผลกระทบอย่างมากต่อต้นทุนและความหน่วงเวลา
- การดำเนินการ fork ต้องใช้ prefix เดียวกับต้นทาง หากคุณต้องรันการคำนวณเสริม (การบีบอัด การสรุป การดำเนินการทักษะ) ให้ใช้พารามิเตอร์ที่ปลอดภัยต่อ cache ที่เหมือนกัน เพื่อให้คุณได้รับ cache hits บน prefix ของต้นทาง
Claude Code สร้างขึ้นบน prompt caching ตั้งแต่วันแรก คุณควรทำเช่นเดียวกันหากคุณกำลังสร้างเอเจนต์





