Agen pengodean itu percaya diri, cepat, dan tidak tahu apa-apa tentang arsitektur basis kode Anda sampai Anda memberi tahu mereka. Berikan tiket yang samar kepada Claude Code atau Codex dan mereka dengan senang hati akan menulis kode yang berhasil dikompilasi, lolos tes cepat, dan secara diam-diam melanggar batas antara lapisan domain dan lapisan HTTP Anda. Agen tidak membaca dokumen desain Anda. Mereka membaca file-file yang bisa mereka lihat, melakukan pencocokan pola, dan menebak. File DESIGN.md memperbaiki masalah tebak-tebakan dengan menuliskan maksud arsitektur Anda di satu tempat yang selalu dilihat agen: repositori itu sendiri.
TL;DR
DESIGN.md adalah file repositori konvensi komunitas yang mencatat maksud arsitektur, batasan, dan keputusan desain basis kode dalam format Markdown biasa sehingga agen pengodean (Claude Code, Codex, Cursor) menghasilkan kode yang sesuai dengan sistem, bukan melawannya. Ini menjawab "mengapa kode berbentuk seperti ini," sedangkan AGENTS.md menjawab "bagaimana cara membangun dan menguji."
Pendahuluan
Berikut adalah mode kegagalan yang dialami setiap tim yang mengadopsi agen pengodean dalam waktu seminggu. Anda meminta agen untuk menambahkan *endpoint* pengembalian dana ke layanan pembayaran. Ia mengembalikan *handler* yang berfungsi yang memanggil *database* langsung dari *controller*, menelan kesalahan *gateway*, dan menciptakan jenis uang baru karena tidak menyadari bahwa Anda sudah memilikinya. *Diff*-nya bersih. Tes lolos. Namun juga salah dalam tiga hal yang hanya dapat ditangkap oleh *reviewer* yang mengetahui arsitektur. Agen tidak buruk dalam pengodean; ia buta terhadap keputusan yang ada di kepala Anda, di halaman Notion, atau di utas Slack dari delapan bulan yang lalu.
DESIGN.md adalah jawaban yang telah disepakati oleh semakin banyak tim. Ini adalah satu file Markdown, yang di-*commit* ke *root* repositori, yang memberi tahu agen mana pun fakta-fakta penting tentang sistem Anda: aturan *layering*, *invariant* yang tidak boleh rusak, pola yang Anda pilih dengan sengaja, dan yang Anda tolak. Ini bukan spesifikasi vendor dan tidak ada komite yang memilikinya; ini adalah konvensi, sama seperti ARCHITECTURE.md dan CONTRIBUTING.md adalah konvensi. Namun, ini secara alami berpasangan dengan file instruksi khusus alat yang sudah dibaca agen, dan untuk pekerjaan API dan *backend*, ini adalah salah satu dokumen dengan *leverage* tertinggi yang dapat Anda tulis.
Apa sebenarnya DESIGN.md itu
DESIGN.md adalah catatan teks biasa tentang mengapa kode Anda terlihat seperti itu. Bukan apa yang dilakukannya (itu README), bukan cara menjalankannya (itu AGENTS.md), tetapi alasan yang akan dijelaskan oleh insinyur senior kepada karyawan baru pada hari pertama sebelum membiarkan mereka menyentuh hal penting apa pun.
Pikirkan tentang percakapan yang tidak ada dalam file apa pun. "Kami tidak memanggil *payment gateway* dari *request thread*; semuanya melewati tabel *outbox* karena *gateway* mengalami *timeout* saat *load* tinggi." "Uang selalu berupa jumlah integer unit minor; kami melarang *float* setelah insiden pembulatan." "Agregat Account memiliki mutasi saldo; tidak ada yang lain yang menulis ke *ledger*." Itu semua adalah keputusan desain. Mereka tidak terlihat oleh agen yang membaca kode sumber, karena sumber menunjukkan hasil dari keputusan, bukan keputusan atau alasannya. Agen dapat melihat bahwa Account.debit() ada. Ia tidak dapat melihat bahwa Anda sengaja menjadikannya satu-satunya jalur penulisan, sehingga ia dengan senang hati akan menambahkan jalur kedua.
Konvensi ini berakar pada praktik yang lebih tua dan mapan. Pola ARCHITECTURE.md (dipopulerkan oleh tulisan Alex Kladov yang banyak dikutip) berpendapat bahwa repositori harus berisi peta tingkat tinggi basis kode yang menjelaskan struktur dan *invariant* tanpa mencoba untuk tetap tersinkronisasi baris demi baris dengan kode. Architecture Decision Records (ADR) menangkap keputusan individual dan alasannya dari waktu ke waktu. DESIGN.md adalah apa yang Anda dapatkan ketika Anda menulis dokumen semacam itu untuk audiens yang mencakup agen pengodean: ringkas, deklaratif, berorientasi keputusan, dan diletakkan di tempat agen benar-benar akan memuatnya.
Dua properti membuatnya berfungsi. Ini ada di repositori, sehingga agen membacanya dengan alat yang sama dengan saat ia membaca kode; Anda tidak memerlukan *plugin* atau panggilan API. Dan ini tentang maksud, sehingga tetap berguna meskipun file dipindahkan. Ganti nama paket dan *screenshot* README Anda rusak; aturan "logika domain tidak pernah mengimpor *web framework*" masih berlaku.
DESIGN.md vs AGENTS.md vs CLAUDE.md vs README
File-file ini cukup tumpang tindih untuk membingungkan orang dan cukup berbeda sehingga menyatukannya menjadi satu adalah kesalahan. Versi singkatnya: README untuk *onboarding* manusia, AGENTS.md adalah kontrak operasional untuk agen, CLAUDE.md adalah file instruksi khusus Claude, dan DESIGN.md adalah alasan arsitektur yang menguntungkan semuanya.
AGENTS.md sekarang adalah format yang nyata dan banyak diadopsi; proyek agents.md menggambarkannya sebagai "format sederhana dan terbuka untuk memandu agen pengodean," digunakan di puluhan ribu proyek dan diatur di bawah *Agentic AI Foundation* dari *Linux Foundation*. Tugasnya adalah operasional: langkah-langkah pembangunan, perintah pengujian, gaya kode, konvensi *commit*, hal-hal yang akan Anda beritahukan kepada rekan tim baru agar mereka tidak terhambat. Sesuai dokumentasi memori Claude Code dari Anthropic, CLAUDE.md memainkan peran instruksi yang sama khusus untuk Claude; dokumen tersebut bahkan merekomendasikan bahwa jika Anda sudah memiliki AGENTS.md, Anda membuat CLAUDE.md yang mengimpornya dengan @AGENTS.md sehingga kedua alat membaca satu sumber kebenaran.
Perhatikan apa yang hilang dari deskripsi tersebut: alasan arsitektur yang mendalam. AGENTS.md dan CLAUDE.md disetel agar singkat. Dokumen Claude Code secara eksplisit merekomendasikan untuk menjaga CLAUDE.md di bawah 200 baris karena file yang lebih panjang mengonsumsi *konteks* dan mengurangi seberapa andal model mengikutinya. Penjelasan arsitektur yang nyata, batasan, *invariant*, alternatif yang ditolak, aturan model data, tidak akan muat di sana tanpa memperbesarnya. Jadi Anda mereferensikannya sebagai gantinya. DESIGN.md menjadi dokumen yang mendalam; AGENTS.md / CLAUDE.md menunjuknya dengan satu baris.
| File | Audiens | Menjawab | Masa pakai / tingkat perubahan | Panjang |
|---|---|---|---|---|
README.md |
Manusia (pengguna, kontributor baru) | Apa ini, bagaimana cara memulainya | Berubah dengan fitur | Sedang |
AGENTS.md |
Agen pengodean apa pun | Bagaimana cara membuat, menguji, melakukan *lint*, melakukan *commit* di sini | Berubah dengan *tooling* | Pendek (operasional) |
CLAUDE.md |
Khusus Claude Code | Sama seperti AGENTS.md, ditambah aturan khusus Claude | Berubah dengan *tooling* | Pendek (di bawah ~200 baris) |
DESIGN.md |
Agen + insinyur + *reviewer* | Mengapa sistem berbentuk seperti ini; apa yang tidak boleh rusak | Berubah dengan arsitektur (jarang) | Sedang, padat keputusan |
Hubungan ini saling melengkapi, bukan bersaing. Pengaturan yang bersih untuk toko Claude + Codex terlihat seperti ini: README.md untuk manusia; satu AGENTS.md dengan *build*/tes/*style*; CLAUDE.md yang hanya @AGENTS.md ditambah dua baris khusus Claude; dan DESIGN.md memegang arsitektur, dihubungkan dari AGENTS.md sehingga setiap agen memuatnya sesuai permintaan. Tidak ada duplikasi, setiap file memiliki satu pekerjaan. Jika Anda ingin tur yang lebih mendalam tentang struktur *konteks* Claude di seluruh file ini, Claude Code workflows membahas model memori dalam praktik.
Apa yang harus dimasukkan ke dalam DESIGN.md (dengan templat)
DESIGN.md harus menjawab pertanyaan yang tidak dapat disimpulkan agen dari kode: bentuk sistem, aturan yang tidak muncul dalam satu file pun, dan keputusan yang Anda buat dengan sengaja. Jagalah agar tetap deklaratif. Setiap bagian harus terbaca seperti aturan yang akan ditegakkan *reviewer*, bukan esai.
Sertakan ini:
- Bentuk sistem: *layer* atau modul dan arah aliran dependensi. Satu kalimat per batas.
- Invarian: hal-hal yang harus selalu benar. Nyatakan sebagai *absolute*. "Saldo tidak pernah negatif di luar *overdraft* yang diotorisasi." "Setiap panggilan eksternal adalah *idempotent* berdasarkan kunci permintaan."
- Keputusan utama dan alasannya: pilihan yang terlihat sewenang-wenang sampai Anda tahu alasannya. Sertakan alasannya; alasan itulah yang menghentikan agen dari "memperbaikinya".
- Alternatif yang ditolak: apa yang sengaja tidak Anda lakukan, sehingga agen tidak mengusulkannya sebagai ide baru. Bagian tunggal ini mencegah sebagian besar saran buruk.
- Aturan data dan domain: representasi uang, penanganan waktu/zona waktu, *identifier*, *soft-delete*, *multi-tenancy*.
- Sumber kebenaran kontrak API: di mana spesifikasi OpenAPI berada dan aturan bahwa itu adalah otoritatif atas tipe yang ditulis tangan.
- Di mana kode baru ditempatkan: peta singkat "jika Anda menambahkan X, itu termasuk dalam Y" sehingga agen berhenti menyebarkan logika.
- Di luar cakupan / jangan sentuh: file yang dihasilkan, modul lama yang sedang dimigrasi, apa pun yang harus dibiarkan oleh agen.
Berikut adalah templat lengkap, ditulis untuk layanan API pembayaran yang realistis. Salin, hapus yang tidak berlaku, isi sisanya.
# DESIGN.md: Layanan API Pembayaran
File ini mencatat maksud arsitektur dan keputusan di baliknya.
Baca ini sebelum membuat atau memodifikasi kode. Jika perubahan
bertentangan dengan aturan di sini, berhenti dan tandai alih-alih
mencari jalan keluar.
## Bentuk Sistem
Berlapis, dependensi hanya mengarah ke dalam:
http (handler, DTO) -> app (use case) -> domain (entity,
invariant) <- infra (db, klien gateway)
- `domain/` tidak memiliki import dari `http/`, `app/`, atau framework apa pun.
- `infra/` mengimplementasikan antarmuka yang dideklarasikan di `domain/` atau `app/`.
- `http/` tidak pernah menyentuh database atau payment gateway secara langsung.
Ini memanggil use case di `app/`.
## Invarian (harus selalu berlaku)
- Entri ledger tidak dapat diubah setelah ditulis. Koreksi adalah entri
kompensasi baru, bukan pembaruan atau penghapusan.
- Saldo akun berasal dari entri ledger, tidak disimpan sebagai field yang dapat
diubah yang dapat diatur langsung oleh kode.
- Uang adalah jumlah integer unit minor (sen) ditambah kode mata uang ISO-4217.
Tidak pernah float. Jangan pernah mencampur mata uang dalam satu operasi.
- Setiap panggilan ke payment gateway eksternal adalah idempotent, dikunci oleh
`idempotency_key`. Retri tidak boleh melakukan double-charge.
- Saldo tidak pernah menjadi negatif kecuali `OverdraftPolicy` eksplisit
mengotorisasinya untuk akun tersebut.
## Keputusan utama dan alasan
- **Pola Outbox untuk panggilan gateway.** Handler menulis baris intent
dalam transaksi DB yang sama dengan perubahan bisnis, kemudian worker
memanggil gateway. Alasan: gateway mengalami timeout di bawah beban;
melakukannya secara inline menyebabkan latensi permintaan dan penanganan
kegagalan tidak terkelola. Jangan panggil gateway dari handler permintaan.
- **Satu jalur tulis per agregat.** Hanya `Account.post_entry()` yang
menulis ke ledger. Alasan: jalur tulis kedua menyebabkan penyimpangan
saldo Mar-2025. Tambahkan perilaku baru sebagai metode pada agregat,
bukan query baru.
- **Event sourcing hanya untuk ledger.** Sisa sistem adalah CRUD.
Alasan: kami memerlukan audit trail yang sempurna untuk uang dan
tidak ada yang lain, dan event sourcing penuh terlalu mahal di tempat lain.
## Alternatif yang ditolak (jangan diperkenalkan kembali)
- ORM lazy-loading di seluruh agregat; menyebabkan N+1 dan batas
transaksi yang tidak jelas. Repositori mengembalikan agregat yang
dimuat sepenuhnya.
- Menyimpan saldo sebagai kolom yang diperbarui di tempat; lihat
insiden penyimpangan saldo. Saldo selalu diturunkan.
- Pustaka `Money` generik yang ditarik dari registry; kami memiliki
`domain/money.py` sendiri; gunakan itu.
- Webhook sinkron ke merchant dari thread permintaan; mereka memblokir
dan gagal secara diam-diam. Gunakan antrian notifikasi.
## Aturan data dan domain
- Semua timestamp adalah UTC, disimpan sebagai timestamptz, diformat
RFC 3339 di edge. Tidak ada datetime naive yang melewati batas fungsi.
- ID adalah ULID yang dihasilkan di lapisan aplikasi, bukan autoincrement DB.
- Soft delete tidak digunakan. Record aktif atau dipindahkan ke tabel
arsip oleh use case eksplisit.
- Multi-tenant: setiap query dilingkupi oleh `tenant_id`. Metode
repositori tanpa lingkup tenant adalah bug.
## Sumber kebenaran kontrak API
- Spesifikasi OpenAPI 3.1 di `api/openapi.yaml` adalah otoritatif.
Tipe permintaan/respons dihasilkan darinya; jangan edit secara manual
tipe yang dihasilkan di `http/generated/`.
- Endpoint baru atau yang diubah: perbarui `api/openapi.yaml` terlebih
dahulu, lalu regenerasi, lalu implementasikan. Spesifikasi dirancang
dan ditinjau di Apidog sebelum perubahan kode.
- Respons kesalahan mengikuti RFC 9457 (problem+json). Gunakan helper
`problem()` bersama; jangan membuat bentuk kesalahan ad-hoc.
## Tempat kode baru ditempatkan
- Endpoint baru: route di `http/routes/`, DTO di `http/dto/`, use
case di `app/usecases/`, logika domain di `domain/`.
- Integrasi eksternal baru: client di `infra/clients/`, interface
di `app/ports/`.
- Cross-cutting concern (auth, logging, idempotency): middleware di
`http/middleware/`, tidak pernah inline di handler.
## Di luar cakupan / jangan sentuh
- `http/generated/`: diregenerasi dari OpenAPI, editan akan hilang.
- `legacy/billing_v1/`: dibekukan, dalam migrasi. Jangan diperluas.
- `migrations/`: jangan pernah mengedit migrasi yang sudah diterapkan;
tambahkan yang baru.
## Jika ragu
Jika perubahan yang diminta memerlukan pelanggaran aturan di atas,
tindakan yang tepat adalah menyatakan hal tersebut dan mengusulkan
alternatif terkecil yang konsisten dengan desain, bukan secara diam-diam
mengatasi aturan tersebut.
Bagian terakhir itu lebih penting dari yang terlihat. Memberi tahu agen apa yang harus dilakukan ketika permintaan bertentangan dengan desain mengubah file dari dokumentasi pasif menjadi pembatas aktif. Tanpa itu, agen yang menemui kendala cenderung melewatinya dan mengirimkan *workaround*.
Bagaimana agen pengodean sebenarnya mengonsumsi DESIGN.md
Agen tidak memiliki *parser* DESIGN.md khusus. Mereka mengonsumsinya dengan cara yang sama seperti mengonsumsi file apa pun: dengan membacanya dengan alat file mereka dan memperlakukan konten sebagai *konteks*. Jadi, mekanisme untuk memuatnya itu penting, dan sedikit berbeda per alat.
Pola yang dapat diandalkan adalah mereferensikan DESIGN.md dari file instruksi yang sudah dimuat setiap agen saat *startup*. Untuk Claude Code, itu adalah CLAUDE.md; dokumen memori menjelaskan sintaks impor @path di mana @DESIGN.md memperluas file ke dalam *konteks* saat sesi dimulai. Untuk ekosistem AGENTS.md, Anda menambahkan baris di AGENTS.md yang menunjuknya ("Aturan arsitektur dan desain: lihat DESIGN.md; baca sebelum perubahan struktural"). Agen yang menjelajahi *directory tree* akan mengambil AGENTS.md terdekat, melihat penunjuk, dan menarik DESIGN.md ketika pekerjaan menyentuh arsitektur. Dengan cara apa pun, Anda tidak menduplikasi konten; Anda menjaga file operasional yang pendek tetap pendek dan membiarkan file yang mendalam menjadi mendalam.
Tiga catatan praktis tentang perilaku alat ini:
Pertama, agen memperlakukan file sebagai *konteks*, bukan sebagai aturan yang ditegakkan. Dokumen Claude Code menyatakan dengan jelas bahwa konten CLAUDE.md adalah panduan yang coba diikuti model, bukan batasan keras. Hal yang sama berlaku untuk apa pun yang Anda referensikan darinya. Itulah mengapa templat mengartikan semuanya sebagai *absolute* yang dapat diuji dan menambahkan instruksi eksplisit "jika ragu"; prosa yang samar diabaikan di bawah tekanan, aturan yang tajam lebih sering diikuti.
Kedua, panjang dan struktur mengubah kepatuhan. *Header* dan *bullet* lebih baik daripada paragraf karena model memindai struktur seperti yang dilakukan pembaca. Dinding filosofi arsitektur setebal 3 halaman akan dibaca sekilas; sepuluh *invariant* yang tajam di bawah judul yang jelas akan digunakan. Tulis untuk *retrieval*, bukan untuk prosa.
Ketiga, file tersebut mengubah ekonomi *review*, tidak hanya *generasi*. Bahkan ketika agen sebagian mengabaikannya, *reviewer* dapat menunjuk aturan yang dilanggar dan agen memperbaikinya dalam satu giliran ("ini melanggar aturan jalur tulis tunggal di DESIGN.md"). Lingkaran umpan balik itu, mendasarkan koreksi pada keputusan tertulis, adalah tempat sebagian besar nilai sebenarnya berada. Tim yang membangun *agent harness* mereka sendiri sangat bergantung pada hal ini; lihat build your own Claude Code untuk bagaimana lingkaran itu dihubungkan ke alur otonom.
Anti-pola dan cara mencegahnya rusak
Cara tercepat untuk membuat DESIGN.md tidak berharga adalah dengan menuliskannya seperti halaman *wiki*. File desain yang rusak lebih buruk daripada tidak ada, karena agen dan manusia sama-sama mempercayainya dan tersesat. Hindari hal-hal ini.
Mengulang kembali kode. "Kelas UserService menangani pengguna" tidak memberi tahu agen apa pun yang tidak dapat dibaca dari user_service.py. Jika sebuah kalimat benar dengan membaca file, hapus. Simpan hanya apa yang tidak dapat diberitahukan oleh kode kepada Anda: alasan, *invariant*, jalur yang ditolak.
Penyebaran tutorial. Langkah-langkah "cara menambahkan fitur" ada di CONTRIBUTING.md atau *skill*, bukan di sini. Saat DESIGN.md memiliki perintah *shell* dan *snippet copy-paste*, itu adalah dokumen yang salah dan akan menjadi usang dengan kecepatan *tooling*.
Aspirasi sebagai fakta. Menulis "sistem menggunakan CQRS" ketika separuh darinya tidak melatih agen untuk menghasilkan kode yang sesuai dengan fiksi. Dokumentasikan apa yang benar sekarang ditambah ke mana Anda sengaja menuju, dan labeli perbedaannya. "Target: semua penulisan melalui *use case*. Saat ini: legacy/ melewati ini; jangan diperpanjang."
Tidak ada pemilik, tidak ada pemicu *review*. File desain yang tidak ada yang bertanggung jawab atasnya akan menyimpang dalam seperempat. Ikatlah pada pemicu: *review* DESIGN.md di PR apa pun yang menambahkan modul, mengubah batas lapisan, atau memperkenalkan dependensi eksternal baru. Letakkan aturan itu di templat PR. Beberapa tim menambahkan item daftar periksa, "apakah perubahan ini mengubah keputusan di DESIGN.md? Jika ya, perbarui di PR yang sama."
Sinkronisasi teater. Jangan mencoba untuk tetap sinkron baris-demi-baris dengan kode; itu adalah permainan yang kalah dan itu adalah alasan mengapa dokumen arsitektur ditinggalkan. Pertahankan pada tingkat keputusan yang berubah beberapa kali setahun, bukan *signature* fungsi yang berubah setiap minggu. Panduan ARCHITECTURE.md dari matklad adalah naluri yang tepat di sini: hanya tuliskan apa yang tidak mungkin sering berubah.
Bertentangan dengan file instruksi lainnya. Jika AGENTS.md mengatakan satu hal tentang penanganan kesalahan dan DESIGN.md mengatakan yang lain, agen memilih salah satu secara acak. Pertahankan aturan operasional di AGENTS.md / CLAUDE.md dan aturan arsitektur di DESIGN.md, dan jangan biarkan mereka tumpang tindih. Ketika mereka harus saling mereferensikan, salah satunya menunjuk ke yang lain; mereka tidak berdua menegaskan fakta yang sama.
DESIGN.md yang sehat itu singkat, padat, deklaratif, memiliki pemilik, dan ditinjau berdasarkan pemicu. Jika milik Anda panjang, naratif, dan terakhir disentuh setahun yang lalu, agen sedang membaca fiksi.
DESIGN.md untuk API dan basis kode *backend*
Di sinilah file itu mendapatkan tempatnya. Layanan API dan *backend* memiliki jenis batasan yang tidak terlihat dan berbiaya tinggi yang paling buruk bagi agen: batas kontrak, semantik transaksi, *idempotency*, integritas data, *layering*. Semua itu tidak jelas dari satu file pun, dan salah menjalankannya akan menghasilkan *bug* yang mencapai produksi dan uang.
Sertakan hal-hal khusus API ini di DESIGN.md dan kualitas *output* agen pada tiket *backend* akan melonjak:
Kontrak adalah sumber kebenaran, dan sebutkan di mana letaknya. Nyatakan dengan jelas bahwa spesifikasi OpenAPI adalah otoritatif dan tipe yang dihasilkan tidak boleh diedit secara manual. Agen suka "dengan ramah" mengubah tipe yang dihasilkan agar *build* lolos; satu baris di DESIGN.md menghentikannya. Arahkan ke jalur file spesifikasi. Jika Anda mendesain kontrak terlebih dahulu di Apidog dan mengekspor dokumen OpenAPI ke repositori, DESIGN.md Anda dapat menamai file tersebut sebagai hal yang harus dipatuhi setiap *endpoint*, dan agen memiliki target yang tidak ambigu. Argumen untuk mendesain kontrak sebelum kode dibahas dalam designing APIs for AI agents; kontrak *design-first* persis seperti yang membuat *handler* yang dihasilkan agen aman untuk diterima.
Batas transaksi dan konsistensi. Di mana transaksi dimulai dan berakhir? Apa yang diizinkan di dalamnya? "Panggilan eksternal tidak pernah terjadi di dalam transaksi DB; gunakan *outbox*." Agen secara default akan melakukan panggilan *inline* yang *naive* setiap saat kecuali file melarangnya.
*Idempotency* dan *retries*. Nyatakan strategi *idempotency* sebagai *invariant*. *Endpoint* pembayaran, pesanan, dan penyediaan adalah tempat di mana kunci *idempotency* yang hilang menjadi *double-charge*. Agen tidak akan menyimpulkan ini dari membaca *handler*.
Model kesalahan. Satu kalimat: "semua kesalahan adalah problem+json melalui *helper* problem(); jangan pernah membuat bentuk kesalahan." Tanpa itu, Anda akan mendapatkan *envelope* kesalahan yang berbeda per *endpoint*, yang merusak setiap klien.
Autentikasi dan lingkup *tenancy*. "Setiap *query* memiliki lingkup *tenant*; metode repositori tanpa lingkup *tenant* adalah *bug*." Ini adalah *invariant* keamanan, dan tidak terlihat dalam *query* individual mana pun, jadi ini adalah jenis aturan yang harus ditulis.
*Versioning* dan aturan *breaking-change*. Apa yang dianggap sebagai *breaking change*, bagaimana Anda melakukan *versioning*, apa yang diizinkan dalam *minor version*. Agen dengan senang hati akan mengganti nama *field* respons; file memberi tahu mereka bahwa itu adalah *breaking change* dengan sebuah proses.
Untuk pekerjaan *backend*, hasilnya konkret: lebih sedikit pelanggaran lapisan, tidak ada panggilan *gateway inline* yang mengejutkan, bentuk kesalahan dan *pagination* yang konsisten, dan *handler* yang sesuai kontrak karena agen diarahkan ke spesifikasi OpenAPI daripada menebak skema. Agen berhenti berinovasi dan mulai menyesuaikan diri. Jika Anda ingin agen juga menjalankan API yang baru ditulisnya, kombinasi kontrak-plus-desain adalah yang memungkinkan alat dan agen menguji terhadap antarmuka yang diketahui; Unduh Apidog memberi Anda ruang kerja *design-first*, ekspor OpenAPI yang ditunjuk oleh DESIGN.md Anda, dan server MCP serta *debugger* agen AI untuk memeriksa apakah *endpoint* yang dihasilkan benar-benar cocok dengan kontrak.
Kesimpulan
DESIGN.mdmencatat mengapa kode Anda berbentuk seperti itu: *invariant*, keputusan, dan alternatif yang ditolak yang tidak dapat dibaca agen dari sumber.- Ini melengkapi, bukan menggantikan,
AGENTS.mddanCLAUDE.md: file-file tersebut tetap singkat dan operasional;DESIGN.mdmemegang arsitektur yang mendalam dan direferensikan dari file-file tersebut. - Tulis secara deklaratif, sebagai *absolute* yang dapat diuji ditambah aturan "jika ragu, tandai jangan cari jalan keluar", sehingga berfungsi sebagai pembatas, bukan prosa pasif.
- Ini paling bermanfaat pada basis kode API dan *backend*, di mana batas kontrak, transaksi, *idempotency*, dan cakupan *tenancy* tidak terlihat dan mahal jika salah.
- Jaga agar tidak rusak dengan pemilik dan pemicu *review* yang terkait dengan templat PR Anda; jangan pernah menyinkronkannya baris demi baris dengan kode.
- Kemenangan *backend* terbesar adalah menamai spesifikasi OpenAPI sebagai otoritatif sehingga agen sesuai dengan kontrak daripada menciptakan skema.
- Rancang kontrak itu terlebih dahulu. Unduh Apidog untuk merancang API secara *design-first*, mengekspor spesifikasi OpenAPI yang ditunjuk oleh
DESIGN.mdAnda, dan menguji bahwa *endpoint* yang dihasilkan agen benar-benar cocok dengannya.
FAQ
Apakah DESIGN.md merupakan standar resmi seperti AGENTS.md?
Tidak. AGENTS.md adalah format yang didefinisikan dan banyak diadopsi sekarang diatur di bawah *Agentic AI Foundation* dari *Linux Foundation*. DESIGN.md adalah konvensi komunitas tanpa pemilik atau spesifikasi tunggal, dalam keluarga yang sama dengan ARCHITECTURE.md dan ADR. Perlakukan itu sebagai pola yang berguna yang Anda adaptasi, bukan standar yang Anda patuhi.
Apakah saya membutuhkan DESIGN.md jika saya sudah memiliki AGENTS.md atau CLAUDE.md?
Jika arsitektur Anda memiliki batasan yang tidak jelas, ya. AGENTS.md dan CLAUDE.md dimaksudkan untuk tetap singkat dan operasional; dokumen Claude Code merekomendasikan untuk menjaga CLAUDE.md di bawah sekitar 200 baris. Alasan arsitektur yang mendalam tidak muat di sana tanpa memperbesarnya dan merugikan kepatuhan, jadi Anda memasukkannya ke DESIGN.md dan mereferensikannya. Untuk file operasional itu sendiri, lihat cara menulis file AGENTS.md.
Apa perbedaan DESIGN.md dengan ARCHITECTURE.md?
Terutama maksud dan audiens. ARCHITECTURE.md adalah konvensi yang lebih tua yang ditujukan untuk kontributor manusia yang memetakan basis kode. DESIGN.md adalah ide yang sama yang ditulis untuk audiens yang mencakup agen pengodean: lebih deklaratif, berfokus pada keputusan dan *invariant*, dan secara eksplisit direferensikan dari file instruksi agen sehingga dimuat ke dalam *konteks*. Banyak tim menggunakan satu file dan satu nama; prinsip-prinsipnya sama.
Berapa lama seharusnya DESIGN.md?
Cukup panjang untuk mencakup keputusan yang terus-menerus salah dilakukan agen, cukup singkat sehingga setiap baris mendapatkan tempatnya. Padat keputusan mengalahkan komprehensif. Jika terbaca seperti tutorial atau mengulang kode, hapus. Dua hingga empat halaman *invariant* dan alasan yang terfokus lebih baik daripada narasi lima belas halaman yang tidak akan dibaca agen dengan cermat.
Bagaimana cara membuat agen benar-benar membacanya?
Referensikan dari file yang sudah dimuat agen saat *startup*. Untuk Claude Code, impor dari CLAUDE.md dengan @DESIGN.md. Untuk ekosistem AGENTS.md, tambahkan baris penunjuk di AGENTS.md yang memberi tahu agen untuk membaca DESIGN.md sebelum perubahan struktural. Jangan tempel seluruhnya ke dalam file singkat; referensikan agar file operasional tetap singkat.
Apakah agen akan selalu mengikuti DESIGN.md?
Tidak, dan Anda harus mendesain berdasarkan itu. File instruksi agen adalah *konteks* yang coba diikuti model, bukan konfigurasi yang ditegakkan. Tulis aturan sebagai *absolute* yang tajam, tambahkan instruksi eksplisit "tandai konflik, jangan cari jalan keluar", dan bersandar pada lingkaran *review*; menunjuk ke aturan yang dilanggar di DESIGN.md akan menghasilkan perbaikan cepat dan benar bahkan ketika lintasan pertama melewatkannya.
Apakah DESIGN.md membantu masalah kontrak API secara khusus?
Banyak. Penggunaan *backend* dengan nilai tertinggi adalah menyatakan bahwa spesifikasi OpenAPI adalah otoritatif dan menamai file, sehingga agen sesuai dengan kontrak daripada menciptakan skema atau mengedit tipe yang dihasilkan secara manual. Mendesain kontrak itu terlebih dahulu dalam alat seperti Apidog memberi agen target yang tidak ambigu yang dapat langsung ditunjuk oleh DESIGN.md Anda.
Di mana seharusnya DESIGN.md berada di repositori?
Di *root* repositori, di sebelah README.md dan AGENTS.md, sehingga agen dan manusia menemukannya tanpa perlu mencari. Dalam *monorepo*, DESIGN.md *root* untuk aturan seluruh sistem ditambah satu per paket untuk arsitektur lokal berfungsi dengan baik, mencerminkan bagaimana agen membaca AGENTS.md terdekat di *directory tree*.
