Bạn đã bao giờ cần làm POC/demo gấp một sản phẩm trong vòng 2–3 ngày, trong khi lại bị hạn chế khi Claude có usage limit reset theo chu kỳ 5 giờ chưa?

Mục tiêu của tôi lúc đó rất thực dụng:

Làm sao “bào” hết các khung usage trong ngày mà không phải thức đêm chờ token reset, rồi tiếp tục prompt để implement từng chức năng? Tôi muốn tự động hóa toàn bộ quá trình đó.

I. Case study

1. Bối cảnh

Tôi cần dựng nhanh một POC cho project quản lý căn hộ cho thuê, trong đó có khá nhiều feature liên quan đến nhau.

Dù chỉ là POC, project vẫn phải có database, backend, UI, validation, business rule, phân quyền, dữ liệu mẫu và các flow liên kết với nhau.

Với một prompt, agent có thể dựng khá nhanh một màn hình hoặc một feature. Nhưng để hoàn thành cả project thì vẫn phải chia nhỏ công việc, implement từng phần, kiểm tra kết quả rồi sửa những vấn đề phát sinh ở các bước tiếp theo.

2. Vấn đề

Trong một usage window, agent có thể làm việc khá nhanh. Vấn đề bắt đầu xuất hiện khi quota bị giới hạn.

Nếu muốn tận dụng hết các lượt sử dụng, tôi phải chủ động quay lại đúng thời điểm quota reset, thậm chí có những lần rơi vào giữa đêm.

Nói cách khác, agent đã có thể tự code khá nhiều việc, nhưng phần điều phối vẫn phụ thuộc vào con người: biết lúc nào chạy tiếp, chạy task nào trước, kiểm tra kết quả và xử lý các lỗi phát sinh.

Một “siêu prompt” cũng không giải quyết được vấn đề này. Prompt càng dài có thể giúp agent bắt đầu tốt hơn, nhưng sau đó vẫn cần người theo dõi tiến độ và quyết định bước tiếp theo.

3. Cách tôi chuẩn bị trước khi chạy Loop

B1. Quyết định tech stack

Chốt trước framework, database, các thư viện chính và cách chia architecture.

B2. Dựng source base và môi trường coding

Chuẩn bị sẵn project skeleton, local environment và các command cần thiết như lint, type check, test, build... để agent có thể tự chạy và nhận feedback sau mỗi lần implement.

B3. Design database

Thiết kế trước các entity, relationship, enum và constraint dựa trên flow nghiệp vụ của từng chức năng.

B4. Viết detailed design

Với mỗi feature, tôi mô tả trước input, output, user flow và cách xử lý business logic. Các phần như validation, permission, chuyển trạng thái, dữ liệu liên quan, error case và edge case cũng được ghi rõ.

Acceptance criteria cũng cần cụ thể để agent biết chính xác chức năng này phải làm đến đâu và sau khi làm xong thì kiểm tra bằng cách nào.

B5. Chia danh sách chức năng thành các slices nhỏ

Mỗi slice implement một chức năng nhỏ, có kết quả kiểm chứng được từ đầu đến cuối:

Nếu một chức năng quá lớn để hoàn thành trong một usage window, nó được tách thành nhiều slice nhỏ hơn.

Mỗi slice khai báo:

Thành phần Mục đích
id, name, phase Định danh, tên và giai đoạn của slice
status Trạng thái triển khai hiện tại
spec, section Đúng tài liệu và section Agent cần đọc
blocks_on ID của các slice phải hoàn thành trước
touches Vùng file slice được phép thay đổi
invariants Các quy tắc không được vi phạm
verify Lệnh kiểm chứng bắt buộc
note Kết quả thực tế, quyết định và bằng chứng sau khi chạy

Ví dụ đơn giản: Tạo file slices.yml mô tả các chức năng có quan hệ phụ thuộc.

defaults:
  gate: bash scripts/gate/all.sh
  smoke: bash scripts/gate/smoke.sh
  spec_root: design/

slices:
  - id: 1
    name: room-list
    status: ready
    phase: B-chức-năng
    spec: design/features/01-rooms.md
    section: "Danh sách phòng trống"
    blocks_on: []
    touches:
      - src/server/services/rooms/
      - src/app/rooms/
      - scripts/gate/smoke.sh
    invariants:
      - "Chỉ hiển thị phòng đang sẵn sàng cho thuê"
      - "Giá phòng phải lấy từ cơ sở dữ liệu"
    verify:
      - "bash scripts/gate/smoke.sh"
    note:

  - id: 2
    name: booking-create
    status: blocked
    phase: B-chức-năng
    spec: design/features/02-bookings.md
    section: "Tạo đặt phòng"
    blocks_on: [1]
    touches:
      - src/server/services/bookings/
      - src/app/bookings/new/
      - scripts/gate/smoke.sh
    invariants:
      - "Chỉ được đặt phòng đang sẵn sàng cho thuê"
      - "Không được tạo hai lượt đặt trùng thời gian cho cùng một phòng"
    verify:
      - "bash scripts/gate/smoke.sh"
      - "npm test -- booking-create"
    note:
  • Slice room-list không phụ thuộc chức năng nào nên được triển khai trước.
  • Slice booking-create có blocks_on: [1], vì chức năng đặt phòng cần danh sách và quy tắc phòng trống từ slice đầu tiên.
  • → Khi slice 1 hoàn thành status chuyển thành done
  • → Loop tiếp tục sang slice 2, chuyển status từ blocked sang ready rồi tiếp tục triển khai.

4. Thiết kế Loop chạy các Slice

Để Loop chạy được toàn bộ danh sách mà vẫn tách rõ trách nhiệm, tôi dùng hai skill:

Skill Mục đích
.claude/skills/run-slices/SKILL.md - /run-slices Project Loop: đọc slices.yml, chọn slice sẵn sàng, gọi Slice Runner và tiếp tục cho tới khi hoàn thành hoặc gặp điều kiện dừng.
.claude/skills/slices/SKILL.md - /slices <id> Slice Runner: nhận một slice cụ thể, đọc đúng context, implement, chạy gate, tự sửa có giới hạn rồi cập nhật state và commit.

Project Loop dừng khi mọi slice đã hoàn thành, không còn slice sẵn sàng, một slice thất bại quá số lần cho phép hoặc sắp chạm usage limit. State đã được ghi xuống disk nên lần chạy sau có thể tiếp tục.

Bên trong mỗi slice, skill thực hiện quy trình cố định:

4.1. Select và Analyze

Loop chỉ chọn slice khi dependency đã hoàn thành và vùng file không xung đột với task khác.

Agent sau đó đọc đúng section của spec, ADR, schema, enum và code liên quan. Không load toàn bộ tài liệu vào mỗi usage window.

4.2. Plan và Implement

Trước khi code, agent liệt kê service, handler, component, checker và file dự kiến thay đổi.

Nếu cần vượt touches, thêm dependency hoặc đổi shared schema, Loop dừng và báo lại. Nếu plan hợp lệ, agent implement feature theo vertical slice.

4.3. Gate và Auto-fix

Agent được tự sửa tối đa ba vòng. Nếu vẫn fail, Loop dừng và lưu checker, output thật, các cách đã thử cùng trạng thái file hiện tại.

Không sửa gate để làm pass testcase. Không đánh dấu done khi gate chưa pass.

4.4. Close và Next

Khi gate pass, Loop cập nhật state và ghi note ở slices.yml:

  1. Done: thực tế đã implement gì.
  2. Decisions: chỗ tài liệu chưa nói rõ và đã chọn cách nào.
  3. NOT done: phần nào chưa làm và vì sao.

Slice được đánh dấu done, sau đó Loop tự chọn slice ready tiếp theo mà không chờ người dùng prompt lại.


5. Schedule: đánh thức Loop sau khi Usage Limit Reset

Với project chạy ở local, cách đơn giản nhất là tạo một Local Routine trong Claude Desktop:

  1. Mở Code → Routines → New routine → Local.
  2. Đặt tên, ví dụ 'wake-project-loop'.
  3. Chọn folder chứa project.
  4. Chọn lịch chạy sau thời điểm usage limit thường được reset vài phút.
  5. Nhập instruction để Routine đánh thức Project Loop.

Instruction chỉ cần ngắn gọn:

Tiếp tục Project Loop của repository này.

1. Nếu có lượt `/run-slices` khác đang hoạt động, dừng an toàn.
2. Gọi skill `/run-slices` để tiếp tục từ state trên disk.
3. Không tự chọn slice và không gọi `/slices` trực tiếp.
4. Không push và không tạo pull request.

Routine kết thúc trách nhiệm ngay sau khi gọi /run-slices. Việc chọn task, kiểm dependency, chạy slice, cập nhật state và quyết định dừng đều do Project Loop xử lý.


6. Kết quả thực tế triển khai

Rất nhiều commit được tự động thực hiện lúc 01:00~08:00 AM trong lúc tôi đang ngủ.

7. Chú ý

Cách làm trong bài cho phép Loop tiếp tục qua nhiều feature và usage window mà không chờ con người duyệt sau từng bước.

Tôi chọn trade-off này vì mục tiêu là có POC/demo gấp trong 2–3 ngày. Tốc độ được ưu tiên hơn độ chắc chắn của một production workflow.

Con người vẫn phải review từng feature trước khi sử dụng kết quả demo. Nhưng review diễn ra sau khi Loop đã tạo output, không phải là gate đồng bộ chặn Loop giữa các usage window.

Không khuyến khích áp dụng nguyên trạng cách làm này cho project thực tế hoặc production.

II. Kết luận

Quay lại câu hỏi đầu bài: làm sao tận dụng các usage window trong ngày mà không phải cày đêm?

Không phải bằng cách viết một prompt dài hơn.

Cũng không phải bằng cách đặt báo thức sau mỗi lần usage limit reset.

Cách tôi chọn là:
Chốt tech stack
→ Dựng source base và environment
→ Design database
→ Viết detailed design
→ Chia mỗi feature thành vertical slice phù hợp
→ Tạo Loop implement + verify
→ Lưu state ngoài usage window
→ Dùng schedule đánh thức Loop

Ba điều quan trọng nhất:

  • Vai trò của tôi chuyển từ: Người prompt từng bước → Người thiết kế, ra luật, feedback và checkpoint
  • Đừng thức để chờ usage limit reset. Hãy để schedule đánh thức Loop, còn bạn chỉ thức dậy để review kết quả.
  • Một lần nữa: mức tự động hóa trong bài dành cho POC/demo cần tốc độ. Đừng áp dụng nguyên trạng vào project thực tế hoặc production.

Tham khảo

https://pub.towardsai.net/stop-prompting-your-agents-design-loops-unpacking-the-idea-behind-an-8-million-view-tweet-b08dc3348308