- แก้ปัญหา ข้อมูลดิบจำนวนมากที่เกิดขึ้นเมื่อเรียกใช้เครื่องมือภายนอกซึ่งทำให้ context window ถูกใช้หมดอย่างรวดเร็ว
- ทำหน้าที่คั่นกลางระหว่าง Claude Code กับเอาต์พุตของเครื่องมือ โดยบีบอัดและกรองข้อมูล ทำให้ 315KB ลดเหลือ 5.4KB (ลดลง 98%)
- ผ่าน โครงสร้างแบบ sandbox เพื่อแยกการทำงานแต่ละครั้งออกจากกัน และใส่เฉพาะ stdout ลงในคอนเท็กซ์ จึงป้องกันข้อมูลดิบอย่างล็อกและสแนปช็อตรั่วไหลออกมา
- ใช้ knowledge base บน SQLite FTS5 เพื่อทำดัชนีคอนเทนต์ Markdown และรองรับการค้นหาบล็อกโค้ดได้แม่นยำด้วย การจัดอันดับแบบ BM25 และ Porter stemming
- ภายใต้ขีดจำกัด 200K โทเค็นเท่าเดิม ระยะเวลาของเซสชันเพิ่มจาก 30 นาทีเป็น 3 ชั่วโมง ทำให้ AI agent จัดการคอนเท็กซ์ได้อย่างมีประสิทธิภาพ
ปัญหา
- การเรียกใช้ เครื่องมือ MCP ใน Claude Code จะดัมพ์ข้อมูลดิบลงในหน้าต่างคอนเท็กซ์ 200K โดยตรงทุกครั้งที่เรียก
- Playwright snapshot 56KB, GitHub issues 20 รายการ 59KB, access log 45KB เป็นต้น
- ใช้งานประมาณ 30 นาที คอนเท็กซ์ทั้งหมดจะถูกใช้ไป 40%
- แม้ MCP จะกลายเป็นมาตรฐานสำหรับการใช้เครื่องมือภายนอกแล้ว แต่ก็ยังมี ข้อจำกัดเชิงโครงสร้างที่ทั้งนิยามอินพุตและข้อมูลเอาต์พุตต่างเข้ามาเติมคอนเท็กซ์
- เมื่อเปิดใช้งานเครื่องมือมากกว่า 81 ตัว จะมีการใช้ไปแล้ว 72% (143K โทเค็น) ตั้งแต่ก่อนส่งข้อความแรก
โครงสร้างของ Context Mode
- เป็น เซิร์ฟเวอร์ MCP ที่อยู่ระหว่าง Claude Code กับเอาต์พุตของเครื่องมือ เพื่อส่งต่อข้อมูลโดยลดข้อมูลดิบให้น้อยที่สุด
- เอาต์พุต 315KB ลดเหลือ 5.4KB (ลดลง 98%)
- การเรียก
execute แต่ละครั้งจะทำงานใน subprocess ที่แยกออกจากกัน จึงรันได้อย่างอิสระโดยไม่แชร์หน่วยความจำหรือสถานะ
- มีเพียง stdout เท่านั้นที่ถูกใส่ในคอนเท็กซ์ ส่วนล็อก, API response, snapshot ฯลฯ จะถูกเก็บไว้ภายใน sandbox
- รองรับ runtime 10 ภาษา: JavaScript, TypeScript, Python, Shell, Ruby, Go, Rust, PHP, Perl, R
- ตรวจจับ Bun อัตโนมัติ ทำให้การรัน JS/TS เร็วขึ้น 3~5 เท่า
- CLI ที่ต้องยืนยันตัวตน (
gh, aws, gcloud, kubectl, docker) จะส่ง credential อย่างปลอดภัยด้วย การสืบทอด environment variable
ฐานความรู้ (knowledge base)
- เครื่องมือ
index จะ แบ่ง Markdown ตามหน่วย heading และเก็บลงใน ตารางเสมือน SQLite FTS5 โดยคง code block ไว้ตามเดิม
- ระหว่างการค้นหา ใช้ อัลกอริทึมการจัดอันดับ BM25 เพื่อคำนวณความเกี่ยวข้องจากความถี่ของคำ, inverse document frequency และการทำ normalization ตามความยาวเอกสาร
- ใช้ Porter stemming ทำให้ “running”, “runs”, “ran” ถูกจับคู่เป็นรากคำเดียวกัน
- เมื่อเรียก
search จะคืนค่าเป็น code block ที่ตรงกันอย่างแม่นยำและลำดับชั้นของ heading ไม่ใช่สรุปย่อ
fetch_and_index จะดึง URL มา แปลง HTML เป็น Markdown แล้วทำดัชนี โดยจะไม่ใส่หน้าเว็บต้นฉบับเข้าไปในคอนเท็กซ์
ตัวเลขประสิทธิภาพ
- ใน 11 สถานการณ์จริง (เช่น test triage, การวิเคราะห์ข้อผิดพลาด TypeScript, การตรวจสอบ git diff) สามารถ คงเอาต์พุตไว้ไม่เกิน 1KB ได้ทั้งหมด
- Playwright snapshot: 56KB → 299B
- GitHub issues (20 รายการ): 59KB → 1.1KB
- access log (500 รายการ): 45KB → 155B
- การวิเคราะห์ CSV (500 แถว): 85KB → 222B
- git log (153 commits): 11.6KB → 107B
- การสำรวจ repository (subagent): 986KB → 62KB (เรียก 5 ครั้ง เทียบกับ 37 ครั้ง)
- ในระดับทั้งเซสชัน ลดจาก 315KB → 5.4KB ทำให้ ระยะเวลาเซสชัน 30 นาที → 3 ชั่วโมง
- คอนเท็กซ์ที่เหลือหลังผ่านไป 45 นาที: เดิม 60% → 99%
การติดตั้งและใช้งาน
- รองรับ auto-routing hook และ slash command ผ่าน Plugin Marketplace
- ติดตั้งแบบเฉพาะ MCP ก็ได้เช่นกัน
- รีสตาร์ต Claude Code แล้วใช้งานได้ทันที
การเปลี่ยนแปลงที่เกิดขึ้นจริง
- โดยไม่ต้องเปลี่ยนวิธีใช้งาน PreToolUse hook จะจัดเส้นทางเอาต์พุตโดยอัตโนมัติ
- subagent ใช้
batch_execute เป็นเครื่องมือพื้นฐานโดยปริยาย
- Bash subagent ถูกอัปเกรดเป็น
general-purpose ทำให้เข้าถึงเครื่องมือ MCP ได้
- ผลลัพธ์คือ หน้าต่างคอนเท็กซ์จะไม่เต็มอย่างรวดเร็วอีกต่อไป และใช้โทเค็นเดิมเพื่อคงเซสชันได้นานขึ้น
เบื้องหลังการพัฒนา
- ระหว่างดูแล MCP Directory & Hub พบแพตเทิร์นร่วมกันว่า เซิร์ฟเวอร์ MCP ทั้งหมดดัมพ์ข้อมูลดิบลงในคอนเท็กซ์
- ได้แรงบันดาลใจจาก Code Mode ของ Cloudflare ที่บีบอัดนิยามเครื่องมือ แล้วต่อยอดไปสู่แนวทาง บีบอัดข้อมูลเอาต์พุต
- หลังยืนยันแล้วว่าสามารถทำงานในเซสชัน Claude Code ได้นานขึ้น 6 เท่า จึง เปิดซอร์สภายใต้ไลเซนส์ MIT
- GitHub: mksglu/claude-context-mode
1 ความคิดเห็น
ความคิดเห็นจาก Hacker News
แนวทาง FTS5 index ที่เสนอไว้ตรงนี้ถูกต้อง แต่ผมคิดว่าควรไปไกลกว่านั้นอีกขั้น
เอาต์พุตของเครื่องมือมักปะปนกันระหว่างข้อมูลแบบมีโครงสร้าง (JSON, ตาราง, การตั้งค่า) กับภาษาธรรมชาติ (คอมเมนต์, ข้อความผิดพลาด, docstring) ดังนั้น BM25 เพียว ๆ จึงทำงานได้ไม่ดีนัก
ผมเคยสร้างตัวค้นหาแบบไฮบริดเพื่อแก้ปัญหาคล้ายกัน โดยรวม Model2Vec + sqlite-vec + FTS5 เข้าด้วยกัน แล้วนำผลค้นหาทั้งสองฝั่งมารวมด้วย Reciprocal Rank Fusion(RRF) ทำให้ได้ทั้งการจับคู่คีย์เวิร์ดที่แม่นยำแบบ BM25 และการจับคู่เชิงความหมายจาก vector search พร้อมกัน
การทำ incremental indexing ก็สำคัญเช่นกัน indexer ของผมจะ re-embed เฉพาะ chunk ที่เปลี่ยนผ่านแฟลก
--incrementalการ reindex ทั้งหมด 15,800 ไฟล์ใช้เวลา 4 นาที ส่วน incremental รายวันใช้เวลาไม่ถึง 10 วินาทีในแง่ของ caching วิธีนี้ก็ได้เปรียบเช่นกัน เพราะเอาต์พุตที่บีบอัดสำหรับ query เดิมจะเป็นแบบ deterministic ทำให้ prompt cache ทำงานได้อย่างเสถียร
อีกอย่างที่น่าจะเพิ่มเข้าไปในสถาปัตยกรรมของ Context Mode คือให้รันตัวค้นหาตัวเดียวกันผ่าน PostToolUse hook เพื่อบีบอัดเอาต์พุตก่อนที่มันจะเข้าไปในบทสนทนา
ผมเป็นผู้เขียนโพสต์นี้เอง ไม่กี่วันก่อนผมแชร์ GitHub repository ไป แล้วได้รับ feedback ดีมาก โพสต์นี้เลยเป็น คำอธิบายสถาปัตยกรรม ของมัน
ไอเดียหลักคือ แทนที่จะเอาข้อมูลดิบที่ MCP tool call dump ออกมาใส่เข้าไปใน context window ขนาด 200K ตรง ๆ ตัว Context Mode จะสร้าง subprocess ที่แยกออกมา แล้วส่งเฉพาะ stdout เข้า context เท่านั้น โดยไม่ต้องเรียก LLM ใช้อัลกอริทึมล้วน ๆ ด้วย SQLite FTS5 + BM25 + Porter stemming
ช่วงหลังมานี้โปรเจ็กต์ได้ 228 stars และมีข้อมูลการใช้งานจริง ทำให้ผมตระหนักว่า sub-agent routing สำคัญมากแค่ไหน ถ้าอัปเกรด Bash sub-agent ให้เป็นแบบทั่วไปโดยอัตโนมัติแล้วใช้ batch_execute ก็จะไม่ต้องทำให้ context เต็มไปด้วยเอาต์พุตดิบ
ไม่เข้าใจว่าทำไมถึงไม่ใช้ mcp-cli mode ผมทำเวอร์ชันโคลนไว้กับ wener-mcp-cli
งานเจ๋งมาก ผมคิดว่ายังมีพื้นที่ให้ปรับปรุงเรื่อง การจัดการ context window ได้อีกเยอะ ตัวอย่างเช่น ถ้าโมเดลหาคำตอบเจอหลังจากลองหลายครั้ง แนวทางแบบ backtracking ที่ลบความพยายามที่ล้มเหลวออกจาก context ก็น่าจะมีประโยชน์
เห็นโพสต์นี้แล้วทำให้ผมรู้ตัวว่าไม่เคยรู้เลยว่า Claude Code ใช้ token ไปเท่าไร เลยทำ CLI ชื่อ claude-trace ขึ้นมาเมื่อเช้า
มัน parse
~/.claude/projects/*/*.jsonlเพื่อวิเคราะห์การใช้งานและต้นทุน (รวม cache read/write) แยกตาม session, tool, project และ timelineถ้า Context Mode แก้เรื่องการบีบอัดเอาต์พุตได้ดี ตัวนี้ก็จะเป็น measurement layer สำหรับทำให้เห็นภาพการใช้ทรัพยากรก่อนและหลังการเปลี่ยนแปลง
การใช้ token จำนวนมากสามารถลดลงได้ถ้าใช้ แอป CLI แทน MCP เช่น GitHub CLI ทำงานแบบเดียวกันได้โดยใช้ token น้อยกว่า MCP มาก
hook ดู aggressive เกินไป การบล็อก curl/wget/WebFetch ทั้งหมดแล้วสร้าง snapshot 56KB ใน sandbox นั้นก็โอเค แต่สำหรับกรณีง่าย ๆ อย่าง
curl api.example.com/healthที่ต้องการแค่ 200 ไบต์ มันหนักเกินไปถ้าบีบอัด git commit 153 รายการเหลือ 107 ไบต์ โมเดลก็ต้องเขียน extraction script ได้เป๊ะจริง ๆ ถึงจะเห็นข้อมูลได้ ถ้าใช้คำสั่งผิด ข้อมูลที่จำเป็นก็หายไปเลย
benchmark นี้ตั้งอยู่บนสมมติฐานว่าโมเดลจะเขียนโค้ดสรุปที่ถูกต้องได้เสมอ แต่ในความเป็นจริงไม่ใช่แบบนั้น
ไม่เลว แต่มี การสูญเสียความแม่นยำ กับ ความเสี่ยงต่อ hallucination อยู่ เพราะข้อมูลที่ไม่สมบูรณ์หรือ logic การดึงข้อมูลที่ผิดพลาดอาจทำให้ Claude สรุปผิดได้ แนวทางนี้ตั้งอยู่บนสมมติฐานว่า MCP ฉลาดพอจะเขียนทั้ง extraction script และ search query ที่ดีได้ ผมคิดว่าการรักษาข้อมูลให้ครบถ้วนเป็นปัญหาใหญ่จริง ๆ
อัตราการบีบอัดน่าประทับใจ แต่ผมสงสัยว่าเมื่อใช้ context ที่ถูกบีบอัด แล้ว โมเดลยังจะให้ผลลัพธ์คุณภาพเท่าเดิมไหม ต่อให้ยืด session จาก 30 นาทีเป็น 3 ชั่วโมง ก็ต้องรักษาคุณภาพการให้เหตุผลในชั่วโมงที่ 2 ได้ด้วยถึงจะมีความหมาย
เรื่อง ความคุ้มค่าของ cache ที่ esafak พูดถึงก็สำคัญเช่นกัน ถ้า prompt caching ทำงานดี context ที่ยืดยาวก็แทบฟรี แต่ถ้าการบีบอัดทำให้ความต่อเนื่องของ cache ขาดลง ต้นทุนอาจสูงขึ้นแทน
ปัญหาที่ลึกกว่านั้นคือเครื่องมือ MCP ส่วนใหญ่ดึงข้อมูลทั้งหมดด้วย SELECT * นี่เป็น ปัญหาการออกแบบโปรโตคอล ที่ควรรองรับทั้งการสรุปและการ drill-down
ผมสงสัยว่าจำเป็นจริงหรือไม่ที่จะต้องใส่เครื่องมือมากกว่า 80 ตัวเข้าไปใน context เพราะ context มีค่ามาก ยิ่งใส่สิ่งที่ไม่เกี่ยวกับปัญหาเข้าไปเยอะ ผลลัพธ์ก็ยิ่งแย่ แทนที่จะบีบอัดข้อมูล แนวทางที่ดีกว่าน่าจะเป็น การแยก sub-agent