SSD Nodes Learn 🎉 VPS từ $4.99/tháng
Hướng dẫn Matt ConnorBởi Matt Connor

DESIGN.md: File giải thích vì sao code được viết như vậy

AGENTS.md ghi cách làm việc trong repo, còn DESIGN.md ghi lý do đằng sau kiến trúc và các quyết định không được hoàn tác để coding agent không phá code.

DESIGN.md là gì và AGENTS.md không bao quát những gì

DESIGN.md là một file markdown trong thư mục gốc của repository. File này giải thích cho coding agent AI vì sao code được tổ chức theo cách hiện tại. AGENTS.md trả lời một câu hỏi khác: phải làm việc trong repository này như thế nào. Nội dung đó gồm lệnh build, lệnh test, các kiểm tra lint phải đạt và những path không được thay đổi. DESIGN.md ghi lại các quyết định đã được chốt và những gì sẽ hỏng nếu hoàn tác một quyết định.

Coding agent, tức một tool như Claude Code hoặc Cursor có thể tự đọc và chỉnh sửa repository, mặc định thường rất tự tin. Khi gặp một pattern mà nó không nhận ra, nó sẽ cải tiến pattern đó. Một cache được viết thủ công có thể bị thay bằng Redis (một kho dữ liệu trong bộ nhớ), vì đó là cách cache xuất hiện trong phần lớn code mà model đã đọc. AGENTS.md không ngăn được việc này vì make test vẫn pass trong cả hai trường hợp. Quy tắc bị phá chưa từng được ghi lại ở nơi agent có thể đọc.

Nếu bạn chưa viết file đầu tiên, hãy bắt đầu từ đó. AGENTS.md và HUMAN.md nằm bên cạnh file này giải thích format và vị trí mà mỗi tool tìm file. Phần tiếp theo là chương tiếp nối chương đó.

Thực sự có gì bên trong một DESIGN.md được công bố

Cách nhanh nhất để tìm hiểu định dạng này là đọc các file mà các công ty công bố về chính họ. Repository official-design-md chỉ theo dõi những file đó. Quy tắc đưa vào chỉ có một dòng, và dòng đó chính là trọng tâm của bộ sưu tập:

Every entry here is a DESIGN.md published by the company or project itself — not extracted, not reverse-engineered, not community-made.

Tính đến tháng 8 năm 2026, danh sách có 7 file: Atlassian, Clerk, Mintlify, Nuxt, Resend, Vercel và VoltAgent. Mỗi file nằm tại một URL công khai ổn định, nên bạn có thể đọc ngay một file trong terminal.

curl -s https://nuxt.com/design.md | head -n 60
curl -s https://vercel.com/design.md | wc -w

Cả hai file đều là tài liệu design system. Chúng mô tả giao diện của một sản phẩm: màu sắc, kiểu chữ, khoảng cách và chuyển động. Hãy bỏ qua chủ đề cụ thể, vì phần hữu ích nằm ở cấu trúc bài viết chứ không phải chủ đề.

File Nuxt dài khoảng 2.100 từ, và phần lớn nội dung là một quy tắc kèm theo lý do:

Dark mode is the default theme.
Colors are semantic (`primary`, `neutral`, `error`…) rather than hardcoded hex values in components.
Don't hardcode `#00DC82` in UI code — use `text-primary` or `color="primary"`.

File Vercel dài hơn, khoảng 6.500 từ vào tháng 8 năm 2026, và đi thêm một bước. Một trong các heading của file là Reject generated-design reflexes. Bên dưới là danh sách những thứ mà một generator có năng lực sẽ ưu tiên dùng khi không ai bảo nó tránh dùng:

Hard reject decorative gradients, gradient text, glows, blobs, stripes, textures, grid backgrounds, glass effects, paper simulations, colored side rails, ornamental shadows, and fake depth.

Câu đó định nghĩa loại file này. Đây là danh sách bằng văn bản về các giá trị mặc định mà một model tự tin sẽ tạo ra, được công bố để model ngừng tạo ra chúng. Mọi DESIGN.md đáng commit đều là danh sách như vậy cho một domain nào đó.

Vì sao các công ty công bố DESIGN.md của riêng họ?

Cộng đồng đã đi trước. awesome-design-md chứa 73 tệp được reverse-engineer từ các website công khai. Mỗi tệp tuân theo cùng một định dạng gồm 9 phần. Vì vậy, bạn có thể trỏ agent vào một tệp để tạo ra giao diện gần giống với thiết kế đó. Các tệp này hữu ích, nhưng vẫn chỉ là phỏng đoán. Không có ai tại các công ty đó xem xét chúng.

Tệp chính chủ khác ở chỗ nó là nguồn thông tin, không phải bản diễn giải kết quả đầu ra. Khi Vercel thay đổi thang tỷ lệ kiểu chữ, vercel.com/design.md cũng thay đổi theo. Bản sao được scrape vào tháng 3 vẫn tiếp tục dạy agent của bạn thang tỷ lệ cũ. Không có gì trong repository cho biết bản sao đó đã lỗi thời.

7 nhà phát hành là một con số nhỏ, và repository cũng nói rõ điều đó: tiêu chuẩn này còn mới và đang được các bên chính thức áp dụng nhiều hơn. Cả hai bộ sưu tập đều do VoltAgent duy trì. Đây là một agent framework mã nguồn mở cũng công bố tệp riêng. Vì vậy, hãy xem danh sách này như một tracker, không phải một cuộc thống kê trung lập. Tuy vậy, danh sách vẫn đáng theo dõi vì 7 công ty đó là ai. Đây là những công ty có front-end code được các developer khác sao chép nhiều nhất. Các tệp của họ đang trở thành ví dụ thực tế cho DESIGN.md. Hãy so sánh với quá trình phát triển của AGENTS.md: agents.md hiện được hơn 60,000 dự án mã nguồn mở sử dụng, và Agentic AI Foundation thuộc Linux Foundation chịu trách nhiệm quản lý. Các quy ước cho tệp mà agent có thể đọc đang nhanh chóng ổn định, và chúng đang được định hình từ các công ty dẫn đầu.

Nội dung của DESIGN.md khi dự án không có giao diện người dùng

Phần lớn phần mềm chạy trên VPS không có ngôn ngữ trực quan để đặc tả. File này vẫn hữu ích vì cơ chế không liên quan gì đến màu sắc. Nó dùng để ghi lại các ràng buộc mà một editor có kinh nghiệm có thể vô tình vi phạm.

Các bất biến. Mỗi bất biến là một câu, nêu điều phải luôn đúng sau mọi lần chỉnh sửa. “Mọi thao tác ghi đều đi qua queue.enqueue(). Ghi trực tiếp vào database sẽ bỏ qua audit log, trong khi compliance export đọc dữ liệu từ audit log.” Bất biến kèm theo lý do vẫn có tác dụng khi gặp một task không được dự đoán trước. Bất biến đứng riêng sẽ giống một sở thích, và các sở thích thường bị loại bỏ khi tối ưu.

Các phương án bị loại. Nêu lựa chọn hiển nhiên và lý do không dùng nó. “Chúng ta không dùng Redis để caching. Service chạy trên một VPS duy nhất, nên map trong process nhanh hơn và giảm một daemon cần duy trì. Xem xét lại khi có application server thứ hai.” Nếu không có đoạn này, agent được yêu cầu tăng tốc cache sẽ thêm Redis, và làm vậy là hợp lý: bạn chưa nói cho nó biết ràng buộc. Đây là phần mang lại giá trị cho toàn bộ file.

Các ranh giới. Đây là những nơi mà một chỉnh sửa nhỏ có thể gây ảnh hưởng lớn. Database schema. Prefix của public route mà khách hàng đã dùng trong các script. Config file mà deploy đọc trước khi application khởi động. Cron entry giả định chỉ có một bản chạy. Hãy nêu rõ chúng và nói chi phí của việc thay đổi từng thành phần.

Thuật ngữ. Nếu code dùng tenant còn team dùng customer, hãy ghi lại cách quy đổi. Agent đoán sai ở đây có thể tạo ra code đọc vẫn đúng nhưng mô hình hóa sai đối tượng. Đây là loại lỗi khó phát hiện nhất khi review.

DESIGN.md bạn có thể sao chép ngay hôm nay

# DESIGN.md

## What this service is
One paragraph. What it does, who calls it, where it runs.

## Invariants
- Every write goes through `queue.enqueue()`. Direct writes skip the audit log.
- Timestamps are stored as UTC integers. Only the display layer converts them.
- One process writes to SQLite. The database is in WAL mode, and a second writer
  gets `database is locked` under load.

## Rejected alternatives
- **Redis for caching.** Rejected: one VPS, one process, an in-process map is
  enough. Revisit at two application servers.
- **An ORM for the reporting queries.** Rejected: the reports are four hand-tuned
  SQL statements. The generated query joined the same table twice.

## Boundaries
- `schema.sql` is append-only. A column rename needs a migration and a deploy window.
- The `/v1/` routes are public. Customers script against them, so the response
  shape is frozen.

## Vocabulary
- `tenant` in code is what the docs and the billing system call a customer account.

## Keeping this file honest
Update it in the commit that changes the decision. A stale DESIGN.md is worse
than no DESIGN.md, because the agent believes it.

Hãy điền hai phần bạn có thể viết ngay hôm nay từ trí nhớ: các bất biến và những phương án thay thế đã bị loại bỏ. Để các phần còn lại chỉ dưới dạng heading. Một file có bốn dòng trung thực là đủ dùng. Một file có bốn mươi dòng phỏng đoán thì không.

Một số công cụ tải mọi file markdown trong thư mục gốc của repository. Một số công cụ chỉ tải file được chỉ định. Vì vậy, đừng giả định cách hoạt động. Hãy thêm liên kết tham chiếu đến AGENTS.md:

Read DESIGN.md before editing anything under `src/`. It lists the invariants and
the alternatives that were already rejected.

Mẫu anti-pattern: DESIGN.md lặp lại README

Phiên bản kém phổ biến nhất thường đọc khá ổn nhưng không truyền đạt được gì. Nó mở đầu bằng mô tả chức năng của dự án, liệt kê các tính năng, giải thích cách cài đặt rồi kết thúc bằng giấy phép. Mọi dòng trong đó đã có trong README, và không dòng nào giải thích vì sao mọi thứ lại được thiết kế như vậy.

Điều này khiến bạn chịu hai loại chi phí. Chi phí đầu tiên là context. Một file được agent đọc khi bắt đầu mọi task sẽ tạo chi phí ở mọi task, còn phần hướng dẫn cài đặt bị lặp lại chỉ làm lãng phí dung lượng trong một context window cố định. Quản lý context window là một kỹ năng riêng, được đề cập trong quản lý context window trong Claude Code. Tóm lại: mọi nội dung được tự động tải phải là phần có giá trị cao nhất trong repository.

Chi phí thứ hai nghiêm trọng hơn. Hai bản sao của cùng một thông tin sẽ dần lệch nhau. README nói service lắng nghe trên 8080, DESIGN.md vẫn ghi 3000, còn agent không có cách nào xác định bản nào được ưu tiên, nên nó chọn một bản rồi viết code dựa trên đó. Một file đôi khi sai sẽ được tham khảo với cùng mức độ tin cậy như một file luôn đúng.

Bạn có thể kiểm tra nhanh. Nếu một đoạn văn có thể nằm thoải mái trong README, hãy xóa nó khỏi DESIGN.md. Phần còn lại phải là điều bạn sẽ nói thẳng trong một buổi code review, phần bắt đầu bằng câu “chúng ta đã thử cách đó rồi”.

Làm thế nào để biết file đang hoạt động?

Không có linter cho việc này. Bạn có thể chạy một kiểm tra trong 1 phút.

Giao cho agent một task buộc nó phải tuân theo một invariant. “Thêm một background job đánh dấu các row cũ là đã hết hạn.” Nếu file hoạt động đúng, câu trả lời sẽ cho thấy điều đó trước khi có bất kỳ đoạn code nào: agent phải nói rằng job ghi thông qua queue.enqueue(), vì ghi trực tiếp sẽ bỏ qua audit log. Nếu agent mở kết nối database rồi ghi dữ liệu, thì một trong hai điều sau là đúng. File hoàn toàn không được đọc, hoặc invariant được diễn đạt quá lỏng nên có thể tranh luận.

Đồng thời, hãy theo dõi số token vì file này được load ở mỗi lượt. Nếu mức sử dụng context tăng sau khi bạn thêm DESIGN.md mà câu trả lời không tốt hơn, file đang chứa phần diễn giải mà agent đã biết. Đọc bộ đếm token trong Claude Code cho biết ngân sách đó được sử dụng ở đâu.

Điều này đặc biệt quan trọng khi agent chạy trên server thay vì trên laptop của bạn. Một agent hoạt động trong session chạy lâu, như thiết lập trong workspace Claude Code trên VPS với tmux, không nhớ cuộc trò chuyện của ngày hôm qua. Repository là bộ nhớ. Mọi điều bạn giải thích trong chat nhưng không commit sẽ biến mất ở session tiếp theo, còn DESIGN.md là nơi lưu phần giải thích đó để nó tồn tại.

Bắt đầu với những quyết định gây tranh luận

Phiên bản đầu tiên chỉ mất hai mươi phút. Mở vài pull request gần đây nhất có bình luận của reviewer: "không, ở đây chúng ta làm theo cách khác". Mỗi bình luận như vậy là một invariant chưa từng được ghi lại, đồng thời là một chỗ agent sẽ mắc cùng lỗi đó nhanh hơn và thường xuyên hơn con người. Chỉ thêm vào file khi file không hỗ trợ được bạn, không cần cập nhật theo lịch. Nếu bạn vẫn đang xác định agent phù hợp với quy trình phát triển thông thường như thế nào, hướng dẫn tìm hiểu về AI agent năm 2026 là bước tiếp theo hợp lý.

FAQ

DESIGN.md có phải là một tiêu chuẩn chính thức không?

Không theo cách AGENTS.md là tiêu chuẩn chính thức. AGENTS.md có trang chủ tại agents.md, được hơn 60,000 dự án nguồn mở sử dụng và được Agentic AI Foundation, một tổ chức thuộc Linux Foundation, quản lý. Tính đến tháng 8 năm 2026, DESIGN.md chưa có cơ quan quản lý và cũng chưa có đặc tả được công bố. Điểm đáng chú ý là nó đã được các bên cung cấp áp dụng trực tiếp: 7 công ty, gồm Vercel, Nuxt, Atlassian và Resend, công bố một file tại URL công khai. Ngoài ra, một bộ sưu tập cộng đồng có thêm 73 file được reverse-engineer từ các website công khai. Bạn có thể xem đây là một quy ước để áp dụng ngay và tự do mở rộng, vì không có cơ chế nào kiểm tra tên các section của bạn.

Có nên để DESIGN.md chỉ là một section trong AGENTS.md không?

Với repository nhỏ thì nên. Một file mà agent chắc chắn đọc được sẽ tốt hơn 2 file, trong đó có 1 file bị bỏ qua. Hãy tách chúng khi AGENTS.md không còn dễ quét nhanh, hoặc khi bạn nhận thấy 2 phần thay đổi với tốc độ khác nhau. AGENTS.md thay đổi khi build thay đổi. DESIGN.md thay đổi khi một quyết định thay đổi. Trường hợp này ít xảy ra hơn và có ảnh hưởng lớn hơn. Khi tách file, hãy thêm 1 dòng vào AGENTS.md, yêu cầu agent đọc DESIGN.md trước khi sửa code, vì không phải tool nào cũng load mọi file markdown trong thư mục root.

DESIGN.md khác gì so với architecture decision record?

ADR (architecture decision record) là bản ghi có ngày tháng về 1 quyết định. Một project được duy trì tốt sẽ tích lũy hàng chục ADR trong 1 thư mục. Đây là lịch sử, và lịch sử tốn chi phí load, vì agent phải đọc tất cả ADR để xác định những quyết định nào vẫn còn hiệu lực. DESIGN.md mô tả trạng thái hiện tại và được viết để đọc toàn bộ trong mỗi task. Nếu bạn đã viết ADR thì hãy giữ cả 2 loại file. ADR nói quyết định nào đã được đưa ra và vào thời điểm nào. DESIGN.md nói điều gì đang đúng ở hiện tại. Đây là file bạn đưa cho agent đọc.

DESIGN.md nên dài bao nhiêu?

Đủ ngắn để load trong mỗi lượt mà không gây lãng phí. Các ví dụ được công bố khá dài vì chúng đặc tả toàn bộ ngôn ngữ trực quan: file của Nuxt có khoảng 2,100 từ và file của Vercel có khoảng 6,500 từ tính đến tháng 8 năm 2026. Một backend service thường cần ít hơn nhiều. Hãy bắt đầu với 1 trang và chỉ mở rộng khi agent làm sai một việc mà 1 câu duy nhất có thể ngăn được. Độ dài không phải là tiêu chí đánh giá. Mỗi dòng phải mô tả một điều mà nếu không có, agent sẽ có thể làm sai.