ยิ่งทำงานกับ LLM นานเท่าไหร่ ก็ยิ่งพบว่าตัวเองติดอยู่ในสงครามชั่วนิรันดร์ระหว่างบริบทที่มากเกินไป บริบทที่น้อยเกินไป การสิ้นเปลือง token และการบีบอัด (compaction warfare) เมื่อมองไปที่ระบบหน่วยความจำแบบ agentic จะเห็นว่ามีอาวุธที่น่าเกรงขามบางอย่างที่จะช่วยในเรื่องนี้
สิ่งที่ค้นพบซึ่งปรากฏซ้ำๆ ใน 19 ระบบที่ผมศึกษาคือ ยิ่ง window มีขนาดใหญ่ขึ้น ก็ยิ่งทำให้ปัญหาด้านงบประมาณรุนแรงขึ้น แทนที่จะแก้ปัญหา window ขนาด 200K token ไม่ได้ให้ความสำคัญเท่าเทียมกับทั้งหมด 200K token นั้น ประสิทธิภาพจะลดลงก่อนที่ window จะเต็มเสียอีก การเสื่อมประสิทธิภาพไม่เท่ากัน: เนื้อหาที่อยู่ตรงกลางของบริบทยาวๆ จะได้รับความสนใจน้อยกว่าเนื้อหาที่อยู่ขอบเสมอ และภารกิจจริงของ agent ก็กินพื้นที่ส่วนหนึ่งของ window คงที่ ไม่ว่า window จะใหญ่แค่ไหน ซึ่งหมายความว่าทุกอย่างอื่นเป็น overhead ที่ต้องแย่งชิงงบประมาณความสนใจเดียวกัน
ระบบที่จัดการเรื่องนี้ได้ดีได้รวมตัวกันเป็นกลไก 6 ประการ ไม่มีกลไกไหนที่แปลกใหม่เลย หลายอย่างเรียบง่ายจนน่าอาย แต่ระบบที่ข้ามกลไกเหล่านี้ไปจะต้องจ่ายราคา
กลไกทั้งหกประการ
Compaction passes (การบีบอัด)
กลไกที่เห็นได้ชัดที่สุด คุณนำบทสนทนายาวๆ หรือส่วนความจำขนาดใหญ่มาสรุป แล้วแทนที่ต้นฉบับด้วยบทสรุป MemoryOS ทำในระดับ segment: segment summariser จะทำงานเมื่อส่วนสนทนาโตเกินเกณฑ์ที่กำหนด โดยบีบอัดให้เป็นตัวแทนที่กะทัดรัดก่อนที่มันจะเบียดบัง working context wiki แบบ Karpathy-pattern (purpose.md, overview.md) ทำในเวอร์ชันนี้ในระดับความรู้: wiki คือรูปแบบที่ถูกบีบอัดของทุกสิ่งที่ agent ได้เรียนรู้เกี่ยวกับหัวข้อหนึ่ง ซึ่งคงอยู่ข้าม session
ข้อแลกเปลี่ยนคือการสูญเสียข้อมูล การบีบอัดเป็นการดำเนินการที่สูญเสียโดยนิยาม บทสรุปจะจับสิ่งที่ summariser ตัดสินว่ามีความสำคัญในขณะที่บีบอัด ถ้า agent ต้องการรายละเอียดที่ไม่ได้ถูกตัดสินว่าสำคัญในตอนนั้น มันก็จะหายไป นี่ไม่ใช่เหตุผลที่จะหลีกเลี่ยงการบีบอัด แต่มันเป็นเหตุผลที่จะไม่ถือว่ามันเป็นกลไกเดียว
มีค่าใช้จ่ายที่สองที่มองข้ามได้ง่าย การบีบอัดนั้นไม่ฟรีในขณะรันไทม์ MemoryOS อาจต้องจ่ายค่าสรุป segment ถึง 20 ครั้งหรือมากกว่าในการโต้ตอบครั้งเดียว สำหรับระบบที่มีความถี่ในการโต้ตอบสูง นั่นคือค่าใช้จ่ายในการดำเนินงานจริง
Result-preview truncation (การตัดทอนตัวอย่างผลลัพธ์)
แทนที่จะส่งคืนเนื้อหาความจำทั้งหมดในทุกการดึงข้อมูล ให้ส่งคืนตัวอย่างสั้นๆ และให้ agent ตัดสินใจว่าจะดึงข้อมูลเต็มหรือไม่ supermemory เปิดเผยการควบคุมความยาวของตัวอย่างที่ช่วยให้ผู้เรียกปรับแต่งปริมาณข้อความที่ส่งกลับต่อผลลัพธ์ได้ mem9 ไปไกลกว่านั้น: มันตกแต่ง source turns ด้วยตัวแปรสภาพแวดล้อมสามตัว (MEM9_SOURCE_TURN_MIN_SCORE, MEM9_SOURCE_TURN_PER_MEMORY_LIMIT, MEM9_SOURCE_TURN_TOTAL_LIMIT) ที่ให้ผู้ปฏิบัติงานควบคุมอย่างแม่นยำว่ามีกี่ source turn ที่ปรากฏและที่คะแนนความเกี่ยวข้องขั้นต่ำเท่าใด
ข้อแลกเปลี่ยนคือการเรียกใช้เครื่องมือเพิ่มเติมหนึ่งครั้ง ถ้า agent ต้องการเนื้อหาเต็ม มันต้องขอมาอย่างชัดเจน สำหรับรูปแบบการดึงข้อมูลส่วนใหญ่ นี่คือการแลกเปลี่ยนที่ถูกต้อง: agent ได้รับสัญญาณมากพอที่จะตัดสินใจว่าบันทึกนั้นเกี่ยวข้องหรือไม่ ก่อนที่จะจ่ายค่า token เพื่ออ่านทั้งหมด
Two-step retrieval (การดึงข้อมูลสองขั้นตอน)
รูปแบบเฉพาะและสำคัญของ preview truncation การค้นหาจะส่งคืน identifiers และตัวอย่างสั้นๆ การเรียก GetByID แยกต่างหากจะดึงข้อมูลเต็มเมื่อจำเป็น อินเทอร์เฟซ MemoryRepo ของ mem9 สร้างขึ้นรอบรูปแบบนี้: การค้นหาและการดึงข้อมูลเป็นการดำเนินการที่แตกต่างกันซึ่งมีรอยเท้า token ที่แตกต่างกัน
ตัวเลขแสดงให้เห็นอย่างชัดเจน สิบรายการที่รายการละ 1,500 token เท่ากับ 15,000 token ที่ถูกฉีดเข้าไปในบริบท ไม่ว่า agent จะใช้มันหรือไม่ก็ตาม การดึงข้อมูลสองขั้นตอนจะส่งคืน 10 identifiers และตัวอย่างสั้นๆ รวมประมาณ 450 token จากนั้นจึงดึงเฉพาะบันทึกที่ agent ต้องการจริงๆ ใน 20 ขั้นตอนการเรียกคืนภายใน session หนึ่ง ความแตกต่างนี้รวมกันแล้วประหยัด token ได้ประมาณ 200,000 token
นี่คือวินัยที่ถูกที่สุดที่คุณสามารถนำมาใช้ได้ ไม่ต้องเปลี่ยนแปลงโครงสร้างพื้นฐานของที่เก็บความจำ ไม่ต้องเรียก LLM เพิ่ม และไม่มีการสูญเสียข้อมูล มันเป็นการตัดสินใจเกี่ยวกับอินเทอร์เฟซการดึงข้อมูล
Decompose-then-recall (แยกส่วนก่อนแล้วค่อยเรียกคืน)
แทนที่จะส่งคำค้นหาทั้งหมดของผู้ใช้ไปยังชั้นการดึงข้อมูล ให้แยกย่อยเป็นคำค้นหาย่อยก่อน ตัววางแผนการดึงข้อมูลที่รับรู้ความตั้งใจ (intent-aware retrieval planner) ของ SimpleMem จะแบ่งคำค้นหาที่เข้ามาเป็นความตั้งใจในการดึงข้อมูลแบบอะตอมมิกก่อนที่จะเข้าถึงที่เก็บความจำ GitNexus ทำสิ่งที่คล้ายกันด้วยการแยกส่วนเครื่องมือค้นหา: คำค้นหาที่ซับซ้อนจะถูกแบ่งเป็นคำค้นหาย่อยที่เจาะจง ซึ่งแต่ละคำจะดึงข้อมูลส่วนที่โฟกัสของกราฟความจำ
ประโยชน์คือความแม่นยำ คำค้นหาที่ถูกแยกส่วนจะดึงข้อมูลที่ไม่เกี่ยวข้องน้อยลง ซึ่งหมายถึงสัญญาณรบกวนในบริบทน้อยลง ข้อแลกเปลี่ยนคือเวลาแฝง: การแยกส่วนเพิ่มขั้นตอนการวางแผนก่อนที่การดึงข้อมูลจะเริ่ม สำหรับ agent แบบโต้ตอบ สิ่งนี้สำคัญ สำหรับ agent แบบแบตช์หรือพื้นหลัง โดยปกติแล้วไม่ใช่ปัญหา
Tiered storage as budget filter (การจัดเก็บแบบหลายชั้นเป็นตัวกรองงบประมาณ)
ถ้าคุณสร้างสถาปัตยกรรมหน่วยความจำแบบหลายชั้น (Tiered Memory) ไว้แล้ว คุณจะได้การกรองงบประมาณเป็นผลพลอยได้ โมเดลสามชั้นของ supermemory หมายความว่าข้อมูลที่ร้อนแรงและเข้าถึงบ่อยอยู่ในชั้นที่ส่งคืนผลลัพธ์ที่กะทัดรัดและมีสัญญาณสูง ข้อมูลเย็นอยู่ในชั้นที่ไม่ถูกค้นหาโดยค่าเริ่มต้น ชั้นการสังเกต (observation tier) ของ Hindsight ทำงานในลักษณะเดียวกัน: การสังเกตดิบจะไม่ถูกฉีดเข้าไปในบริบทโดยตรง มันจะถูกเลื่อนชั้นไปยังชั้นที่สูงกว่าก่อนที่จะกลายเป็นตัวเลือกในการดึงข้อมูล
ข้อแลกเปลี่ยนคือความสมบูรณ์ในการเรียกคืน ข้อมูลที่ยังไม่ได้รับการเลื่อนชั้นอาจเกี่ยวข้องแต่จะไม่ปรากฏในการดึงข้อมูลมาตรฐาน นี่คือการแลกเปลี่ยนแบบเดียวกับการบีบอัด แต่รูปแบบความล้มเหลวต่างกัน: แทนที่จะสูญเสียข้อมูลผ่านการสรุป คุณสูญเสียมันผ่านการลดชั้น
Self-guiding tool responses (การตอบสนองของเครื่องมือที่นำทางตนเอง)
กลไกที่มีการพูดถึงน้อยที่สุด และเป็นหนึ่งในกลไกที่น่าสนใจกว่า แทนที่จะปล่อยให้ agent ตัดสินใจว่าจะทำอะไรหลังจากการเรียกใช้เครื่องมือ การตอบสนองของเครื่องมือเองจะรวมคำใบ้ว่าควรทำอะไรต่อไป GitNexus แนบบล็อก \---
**Next:**\ ต่อท้ายการตอบสนองของเครื่องมือ โดยแนะนำการดำเนินการติดตามผล mem9 ตกแต่ง source turns ด้วยข้อมูลเมตาที่มีโครงสร้างซึ่งแนะนำขั้นตอนการดึงข้อมูลถัดไปของ agent
ผลก็คือ agent ใช้ token ในการวางแผนระหว่างการเรียกใช้เครื่องมือน้อยลง การตอบสนองของเครื่องมือมีโครงสร้างเพียงพอที่จะทำให้ขั้นตอนถัดไปชัดเจน ข้อแลกเปลี่ยนคือความพยายามในการออกแบบ prompt: การเขียนการตอบสนองแบบนำทางตนเองที่ดีต้องรู้ล่วงหน้าว่า agent น่าจะต้องการอะไรต่อไป ซึ่งไม่สามารถทำได้เสมอไป
กรณีขีดจำกัดของ Tolaria
Tolaria น่าสนใจที่จะดูแยกต่างหากเพราะมันเป็นตัวแทนของจุดสิ้นสุดเชิงตรรกะของวินัยด้านงบประมาณที่ถูกนำไปใช้จนถึงขีดสุด ADR-0009 บันทึกการตัดสินใจที่จะลบ embeddings ออกจากระบบทั้งหมด Tolaria ใช้การค้นหาแบบ substring เท่านั้น ไม่มีดัชนีเวกเตอร์ ไม่มีการดึงข้อมูลเชิงความหมาย (semantic retrieval) ไม่มีการเรียก embedding
เหตุผลนั้นตรงไปตรงมา: token ที่ถูกที่สุดคือ token ที่คุณไม่เคยดึงมาตั้งแต่แรก การดึงข้อมูลแบบ embedding ส่งคืนผลลัพธ์ที่มีความหมายคล้ายกัน (semantically similar) ซึ่งหมายความว่ามันส่งคืนผลลัพธ์ที่ agent ไม่ได้ร้องขออย่างชัดเจน ผลลัพธ์บางอย่างมีประโยชน์ หลายอย่างไม่มีประโยชน์ ทั้งหมดมีค่าใช้จ่ายเป็น token
จุดยืนของ Tolaria คือต้นทุนของผลลัพธ์ที่ไม่เกี่ยวข้องแต่คล้ายกัน ซึ่งทบต้นตลอดทั้ง session มีมากกว่าประโยชน์ของการเรียกคืนเชิงความหมายสำหรับกรณีการใช้งานของมัน การแลกเปลี่ยนนี้จะใช้ได้กับระบบของคุณหรือไม่นั้นขึ้นอยู่กับว่าระบบของคุณมีไว้เพื่ออะไร สำหรับระบบที่คำค้นหามีความแม่นยำและมีโครงสร้าง (การนำทางโค้ด การค้นหาเอกสารด้วย identifier) จุดยืนของ Tolaria ก็ป้องกันได้ สำหรับระบบที่คำค้นหาคลุมเครือและเป็นการสำรวจ การลบ embeddings จะทำลายความสามารถในการเรียกคืนในแบบที่ยากจะฟื้นคืน
คุณค่าของกรณี Tolaria ไม่ใช่เพราะว่าคุณควรเลียนแบบ แต่เป็นเพราะมันทำให้ต้นทุนของการดึงข้อมูลเชิงความหมายมองเห็นได้ในแบบที่ระบบส่วนใหญ่ไม่ทำ
ข้อโต้แย้งต่อระบบที่ใช้การบีบอัดเท่านั้น
หลายระบบใน 19 ระบบอาศัยการบีบอัดเป็นกลไกงบประมาณหลักหรือกลไกเดียว รูปแบบความล้มเหลวนั้นควรค่าแก่การเอ่ยถึง
ประการแรก การสรุปทำให้สูญเสียรายละเอียดที่ไม่ได้ถูกตัดสินว่าสำคัญในขณะที่บีบอัด แต่กลับกลายเป็นสำคัญในภายหลัง นี่ไม่ใช่เรื่องสมมติ: มันเป็นรูปแบบความล้มเหลวมาตรฐานของรูปแบบการบีบอัดแบบสูญเสียใดๆ ที่ใช้กับข้อมูลซึ่งไม่ทราบความสำคัญในอนาคต
ประการที่สอง การบีบอัดเป็นต้นทุนที่เกิดในเส้นทางหลัก (hot-path cost) การที่ MemoryOS จ่ายค่าสรุป 20+ ครั้งต่อการโต้ตอบนั้นไม่ใช่เรื่องผิดปกติสำหรับระบบที่ใช้การบีบอัดหนักหน่วง ในระดับขนาดใหญ่ ต้นทุนนั้นไม่ใช่เรื่องเล็กน้อย
ประการที่สาม และละเอียดอ่อนที่สุด คือการบีบอัดโดยไม่มีทางออก (escape hatch) คือการลืมอย่างช้าๆ (slow forgetting) ถ้าวิธีเดียวที่จะลดขนาดบริบทคือการสรุป และบทสรุปก็สูญเสียข้อมูล ระบบก็จะทิ้งข้อมูลอย่างต่อเนื่องโดยไม่มีทางที่จะกู้คืนได้ การดึงข้อมูลสองขั้นตอน การจัดเก็บแบบหลายชั้น และการตัดทอนตัวอย่างผลลัพธ์ ล้วนเก็บรักษาบันทึกต้นฉบับไว้ การบีบอัดไม่ทำ
ไม่มีข้อใดหมายความว่าการบีบอัดผิด เพียงแต่ว่าการบีบอัดเพียงอย่างเดียวนั้นไม่เพียงพอ
การให้น้ำหนักตามความใหม่ (Recency weighting) และคิวถาวร (Persistent queue)
กลไกสองอย่างที่ไม่เข้ากับหกหมวดหมู่ข้างต้นอย่างเรียบร้อย แต่ควรค่าแก่การจดบันทึก
graymatter ใช้ RRF fusion โดยให้น้ำหนักความใหม่ครึ่งหนึ่ง นี่ไม่ใช่กลไกงบประมาณในความหมายที่เคร่งครัด แต่มันทำหน้าที่เป็นกลไกหนึ่ง: โดยการลดน้ำหนักของข้อมูลเก่าในการจัดอันดับการดึงข้อมูล มันจะลดความน่าจะเป็นที่บันทึกที่เก่าและมีสัญญาณต่ำจะเบียดบังบันทึกที่ใหม่และมีสัญญาณสูง ผลลัพธ์คือการแบ่งชั้นแบบนุ่มนวลผ่านน้ำหนักการจัดอันดับ แทนที่จะเป็นการเลื่อนชั้นอย่างชัดเจน
สถานะเครื่องจักรคิวป้อนเข้า (ingest queue state machine) 540 บรรทัดของ llm-wiki ใช้แนวทางที่แตกต่าง คิวจะจัดลำดับการดำเนินการป้อนเข้า และใช้ตัวจัดอันดับความเกี่ยวข้องสี่สัญญาณก่อนที่อะไรก็ตามจะเข้าสู่ที่เก็บความจำ การควบคุมงบประมาณเกิดขึ้น ณ เวลาเขียน (write time) แทนที่จะเป็นเวลาอ่าน (read time) ข้อมูลที่ไม่ผ่านเกณฑ์ความเกี่ยวข้องจะไม่ถูกเก็บ ซึ่งหมายความว่ามันจะไม่ถูกดึงมาและไม่สามารถใช้บริบทได้ นี่คือการควบคุมงบประมาณทางอ้อม แต่คงทน: การประหยัดจะทบต้นตลอดทุก session ในอนาคต
สิ่งที่ระบบที่ออกแบบมาอย่างดีมีร่วมกัน
เมื่อดูจาก 19 ระบบ ระบบที่จัดการงบประมาณบริบทได้ดีมีคุณสมบัติร่วมกันบางประการ
พวกเขาถือว่าการดึงข้อมูลเป็นการดำเนินการสองขั้นตอน แทนที่จะเป็นการฉีดเข้าไปในขั้นตอนเดียว พวกเขาส่งคืนตัวอย่างก่อนบันทึกเต็ม พวกเขาเก็บรักษาบันทึกต้นฉบับแทนที่จะแทนที่ด้วยบทสรุป พวกเขาให้ผู้ปฏิบัติงานควบคุมปริมาณการดึงข้อมูลผ่านพารามิเตอร์ที่ชัดเจน แทนที่จะเป็นค่าเริ่มต้นที่ถูก hardcode ไว้ และพวกเขาคิดถึงงบประมาณทั้งในเวลาเขียนและเวลาอ่าน
ระบบที่จัดการได้ไม่ดีมักจะพึ่งพากลไกเดียว ซึ่งโดยปกติคือการบีบอัด และปฏิบัติกับหน้าต่างบริบท (context window) เป็นบัฟเฟอร์ที่ต้องเติมให้เต็ม แทนที่จะเป็นทรัพยากรที่ต้องจัดการ
จุดยืนปิดท้ายจากการวิจัยนั้นเรียบง่าย หน้าต่างที่ใหญ่ขึ้นต้องการวินัยมากขึ้น ไม่ใช่น้อยลง ไม่ใช่เพราะการเติมเต็มมันผิดโดยหลักการ แต่เพราะการเติมเต็มมันด้วยวัสดุที่ผิดนั้นมีค่าใช้จ่ายสูงกว่าการปล่อยให้ว่างเปล่า
สำหรับบทความถัดไป ผมวางแผนที่จะเปลี่ยนจากหน่วยความจำแบบฉีดเข้า (memory-as-injection) ไปเป็นหน่วยความจำแบบเครื่องมือ (memory-as-tools) โดยครอบคลุมว่า 19 ระบบจัดการขอบเขตระหว่างสิ่งที่ถูกผลักเข้าไปในบริบทโดยอัตโนมัติกับสิ่งที่ agent ต้องขอมาอย่างชัดเจนอย่างไร*
เช่นเคย ถ้าคุณพบว่าสิ่งนี้น่าสนใจ มีประโยชน์ หรือแค่อยากช่วยกระจายความรู้:
กรุณาแชร์





