JetBrains เปิดซอร์ส KotlinLLM — กลับด้านแนวคิด LLM ในโปรดักชัน ให้โมเดลเขียนโค้ด Kotlin ตอนรัน แล้ว hot-reload เข้า JVM ผ่าน JDI
ในขณะที่ทั้งวงการกำลังเถียงกันว่าจะเอา LLM ไปวางไว้ตรงไหนของแอปพลิเคชัน JetBrains Research เผยแพร่ KotlinLLM เมื่อ 28 กรกฎาคม 2026 (เขียนโดย Anastasia Birillo และ Stanislav Sandler — เราเขียนถึงช้าไปหนึ่งสัปดาห์) พร้อมคำตอบที่กลับด้านกับสิ่งที่ทุกคนกำลังทำอยู่: อย่าเอา LLM ไว้ใน request path เลย เอาไว้ใน compile path แทน
ปลั๊กอินนี้เป็นต้นแบบวิจัยสำหรับ IntelliJ IDEA บนโปรเจกต์ Kotlin/JVM ปล่อยภายใต้ Apache 2.0 ที่ JetBrains-Research/kotlinllm-plugin
Smart macro คืออะไร
แนวคิดหลักคือสิ่งที่ทีมเรียกว่า Smart macro — การเรียกฟังก์ชัน Kotlin ธรรมดาที่ ตัวบอดี้ของมันคือโค้ด Kotlin ที่ถูกสังเคราะห์ขึ้น API สาธารณะมีแค่สองตัว:
import com.jetbrains.kotlinllm.asLlm
import com.jetbrains.kotlinllm.mockLlm
val apiUrl: String = asLlm("JetBrains/kotlin", hint = "Return a GitHub issues API URL")
val service: GithubService = mockLlm()
asLlm<F, T>(from, hint)— แปลงค่าชนิดFเป็นค่าชนิดTที่มี type จริงmockLlm<T>()— สร้าง implementation ของ interfaceTที่พฤติกรรมค่อย ๆ วิวัฒน์จากการเรียกใช้จริงตอนรัน
จุดที่ต่างจากรูปแบบ “เรียก LLM ตอนรัน” ที่คุ้นเคยกัน README ระบุไว้ตรง ๆ ว่า KotlinLLM ไม่ได้เรียกโมเดลทุกครั้งที่ Smart macro ถูก invoke โมเดลถูกเรียกเฉพาะตอนที่โค้ดที่ถูกสร้างไว้แล้วรับมือเคสนั้นไม่ได้ เมื่อสำเร็จ พฤติกรรมนั้นจะถูกเก็บเป็น ไฟล์ Kotlin จริงในโปรเจกต์ และการรันครั้งต่อ ๆ ไปจะเอ็กซิคิวต์โค้ดนั้นตรง ๆ
ผลที่ตามมาคือสิ่งที่ทีมตั้งเป็นเป้าหมายออกแบบ: พฤติกรรมที่ LLM หนุนหลังต้อง ชัดเจนที่จุดเรียก, คงอยู่ในรูปซอร์สโค้ด, และพกพาได้เป็น Kotlin ธรรมดาเมื่อสร้างเสร็จแล้ว — นั่นคือ code review ได้ commit ลง git ได้ และถ้าวันหนึ่งอยากถอด LLM ออกก็แค่ลบปลั๊กอินทิ้ง โค้ดที่เหลือยังรันได้
ลูปวิวัฒนาการตอนรัน — และทำไมต้อง JVM
นี่คือส่วนที่วิศวกรรมน่าสนใจที่สุด เมื่อรันโปรเจกต์ผ่าน run configuration ของ KotlinLLM:
- ปลั๊กอินสแกนหาการเรียก
asLlmและmockLlmทั้งโปรเจกต์ - สร้าง/อัปเดตไฟล์ bootstrap, provider, parser และ mock ที่ถูกเจน
- ลอนช์ run configuration เดิม ภายใต้ JDI (Java Debug Interface)
- ตั้ง breakpoint ไว้ที่ regenerate hook ในโค้ดที่ถูกเจน
- ถ้าตรรกะเดิมไม่ตรงกับสถานการณ์ตอนรัน execution จะไปหยุดที่ hook นั้น
- ปลั๊กอิน ดึงค่าจริงและข้อมูล type ออกจาก frame ที่ถูก suspend ไว้
- LLM agent ได้เครื่องมือเฉพาะทาง — อ่านค่า, grep อินพุตก้อนใหญ่, ตรวจ target type, และส่ง code update กลับ
- ปลั๊กอินแทรก update ลงในซอร์ส คอมไพล์ แล้ว redefine คลาสที่โหลดอยู่
- รีทรายการเรียกเดิมกับ implementation ใหม่
เหตุผลที่ผูกกับ Kotlin/JVM ไม่ใช่ความชอบส่วนตัว — ทั้งลูปนี้ตั้งอยู่บน การ redefine คลาสของ JVM ผ่าน JDI ซึ่งเป็นความสามารถที่ runtime ส่วนใหญ่ไม่มี พูดอีกอย่างคือ JetBrains ใช้กลไก debugger ที่ตัวเองรู้ดีที่สุดในโลกมาเป็นเครื่องยนต์ของ self-modifying code ที่ยังตรวจสอบได้
ตัวเลขจากการประเมินในบล็อกประกาศ ทดสอบบนโปรเจกต์ Kotlin/JVM สองตัว:
- Spring Petclinic ฉบับดัดแปลง: ผ่าน 24 จาก 24 สถานการณ์ หลัง Smart macro วิวัฒน์ครบ โดยมีอัตราสำเร็จของ hot-reload 100%
- GitHub Issue Radar: recall ราว 0.89 ในงานจำแนก issue ที่เหมาะกับมือใหม่ บนชุดข้อมูลกว่า 30,000 issue
ข้อจำกัดที่ต้องรู้ก่อนตื่นเต้น
ทีมเรียกมันว่า prototype และ README ก็สะท้อนสถานะนั้นตรง ๆ:
- ต้องใช้ IntelliJ IDEA 2025.2.x (Gradle target ตรึงที่
2025.2.4) และ JDK 21 - ต้องมี OpenAI API key เก็บในไฟล์
.kotlinllmของโปรเจกต์เป้าหมาย ผ่านTools > KotlinLLM Settings— ปลั๊กอินคุยกับโมเดลผ่าน Koog เฟรมเวิร์ก agent ของ JetBrains เอง - โปรเจกต์เป้าหมายต้องคัดลอกไฟล์ API
KotlinLlm.ktเข้าไปในแพ็กเกจcom.jetbrains.kotlinllmด้วยตัวเอง - ต้องระบุ builds folder ให้ชัด ไม่งั้น hot-reload หาไฟล์คลาสที่คอมไพล์แล้วไม่เจอ
mockLlm<T>()ตั้งใจไว้สำหรับ interface เท่านั้น
repo ยัง push ล่าสุดเมื่อ 22 มิถุนายน — คือโค้ดนิ่งมาระยะหนึ่งก่อนจะประกาศเปิดซอร์ส นี่คืองานวิจัยที่เอามาแบ่งปัน ไม่ใช่ผลิตภัณฑ์ที่มีโรดแมป
มุมมอง AI Curator
ผมคิดว่า KotlinLLM สำคัญในฐานะ ข้อเสนอเชิงสถาปัตยกรรม มากกว่าในฐานะเครื่องมือที่จะได้ใช้จริงเร็ว ๆ นี้
ปัญหาที่มันโจมตีคือปัญหาที่ทุกทีมที่เอา LLM ขึ้นโปรดักชันเจอหมด และแทบไม่มีใครแก้ได้สวย: การเรียกโมเดลตอนรันคือการยอมรับ non-determinism, latency, ค่าใช้จ่ายต่อคำขอ และการพึ่งพา external service เข้ามาไว้ใน critical path ถาวร เราจ่ายสี่อย่างนี้ทุกรีเควสต์ ตลอดอายุของระบบ เพื่อความยืดหยุ่นที่ส่วนใหญ่แล้วต้องการแค่ตอนเจอเคสใหม่
ข้อเสนอของ KotlinLLM คือจ่ายมันครั้งเดียวต่อเคส แล้วเก็บผลลัพธ์ไว้เป็นโค้ด — คิดถึงมันเหมือน memoization แต่ memo ที่เก็บคือ implementation ไม่ใช่คำตอบ และเพราะสิ่งที่เก็บเป็นซอร์สโค้ดจริง มันจึงเข้ากันได้กับทุกอย่างที่วิศวกรรมซอฟต์แวร์สร้างมา 50 ปี: diff, review, test, rollback, audit
นี่คือสิ่งที่ผมอยากให้ทีมไทยที่กำลังจะขึ้น production คิดตาม โดยเฉพาะทีมที่งานหลักคือ การแปลงข้อมูลไม่มีโครงสร้างให้เป็นข้อมูลมีโครงสร้าง — พาร์สใบเสร็จ, อ่านเอกสารราชการ, ดึงฟิลด์จากอีเมลลูกค้า ซึ่งเป็นงาน AI ที่ใช้จริงและทำเงินจริงมากที่สุดในตลาดไทยตอนนี้ งานพวกนี้ส่วนใหญ่ ไม่ต้องการโมเดลตอนรัน มันต้องการโมเดลตอนที่เจอฟอร์แมตใหม่ ซึ่งอาจจะเดือนละครั้ง ทีมที่ยิง LLM ทุกใบเสร็จกำลังจ่ายค่าความยืดหยุ่นในอัตราต่อธุรกรรม ทั้งที่ควรจ่ายในอัตราต่อฟอร์แมต
ข้อควรระวังที่ต้องพูดให้ครบ: แนวคิดนี้ย้ายความเสี่ยงมากกว่าจะกำจัดมัน โค้ดที่ LLM เขียนแล้วถูก hot-reload เข้าโปรเซสที่กำลังรันอยู่ คือ arbitrary code execution ที่คุณเซ็นอนุมัติเอง ถ้ารันแบบนี้ในสภาพแวดล้อมโปรดักชันจริงโดยไม่มีมนุษย์รีวิว diff ก่อน คุณได้สร้างช่องทางที่ prompt injection ผ่านข้อมูลอินพุตกลายเป็นโค้ดที่รันบนเซิร์ฟเวอร์ได้ — ซึ่งเชื่อมโดยตรงกับข้อมูลที่เราเขียนถึงในโพสต์อีกชิ้นวันนี้ว่า เครื่องมือนักพัฒนาติดอันดับสามของกลุ่มที่ถูกโจมตีจริง โมเดลการใช้งานที่ปลอดภัยคือให้ลูปวิวัฒน์อยู่ในเครื่อง dev หรือ CI แล้ว commit ผลลัพธ์ผ่าน PR ปกติ ไม่ใช่ปล่อยให้มันวิวัฒน์เองบน production
ถ้าถามว่าจะได้เห็นแนวคิดนี้แพร่หลายไหม — ผมคิดว่าใช่ แต่จะไม่ใช่ในรูปปลั๊กอิน IntelliJ มันจะโผล่มาในรูป “AI codegen ที่ commit ผลงานตัวเองลง repo” ซึ่งเป็นทิศทางที่ coding agent ทุกเจ้ากำลังเดินอยู่แล้ว ส่วนที่ JetBrains เติมเข้ามาและยังไม่มีใครทำ คือการทำให้ลูปนั้น ปิดตัวเองได้ตอนรัน จาก stack frame จริง พร้อมค่าจริง แทนที่จะปิดจากคำอธิบายของมนุษย์ — และนั่นคือส่วนที่ควรจับตา
แหล่งข่าว
อ่านเพิ่มในหมวด เครื่องมือนักพัฒนา
Betelgeuse รัน Qwen3.8 Flash Next ขนาด 68GB บน RTX 3060 กับแรม 16GB ส่วน Basalt วัดให้เห็นว่าเอนจินที่เร่งด้วยแฟล็กลัดทำให้โมเดลลืมของ
Betelgeuse ฟอร์ก llama.cpp ที่เปิดเมื่อ 31 ต.ค. ดึง expert จาก NVMe เข้า VRAM ตามต้องการ อ้าง 22 tok/s แบบไม่ทิ้ง expert แต่ README เตือนเองว่ายังทดลองและตัวเลขมาจากคนละรอบ วันเดียวกันผู้พัฒนา Basalt เผยผลวัดว่าแฟล็กเร่งความเร็วทำคุณภาพ Q8 ตกไปใกล้ Q2
กฎห้ามโคลนเกมของ Claude Code เริ่มกระทบงานจริง บริษัทรับทำเกมกระดานร้องงานลูกค้าหยุด แต่รายงานหลายชิ้นปนกับตัวกรองไซเบอร์คนละเรื่อง
ต่อจากที่เราพบกฎนี้ในไบนารี Claude Code ผู้ใช้เริ่มรายงานว่างานเชิงพาณิชย์ถูกปฏิเสธ และ Tom's Hardware กับ Mashable หยิบไปรายงาน แต่เมื่อไล่ issue ที่อ้างถึง พบว่าหลายรายการเกิดก่อนกฎจะมา จึงน่าจะเป็นตัวกรองด้านไซเบอร์ ส่วน Anthropic ยังไม่ชี้แจง
Claude Code ส่ง transcript ของ background agent ให้โมเดลทุก ~30 วินาทีเพื่อเขียนสถานะ 3–5 คำ ผู้วัดรายงานกินราว 16% และยังปิดแบบทางการไม่ได้
รายงานอิสระพบว่าฟีเจอร์ agent_summary ของ Claude Code ส่ง transcript เต็มของ background agent ไปถามสถานะทุก ~30 วินาที คิดเป็น 16.4% ของค่าใช้จ่ายในระบบของผู้วัด Issue เปิดมาตั้งแต่ ส.ค. ยังไม่มีสวิตช์ปิดที่รองรับ เราตรวจพบโค้ดนี้ใน 2.1.314 และพบกฎใหม่เรื่องเกมที่ไม่อยู่ใน changelog