การจัดโครงสร้างหน่วยความจำตามประเภทช่วยลดจำนวนโทเคน (tokens) ที่ดึงมาได้ประมาณ 40%
ทำไมการจัดเก็บหน่วยความจำแบบแบน (flat memory store) ถึงล้มเหลว
บทเรียนสำหรับมือใหม่ส่วนใหญ่มักสอนให้ LLM agent "จดจำ" โดยการเพิ่มข้อมูลใหม่ทุกชิ้นต่อท้ายรายการ (list) เดียวกัน แล้วส่งรายการนั้นกลับไปยังโมเดลในทุกๆ รอบการทำงาน โค้ดมีเพียงแค่สามบรรทัดและสามารถสร้างเดโมที่ใช้งานได้จริง แต่ในทางปฏิบัติ รายการดังกล่าวจะเติบโตขึ้นอย่างไม่มีการควบคุม ซึ่งจะทำให้เกิดอาการสองอย่างดังนี้:
- Agent ปฏิบัติต่อข้อมูลที่ล้าสมัยราวกับว่าเป็นข้อมูลที่ยังเป็นจริงอยู่ เช่น การแจ้งเวลาที่จะมาถึง (ETA) ที่หมดอายุไปแล้วหลายชั่วโมง
- Context window เต็มไปด้วยข้อมูลจิปาถะที่ไม่เคยส่งผลต่อคำตอบ ซึ่งเป็นการเพิ่มค่าใช้จ่าย API และทำให้การตอบสนองช้าลง
Vector store ธรรมดาหรือ key-value cache แบบง่ายๆ ไม่สามารถแยกแยะระหว่างตำแหน่งงานของผู้ใช้กับสถานะโครงการชั่วคราวได้ เมื่อ agent ทำการค้นหาเชิงความหมาย (semantic search) อัลกอริทึมความคล้ายคลึง (similarity algorithm) อาจดึงข้อมูล ETA เก่าขึ้นมาเพียงเพราะคำค้นหามีคำที่เหมือนกัน ทั้งที่ข้อมูลนั้นไม่เกี่ยวข้องอีกต่อไปแล้ว
หน่วยความจำแบบมีโครงสร้าง: สี่หมวดหมู่ หนึ่งวัตถุประสงค์
วิธีแก้ไขคือการเลิกปฏิบัติกับหน่วยความจำเหมือนเป็นก้อนข้อมูลขนาดใหญ่เพียงก้อนเดียว (monolith) และเริ่มจำแนกแต่ละรายการออกเป็นหนึ่งในสี่หมวดหมู่ดังนี้:
- User facts (ข้อมูลผู้ใช้) – คุณลักษณะที่คงที่ เช่น บทบาทของผู้ใช้, ภาษาที่ต้องการ หรือระดับการรักษาความปลอดภัย ข้อมูลเหล่านี้แทบจะไม่เปลี่ยนแปลงและสามารถทำ cache ไว้ได้ตลอดทั้งเซสชัน
- Feedback (ข้อเสนอแนะ/กฎเกณฑ์) – กฎที่ชัดเจนที่ agent ต้องปฏิบัติตาม เช่น "ห้ามเปิดเผยรหัสผ่านฐานข้อมูล" หรือ "หลีกเลี่ยงการใช้มุกตลกในการตอบคำถามด้านการปฏิบัติตามกฎระเบียบ" เนื่องจากกฎเหล่านี้ควบคุมพฤติกรรม จึงควรอยู่ใน system prompt มากกว่าที่จะอยู่ในกลุ่มข้อมูลที่ใช้ค้นหา
- Project state (สถานะโครงการ) – ข้อมูลที่มีการเปลี่ยนแปลงรวดเร็ว เช่น ETA ปัจจุบัน, ความคืบหน้าของงาน หรือโทเคนชั่วคราว หมวดหมู่นี้จำเป็นต้องมีการตรวจสอบวันหมดอายุ เมื่อเวลา (timestamp) ไม่อยู่ในช่วงที่กำหนด ข้อมูลนั้นควรถูกลบออก
- References (ข้อมูลอ้างอิง) – ตัวชี้ไปยังบริการภายนอก, ID ของเอกสาร หรือ API endpoints ข้อมูลเหล่านี้ไม่ใช่เนื้อหาที่จะนำมาแสดงผล แต่เป็นเส้นทางในการดึงข้อมูลใหม่เมื่อจำเป็น
Mem0 ช่วยให้นักพัฒนาสามารถแนบ metadata ใดๆ ก็ได้ลงในแต่ละบันทึกหน่วยความจำ การทำดัชนี (indexing) บนฟิลด์ "kind" จะช่วยให้การค้นหาสามารถกรองเฉพาะหมวดหมู่ที่เกี่ยวข้องได้ก่อนที่ LLM จะตัดสินใจว่าจะใช้ผลลัพธ์นั้นอย่างไร
การดึงข้อมูลแบบสองขั้นตอนด้วย Mem0
- ดึงหน่วยความจำตามประเภท (kind) – ใช้คำสั่งกรองสั้นๆ ถาม Mem0 เพื่อขอ "feedback ทั้งหมด" หรือ "รายการสถานะโครงการที่ใหม่กว่าช่วงเวลาสั้นๆ" ชุดผลลัพธ์ที่ได้จะถูกตัดให้เหลือเฉพาะหมวดหมู่ที่เหมาะสมแล้ว
- ให้ LLM ตัดสินใจ – ชิ้นส่วนข้อมูลที่ผ่านการกรองแล้วจะถูกใส่เข้าไปใน prompt พร้อมกับคำถามปัจจุบันของผู้ใช้ ตอนนี้โมเดลสามารถใช้เหตุผลกับข้อมูลเหล่านั้นได้โดยไม่ต้องเสียเวลาคัดกรองข้อเท็จจริงที่ไม่เกี่ยวข้อง
ตัวอย่างที่เป็นรูปธรรม: แทนที่จะรอให้การค้นหาเชิงความหมาย (semantic match) ดึงกฎ "ห้ามล้อเลียนฐานข้อมูล" ขึ้นมา นักพัฒนาสามารถใส่กฎนั้นลงใน system prompt โดยตรงเมื่อเริ่มเซสชันและทำ cache ไว้ตลอดการโต้ตอบ แม้ว่าคำถามของผู้ใช้จะไม่มีการอ้างถึงฐานข้อมูลโดยตรง แต่โมเดลก็ทราบถึงข้อจำกัดนั้นอยู่แล้ว
เคล็ดลับที่ใช้งานได้จริงเพื่อช่วยลดค่าใช้จ่าย
- ทำ cache กฎ feedback – เก็บชุดกฎไว้เพียงครั้งเดียวต่อหนึ่งเซสชันและนำกลับมาใช้ใหม่ แทนที่จะต้องค้นหาใหม่ในทุกๆ รอบ วิธีนี้จะช่วยลดการใช้โทเคนในแต่ละรอบ
- ข้ามการค้นหาสถานะโครงการเมื่อไม่เกี่ยวข้อง – หากผู้ใช้ถามคำถามเชิงแนวคิดล้วนๆ (เช่น "ความแตกต่างระหว่าง supervised และ reinforcement learning คืออะไร?") ก็ไม่มีความจำเป็นต้องดึงข้อมูล ETA หรือความคืบหน้าของงานมาเลย
การนำนิสัยสองอย่างนี้ไปใช้ สามารถลดการใช้โทเคนลงได้ประมาณ 40% เมื่อเทียบกับวิธีการจัดเก็บหน่วยความจำแบบแบน (flat memory) แบบดั้งเดิม การประหยัดนี้จะเปลี่ยนเป็นค่าใช้จ่าย API ที่ต่ำลงและการตอบสนองที่รวดเร็วขึ้น โดยเฉพาะอย่างยิ่งสำหรับ agent ที่มีการโต้ตอบกันหลายครั้ง
ใครได้ประโยชน์ ใครต้องกังวล
ผู้ที่ได้ประโยชน์ – ทีมที่สร้างบอทสนับสนุนลูกค้า, ผู้ช่วยเวิร์กโฟลว์ภายในองค์กร หรืออินเทอร์เฟซ LLM แบบโต้ตอบหลายรอบ (multi-turn) พวกเขาจะได้รับคำตอบที่น่าเชื่อถือมากขึ้น หลีกเลี่ยงความผิดพลาดที่น่าอับอายซึ่งเกิดจากข้อมูลที่ล้าสมัย และสามารถบริหารจัดการงบประมาณได้ดียิ่งขึ้น
บทสรุป
หากคุณต้องการ LLM agent ที่ยังคงความแม่นยำตลอดเซสชันที่ยาวนาน จงหยุดยัดทุกข้อเท็จจริงลงใน context window เดียวกัน ให้ติดแท็กหน่วยความจำแต่ละรายการว่าเป็น user fact, feedback, project state หรือ reference กำหนดวันหมดอายุเมื่อจำเป็น และปล่อยให้เครื่องมืออย่าง Mem0 ทำงานหนักแทน ผลลัพธ์ที่ได้คือคำตอบที่สดใหม่กว่า ลดการใช้โทเคนที่ไม่จำเป็น และลดต้นทุนการดำเนินงานได้อย่างเห็นได้ชัด