Quy trình code với LLM
Đầy đủ các công cụ và phương pháp mình vắt cực khô LLM: đặc tính mô hình, cách tận dụng, chọn tool nào để làm gì.
Mục lục
Đầu xuân năm Bính Ngọ, đất trời hân hoan. Tiện tranh thủ khai bút, mình viết luôn một bài đăng chia sẻ cách mình sử dụng LLM để code, cũng coi như một cái mốc để mình nhìn thử xem sau sáu tháng, hoặc một năm nữa, AI sẽ phát triển như thế nào nhé.
Bối cảnh
Mình chủ yếu code web, động tay chân với NextJS và Typescript. Trước đây phải ngồi đọc docs và sửa syntax rất khổ, mất thời gian setup codebase. Nhờ có LLM, thay vì mất thời gian vào language syntax và viết test case, mình đã có nhiều thời gian để tập trung vào những thứ căn bản hơn, như phân tích thiết kế và system design. Mình cũng lần đầu tiên bắt đầu đi phân tích đề bài và đi khảo sát người dùng để xây dựng sản phẩm phù hợp thị trường.
Mình theo dõi quá trình phát triển của các công cụ LLM từ năm 2022. Trong suốt 4 năm, workflow của mình, cũng như quan điểm về LLM thay đổi liên tục để thích ứng với công cụ mới. Ban đầu mình chỉ để LLM sửa linh tinh vớ vẩn, còn hiện tại một số tính năng nhỏ đã có thể để LLM chạy không cần duyệt.Cứ mỗi ba tháng lại có một mô hình mới vượt trội hơn, làm được nhiều việc hơn trước, nhưng cho đến hiện tại, mình cảm thấy đặc tính của các mô hình cũng tương đối ổn định. Giống như là mỗi một mô hình sẽ có một tính cách vậy.
Mình cũng cảm thấy khá may mắn, vì thời gian mình còn code C++ và cày DSA thuần chay thì LLM chưa phổ biến như hiện tại. Nhờ những “khó khăn” đó mà mình có thể nhanh chóng bù khuyết những tác vụ LLM chưa làm tốt mà không bị lệ thuộc. Code từ LLM viết chuẩn chỉ syntax, nhưng mình phải dành nhiều thời gian để review business logic và phân tích thiết kế hơn. Mình vẫn sợ LLM thay thế mình, vì trình độ mình yếu, học nghệ chưa tinh, mình phải học system design và architecture để chuyển dịch vai trò từ người triển khai sang người ra quyết định. Mình thấy gian khổ lắm, nhưng mà phải sống chết với nghề thôi. Suy cho cùng, nhiệm vụ của kỹ sư là giải quyết vấn đề mà.
Má nó, từ ngày dùng LLM, chưa thấy nhàn đi, chỉ ước một ngày có 48 tiếng để làm được nhiều việc hơn.
Công cụ sử dụng
Mô hình LLM
Các model mình thường xuyên sử dụng là Anthropic Claude (Opus 4.5, Sonnet 4.5, Haiku), Google Gemini (Gemini 3 Pro, Gemini 3 Flash).
Họ Anthropic Claude
Theo trải nghiệm cá nhân của mình
- Cladue Opus 4.5 phân tích đề bài và lập kế hoạch rất tốt.
- Sonnet 4.5 có thể dùng để sửa một vài bug nhỏ.
- Haiku thì thôi … thực sự là mô hình này vẫn hơi phế, mình nghĩ là cần phải finetune để function calling hoặc call tool tốt hơn, chứ diff edit và code tạo ra từ mô hình vẫn chưa đủ tốt.
Họ Google Gemini
So với Claude, các mô hình của Google (Gemini 3 Pro, Gemini 3 Flash) cho kết quả chấp nhận được, hợp lý với chi phí, hoặc do mình quen với mức giá cắt cổ từ Anthropic, nên giá token của Google đúng nghĩa rẻ gần như cho. Cũng phải thôi, Google không cần mua chip từ NVIDIA.
- Gemini 3 Pro có 1M context window, đọc codebase lớn rất tốt, tuy nhiên khi suy luận phức tạp thì bắt đầu trả về nội dung sai loạn, lặp lại nội dung.
- Gemini 3 Flash sửa code, gọi tool rất tốt, nhưng cũng gặp phải vấn đề trên, đặc biệt là thường xuyên đi lệch vấn đề, phải cầm tay chỉ việc rất nhiều chứ không one-shot được như Claude.
Điểm chung của 2 mô hình này là ảo giác mạnh, cần grounding. Mình giảm bớt ngẫu nhiên bằng cách tận dụng tính năng research sẵn có, hoặc review trên codebase cho trước, nhìn chung phải mớm context. Mình cũng tận dụng ảo giác của Gemini để brainstorm hoặc làm giao diện rất ổn. Còn để code 1 feature lớn thì nah.
Sinh viên tiết kiệm chi phí nên tháng nào dư xăng, mình đăng ký Pro subscription của Claude, còn lại xài chùa Google Antigravity và Github Student. Antigravity cung cấp quyền truy cập đến các mô hình của Claude và Google, còn Copilot bật riêng Claude Sonnot 4.5.
Ngoài ra, Google cũng cho 1 năm sử dụng Gemini Pro, mình tận dụng làm market research.
Thời điểm mình viết bài này thì Opus 4.6 đã ra mắt với 1M context window. Mình và bá tánh nghi ngờ là dùng foundation model của Google vì Opus 4.6 cũng bị ảo giác. Kỳ vọng của mình vào Opus rất cao, nên mình chọn đợi đến Opus 5 thì nhảy thuyền.
Công cụ sử dụng
Trước đây, mình tải cả 3 code editor: Antigravity, VS Code, Cursor, cả ba đều chung ruột của VS Code, cái nào có AI thì dùng cái đó, hết token thì xoay luân phiên, cài thêm cả Claude Code hỗ trợ. Hiện tại mình xoá hết, chỉ để lại VS Code và cài OpenCode.
Vậy tại sao là OpenCode chứ không phải Claude Code? Không phải 2 bên đều là TUI à?
OpenCode tích hợp sẵn LSP, bắt lỗi syntax và linting cho LLM rất nhanh, đồng nghĩa với việc LLM được grounding tốt hơn và luôn luôn đảm bảo là sẽ follow syntax. Tool call của OpenCode cũng thông minh, nếu không thể gọi tool thì nó sẽ tự động chuyển sang bash command. Đến thời điểm viết bài thì OpenCode thông minh hơn hẳn Claude Code rồi :) Biết sao được, Anthropic làm mô hình ngu đi để vắt cực khô người dùng mà.
Thiết lập codebase
Với mỗi project, chúng ta đều phải tạo một file CLAUDE.md cho Claude Code sử dụng ha, mọi người có thể dùng /init trên Claude Code để tổng hợp thông tin codebase: mô tả sản phẩm, thư viện đang dùng, cấu trúc thư mục, coding convention giúp Claude navigate tốt hơn nhé. Rồi mình lại phải tạo lại GEMINI.md, AGENTS.md cho các AI editor khác nhau, mình thấy rất khó chịu, nên mình softlink CLAUDE.md thành GEMINI.md, AGENTS.md để đỡ phải tạo nhiều file, cũng đỡ phải copy paste nhiều lần. Có lẽ mình sẽ cân nhắc softlink luôn thành README.md, còn gì tuyệt hơn một file README cho cả AI và contributor dùng chung chứ? Sau khi tạo, mình cũng kiểm tra lại và viết tay bổ sung một số phần quan trọng như business logic, chứ mình vẫn chưa tin LLM lắm, còn viết cho người đọc nữa chứ. Mà thôi, lỡ đâu người ta cũng dùng LLM để đọc…
Ngoài ra, mình cũng tạo thư mục docs/ và yêu cầu LLM mỗi lần thực hiện thay đổi hoặc nghiên cứu sẽ tạo file trong đó. Thư mục này sẽ được thêm vào .gitignore để tránh bị commit lên repo.
MCP và Skill
Để tiết kiệm context cho LLM và grounding chống bịa, mình cài cắm MCP cho LLM, và sử dụng các skill để LLM thực hiện các tác vụ cụ thể.
Hiện giờ mình chỉ dùng Context7, nhưng vẫn giới thiệu đủ:
Serena (đã ngừng sử dụng, gây context rotting trong các codebase của mình):Hỗ trợ index codebase và memory.- Context7: Hỗ trợ tra cứu tài liệu của các thư viện để LLM cài đặt đúng syntax.
ShadCN (đã ngừng sử dụng, Context7 là đủ):Tra cứu tài liệu của ShadCN component library.Next Devtool (ngừng sử dụng do OpenCode không câu móc được log của Next): Giúp LLM debug NextJS và tra tài liệu
Riêng Skill, mọi người có thể sử dụng Vercel SKILL.sh để xem skill nào ưng ý rồi tải về. Nhưng mọi người cũng nhớ chú ý nguy cơ prompt injection nhé, kẻo đến ngày auto approve xong code của mình bị cắm mã độc lúc nào chẳng hay. Mình khó tính nên manual approve từng lệnh một nhưng cũng mệt mỏi lắm.
Có hai skill mình thấy rất hay và muốn giới thiệu với mọi người:
- BMAD method: Đóng gói Agile vào làm quy trình cho LLM. Ngày đẹp trời mà mọi người không muốn để LLM đọc thì tự đọc cũng được, có thể xem cách làm việc với Agile.
- vercel-react-best-practices: Tinh hoa đúc kết kinh nghiệm làm việc với React của team Vercel hàng chục năm. Cá nhân mình chỉ dùng 2 chiếc này. Skill.sh cũng có phần tự tìm tự cài skill thì phải, nhưng mình thích kiểm soát hơn.
Linting và type generator
Đây là hai thứ mà mình thấy không thể thiếu vì nó giúp vạch ranh giới cho LLM rất tốt. Linting để LLM không sai syntax, type generator để nhanh chóng lấy type từ OpenAPI Swagger thay vì để LLM tự mò mẫm. Trước kia thì mình thường để LLM tự truy cập Swagger JSON, nhưng giờ thì không cần nữa, vì type generated không bao giờ sai :) Nếu có gì bất hợp lý, mình có thể quay qua sửa backend.
Mình sử dụng biome cho linting vì thay thế được phần lớn Prettier và ESLint. Orval generate TS type + Zod. Thực ra có openapi-typescript-codegen nhưng không xịn bằng Orval ở khoản không chơi cùng với Zod.
Ngoài ra còn có knip dùng để tìm deadcode trong repo nữa, dùng để phát hiện rác thải từ LLM rất tốt.
Các công cụ khác
Để làm việc với codebase kỹ hơn, không để LLM cho ăn quả lừa kèm 1 nùi slop, mình cũng xài cả các công cụ này nữa
- Google CodeWiki giúp mình tìm hiểu nhanh cơ chế hoạt động của 1 thư viện/framework nổi tiếng. Tài liệu được tạo bằng Gemini 3.
- Google Stitch tạo UI draft rất ngon, nhưng chưa có kéo thả, mỗi lần muốn làm gì lại phải chat, rất tốn thời gian. Từ xương sườn này có thể để LLM phát triển tiếp giao diện và adapt vào codebase cũng như system design hiện tại.
- Apple Human Design Interface Guideline cung cấp các phương pháp, từ khoá để thiết kế chỉn chu hơn chứ LLM làm gì có taste :)
- Detail Design các mẹo sửa tiểu tiết, handcrafting giao diện đến tận cùng
- Agentaton chú thích thẳng vào UI, copy dán ngược vào LLM sửa lỗi giao diện rất chuẩn
- TweakCN tạo Tailwind theme cho ShadCN để đồng nhất giao diện
- Dribble, Mobbin, Component Gallery, Awwwards, Arena để tìm cảm hứng tham khảo
- ClaudeKit nâng tầm LLM vô địch thiên hạ, setup codebase và tạo sản phẩm nhanh. 99 đô na, của anh Goon Nguyen phát triển.
Quy trình làm việc
Trước khi sử dụng BMAD thì mình thực hiện theo trình tự sau thù công, về sau BMAD hỏi luôn thành khung rồi nên cũng tiện. Đọc rất là sách giáo khoa, nhưng mình tuân thủ khá chặt chẽ. Mất 1-2 ngày setup codebase còn hơn là làm nửa chừng đập đi xây lại, căn cơ phải chắc chứ đúng không?
Xác định yêu cầu
Ngay khi mình nhận brief của khách, mình bẻ nó ra. Trên trường mình cũng được học môn phân tích thiết kế hệ thống, nên mình cũng hiểu được sườn câu hỏi. Mình là người giải quyết vấn đề, vậy nên tập trung vào vấn đề. Nhiều khi khách nhảy thẳng đến giải pháp (anh muốn làm 1 cái app để quản lý cửa hàng) thì mình cũng kiên nhẫn hỏi lại xem là anh hay làm kiểu gì, và gặp vấn đề ở đâu trong quy trình. Nhiều khi họ cứ nói vậy vì có người xui họ, nhiệm vụ của mình là tư vấn cho phù hợp với túi tiền của khách mà lại giải quyết vấn đề trơn tru. Còn khách nhét tiền thì bảo gì cũng ừ bảo sao cũng gật.
Tiếp theo là nắm bắt được cái taste của khách. Bước này thì mình sẽ đi stalk FB của khách, của quý công ty xem gu thẩm mỹ của khách như thế nào, công ty ngành nghề ra sao để xem họ sẽ thích kiểu gì. Thậm chí có công ty muốn giao diện phải thật nhiều chữ, phải rực rỡ, mà mình sửa tới hồi mới hiểu ý của khách là đẩy tất cả thành màu đỏ. Thậm chí có khách quái thai hơn, muốn chữ nhỏ xíu để nhồi càng nhiều nội dung càng tốt. Những tình huống đó sẽ được giải quyết ở bước 3.
Sau bước này, ta sẽ xác định được cơ bản
- Vấn đề của khách
- Gu của khách
- Cách làm việc, trao đổi của khách. Mình cũng sẽ một phần dự đoán được là khi nào khách trả tiền cho mình
Nếu được và tốt nhất thì làm cái việc khách đang kẹt 1 lần, mình trước khi code web cũng lăn lộn đủ việc chân tay, nên thừa hiểu cái việc đó nhức nhối ở đâu, và nhanh chóng đưa tư vấn phù hợp cho khách. Bằng không thì cứ thân với nhân viên là họ cũng kể khổ với mình cho khách quan. Đoạn nào họ nói xấu sếp thì cứ ừ gật chứ đừng hùa nhé kẻo người ta bẫy mình bật ghi âm ghi hình.
Phân tích yêu cầu
Từ các vấn đề và thông tin khách đưa ra, mình sẽ bẻ vấn đề ra nhỏ hơn, rồi nghiên cứu thử có hệ thống nào tồn tại trước đó mà giải quyết bài toán này không. Tìm các vấn đề chính để xác định demo phải trưng ra cho khách xem cái gì. Chi tiết thì mọi người tìm hiểu từ khoá design system, nhiều người viết lắm rồi. Phần này mình cũng brainstorm cùng với LLM, mình tìm dẫn chứng phản biện, đến đoạn nào mà đọc ổn ổn rồi thì validate lại lần cuối bằng cách bắt LLM research tiếp.
Sau bước này thì mình hòm hòm biết được mình cần làm những tính năng nào, ước tính thời gian, cũng như biết là phải dùng tool gì rồi. Có thể bắt đầu báo giá.
Prototype
Khách cọc xong thì mình bắt đầu setup codebase, viết file CLAUDE.md mô tả, rồi đem trích một phần lên Stitch để tạo layout. Đưa cho khách duyệt, ưng phương án nào thì lấy phương án đấy triển khai tiếp. Trong lúc đó, tranh thủ đi xem reference, copy ảnh đưa vào Gemini lấy design keyword. Nhớ lưu lại lịch sử thay đổi nhé, phòng tình huống 7749 option xong khách chốt cái đầu tiên. Tình huống mà mình đề xuất sửa gáy khách thì cứ làm 1 bản khách 1 bản của mình rồi cho họ quyết định, nhiều khi khách còn chả biết mình muốn gì nên Prototype phải làm thật tốt để cho thấy mình phân tích ngon đét còn hơn cả khách.
Trong lúc đấy, tranh thủ giấu dốt, lên CodeWiki đọc tài liệu về công cụ sẽ sử dụng. Nó sẽ rất phụ thuộc tình huống. Landing page kèm tin tức thì Hugo, tối ưu SEO thì NextJS, cần lưu trữ quản lý thì Postgres, lưu lượng cao thì Redis cache, task chạy lâu thì thêm RabbitMQ. Cắm thêm backend Django rồi charge tiền khách.
Trong trường hợp budget của khách kẹt sỉ mà đòi phải ổn thì sử dụng stack của Cloudflare (D1, R2, Workers). Free Tier của CF khá ổn cho phần lớn nhu cầu. Cần thì lại tận dụng cả Supabase/Neon nữa. Muốn nhàn thân với NextJS thì deploy Vercel, nhưng coi chừng vendor locking.
Khách duyệt các thứ OK thì sẽ đến màu. Mình sẽ lấy màu dựa trên màu thương hiệu của khách, hoặc brand guideline. Nếu khách làm thương hiệu không OK thì xem tuổi khách hợp mệnh nào rồi chọn color pallete là xong.
Sau đó thì bắt đầu ngồi nghĩ layout, lên awwward tìm mỏi mắt, làm visual board tổng hợp ref vào Arena. Bần cùng nữa thì dùng Pinterest.
Sau đó thì bắt tay vào implement. Trong quá trình implement nhớ phòng chừa trường hợp khách muốn sửa yêu cầu, đặc biệt nhằm vào các phần mà khách hay đòi đổi như Hero Section, hoặc là cái này phải trông như thế này. Dùng ShadCN sẽ đỡ nhiều công, bảo LLM sửa component theo ý khách là được, nhưng trước đó phải lập danh sách task để đảm bảo LLM sửa đủ file. Tập trung các tính năng giải quyết nỗi vất vả to nhất của khách hàng làm prototype. Bước này ưu tiên dùng được.
Triển khai
Ở đây mình đổi mô hình liên tục. Dùng OpenCode, mình để Plan rồi chọn Opus 4.5 để xác định danh sách tính năng, sau đó bổ sung bằng tay, và hỏi ngược lại để LLM đóng vai người dùng và hoài nghi. Tranh luận và chốt xong sẽ bắt đầu chuyển về Sonnet 4.5 để bắt đầu triển khai từng mục một. Thường LLM sẽ chạy rất nhanh cho ra một bộ khung 70% nhưng mà tasteless. Bước này thì có thể tiếp tục xoay tua Opus và Claude để viết test case. Nếu có bug pátt sinh, xử lý bằng Gemini Flash, cái nào khó quá thì Sonnet là được.
Khi nào mà khách ưng layout rồi và codebase ổn định thì mình mới bắt đầu cải thiện design hiện tại.
Kết
Tay mình mỏi nên cũng chưa nghĩ ra gì thêm. Mọi người góp ý mình qua thư contact@truongson.dev nhé. Mình rất muốn nghe setup của mọi người, cũng như các mong muốn để mình xem có thể viết phần nào kỹ hơn nữa. Cảm ơn mọi người đã đọc.