7 điểm bởi chebread 2026-01-29 | 12 bình luận | Chia sẻ qua WhatsApp

Mở đầu

Xin chào. Mình là một sinh viên có hứng thú với ngành khoa học máy tính. Gần đây mình đã phát triển một chương trình tên là lx, nên muốn lần đầu đăng bài trên GeekNews — nơi trước giờ mình chỉ đọc bài.

Dạo gần đây, vibe coding — nơi bạn ra lệnh cho AI bằng ngôn ngữ tự nhiên và nó tự viết toàn bộ mã — đang trở thành xu hướng.
Mình cảm thấy sợ kiểu vibe coding này.
Không chỉ đơn giản là nỗi sợ thất nghiệp, mà còn là cảm giác mất mát trong lập trình khi chúng ta đang bị tước đi “niềm vui viết code (Wrangling code) (nguồn: Kent Beck - Augmented Coding: Beyond the Vibes)” và “quyền kiểm soát của lập trình viên”.

Có người cho rằng sự thay đổi lần này là bước tiến hóa tự nhiên của lập trình, từ thẻ đục lỗ sang mã máy, hợp ngữ rồi C. Nhưng mình nghĩ phép so sánh đó là sai.
Những tầng trừu tượng trong quá khứ là quá trình trao cho lập trình viên “một chiếc búa tốt hơn”.
Công cụ liên tục tiến hóa, nhưng chủ thể vung búa vẫn luôn là con người, và kết quả hoàn toàn nằm trong sự kiểm soát của lập trình viên.
Nhưng AI coding ngày nay thì khác.
Giờ đây robot vung búa thay chúng ta, còn lập trình viên chỉ đứng xem, hoặc nhiều lắm là cố dỗ dành robot một chút.
Nếu chúng ta không thể tự vung búa, thì mình cho rằng đó không còn có thể gọi là lập trình nữa.
Bởi vì nó không hoàn toàn nằm dưới sự kiểm soát của chúng ta.

Vì vậy mình đã tạo ra lx.
lx là công cụ giành lại chiếc búa từ tay robot và đặt nó trở lại vào tay lập trình viên.
lx giúp bạn sử dụng AI như một công cụ có thể bị kiểm soát triệt để.

Nội dung chính

lx có triết lý: “giao diện do con người, logic do AI”.
Lập trình viên định nghĩa đầu vào/đầu ra của hàm và công việc mà hàm đó thực hiện để thiết lập một “hợp đồng”, còn AI chỉ phụ trách phần hiện thực bên trong hàm.

Cách tiếp cận này đảm bảo tính liên tục trong quá trình phát triển.
Ngay tại thời điểm viết đầu vào/đầu ra của hàm, logic đó đã được xem như hoàn thành.
Lập trình viên không bị sa lầy vào chi tiết triển khai mà có thể lập tức viết logic cấp cao hơn, giữ cho luồng phát triển không bị gián đoạn.

Ngoài ra, lx không phải là thay thế văn bản đơn thuần. Nó dùng gói github.com/tree-sitter/go-tree-sitter để phân tích mã nguồn dựa trên AST (cây cú pháp trừu tượng). Vì vậy nó không làm nhiễm bẩn mã khác trong tệp, comment hay thụt lề, mà chỉ thay thế an toàn phần logic trong đúng scope được chỉ định.

Cách dùng cơ bản

Dạng sử dụng cơ bản của lx như sau.

package main  
  
import (  
	"fmt"  
  
	lx "github.com/chebread/lxgo"  
)  
  
func main() {  
	var year string = "2025-01-02"  
    // Lập trình viên kiểm soát phần gọi hàm và luồng xử lý.  
	result1 := LX_GetYear(year)  
  
	var age = 30  
	result2 := LX_GetAge(age)  
  
	fmt.Println(result1, result2)  
}  
  
func LX_GetYear(year string) (result string) {  
	// Prompt sẽ được truyền cho AI  
	lx.Generate("chuyển định dạng yyyy-dd-mm sang ngày tháng kiểu Hàn Quốc")  
	return  
}  
  
func LX_GetAge(year int) (result string) {  
	// Để dành cho trường hợp ngại phải cài riêng thư viện lx theo từng ngôn ngữ lập trình, bên dưới cũng hỗ trợ dạng marker comment lx().  
    // lx("chuyển tuổi kiểu Hàn Quốc sang tuổi quốc tế")  
	return  
}  

Trong đoạn mã trên, hàm LX_GetYear là hợp đồng do lập trình viên định nghĩa.
Khi chạy công cụ lx, nó sẽ nhận diện lx.Generate(...) hoặc marker // lx(...), gửi prompt tới LLM, rồi ghi đè phần thân hàm đó bằng mã thực sự hoạt động.

Lúc này sẽ có tối ưu token. Thay vì gửi toàn bộ tệp, chỉ chữ ký hàm và prompt của hàm đó được gửi tới LLM, giúp giảm chi phí và tăng cường bảo mật.

2. Quyền kiểm soát của lập trình viên

Logic bên trong hàm lx do AI viết, nhưng chủ thể sử dụng hàm đó vẫn phải là lập trình viên.
Tuy nhiên, nếu trộn logic tự định nghĩa vào bên trong hàm lx thì sẽ bị bỏ qua, nên bạn có thể kiểm soát bằng hàm bọc như dưới đây.

package test  
  
import (  
	"fmt"  
	lx "github.com/chebread/lxgo"  
)  
  
func main() {  
	var year string = "2025-01-02"  
	result1 := ParseYear(year) // Gọi hàm wrapper  
  
	fmt.Println(result1)  
}  
  
// Logic nghiệp vụ do lập trình viên kiểm soát  
func ParseYear(year string) string {  
    // Dùng logic do AI tạo ra như một linh kiện  
	res := LX_GetYear(year)  
    
    // Phần xử lý bổ sung cho kết quả là phần của lập trình viên  
	foo := fmt.Sprintf("Hôm nay là %v!", res)  
	return foo  
}  
  
func LX_GetYear(year string) (result string) {  
	lx.Generate("chuyển định dạng yyyy-dd-mm sang ngày tháng kiểu Hàn Quốc")  
	return  
}  

3. Quản lý phụ thuộc an toàn và tính minh bạch

lx hướng tới nguyên tắc trách nhiệm đơn nhất (SRP).
Nó chỉ tạo mã, không build hay chạy chương trình.
Ngoài ra, nếu mã do AI tạo ra cần thư viện bên ngoài, lx cũng không tự ý cài package.

  1. Code: ghi comment // lx-dep: ... ở đầu đoạn mã được tạo

  2. Output: báo cáo danh sách cần cài đặt qua standard output của CLI

Thay vào đó, nó báo cho lập trình viên theo hai cách này.
Lập trình viên có thể kiểm tra và tự quyết định có cài dependency hay không.

4. Cấu hình

Để dùng lx, bạn cần cấu hình LLM. Chỉ cần tạo lx-config.yaml trong thư mục home (~/) hoặc thư mục gốc của dự án (./). Nếu cả hai đường dẫn đều có tệp, cấu hình local sẽ được ưu tiên áp dụng, vì vậy bạn có thể quản lý cấu hình lx khác nhau cho từng dự án.

# lx-config.yaml  
provider: "gemini"  
api_key: "foo"  
model: "bar"  

5. Cài đặt và chạy

Người dùng Mac có thể cài qua Homebrew, còn các OS khác có thể tải binary từ GitHub Releases của lx để cài đặt.

brew tap chebread/lx  
brew install lx  

Sau khi cài xong, chạy lệnh lx tại đường dẫn dự án là mã thực tế sẽ được tạo ra.
lx có tính năng tạo thông minh, nên với những hàm đã được tạo mã, nó sẽ không gọi lại LLM. Vì vậy bạn có thể yên tâm chạy lặp lại lệnh lx.

Lưu ý: để format mã được tạo ra, lx sử dụng các công cụ theo từng ngôn ngữ (Go: goimports, Python: ruff, JS: prettier). Những công cụ này cần được cài sẵn từ trước.

6. Giấy phép

lx được phát hành theo giấy phép AGPL-3.0 License.
Mục đích là để lx đóng góp cho hệ sinh thái mã nguồn mở, đồng thời ngăn công cụ này bị tư hữu hóa theo hướng đóng kín.

Kết luận

Phần mềm là kết tinh được dệt nên từ những nỗ lực bền bỉ của con người. Ngay cả trong thời đại AI, lập trình viên vẫn phải là chủ nhân của mã nguồn.
lx cho phép giao cho AI những “triển khai nhàm chán” như regex phiền phức hay parsing dữ liệu, trong khi cấu trúc và luồng của chương trình vẫn do con người nắm giữ hoàn toàn.
Mình xin giới thiệu công cụ này tới những lập trình viên không muốn đánh mất niềm vui viết code (Wrangling code) và quyền kiểm soát!

12 bình luận

 
moderator 2026-01-31

Theo chính sách vận hành, bình luận không phù hợp đã bị xóa và tài khoản liên quan đã bị hạn chế sử dụng.

 
callakrsos 2026-01-30

Hiện tại việc lập trình về bản chất cũng vẫn dựa trên tiêu chuẩn của con người
Trong tương lai có lẽ sẽ được phát triển dưới một dạng không phải là ngôn ngữ theo tiêu chuẩn con người kém hiệu quả
Hãy tận hưởng thật nhiều các framework theo tiêu chuẩn con người ở thời điểm hiện tại

 
galadbran 2026-01-31

Điều này rất thú vị vì nó tiếp cận hoàn toàn ngược lại với bầu không khí dạo gần đây rằng phải gần như không nhìn vào code thì mới làm đúng kiểu đó.
Tùy cách lựa chọn, có vẻ cũng có thể dùng nó chỉ như một cách để xác định thật rõ những phần mà AI được phép can thiệp.
Có lẽ thử biến nó thành kỹ năng cho các coding agent cũng sẽ khá ổn đấy nhỉ?

 
chebread 2026-01-31

Tôi sẽ tích cực xem xét. Nếu bạn quan tâm, rất mong nhận được nhiều PR!

 
narubrown 2026-01-30

Có vẻ là một dự án thú vị!

Viết đặc tả lx -> dùng Ix Tool để thay các hàm lx thành hàm thật -> rồi biên dịch bằng Go.
Khi trong dự án xuất hiện một layer dùng lx,
có vẻ sẽ có thể tách riêng phần layer được viết bằng LLM, nên về sau khi bảo trì cũng sẽ thuận tiện hơn.

Có vẻ đây là một thử nghiệm thú vị sử dụng LLM!

 
chebread 2026-01-30

Cảm ơn bạn. lx cũng hỗ trợ các ngôn ngữ ngoài Go, nên rất mong nhận được nhiều sự sử dụng và góp ý từ mọi người!

 
iknowca 2026-01-30

Mục tiêu thì thú vị đấy, nhưng xuyên suốt bài viết đều có cảm giác rất rõ về văn phong đặc trưng của AI
nên khó mà tin tưởng được.

 
chebread 2026-01-30

Bạn nói rất đúng. Vì tôi còn là học sinh trung học nên không có nhiều thời gian, và trong lúc tận dụng AI để viết bài, nội dung đã bị biến thành những bài có độ tin cậy giảm đi khá nhiều. Dù có thể hơi bất tiện, mong bạn thông cảm.

 
wegaia 2026-01-31

Wow, thật quá ấn tượng khi một học sinh trung học lại nghĩ ra được thứ như thế này.
Khi tích lũy thêm kinh nghiệm, có lẽ bạn ấy sẽ còn tạo ra những điều tuyệt vời hơn nữa.

 
siabard 2026-01-30

Có đúng là khi mã gọi lx.Generate đưa ra lệnh từ dòng lệnh thì nó sẽ được thay thế bằng đoạn mã do LLM viết ra phải không?
Phần gọi đó có thể đóng vai trò như một dạng ràng buộc kiểu, nên tôi thấy đây là một ý tưởng hay. Tôi cũng tò mò không biết anh/chị có đang cân nhắc cách để lệnh lx được tự động chạy trong editor chẳng hạn, rồi thay thế phần mã triển khai hay không. (Ngoài ra, sẽ rất tốt nếu có cách tạo lại khi không ưng đoạn mã đã được sinh ra.)
Tôi đã xem dự án rất thú vị.

 
chebread 2026-01-30

Ý là đoạn mã gọi lx.Generate sẽ được thay thế bằng mã do LLM viết khi ra lệnh từ dòng lệnh, đúng không? -> Vâng, đúng vậy!

Phần gọi đó có thể trở thành một dạng ràng buộc kiểu là một ý tưởng hay. Tôi cũng tò mò không biết các bạn có cân nhắc cách để lệnh lx được tự động chạy trong editor v.v. rồi thay thế mã triển khai hay không. -> Đây quả là một ý tưởng rất hay. Chúng tôi sẽ tích cực tham khảo.

Ngoài ra, sẽ rất tốt nếu có cách tạo lại khi không ưng ý với mã đã được sinh ra. -> Vì triết lý của dự án là AI dưới sự kiểm soát của nhà phát triển, nên nếu cần tạo lại thì chúng tôi đã thiết kế để bạn tạo lại marker lx một lần nữa.

 
maneuling 2026-01-30

Nhìn cái mức bình luận lao vào gắng gượng để lại sau khi thấy một học sinh cấp ba nhỏ tuổi làm ra thứ này là cũng đủ biết trình độ nhận thức đến đâu rồi.

Hãy soi gương rồi đi chữa trị đi.

killdong | 9 tháng trước | parent | on: Tôi dùng bom ZIP để bảo vệ máy chủ của mình (idiallo.com)
Tôi nghĩ rằng nếu ngay cả trên Internet cũng không phải chịu trách nhiệm cho thứ mình thải ra thì nên bị cấm dùng Internet. Đã thải ra rồi thì hãy tự dọn dẹp đi.