chuatungyeu.ai
Tầm mấy năm đầu 2020, trước khi ChatGPT ra lò thì cũng có khá nhiều các discussion về các thể loại AI startup, nào là ứng dụng AI trong cái nọ cái kia.
Cũng là người theo tech và data, thì mình chỉ đùa với bạn bè mình là mình nên lập một cái startup rồi mua cái domain chuatungyeu.ai
, chưa biết đến làm gì nhưng mà chắc chắn là funny. Bạn có biết tên miền .ai là của một lãnh thổ hải ngoại của Anh tên là Anguilla, và revenue họ thu được từ việc bán tên miền đuôi .ai chiếm 10% GDP của họ không?
Đi nhanh đến những năm gần đây, thì các câu chuyện về AI xuất hiện đều đến chóng mặt. Đương nhiên, để nói đúng thì phải nhắc đến nó là LLM, nhưng mà bây giờ thì qua các loại báo chí, trang tin mạng đi qua đi lại rồi thì mọi người chỉ có một khái niệm duy nhất đó là AI. Khác với những cái AI mà ngày xưa mình từng biết (DotA Allstars v6.48b AI+ 1.52 anyone?) thì bây giờ mọi người sẽ nghĩ đến chatbot, đến agent hoạt động để chạy các tác vụ nọ kia.
Bản thân mình thì mình thấy các cuộc tranh luận như kiểu con AI nào thông minh hơn con nào nó cũng không quá quan trọng, mà mình thì quan tâm vào hai thứ chính: một là công nghệ đi kèm với nó, và hai là tính ứng dụng thực tế của nó. Công nghệ đằng sau nó thì rất hay rồi, và mình vẫn khá là hóng theo dõi các biến đổi mới về công nghệ hay quy trình đằng sau, tăng hiệu suất hay công năng gì đó.
Nhưng ứng dụng thực tế thì lại không được như thế. Một công cụ rất nhanh để trả ra những nội dung gần giống với người thực, điều đầu tiên mình nhận thấy đó là mọi người dùng nó để spam. Rồi đến các tranh cãi về vấn đề bản quyền nội dung, rồi tác hại lên khả năng nghiên cứu đọc hiểu của người dùng, cũng như các yếu tố liên quan đến môi trường, vân vân.. Cảm giác của mình như thể nó là một sản phẩm rất mạnh nhưng vẫn chưa được hoàn thiện; và độ mở của nó quá cao nên là chưa có một cách dùng nào là hoàn toàn đúng, mà lại dễ có thể bị exploited bởi các cá nhân xấu.
Coding cũng là một phần trong đó, cũng như các câu chuyện về việc các CEO yêu cầu nhân viên phải biết sử dụng GenAI, về việc các coder có thể bị thay thế.. đó là những câu chuyện cũng gần với mình, gần với ngành của mình và những người mình quan tâm. Nhưng, cũng chính những người bạn, người senior của mình có một góc nhìn khá là lạc quan, và cũng đánh giá khá cao Cursor, làm mình bắt buộc phải có một góc nhìn đánh giá khác. Phải thử mới biết được, và mình bắt tay vào thử start một cái project với Cursor xem sao.
Hai tiếng và 1 vạn dòng code
Mọi người thì có nói về vibe coding, về việc chỉ dùng AI để tạo ra code, và là một cách để các bạn amateur coder có thể nhanh chóng tạo ra được sản phẩm. Tuy nhiên khi bạn đã trải qua cuộc đời coder rồi thì sẽ hơi khó để chuyển lại bản thân thành một amateur coder một lần nữa mà chỉ giải thích về tính năng, thế nên cuối cùng mình vẫn thấy cách mình sử dụng nó vẫn có một chút cồng kềnh corporate.
Cho quen thuộc với những thứ mình có đụng đến gần đây thì mình thử tự mày mò làm một cái backend server với Golang (có thể đoạn dưới mình sẽ viết hơi specific với Golang và backend server một xíu)
Mình prompt đơn giản từ đầu “I want to build a Golang backend server for a web application”. Ngay lập tức cursor đã vẽ ra 3000 dòng code đầu tiên, khá đúng với cấu trúc repo được suggested của 1 Go backend, với Backend là Postgres và Router dùng Gin. Code cũng viết sẵn ra 1 data model với tên là User và có 1 cái handler đơn giản.
Chuyển sang sử dụng
gorilla/mux
làm Router và dùng mysql backend (Cursor cũng làm phần này khá là mượt, và mình cũng bắt đầu impressed với tốc độ làm việc của nó).DB credentials đang được hardcoded vào trong
main.go
luôn → đổi sang lấy config từ environment variables, đồng thời tạo ra một file.gitignore
căn bản cho repo.Thay đổi lại cấu trúc folder để sử dụng handler/service/repository pattern.
Thêm context object cho tất cả các function call.
Tạo file
README.md
Thay việc sử dụng mysql library, thì chuyển sang dùng
GORM
làm ORM layer. Cả model Users cũng được update luônThêm pre-commit hooks, để check linter và các lỗi thường gặp trước khi commit
pre-commit
được cài qua terminal khá là chính xác, tuy nhiênpre-commit-config.yaml
được tạo ra thì không, nó mất khoảng 2-3 lần để ra một cái bảnpre-commit
ngắn gọn và chạy được.pre-commit bắt đầu bắt được các lỗi:
lúc chuyển qua
gorm
, thì vẫn chưa bỏ đi functionDB.close()
khi dùng go-mysqlgorm
thì sử dụnguint64
, nhưng mà code ban đầu được tạo ra lại dùng userID bằnguint
→ mất một vài bước để sửa
Tạo Dockerfile với multistage build
Tạo startup flag
—run-migration
để có thể chạy gorm migration ở startupcần chỉnh thêm để migration script chạy đúng, vì phải pass thêm AutoMigration flag trong code
Tạo thêm 1 model mới topics (idea đang là một câu hỏi và nhiều câu trả lời, mình đang thử với topics - topic-options mapping)
Tạo thêm repo và service layer cho model này
Tạo thêm handler cho topics
Ở đoạn này thì mình nhận ra là code đang đi theo REST convention, với DELETE và PUT endpoints. mình request đổi hết từ PUT sang POST
Thêm 1 trường vào topic model, và cascade field đó ra tất cả các endpoint
Build swagger doc
Go version mình báo lỗi ở đây vì không compatible, mình phải fix ở ngoài chứ cursor chưa tự sửa được.
Tạo một model mới topic-options, map với 1 topic nhất định
Cursor mất 1-2 lần ở đây để tạo ra được model chính xác với ReferenceKey sang table Topics
Tạo thêm các handler, repo và service layer tương ứng, với thêm 1 function là
GetOptionsByTopic
sẽ pass thêm trườngtopicID
Cursor bắt đầu tạo ra một folder utils để tái sử dụng một số HTTP function, tuy nhiên đoạn code này bị viết sai nên mất 2-3 lần nó mới handle được HTTP code đúng.
Để làm đúng best practices, mình build một cái
Makefile
. Cursor cũng generate ra đúng các options cần thiết để chạy 1, có đầy đủbuild
,run
,migrate
,swagger
, vân vânMỗi lần thêm code mới thì swagger
docs.go
sẽ tự generate, và cái swagger file chạy tốn quá nhiều thời gian. Mình cũng force Cursor là không tự chỉnh swagger file mà chỉ update swagger bằng make swagger call.
Chạy thử application, tuy nhiên code fail luôn vì không có DB
request để start một cái docker mysql. Cursor suggest chạy
docker-compose
, tuy nhiên nó không làm được vì nó không connect được 2 cái docker với nhau (không biết cách tạo docker network)khi chỉnh lại để chạy chỉ 1 docker mysql thôi thì cũng work
Cursor không tự xoá code của
docker-compose.yaml
, mà phải yêu cầu nó xoá. Qua đó mình cũng nhận ra là cáirevive.toml
linter được cài từ trước nhưng rồi bị bỏ đi trong pre-commit cũng chưa được loại bỏ → cũng phải yêu cầu xoá
Thêm option
db-up
vàdb-down
choMakefile
Phải yêu cầu lấy thông tin từ
.env
, vì ban đầu nó cũng hardcode db credentials vàoMakefile
luônthêm option
make restart
, vì khi chạymake run
thì nó start lại db từ đầu
Thêm option để seed cái DB với fake data. Bổ sung thêm
seed
vàforce-seed
cho MakefileSeeding function chạy nhưng không terminate service mà dừng cứng lại. Viết lại code để dừng process sau khi chạy seed
Code đã lên và start server, nhưng chạy thử thì không thấy gì → add thêm API log ra stdout vì có vẻ trước đó chưa có option này
Start được server và lần này call thử API → server trả về lỗi
Cursor thử suggest 1 số fix nhưng có vẻ không có cái gì đúng.
Nhận ra là Cursor lúc viết code thì có cả
repository
vàrepositories
,service
vàservices
,handler
vàhandlers
nên là nó vừa không chạy mà lại không tự fix được → bắt viết lại hết và merge 2 folder cho đúng cấu trúc
Sau cùng, start được service, và chạy được code từ đầu đến cuối. Mình bắt đầu chỉnh các API call, thay đổi các logic một chút.
Cuối cùng thì sau khoảng 2h thì mình có 1 cái service khá là okie, đầy đủ tool cũng như workflow để tiếp tục coding. Cũng có thể là do trình độ prompt của mình vẫn chưa quá xịn xò, nhưng mà mình vẫn có thấy được các cái lỗi Cursor mắc phải nó cũng khá là dị.
Trải nghiệm và nhận định
Một điều chắc chắn phải nói là Cursor thì tăng tốc độ tạo ra code lên rất nhiều, và nếu mà mình biết mình làm gì thì có thể điều khiển được hướng đi của cái IDE khá là hiệu quả. Một phần là nó “ngoan” hơn con người rất nhiều, nên là có bảo nó viết lại cả những đoạn code rất dài nó cũng không hề ngại, đặc biệt là với các boilerplate code thì nó đi vèo vèo với tốc độ ánh sáng. Bình thường ngồi vừa code vừa copy paste vừa tab mệt nghỉ thì mình cũng không thể code 1000 dòng trong vòng một tiếng được, vậy mà bây giờ mình lại có thể làm được, mà mình cũng không nghĩ mình là một coder quá là xịn xò.
Điều nữa mình nhận thấy là về việc review code. Ngày xưa các coder luôn có cái meme, đó là nếu merge request có 10 dòng thì sẽ bị 10 cái comments, còn MR mà có 1000 dòng thì sẽ LGTM (looks good to me). Cảm giác khi lượng code đi ra nhanh như vậy, thì với bản thân mình là người đọc code, cũng sẽ dễ rơi vào tình trạng tương tự. Truyền thống, bạn có thể code được 100-200 dòng trong 1 giờ deepwork, thì trong thời gian 1 tiếng đó cũng là thời gian bạn nghiền ngẫm 200 dòng code đó; vừa làm vừa suy nghĩ vừa review. Khi tốc độ code đi ra quá cao, và phải review 1000 dòng code của AI trong vòng 1h đồng hồ sẽ trở thành việc rất là quá sức với bạn. Điều đó dễ dẫn đến việc lười và bỏ qua các chi tiết lặt vặt, và khả năng dẫn đến các bugs là khá cao.
Chính vì điều đó, thì mình đánh giá là với người đã từng viết và đọc càng nhiều code, thì sẽ trở thành những người sử dụng AI hiệu quả hơn. Khi bạn còn là junior, thì bạn sẽ đọc code chậm vì chưa biết cách hệ thống, chưa biết cách theo dõi, cũng như chưa có nhiều kinh nghiệm để có thể biết cách bỏ qua những thứ nhỏ nhặt lặt vặt không cần thiết. Những con người đã trải nghiệm và viết càng nhiều code, thì những phản xạ đó lại trở nên tốt cho họ: họ biết cách theo dõi code, biết cách sử dụng IDE thành thạo, nhìn qua những đoạn code quen thuộc có thể hiểu tác dụng ngay. Họ cũng biết sử dụng thêm các hệ thống tool khác, với optimized workflow, ví dụ như automated linters, code checkers, để tăng tốc độ làm việc của bản thân lên nhiều lần. Thế nên, bạn càng tự code tay nhiều, thì bạn lại dùng AI code càng hiệu quả.
Một mặt khác, khi nói về code với AI và ra sản phẩm nhanh chóng, thì mình nghĩ đây cũng sẽ dẫn đến một sự thay đổi về cách phát triển của tech business. Ngày xưa, điểm mạnh của Tech luôn được đánh giá là nằm ở giai đoạn start: asset-light, không cần inventory gì nhiều, ở trên một mảnh đất Internet chưa chật chội. Có technical skills là một lợi thế rất lớn cho việc start một business mới. Tuy nhiên, đến thời nay thì Tech lại không mang lại lợi thế nữa: Internet đã chật chội hơn, và bạn không cần technical skills để có thể bắt đầu nữa (barrier to entry đã giảm xuống nhiều). Cũng tương tự như thế, khả năng defense các startup cũng sẽ giảm xuống, vì nếu bạn đã có ý tưởng và được người khác biết đến, thì họ có thể áng chừng và “copy” bạn một cách nhanh chóng hơn, nhờ các công cụ mới hiện giờ. Tech skills, bây giờ lại trở thành một lợi thế ở giai đoạn scale up: với 10-100 users thì ai cũng có thể viết ra được sản phẩm, tuy nhiên khi con số lên đến hàng ngàn hàng vạn, thì bắt đầu các kiến thức tech sẽ có giá trị hơn rất nhiều. Tech sẽ không giúp bạn start trước, nhưng sẽ là thứ giúp bạn chiến thắng trong cuộc đua đường dài.
Kết
Một chút trải nghiệm của bản thân mình, và cũng là những thứ mình nhận ra sau khi thử trải nghiệm Cursor. Thế giới đang thay đổi, và bổ sung những trải nghiệm cho bản thân sẽ là cách để bạn có thể ngẫm trước về tương lai