Kythe โปรเจกต์โอเพนซอร์สของ Google ที่ให้เครื่องมือทุกภาษาคุยกันผ่านกราฟของโค้ด ลดงานเชื่อมต่อจาก O(L×C×B) เหลือ O(L+C+B)
Kythe คือโปรเจกต์โอเพนซอร์สจาก Google ที่ให้เครื่องมือของทุกภาษาคุยกันผ่านกราฟของโค้ด งานเชื่อมต่อระหว่างเครื่องมือจึงลดจาก O(L×C×B) เหลือเพียง O(L+C+B)

Kythe เป็นโปรเจกต์โอเพนซอร์สของ Google ที่สร้างขึ้นมาแก้ปัญหาคลาสสิกของ repository ที่มีหลายภาษา นั่นคือเครื่องมือของแต่ละภาษามักจะคุยกันไม่รู้เรื่อง
ลองนึกภาพโปรเจกต์ที่ส่วนหน้าบ้านเขียนด้วย TypeScript, ส่วนหลังบ้านเขียนด้วย Go และมีสคริปต์ Python คอยเชื่อมการทำงานในอีกโฟลเดอร์หนึ่ง เวลาเราเปิดไฟล์ TypeScript แล้วกด Go to Definition เพื่อดูจุดประกาศฟังก์ชัน ตัว Editor จะพาเราไปได้แค่ภายในขอบเขตของ TypeScript เท่านั้น เพราะโปรแกรมรู้จักแค่ TypeScript แต่ไม่รู้เลยว่าฝั่ง Go ไปเรียกใช้ฟังก์ชันนี้จากตรงไหน หรือมีสคริปต์ Python ตัวไหนเรียกใช้ฟังก์ชันนี้อยู่บ้าง เมื่อเครื่องมือไม่สามารถวิเคราะห์ข้ามภาษาได้ ทางออกที่แต่ละทีมมักเลือกจึงมีแค่สองทาง คือเขียนเครื่องมือขึ้นมาใช้เอง หรือบังคับให้ทุกคนในทีมเปลี่ยนมาใช้ชุดเครื่องมือเดียวกันทั้งหมด
Google เองก็เจอปัญหานี้ในระดับที่ใหญ่มาก โค้ดหลายภาษาเก็บรวมอยู่ใน monorepo ขนาดมหึมา จนไม่สามารถเปิดหรือจัดการผ่าน IDE บนเครื่องเดี่ยวๆ ได้ เอกสารแนะนำภาพรวมของ Kythe (kythe.io) ระบุไว้ชัดเจนว่า วิศวกรต้องเสียเวลาไปมากกับการปรับแต่งเครื่องมือใหม่ให้เข้ากับโปรเจกต์ และหลายครั้งต้องเขียนฟังก์ชันวิเคราะห์โค้ดขึ้นมาซ้ำซ้อนกับสิ่งที่ compiler หรือตัววิเคราะห์ของ IDE เคยทำไว้อยู่แล้ว เพียงเพราะเครื่องมือเดิมไม่สามารถส่งต่อข้อมูลให้เครื่องมือตัวอื่นได้ ส่วนทางออกที่บังคับให้ทุกคนใช้เครื่องมือชุดเดียวกัน เมื่อทีมขยายใหญ่ขึ้นก็เริ่มไปต่อไม่ไหว เพราะเครื่องมือแบบรวมศูนย์มักรองรับได้ดีเฉพาะภาษาหรือระบบเดิมที่มีอยู่แล้ว การเพิ่มภาษาใหม่มีต้นทุนสูงมาก และการบังคับให้นักพัฒนาใช้เครื่องมือที่ไม่ถนัดก็ทำให้ทำงานช้าลงอย่างเห็นได้ชัด
ทางออกของ Google จึงไม่ใช่การให้เครื่องมือแต่ละตัวเชื่อมต่อกันเองตรงๆ แต่เป็นการกำหนด "ภาษากลาง" ขึ้นมาภาษาเดียว นั่นคือแผนผังความสัมพันธ์ในรูปกราฟของโค้ด หรือ Code Graph แล้วเปิดเป็นโปรเจกต์โอเพนซอร์สในชื่อ Kythe ซึ่งประกอบด้วยรูปแบบข้อมูลกราฟ ข้อกำหนดโครงสร้างอย่าง Schema และชุดเครื่องมือพร้อมใช้งาน
O(L×C×B) กับ O(L+C+B): สมการที่ Kythe ใช้อธิบายปัญหา

หัวใจของ Kythe สรุปได้ด้วยสมการสั้นๆ จากเอกสารทางการ กำหนดให้:
- L คือจำนวนภาษา
- C คือจำนวน client หรือโปรแกรมฝั่งเรียกใช้ เช่น Editor, IDE หรือ Code Browser
- B คือจำนวน Build System หรือระบบ build โค้ด
ถ้าเราต้องการให้เครื่องมือทุกตัวทำงานร่วมกันได้โดยตรง งานเชื่อมต่อในกรณีที่แย่ที่สุดจะเท่ากับ O(L×C×B) โดยสัญลักษณ์ O(...) เป็นวิธีเขียนทางคณิตศาสตร์ที่บอกว่าปริมาณงานจะเพิ่มขึ้นตามตัวแปรเหล่านี้
ลองยกตัวอย่างด้วยตัวเลขง่ายๆ: สมมติว่าทีมพัฒนาใช้ 3 ภาษา, ใช้ Editor 3 ตัว และมี Build System 2 ระบบ ถ้าจะทำให้ Editor ทุกตัวเข้าใจทุกภาษาบนทุก Build System ด้วยการเขียนตัวเชื่อมต่อหากันตรงๆ จะต้องสร้างตัวเชื่อมต่อทั้งหมด 3 × 3 × 2 = 18 ตัว และถ้าทีมเพิ่มภาษาที่ 4 เข้ามา งานจะกระโดดไปเป็น 4 × 3 × 2 = 24 ตัวทันที ทุกครั้งที่เปลี่ยน Editor หรือเพิ่ม Build System ตัวคูณทั้งหมดจะยิ่งเพิ่มขึ้นทั้งระบบ
Kythe แก้ปัญหานี้ด้วยการวางตัวเองเป็นศูนย์กลางเชื่อมต่อที่เรียกว่า Hub แทน โดยเครื่องมือแต่ละตัวไม่จำเป็นต้องรู้จักเครื่องมืออื่นเลย รู้จักแค่ภาษากลางของ Kythe ก็พอ เอกสารอธิบายว่า การทำให้ Compiler, Editor หรือ Build System ตัวใดตัวหนึ่งรองรับ Kythe นั้นเป็นต้นทุนคงที่ที่ลงแรงทำเพียงครั้งเดียว จากนั้นเครื่องมือนั้นก็ทำงานร่วมกับเครื่องมือตัวอื่นในระบบได้ทันที ทำให้ปริมาณงานลดลงเหลือเพียง O(L+C+B) จากตัวอย่างเดิม ทีมจะต้องเขียนตัวเชื่อมต่อแค่ 3 + 3 + 2 = 8 ตัวเท่านั้น และเมื่อมีภาษาที่ 4 เพิ่มเข้ามา ก็เขียนตัวเชื่อมต่อเพิ่มแค่อีก 1 ตัว ไม่ใช่เพิ่มขึ้นมาอีก 6 ตัวเหมือนเดิม
แต่จุดที่หลายคนมักเข้าใจผิดเกี่ยวกับคำว่า Hub คือ Kythe ไม่ได้เป็นโปรแกรมหรือเซิร์ฟเวอร์ส่วนกลางที่ทุกเครื่องมือต้องเปิดเชื่อมต่อตลอดเวลา แต่นิยามของมันคือชุดข้อตกลงและรูปแบบข้อมูลกลางที่ไม่ขึ้นกับภาษาใดภาษาหนึ่ง ฝั่งผลิตข้อมูลก็แปลงข้อมูลให้อยู่ในรูปแบบนี้ ฝั่งอ่านก็นำรูปแบบนี้ไปใช้ ตัวข้อมูลกราฟเองต่างหากที่ทำหน้าที่เป็น Hub
ภาษากลางของ Kythe คือกราฟ ไม่ใช่ข้อความธรรมดา
ภาษากลางของ Kythe ออกแบบมาในรูปของกราฟที่ประกอบด้วยโหนด (Node) และเส้นเชื่อม (Edge) โดยในโครงสร้างเดียวกันนี้จะเก็บข้อมูลไว้ 2 ระดับ: ระดับแรกคือ Metadata จาก Build System และ Compiler ส่วนระดับที่สองคือข้อมูลเชิงความหมายของโค้ด เช่น จุดประกาศฟังก์ชัน, จุดเรียกใช้, ชนิดข้อมูล รวมถึงความสัมพันธ์ข้ามภาษา
เพื่อให้เห็นภาพง่ายขึ้น: โหนดหนึ่งอาจแทนตำแหน่งที่ประกาศฟังก์ชันไว้ในไฟล์ Go ส่วนอีกโหนดหนึ่งแทนตำแหน่งที่มีคนเรียกใช้ฟังก์ชันนั้นในไฟล์ TypeScript และเส้นเชื่อมคือตัวระบุว่าทั้งสองจุดนี้เกี่ยวข้องกันอย่างไร เมื่อเก็บข้อมูลทั้งหมดไว้ในกราฟเดียวกัน คำถามที่ Editor เคยตอบไม่ได้ในตอนต้น ก็จะเหลือเพียงการไล่ตามเส้นเชื่อมจากโหนดหนึ่งไปยังอีกโหนดหนึ่ง โดยไม่ต้องสนใจว่าปลายทางจะเขียนด้วยภาษาอะไร ซึ่งต่างจากการค้นหาข้อความทั่วไป ที่จะเจอเฉพาะคำที่สะกดเหมือนกัน แต่ไม่รู้ว่าเป็นตัวแปรหรือฟังก์ชันเดียวกันจริงๆ หรือไม่
ข้อกำหนดที่ระบุว่ากราฟจะมี Node และ Edge ชนิดใดได้บ้าง เรียกว่า Schema ซึ่งเอกสารระบุไว้ชัดเจนว่าออกแบบมาให้ยืดหยุ่นและต่อยอดได้ง่าย ทีมงาน Kythe ได้เตรียมโครงสร้างกราฟสำหรับกรณีใช้งานทั่วไปไว้ให้ส่วนหนึ่งแล้ว แต่ใครๆ ก็เพิ่มชนิดของ Node หรือ Edge ใหม่ๆ ได้เองโดยไม่ต้องรอให้ส่วนกลางอนุมัติ
เอกสารของ Kythe ยังระบุหลักการออกแบบสำคัญไว้ 3 ข้อ:
- ข้อแรก: การทำงานร่วมกันไม่จำเป็นต้องรอให้สมบูรณ์ทั้งหมดถึงจะทำงานได้ เครื่องมือต้องรับมือกับข้อมูลที่ขาดหายหรือไม่ครบถ้วนได้ เพราะการมีข้อมูลเพียงบางส่วนย่อมดีกว่าไม่มีข้อมูลเลย
- ข้อสอง: เอกสารระบุไว้อย่างสั้นและชัดเจนว่า
ส่งข้อมูลที่ไม่ครบออกมา ดีกว่าส่งข้อมูลที่ผิด
- ข้อสาม: เครื่องมือต้องไม่หยุดทำงานทันทีเมื่อเจอข้อมูลไม่ครบ เพราะผลลัพธ์เพียงบางส่วนก็ยังคงมีประโยชน์สำหรับผู้ใช้งาน
หลักการทั้ง 3 ข้อนี้สะท้อนเรื่องเดียวกัน: ถ้าคุณกำลังพัฒนาเครื่องมือที่ต้องอ่านโค้ดต่อจากคนอื่น ในวันที่ตัววิเคราะห์ของบางภาษายังพัฒนาไม่เสร็จ เครื่องมือของคุณก็ยังต้องทำงานต่อไปได้เท่าที่มีข้อมูล และถ้าข้อมูลจุดไหนไม่ชัดเจน ระบบควรเลือกที่จะไม่ส่งข้อมูลออกมา แทนที่จะเดาสุ่มจนให้ข้อมูลที่ผิดพลาด
Kythe มีอะไรมาให้บ้าง และถ้าต้องการเชื่อมต่อระบบใหม่ต้องทำอย่างไร

เอกสารแบ่งสิ่งที่ Kythe เตรียมไว้ให้ออกเป็น 3 ส่วนหลัก:
- Storage Format รูปแบบการจัดเก็บข้อมูลของกราฟ: ออกแบบมาให้เรียบง่าย เคลื่อนย้ายสะดวก ฝั่ง Compiler สามารถฝังตัวดึงข้อมูลเพื่อส่งกราฟออกมาได้ง่าย และฝั่งเครื่องมือปลายทางก็อ่านข้อมูลไปใช้งานได้ไม่ซับซ้อน
- Schema: ข้อกำหนดโครงสร้างของกราฟ พร้อมเครื่องมือสำหรับเพิ่มองค์ประกอบใหม่เข้า Schema และตัวทดสอบว่าตัววิเคราะห์ส่งข้อมูลตรงตามข้อตกลงจริง
- ชุดเครื่องมือโอเพนซอร์ส ใน repository kythe/kythe
สำหรับชุดเครื่องมือโอเพนซอร์ส หน้าแรกของเว็บไซต์ Kythe ระบุรายการที่พร้อมใช้งานไว้ดังนี้:
- Indexer โปรแกรมอ่านโค้ดเพื่อสร้างข้อมูลกราฟ รองรับภาษา C++ และ Java
- Extractor ทำหน้าที่ดึงข้อมูลสภาพแวดล้อมตอนคอมไพล์จากกระบวนการ build รองรับ javac, Maven, CMake, Go และ Bazel
- Verifier เครื่องมือทดสอบส่วนกลาง สำหรับตรวจว่า Indexer ตัวใดก็ตามสร้างข้อมูลถูกต้องตาม Schema หรือไม่
- Server ตัวอย่าง ที่รองรับการค้นหาจุดอ้างอิงในโค้ดอย่าง Cross-reference เช่น ถามหาจุดประกาศ หรือจุดที่เรียกใช้ฟังก์ชัน
- ชุดคำสั่งยูทิลิตี สำหรับจัดการและประมวลผลไฟล์กราฟของ Kythe
จุดที่คนมักจะสับสนคือ Extractor กับ Indexer ทำหน้าที่คนละอย่างกัน:
- Extractor จะผูกกับ Build System ทำหน้าที่ดึงข้อมูลตอนคอมไพล์ออกมาจากกระบวนการ build ว่าโค้ดชุดนี้ต้องพึ่งพาไลบรารีหรือส่วนเสริมใดบ้าง เพื่อให้ตัววิเคราะห์ทำงานร่วมกับส่วนเสริมเหล่านั้นได้อย่างถูกต้อง
- Indexer จะผูกกับตัวภาษา ทำหน้าที่อ่านโค้ดจริงแล้วสร้าง Node กับ Edge ของกราฟออกมา
ตัวอย่างของภาษา Go ช่วยให้เห็นความต่างนี้ได้ชัดเจน: หน้าแรกของ Kythe ระบุว่ามี Extractor สำหรับ Go แล้ว แต่ในเอกสารระบุว่า Indexer และ Schema ของ Go ยังอยู่ระหว่างการพัฒนา ดังนั้น การมี Extractor ไม่ได้แปลว่าภาษานั้นจะมี Indexer ครบถ้วนพร้อมใช้งาน
สำหรับการนำระบบใหม่เข้ามาเชื่อมต่อ เอกสารแนะนำการพัฒนาเครื่องมือให้เข้ากับ Kythe ได้แบ่งแนวทางออกเป็น 3 กรณี:
- หากต้องการเพิ่มภาษาใหม่: ต้องมี Compiler ที่เปิดให้ฝังโค้ดดึงข้อมูลเข้าไป เพื่อสร้าง Indexer ที่ส่งออกข้อมูลตามรูปแบบของ Kythe ได้
- หากต้องการเพิ่ม Build System ใหม่: ต้องเขียน Extractor เพื่อดึงข้อมูลการคอมไพล์ออกมาจากกระบวนการ build แล้วส่งต่อให้ตัววิเคราะห์ของภาษานั้นนำไปทำงานต่อ
- หากต้องการสร้าง UI Tool หรือเครื่องมือแสดงผลใหม่: ฝั่งนี้จะง่ายที่สุด เพียงแค่เขียนโปรแกรมให้อ่านไฟล์กราฟของ Kythe ออก และเข้าใจรูปแบบการตั้งชื่อโหนดก็เพียงพอแล้ว
ทั้ง 3 กรณีนี้มีปริมาณงานและความยากง่ายต่างกันอย่างชัดเจน เป็นเรื่องที่ผู้พัฒนาเครื่องมือต้องรู้ก่อนตัดสินใจลงมือ: ถ้าภาษาที่คุณต้องการใช้งานมี Indexer อยู่แล้ว งานของคุณก็อยู่แค่ฝั่ง UI หรือ Client ซึ่งเบาที่สุด เพราะข้อมูลของ Kythe อยู่ในรูปแบบ flat และย้ายไปประมวลผลได้ง่าย จะนำไปแปลงเป็นตารางหรือแสดงผลก็ทำได้อย่างรวดเร็ว แต่ถ้าภาษาที่คุณใช้ยังไม่มี Indexer คุณจะต้องลงไปจัดการถึงระดับ Compiler ซึ่งเป็นงานส่วนที่ซับซ้อนและหนักที่สุดของทั้งระบบ
สถานะของโปรเจกต์ในปัจจุบัน ดูได้จาก Release ล่าสุด
ในแง่การดูแลโปรเจกต์ Release ล่าสุดของ repository คือเวอร์ชัน v0.0.76 (เผยแพร่เมื่อ 16 กรกฎาคม 2026) มีการเปลี่ยนแปลง 2 รายการ โดยทั้งคู่เป็นงานในฝั่ง Extractor ของภาษา Rust ได้แก่ การย้าย root module ไปไว้ที่จุดเริ่มต้นของ source_file และการตั้งค่า is_workspace_member เพื่อระบุว่ากำลังประมวลผล crate หรือแพ็กเกจโค้ดใดอยู่ การเปลี่ยนแปลงทั้งสองนี้เป็นเพียงงานระดับ Extractor ไม่ใช่การประกาศว่า Kythe รองรับภาษา Rust อย่างเต็มรูปแบบแล้ว
สำหรับสถิติของ repository บน GitHub ล่าสุดอยู่ที่ประมาณ 2,200 Stars, 276 Forks, มี Issue ที่เปิดอยู่ 235 รายการ และมี Pull Request ที่รอ merge 43 รายการ ตัวเลขเหล่านี้สะท้อนว่าโปรเจกต์ยังคงมีความเคลื่อนไหวและพัฒนาอยู่เรื่อยๆ ไม่ใช่โปรเจกต์ที่ถูกปล่อยร้าง
2 ข้อควรรู้ก่อนตัดสินใจนำ Kythe ไปใช้งาน
เรื่องแรก: นี่ไม่ใช่เครื่องมือประเภทที่ติดตั้งเสร็จแล้วจะพร้อมใช้งานได้ทันที ไฟล์ release ของเวอร์ชัน v0.0.76 (kythe-v0.0.76.tar.gz) มีขนาดประมาณ 337 MB และเครื่องมือภายในไม่ได้ทำงานเดี่ยวๆ ได้ด้วยตัวเอง เพราะ Extractor แต่ละตัวต้องผูกเข้ากับ Build System เช่น Bazel หรือ Maven ส่วนภาษาที่ยังไม่มี Indexer ก็จำเป็นต้องอาศัย Compiler ที่ฝังตัวดึงข้อมูลได้ตามที่เล่าไป ต้นทุนคงที่ในการติดตั้งและเชื่อมต่อระบบตามที่เอกสารระบุจึงเป็นต้นทุนจริงที่ต้องลงแรง แม้ว่าจะเป็นการทำเพียงครั้งเดียวก็ตาม
เรื่องที่สอง: Kythe ระบุสิ่งที่ไม่ใช่เป้าหมายไว้อย่างชัดเจนในเอกสาร โดยไม่ได้ตั้งใจจะเป็น Compiler หรือตัวปรับแต่งประสิทธิภาพโค้ด เพราะกราฟของมันเน้นเก็บข้อมูลระดับสูงที่มีหน้าตาคล้ายกันข้ามภาษา ส่วนการแปลงโค้ดเป็นภาษาเครื่องหรือการปรับแต่งประสิทธิภาพเป็นเรื่องเฉพาะของแต่ละภาษา และ Kythe ก็ไม่ได้ตั้งใจจะมาแทนที่โครงสร้างข้อมูลภายในอย่าง IR ของเครื่องมือวิเคราะห์โค้ด หรือ Static Analyzer แต่มีเป้าหมายเพื่อเป็นสื่อกลางให้เครื่องมือเหล่านั้นดึงผลวิเคราะห์ส่วนสำคัญออกมาส่งต่อให้เครื่องมือตัวอื่นใช้งานร่วมกันได้ สรุปสั้นๆ คือ Kythe เป็นภาษากลางสำหรับแลกเปลี่ยนข้อมูลระหว่างเครื่องมือ ไม่ใช่ตัววิเคราะห์โค้ดเสียเอง
แนวคิดที่นำไปปรับใช้ได้ทันที แม้ไม่ได้ติดตั้ง Kythe
ครั้งต่อไปที่คุณต้องพัฒนาเครื่องมือสำหรับอ่านหรือวิเคราะห์โค้ด ไม่ว่าจะเป็น Linter สำหรับตรวจจับข้อผิดพลาดในโค้ด, สคริปต์สรุปโครงสร้างคลังโค้ด หรือระบบเตรียมบริบทสำหรับ Coding Agent ลองตั้งคำถามกับตัวเองก่อนข้อหนึ่งว่า: สถาปัตยกรรมของคุณกำลังแบกรับภาระที่โตตาม O(L×C×B) อยู่หรือไม่? วิธีสังเกตง่ายๆ คือ ถ้าต้องการรองรับภาษาใหม่เพิ่มขึ้นมาอีกหนึ่งภาษา คุณจำเป็นต้องแก้ไขทั้งส่วนที่อ่านวิเคราะห์โค้ดและส่วนที่แสดงผลพร้อมกันหรือไม่ ถ้าต้องแก้ทั้งสองส่วน แปลว่าคุณกำลังแบกรับต้นทุนแบบทวีคูณอยู่แน่นอน
ถ้าเป็นแบบนั้น ให้ลองแยกชั้นการดึงข้อมูลออกจากชั้นการแสดงผลตั้งแต่แรกแบบที่ Kythe ทำ โดยให้ชั้นหนึ่งมีหน้าที่อ่านโค้ดแล้วส่งข้อมูลออกมาในรูปแบบมาตรฐานกลางที่ไม่ผูกติดกับภาษาใด ส่วนอีกชั้นก็มีหน้าที่อ่านข้อมูลมาตรฐานนั้นไปประมวลผลหรือแสดงผลต่อ เมื่อแยกแบบนี้ การเพิ่มภาษาใหม่ก็มีภาระงานเพิ่มขึ้นแค่ฝั่งดึงข้อมูลฝั่งเดียว และในวันที่ข้อมูลของภาษาใหม่ยังได้มาไม่ครบถ้วน ชั้นแสดงผลก็ยังคงทำงานกับข้อมูลเท่าที่มีอยู่ได้อย่างราบรื่น
ในวันที่ระบบเติบโตจนมีโค้ดอยู่หลากหลายภาษา สิ่งที่โปรเจกต์ต้องการเพิ่มขึ้นมาอีกหนึ่งอย่าง อาจไม่ใช่ภาษาโปรแกรมใหม่ แต่เป็นภาษามาตรฐานกลางที่เครื่องมือพัฒนาทั้งหลายใช้สื่อสารร่วมกัน
ที่มา:
- เว็บไซต์ Kythe จาก Kythe (kythe.io)
- บทความ An Overview of Kythe จาก Kythe (kythe.io)
- หน้า Release v0.0.76 จาก kythe/kythe on GitHub
ชอบเรื่องแนวนี้ มีอีบุ๊คฟรีให้อ่านต่อ
NotebookLM ฉบับเข้าใจง่าย โยนเอกสารให้ AI อ่าน แล้วได้สรุป พอดแคสต์ และคลังความรู้ส่วนตัว
กดสมัครแล้วเราจะส่งเทคนิค AI และของแจกใหม่ๆ ให้ทางอีเมล เลิกรับได้ตลอด
Claude Cowork · The Business Playbook

ฉบับภาษาไทย 15 บท เรียนรู้ผ่านโปรเจกต์จำลองต่อเนื่องทั้งเล่ม ตั้งแต่ตั้งค่า Workspace จัดการไฟล์ เชื่อมแอป ตั้งระบบอัตโนมัติ จนถึงสร้าง Plugin


