Xây dựng tính năng hoàn chỉnh từ đầu đến cuối bằng AI

Kết hợp mọi thứ với nhau

Trong bài học trước, chúng ta đã khám phá các quyết định về kiến ​​trúc và thiết kế hệ thống. Giờ hãy xây dựng trên nền tảng đó. Trong 7 bài học vừa qua, bạn đã học cách sử dụng AI để tạo code, gỡ lỗi, kiểm thử, xem xét code, lập tài liệu và đưa ra các quyết định về kiến ​​trúc. Giờ là lúc sử dụng tất cả chúng trên một tính năng duy nhất, từ trang trắng đến code sẵn sàng cho sản xuất.

Đây không phải là một bài tập đơn giản. Chúng ta sẽ xây dựng một tính năng mà một ứng dụng thực tế có thể cần, và chúng ta sẽ sử dụng AI ở mọi giai đoạn của quá trình. Bạn sẽ thấy các kỹ thuật này được kết hợp như thế nào - mỗi giai đoạn đều nhanh hơn và hiệu quả hơn nhờ các giai đoạn được hỗ trợ bởi AI trước đó.

Tính năng: API giới hạn tốc độ

Chúng ta đang xây dựng một hệ thống giới hạn tốc độ cho một API. Đây là lý do tại sao đây là một dự án cuối khóa tuyệt vời:

  • Nó liên quan đến các quyết định về kiến ​​trúc (nơi lưu trữ bộ đếm, thuật toán nào)
  • Nó cần triển khai cẩn thận (điều kiện tranh chấp, trường hợp ngoại lệ)
  • Kiểm thử rất quan trọng (thời gian, đồng thời, điều kiện)
  • Nó cần tài liệu rõ ràng (các nhà phát triển khác sẽ cấu hình nó)
  • Các vấn đề về bảo mật yêu cầu xem xét cẩn thận

Yêu cầu:

  • Giới hạn số lượng yêu cầu API cho mỗi người dùng trong mỗi khoảng thời gian
  • Hỗ trợ các giới hạn khác nhau cho những endpoint khác nhau
  • Trả về các tiêu đề giới hạn tỷ lệ chuẩn (X-RateLimit-Limit, X-RateLimit-Remaining, X-RateLimit-Reset)
  • Xử lý các trường hợp ngoại lệ (lệch đồng hồ, máy chủ phân tán, lưu lượng truy cập đột biến)
  • Có thể cấu hình thông qua middleware (dễ dàng thêm vào bất kỳ tuyến nào)

Giai đoạn 1: Quyết định kiến trúc (Bài học 7)

Trước tiên, hãy quyết định cách xây dựng điều này. Đây là gợi ý:

📍 Nơi dán: Mở ChatGPT (chat.openai.com), Claude (claude.ai) hoặc Gemini (gemini.google.com) và bắt đầu một cuộc trò chuyện mới.

📋 Cách sao chép prompt này: Nhấp vào bất kỳ đâu bên trong khối màu xám, nhấn Cmd+A rồi Cmd+C (Mac) hoặc Ctrl+A rồi Ctrl+C (Windows). Hoặc sử dụng biểu tượng sao chép xuất hiện.

Tôi cần thêm giới hạn tốc độ cho API Express.js/TypeScript của chúng tôi.
Chúng tôi đã sử dụng Redis để lưu cache.

Hãy so sánh các phương pháp giới hạn tốc độ này cho trường hợp của chúng tôi:
1. Fixed window counter
2. Sliding window log
3. Sliding window counter
4. Token bucket

Các ràng buộc của chúng tôi:
- Khoảng 10.000 người dùng hoạt động
- Cần giới hạn cho mỗi người dùng, mỗi endpoint
- Chạy 3 phiên bản máy chủ API phía sau bộ cân bằng tải
- Redis có sẵn (đã có trong hệ thống của chúng tôi)
- Phải xử lý mức cao điểm 1.000 yêu cầu/giây

Đối với mỗi phương pháp, hãy phân tích: độ chính xác, mức sử dụng bộ nhớ Redis,
độ phức tạp triển khai và hành vi tại các ranh giới cửa sổ.

✏️ ​​Cách điền thông tin chi tiết: Thay thế mỗi dấu ngoặc vuông [] và trình giữ chỗ trong ngoặc bằng thông tin cụ thể từ tình huống thực tế của bạn. Thông tin đầu vào mơ hồ sẽ tạo ra kết quả mơ hồ — hãy cụ thể.

👀 Những gì bạn sẽ thấy: Trong vòng vài giây, AI sẽ trả về một phản hồi có cấu trúc dựa vào prompt ở trên. Hãy đọc kỹ và coi đó là bản nháp, không phải câu trả lời cuối cùng.

📌 Nên làm gì với kết quả: Lưu phản hồi vào file Notes. Chọn gợi ý có hiệu quả cao nhất và thực hiện nó trong tuần này — đừng cố gắng làm tất cả cùng một lúc.

⚠️ Nếu kết quả không ổn: Nếu các gợi ý có vẻ chung chung, hãy dán nội dung sau: "Hãy cụ thể hơn với bối cảnh thực tế của tôi. Bỏ qua lời khuyên chung chung." Nếu nó bỏ qua các chi tiết quan trọng bạn đã cung cấp, hãy hỏi: "Bạn đã bỏ sót [X] trong bối cảnh của tôi — hãy thực hiện lại với điều đó làm ràng buộc chính."

AI sẽ chỉ ra những sự đánh đổi. Trong trường hợp của chúng ta, phương pháp sử dụng sliding window counter được khuyến nghị — nó đủ chính xác (không có các đỉnh nhọn ở ranh giới cứng như fixed window), tiết kiệm bộ nhớ (không giống như nhật ký sliding window), và đơn giản hơn so với token bucket.

Quyết định của bạn: Sử dụng sliding window counter với Redis. Ghi lại nó như một ADR.

Giai đoạn 2: Tạo code (Bài học 2)

Bây giờ hãy tạo code triển khai. Lưu ý cách chúng ta cung cấp ngữ cảnh cho codebase của mình:

Triển khai middleware giới hạn tốc độ cho Express.js
bằng TypeScript.

Thuật toán: sliding window counter sử dụng Redis
Lưu trữ: Phiên bản Redis hiện có của chúng ta (client ioredis)

Mẫu middleware của chúng ta:
[dán một middleware hiện có làm ví dụ]

Yêu cầu:
- Chấp nhận cấu hình: { windowMs: number, maxRequests: number }
- Định dạng key: ratelimit:{userId}:{endpoint}:{windowId}
- Trả về 429 với tiêu đề Retry-After khi vượt quá giới hạn
- Thêm tiêu đề X-RateLimit-* vào tất cả các phản hồi
- Xử lý lỗi kết nối Redis một cách khéo léo (fail open)
- TypeScript với kiểu dữ liệu nghiêm ngặt

Tạo:
1. Giao diện RateLimitConfig
2. Hàm tạo middleware
3. Các thao tác Redis (tăng, kiểm tra, dọn dẹp)

AI tạo ra middleware. Giả sử phần lõi trông giống như thế này:

interface RateLimitConfig {
  windowMs: number;
  maxRequests: number;
  keyPrefix?: string;
  failOpen?: boolean;
}

const createRateLimiter = (config: RateLimitConfig) => {
  return async (req: Request, res: Response, next: NextFunction) => {
    const userId = req.user?.id ?? req.ip;
    const endpoint = req.route?.path ?? req.path;
    const windowId = Math.floor(Date.now() / config.windowMs);
    const prevWindowId = windowId - 1;

    const currentKey = `ratelimit:${userId}:${endpoint}:${windowId}`;
    const prevKey = `ratelimit:${userId}:${endpoint}:${prevWindowId}`;

    try {
      const [currentCount, prevCount] = await Promise.all([
        redis.incr(currentKey),
        redis.get(prevKey),
      ]);

      // Set expiry on current window key
      if (currentCount === 1) {
        await redis.expire(currentKey, Math.ceil(config.windowMs / 1000) * 2);
      }

      // Sliding window calculation
      const elapsed = (Date.now() % config.windowMs) / config.windowMs;
      const weight = (Number(prevCount) || 0) * (1 - elapsed) + currentCount;

      const remaining = Math.max(0, config.maxRequests - Math.ceil(weight));
      const resetTime = (windowId + 1) * config.windowMs;

      res.set({
        'X-RateLimit-Limit': String(config.maxRequests),
        'X-RateLimit-Remaining': String(remaining),
        'X-RateLimit-Reset': String(Math.ceil(resetTime / 1000)),
      });

      if (remaining <= 0) {
        const retryAfter = Math.ceil((resetTime - Date.now()) / 1000);
        res.set('Retry-After', String(retryAfter));
        return res.status(429).json({
          error: 'Too many requests',
          retryAfter,
        });
      }

      next();
    } catch (error) {
      if (config.failOpen !== false) {
        next(); // Fail open: allow request if Redis is down
      } else {
        res.status(503).json({ error: 'Service temporarily unavailable' });
      }
    }
  };
};

Giai đoạn 3: Gỡ lỗi (Bài học 3)

Bạn chạy chương trình cục bộ và nhận thấy điều gì đó bất thường: Số lượng giới hạn tỷ lệ truy cập hơi sai lệch khi nhiều yêu cầu đến đồng thời. Đến lúc gỡ lỗi:

Tôi thấy có hiện tượng tranh chấp dữ liệu trong bộ giới hạn tỷ lệ truy cập. Khi
10 yêu cầu đồng thời đến, bộ đếm đôi khi
hiển thị 8 hoặc 9 thay vì 10.

Đây là code:
[dán middleware]

Vấn đề: redis.incr() và redis.get() là các lệnh riêng biệt
Giữa lệnh INCR và GET, một yêu cầu khác
có thể sửa đổi bộ đếm.

Làm thế nào để khắc phục hiện tượng tranh chấp dữ liệu này?

AI đề xuất sử dụng script Redis Lua để thực hiện việc kiểm tra:

local current = redis.call('INCR', KEYS[1])
if current == 1 then
  redis.call('EXPIRE', KEYS[1], ARGV[1])
end
local prev = redis.call('GET', KEYS[2]) or 0
return {current, prev}

Script này chạy trên máy chủ Redis — không thể xảy ra tình trạng tranh chấp tài nguyên.

Giai đoạn 4: Kiểm thử (Bài học 4)

Bây giờ hãy tạo các bài kiểm tra cho bộ giới hạn tốc độ:

Viết các bài kiểm tra toàn diện cho middleware giới hạn tốc độ này
sử dụng Jest và supertest.

[Dán code middleware cuối cùng]

Các hạng mục kiểm tra cần thiết:
1. Giới hạn tốc độ cơ bản (các yêu cầu trong giới hạn được chấp nhận, vượt quá giới hạn trả về lỗi 429)
2. Hành vi sliding window (các yêu cầu trong cửa sổ trước ảnh hưởng đến cửa sổ hiện tại)
3. Tính chính xác của tiêu đề (các tiêu đề X-RateLimit-* có giá trị chính xác)
4. Xử lý lỗi Redis (hành vi mở khi thất bại)
5. Cách ly theo người dùng (các yêu cầu của người dùng A không ảnh hưởng đến người dùng B)
6. Cách ly theo endpoint (các cuộc gọi đến /api/users không được tính vào /api/posts)
7. Hành vi reset cửa sổ (giới hạn được reset sau khi cửa sổ trôi qua)
8. Xử lý yêu cầu đồng thời

Sử dụng jest.useFakeTimers() cho các bài kiểm tra phụ thuộc vào thời gian.
Sử dụng Redis giả lập cho các bài kiểm thử đơn vị.

AI tạo ra các bài kiểm thử bao gồm tất cả các kịch bản này. Hãy đặc biệt chú ý đến các bài kiểm thử yêu cầu đồng thời và các bài kiểm tra ranh giới cửa sổ — đây là các trường hợp ngoại lệ làm hỏng bộ giới hạn tốc độ trong môi trường sản xuất.

Giai đoạn 5: Xem xét code (Bài học 5)

Trước khi hợp nhất, hãy chạy code qua quá trình xem xét bằng AI:

Xem xét middleware giới hạn tốc độ này để đảm bảo sẵn sàng cho môi trường sản xuất.

Tập ​​trung vào:
1. Bảo mật: Người dùng có thể vượt qua giới hạn tốc độ không?
2. Hiệu suất: Có bất kỳ điểm nghẽn nào khi tải nặng không?
3. Độ tin cậy: Điều gì xảy ra khi có sự cố?
4. Tính chính xác: Phép toán sliding window có đúng không?

[dán toàn bộ code middleware và các bài kiểm tra]

AI có thể gắn cờ:

  • "Người dùng có thể vượt qua giới hạn tốc độ bằng cách giả mạo tiêu đề X-Forwarded-For nếu bạn chuyển sang sử dụng req.ip. Đảm bảo proxy của bạn được cấu hình để ghi đè, không phải thêm vào." 
  • "Lua script nên xử lý trường hợp KEYS[2] đã hết hạn. Hiện tại redis.call('GET') trả về false, không phải 0 — hãy ép kiểu rõ ràng." 
  • "Hãy xem xét thêm một hàm skip vào cấu hình để các endpoint kiểm tra sức khỏe có thể vượt qua giới hạn tốc độ."

Mỗi flag ngăn chặn một sự cố tiềm ẩn trong môi trường sản xuất.

Giai đoạn 6: Tạo tài liệu (Bài học 6)

Cuối cùng, hãy tạo tài liệu cho tính năng:

Tạo tài liệu cho middleware giới hạn tốc độ của chúng ta.
Đối tượng: các nhà phát triển trong nhóm cần thêm giới hạn tốc độ
vào các endpoint của họ.

Bao gồm:
1. Hướng dẫn nhanh (cách thêm giới hạn tốc độ vào một route)
2. Các tùy chọn cấu hình với giá trị mặc định
3. Cách hoạt động của thuật toán sliding window (ngắn gọn)
4. Giải thích về tiêu đề phản hồi
5. Phản hồi lỗi
6. Các cấu hình phổ biến (nghiêm ngặt cho xác thực, nới lỏng cho việc đọc)
7. Hướng dẫn khắc phục sự cố

[dán code middleware cuối cùng]

AI tạo ra tài liệu cho phép bất kỳ thành viên nào trong nhóm thêm giới hạn tốc độ vào các endpoint của họ trong vài phút, mà không cần phải hiểu về cơ chế hoạt động bên trong của sliding window.

Tóm tắt quy trình làm việc hoàn chỉnh

Đây là những gì chúng ta vừa làm và thời gian mỗi giai đoạn mất bao lâu với AI:

Giai đoạn Không có AI Có AI Đóng góp của AI
Quyết định kiến ​​trúc Nghiên cứu trong 2-4 giờ 20 phút Phân tích đánh đổi, so sánh các lựa chọn
Tạo code 4-6 giờ 30-45 phút Triển khai ban đầu, mẫu cơ bản
Gỡ lỗi 1-2 giờ (điều kiện tranh chấp) 15 phút Phân tích nguyên nhân gốc rễ, giải pháp atomic
Test 3-4 giờ 30-45 phút Các trường hợp ngoại lệ toàn diện, test code
Đánh giá code 30-60 phút (đang chờ người đánh giá) 10 phút Kiểm tra bảo mật, hiệu năng và tính chính xác
Tạo tài liệu 2-3 giờ 15-20 phút Tài liệu có cấu trúc từ code
  • Tổng thời gian không dùng AI: 12-20 giờ trong nhiều ngày.
  • Tổng thời gian dùng AI: 2-3 giờ trong một phiên làm việc.

Đây không phải là tăng gấp 10 lần bằng cách cắt giảm công đoạn. Mỗi giai đoạn đều được thực hiện kỹ lưỡng - có thể nói là kỹ lưỡng hơn so với phiên bản không dùng AI, bởi vì AI phát hiện ra các trường hợp ngoại lệ và những vấn đề bảo mật mà con người bỏ sót do áp lực thời gian.

Thử thách của bạn

Xây dựng một tính năng từ dự án của riêng bạn bằng cách sử dụng quy trình làm việc hoàn chỉnh này:

  1. Chọn một tính năng liên quan đến các quyết định thực tế (không chỉ là CRUD)
  2. Kiến trúc: Sử dụng AI để khám phá các tùy chọn và ghi lại quyết định của bạn
  3. Tạo: Viết code với AI sử dụng ngữ cảnh codebase của bạn
  4. Gỡ lỗi: Khi có sự cố xảy ra, hãy sử dụng bộ ba gỡ lỗi
  5. Kiểm thử: Tạo các bài kiểm thử toàn diện bao gồm cả những trường hợp ngoại lệ
  6. Xem xét: Chạy đánh giá code bằng AI tập trung vào bảo mật và hiệu suất
  7. Tài liệu: Tạo tài liệu dành cho nhà phát triển từ code cuối cùng

Hãy tự tính thời gian. So sánh với thời gian thực hiện thông thường. Sự khác biệt chính là hệ số nhân phát triển AI của bạn.

Những điểm chính cần ghi nhớ

  • Quy trình làm việc có sự hỗ trợ của AI tác động đến mọi giai đoạn phát triển, không chỉ là viết code
  • Mỗi giai đoạn đều thúc đẩy giai đoạn tiếp theo — các quyết định kiến ​​trúc tốt giúp việc tạo code dễ dàng hơn, những bài kiểm tra tốt giúp việc xem xét nhanh hơn
  • AI rút ngắn quá trình xây dựng tính năng kéo dài nhiều ngày xuống còn vài giờ tập trung
  • Bạn đưa ra quyết định, AI tăng tốc quá trình thực hiện
  • Kết quả tốt nhất đến từ sự kết hợp giữa phán đoán của bạn với sự kỹ lưỡng của AI
  • Hãy bắt đầu sử dụng các kỹ thuật này trong công việc thực tế — quá trình học tập ngắn và hiệu quả tức thì

Chúc mừng! Bạn đã hoàn thành khóa học "Code nhanh hơn với AI". Hãy xây dựng một thứ gì đó tuyệt vời, và để AI xử lý những phần từng làm chậm bạn.

  • Câu 1:

    Bài học quan trọng nhất từ ​​việc xây dựng tính năng với AI là gì?

    GIẢI THÍCH:

    AI là một yếu tố nhân rộng sức mạnh, chứ không phải là chế độ autopilot. Kết quả tốt nhất đến từ sự kết hợp giữa khả năng phán đoán, kinh nghiệm và kiến ​​thức chuyên môn của bạn với tốc độ thực thi, khả năng nhận dạng mẫu và phân tích kỹ lưỡng của AI.

  • Câu 2:

    Trong quá trình xây dựng tính năng, khi nào bạn nên sử dụng AI?

    GIẢI THÍCH:

    Mục đích chính của khóa học này là tích hợp AI vào quy trình phát triển hoàn chỉnh của bạn. Mỗi giai đoạn đều được hưởng lợi từ sự hỗ trợ của AI — từ các quyết định về kiến ​​trúc đến lập tài liệu.

  • Câu 3:

    Bước đầu tiên khi xây dựng tính năng với sự hỗ trợ của AI là gì?

    GIẢI THÍCH:

    Việc nhảy vào tạo code mà không có yêu cầu rõ ràng sẽ dẫn đến việc phải làm lại. Xác định những gì bạn đang xây dựng, đưa ra các quyết định quan trọng về kiến ​​trúc, sau đó sử dụng AI để tăng tốc quá trình triển khai.

Thứ Năm, 11/06/2026 07:30
51 👨 5
Xác thực tài khoản!

Theo Nghị định 147/2024/ND-CP, bạn cần xác thực tài khoản trước khi sử dụng tính năng này. Chúng tôi sẽ gửi mã xác thực qua SMS hoặc Zalo tới số điện thoại mà bạn nhập dưới đây:

Số điện thoại chưa đúng định dạng!
Số điện thoại này đã được xác thực!
Bạn có thể dùng Sđt này đăng nhập tại đây!
Lỗi gửi SMS, liên hệ Admin
0 Bình luận
Sắp xếp theo
❖ Phát triển Web với AI