Thử gõ vào Claude Code một dòng:
$ claude-code "Tạo cho tôi API đăng nhập."
Vài giây sau bạn có một endpoint chạy được. Nhưng AI vừa phải tự đoán hàng loạt thứ thay bạn: dùng JWT hay session? Payload validate thế nào? Tài khoản bị khóa thì sao? Token sống bao lâu? Mỗi câu nó đoán sai một chút, cộng dồn qua vài chục prompt, và bạn có một hệ thống chạy được nhưng không ai giải thích nổi kiến trúc.
Đây là câu chuyện mình muốn chia sẻ với anh em: từ ngày có Codex, Claude Code và mấy tool tương tự, tốc độ build một ứng dụng tăng chóng mặt. Trước đây một app cần vài tuần đến vài tháng để phân tích, code, debug, hoàn thiện. Giờ đưa yêu cầu cho AI, nó tạo giao diện, backend, database, API, authentication, viết test, thậm chí tự sửa lỗi rồi làm tiếp chức năng mới.
Và câu hỏi tự nhiên bật ra: nếu AI viết code nhanh như vậy, có còn cần phân tích và thiết kế hệ thống trước khi xây không?
Câu trả lời của mình sau một thời gian làm việc với AI Agent: cần, và cần hơn trước rất nhiều.
"Xây được" và "xây đúng" là hai chuyện khác nhau
Có một sự khác biệt rất lớn giữa hai thứ:
- Xây dựng được một phần mềm — prompt "AI, viết cho tôi app quản lý công việc", nhận về 10.000 dòng code sinh ngẫu nhiên chưa qua phân tích nghiệp vụ.
- Xây dựng đúng hệ thống — có Problem Definition, Requirements Analysis, System Architecture, Database Schema trước khi một dòng code nào được sinh ra.
AI làm rất tốt vế thứ nhất. Nhưng AI không thể tự biết chính xác bạn đang muốn giải quyết vấn đề gì nếu ngay từ đầu bài toán chưa được phân tích rõ ràng. Nó chỉ có thể lấp chỗ trống bằng phỏng đoán, và phỏng đoán thì có xác suất sai.
Nên thay vì bỏ bước thiết kế, mình chuyển bước thiết kế thành đầu vào cho AI. Cụ thể là quy trình 8 bước dưới đây. Mình sẽ dùng một ví dụ xuyên suốt: Task App cho sinh viên.

Bước 1 — Xác định bài toán (Problem Definition)
Việc đầu tiên không phải là chọn React, Node.js hay MySQL. Mà là trả lời: chúng ta đang giải quyết vấn đề gì?
Nếu chỉ nói "Tôi muốn xây dựng một ứng dụng quản lý công việc" thì đây chưa phải là yêu cầu đủ rõ để bắt đầu. Cần hiểu tại sao ứng dụng này tồn tại:
Sinh viên có rất nhiều bài tập, deadline, lịch học và việc cá nhân, nhưng đang dùng quá nhiều công cụ khác nhau để quản lý. Chúng ta muốn một hệ thống giúp sinh viên quản lý công việc, deadline và lịch cá nhân trong một nơi duy nhất.
Ba câu hỏi bắt buộc phải trả lời ở bước này:
- Ai đang gặp vấn đề? (sinh viên đại học & cao đẳng)
- Vấn đề thực sự là gì? (phân tán công cụ → bỏ sót deadline — tìm root cause, đừng chữa triệu chứng)
- Tại sao cần giải quyết? (tập trung hóa quản lý trên một nền tảng)
Nếu bước đầu tiên đã xác định sai vấn đề, những bước phía sau dù làm tốt đến đâu cũng có thể vô nghĩa. AI code càng nhanh thì cái "vô nghĩa" đó đến càng sớm.
Bước 2 — Phân tích yêu cầu (Requirements)
Khi đã hiểu bài toán, câu hỏi tiếp theo: hệ thống cần làm được những gì?
Functional Requirements — với Task App, sinh viên cần:
- Đăng ký tài khoản, đăng nhập
- Tạo / chỉnh sửa / xóa công việc
- Đặt deadline, phân loại công việc
- Đánh dấu hoàn thành
- Nhận thông báo khi gần đến deadline
Non-functional Requirements — phần hay bị bỏ qua khi prompt AI, nhưng lại quyết định kiến trúc:
- Hệ thống phải phản hồi nhanh
- Dữ liệu người dùng phải được bảo mật
- Phục vụ được nhiều người dùng đồng thời
- Dữ liệu phải được backup
- Có khả năng mở rộng trong tương lai
Bước này biến một ý tưởng chung chung thành danh sách những thứ hệ thống thực sự phải đáp ứng. Danh sách đó sau này chính là tiêu chí để review code AI sinh ra.
Bước 3 — Business Rules: chỗ AI hay "tự ý" nhất
Đây là bước mình thấy khác biệt rõ nhất giữa người có kinh nghiệm và người mới prompt AI.
Ví dụ một task có 3 trạng thái: Todo → In Progress → Done. Nghe đơn giản, nhưng phải hỏi tiếp:
- Task đã
Donecó được chuyển lạiIn Progresskhông? - Ai được phép thay đổi trạng thái?
- Người dùng xóa task thì xử lý thế nào — soft delete hay hard delete?
- Một user bị xóa thì các task của họ đi đâu?
Lấy riêng câu soft/hard delete. Nếu không nói rõ, AI sẽ tự chọn:
-- AI "tự đoán": hard delete
DELETE FROM tasks WHERE id = ?;
-- Mất hoàn toàn, không khôi phục được, dễ gây mâu thuẫn FK
trong khi cái bạn cần có thể là:
-- Soft delete: chuyển vào thùng rác
UPDATE tasks SET is_deleted = true, deleted_at = NOW() WHERE id = ?;
-- Cho phép khôi phục trong 30 ngày, an toàn dữ liệu người dùng
Hai lựa chọn này kéo theo hai schema khác nhau, hai bộ query khác nhau, hai kiểu xử lý FK khác nhau. Xác định rõ trước khi yêu cầu AI sinh code, để AI không tự thiết kế sai database.
Ở giai đoạn này mình dùng Use Case Diagram, Activity Diagram, Sequence Diagram, User Flow hoặc đơn giản là một tài liệu Business Rules dạng bullet. Mục tiêu duy nhất: biến mong muốn mơ hồ thành mô tả kỹ thuật để AI triển khai chính xác.
Bước 4 — Kiến trúc hệ thống (System Architecture)
Khi đã hiểu hệ thống, lúc này mới bắt đầu trả lời: hệ thống này sẽ được xây dựng như thế nào?

Với Task App, các thành phần và cách chúng nói chuyện với nhau:
- Web / Mobile (React UI) gửi request HTTPS + JSON đến Backend
- Backend API xử lý business logic, gồm các module Auth, Task, Calendar, Notification
- PostgreSQL là source of truth
- Message Queue nhận event
deadline.reminder.requested, worker gửi Email / Push
Nguyên tắc mình chốt: business logic nằm ở backend; database là nguồn dữ liệu chuẩn; notification chạy bất đồng bộ để cô lập lỗi (external side effect không được kéo sập luồng chính).
Bước này xuất hiện rất nhiều quyết định kỹ thuật mà developer phải tự chốt, đừng đẩy cho AI:
- Frontend: React hay Vue?
- Backend: Node.js, Java hay Python?
- Database: PostgreSQL, MySQL hay MongoDB?
- API: REST hay GraphQL?
- Authentication: JWT hay Session?
- Cache: có cần Redis không?
- Async: có cần Message Queue không?
- Hình thái: Monolith hay Microservices?
Đây là phần quan trọng nhất mà developer cần đầu tư. Bởi vì nếu kiến trúc sai, AI code càng nhanh thì hệ thống càng đi xa khỏi hướng đúng. 15.000 dòng code sinh ra trong 4 giây trên một kiến trúc không xác định = 15.000 dòng coupling cao và zero boundary check.
Bước 5 — Thiết kế dữ liệu (Data Design)
Có kiến trúc tổng thể rồi, xác định hệ thống cần lưu những dữ liệu gì.
Task App có hai entity chính:
CREATE TABLE users (
id SERIAL PRIMARY KEY,
name VARCHAR(100) NOT NULL,
email VARCHAR(255) UNIQUE NOT NULL,
password VARCHAR(255) NOT NULL
);
CREATE TABLE tasks (
id SERIAL PRIMARY KEY,
title VARCHAR(200) NOT NULL,
description TEXT,
status VARCHAR(20) NOT NULL DEFAULT 'todo'
CHECK (status IN ('todo', 'in_progress', 'done')),
deadline TIMESTAMP,
user_id INT NOT NULL REFERENCES users(id),
-- Soft delete (quyết định ở bước 3)
is_deleted BOOLEAN NOT NULL DEFAULT false,
deleted_at TIMESTAMP
);
Quan hệ: một User có nhiều Task, một Task thuộc về đúng một User (1:N). Từ đó ra Database Schema.
Để ý hai cột is_deleted và deleted_at: đó là hệ quả trực tiếp của quyết định soft delete ở bước 3, khớp với câu UPDATE ở trên. Tương tự, CHECK trên cột status khóa đúng vòng đời todo → in_progress → done. Business rule nào đã chốt thì phải hiện ra trong schema, nếu không AI sẽ sinh query hard delete hoặc tự chế thêm trạng thái mới.
Nhưng thiết kế database không chỉ là tạo vài bảng. Phải nghĩ đến Foreign Key, Relationship, Index, Constraint, Transaction, Data Consistency, Security và khả năng mở rộng. Nếu database sai ngay từ đầu, backend, API và thậm chí frontend đều phải làm lại — sai một bảng là kéo cả hệ thống theo.
Bước 6 — Chia module (Component Design)
Chia hệ thống thành các module độc lập để AI Agent viết code chính xác trong phạm vi hẹp, thay vì "viết cả app" một lượt.
Task App chia thành:
- Authentication & User Module — xác thực JWT, phân quyền, quản lý hồ sơ. Emits:
AuthToken,UserPayload - Task Management Engine — business rules, vòng đời
Todo → In Progress → Done. Requires: valid JWT. Emits:TaskCreated,StatusChanged - Notification & Event Service — subscribe
TaskEvents, gửi cảnh báo deadline. Output: Push Notification - Calendar, Reporting tách riêng tương tự
Trong từng module lại có Controller / Service (ví dụ TaskController, TaskService). Mỗi module đúng một trách nhiệm (Single Responsibility).
Mục tiêu của bước này là trả lời: module nào chịu trách nhiệm cho việc gì, dữ liệu được truyền qua các module như thế nào? Làm tốt thì hệ thống dễ phát triển, dễ bảo trì, dễ mở rộng — và AI nhận task theo đúng ranh giới module, không "chọc" lung tung sang chỗ khác.
Bước 7 — Specification: bước quan trọng nhất trong thời đại AI
Đây là bước biến toàn bộ phân tích và thiết kế ở trên thành tài liệu AI có thể thực thi.
Quay lại ví dụ mở đầu. Thay vì nói với Claude Code "Tạo cho tôi API đăng nhập", mình đưa một specification cụ thể:
{
"endpoint": "/api/auth/login",
"method": "POST",
"input": {
"email": "user@domain.com",
"password": "string (min 8 chars)"
},
"rules": [
"Email không tồn tại hoặc password sai → trả về cùng một lỗi 401 'Email hoặc mật khẩu không đúng'",
"Không để lộ email có tồn tại hay không qua message, status code hay thời gian phản hồi",
"Sai quá 5 lần trong 15 phút → tạm khóa đăng nhập 15 phút (rate limit theo email + IP)",
"Tài khoản bị khóa → chỉ thông báo khóa sau khi email và password đã đúng",
"Đăng nhập thành công → trả về access token và refresh token"
],
"tokens": {
"access_token_ttl": "15 phút",
"refresh_token_ttl": "7 ngày"
}
}
Chú ý rule đầu tiên. Nếu spec ghi "email không tồn tại → lỗi A, password sai → lỗi B", AI sẽ làm đúng y như vậy, và kẻ tấn công chỉ cần thử từng email để biết email nào đã đăng ký (user enumeration). Spec tốt phải chốt luôn cả những yêu cầu bảo mật kiểu này, vì AI sẽ không tự thêm vào nếu bạn không nói.
Khi mô tả rõ như vậy, AI không cần phải tự đoán. Nó chỉ cần dựa trên specification để triển khai. Và đây chính là lúc thấy rõ mối quan hệ giữa System Design và AI Agent:
System Design là bản đồ. AI Agent là động cơ. Có bản đồ rõ ràng, AI không đi sai hướng.

Bước 8 — Implementation: giao cho AI, nhưng con người vẫn review
Đến đây mới bắt đầu code. Và đây là phần AI Agent hỗ trợ cực kỳ mạnh:
- Tạo API, tạo frontend
- Viết authentication
- Viết unit test, integration test
- Refactor, thậm chí tự kiểm tra code
Nhưng có một nguyên tắc mình không bỏ: AI không nên là người duy nhất đánh giá kết quả của chính nó. Checklist review của mình sau mỗi lượt AI sinh code:
- Code có đúng architecture đã thiết kế không?
- Business logic có đúng rules ở bước 3 không?
- Database có đúng schema ở bước 5 không?
- Có vấn đề security không?
- Có thêm dependency không cần thiết không?
- Có phá vỡ những phần khác của hệ thống không? (AI sửa Task Service, Notification có gãy theo không?)
Vì sao review lại quan trọng hơn trước — bài toán tốc độ lệch pha
Lý do nằm ở một vấn đề mới của thời AI: tốc độ AI sinh code vượt xa tốc độ con người đọc hiểu code.
- AI sinh code: một module phức tạp trong vài phút — tốc độ ~1.500+ dòng / phút
- Con người đọc hiểu: cùng module đó mất vài ngày — tốc độ ~200 dòng / giờ
Kịch bản quen thuộc mình từng chứng kiến:
- AI tạo module đầu tiên. Ổn.
- Prompt tiếp: thêm authentication. AI sửa code.
- Thêm notification. AI sửa tiếp.
- Thêm payment. AI sửa tiếp.
- Vài tuần sau: hàng chục nghìn dòng code tự sinh, ứng dụng vẫn chạy, xuất hiện hàng trăm circular dependency, và không ai trong team hiểu kiến trúc.
Đó chính là lúc technical debt bắt đầu. Và sửa một hệ thống đã xây sai kiến trúc khó hơn rất nhiều so với thiết kế đúng ngay từ đầu — vì lúc này bạn phải đọc hiểu với tốc độ 200 dòng/giờ thứ đã được sinh ra với tốc độ 1.500 dòng/phút.
Vai trò của Software Engineer đang dịch chuyển
Quy trình cũ chúng ta hay hình dung là 4 bước: nhận yêu cầu, viết code, test, deploy. Trong thời AI Agent, nó giãn ra thành 8 bước — và bước "viết code" không còn là của con người nữa:

Nói cách khác:
- Con người quyết định WHAT — xây cái gì, tại sao, business rules là gì, hệ thống phải đáp ứng yêu cầu nào.
- Con người thiết kế HOW — architecture, database, module.
- AI thực hiện IMPLEMENTATION — viết code, tạo test, debug, refactor.
AI đề xuất và thực thi. Con người quyết định, xác minh và chịu trách nhiệm cuối cùng. Specification là shared contract giữa hai bên.
Tóm lại: pipeline mình đang dùng

Đây không phải quy trình chỉ dành cho dự án lớn. Ngay cả một app nhỏ, nếu có tư duy phân tích và thiết kế tốt thì quá trình phát triển rõ ràng hơn rất nhiều — vì mỗi bước đều có đầu vào rõ ràng cho bước sau.
AI có thể giúp chúng ta xây phần mềm nhanh hơn rất nhiều. Nhưng AI không đảm bảo rằng thứ chúng ta đang xây là thứ chúng ta thực sự cần. AI tạo ra hàng nghìn dòng code trong vài phút — và nếu thiết kế ban đầu sai, AI cũng giúp chúng ta tạo ra hàng nghìn dòng code sai nhanh hơn bao giờ hết.
Nên kỹ năng quan trọng nhất của Software Engineer sắp tới, theo mình, không còn là "tôi có thể code nhanh đến đâu?" mà là:
- Tôi hiểu bài toán sâu đến đâu?
- Tôi thiết kế hệ thống tốt đến đâu?
- Tôi sử dụng AI thông minh đến đâu để biến thiết kế thành hệ thống thực tế?
AI không làm Software Engineering thừa thãi. Ngược lại, nó khiến Software Engineering quan trọng hơn. AI giúp xây nhanh hơn, System Analysis giúp hiểu mình cần xây gì, System Design giúp biết phải xây như thế nào, và AI Agent biến thiết kế đó thành sản phẩm nhanh hơn bao giờ hết.
Trước khi bắt đầu bất kỳ ứng dụng nào, đừng hỏi "hôm nay tôi sẽ viết code gì?". Hãy hỏi ba câu:
- Tôi đang giải quyết vấn đề gì?
- Hệ thống này cần hoạt động như thế nào?
- Tôi đã thiết kế nó đủ rõ để AI có thể triển khai đúng hay chưa?
AI là động cơ — System Design là vô lăng.
