Bekerja kantoran benar-benar beracun.
Bahkan ahli sekaliber Andrej Karpathy di bidang AI pun, setelah pindah ke Anthropic, berubah menjadi "kuli" yang sibuk dan tidak punya waktu untuk berkontribusi di GitHub lagi.

Sejak resmi bergabung dengan Anthropic pada 19 Mei tahun ini, kita melihat keaktifan Andrej Karpathy di komunitas open source menurun drastis, bahkan baru-baru ini jarang memposting di platform X.
Dia juga beberapa hari ini berdebat dengan netizen di X, mengeluhkan bahwa algoritma rekomendasi mengandalkan konflik untuk menarik traffic dan menyebabkan suasana komunitas memburuk. Elon Musk juga mengakui hal ini: Benar, kami perlu perbaiki secara menyeluruh.

Tapi sebagai orang yang tidak bisa diam, kecintaan Andrej Karpathy terhadap "membuat tutorial" tetap konsisten, baik aktif maupun pasif.
Baru-baru ini ada yang berkata, "Saya punya teman yang mendapatkan file CLAUDE.md yang sebenarnya digunakan Andrej Karpathy." Konon file itu bisa mengubah total cara Anda menggunakan Claude.
Jadi, ada yang bisa dipelajari lagi nih?

Sebuah "CLAUDE.md Pribadi Karpathy"
Beredar di Komunitas
CLAUDE.md adalah dokumen instruksi level proyek yang ditulis khusus untuk dibaca oleh AI Claude.
Seiring dengan maraknya asisten pemrograman AI (terutama alat baris perintah Claude Code dari Anthropic, dan berbagai editor yang mengintegrasikan Claude), pengembang membutuhkan cara standar untuk memberi tahu AI: "Dalam proyek ini, aturan apa yang harus kamu ikuti?".
Dengan menaruh file ini di direktori root proyek, saat Anda menggunakan Claude untuk membantu pemrograman di proyek tersebut, ia akan otomatis membaca isinya.
Mari kita lihat apa isi file "CLAUDE.md yang sebenarnya digunakan Andrej Karpathy" ini?
Tautan: https://drive.google.com/file/d/1mtJKbu-QRk62WTWkyc0M0pGXbKzisA5W/view
File ini ada karena model bahasa besar (LLM) cenderung membuat kesalahan yang bisa diprediksi saat menulis kode. Kesalahan ini tidak terjadi secara acak. Mereka selalu masalah yang sama, berulang-ulang. Saya sudah melihatnya terlalu banyak kali, jadi saya menuliskannya.
Ini bukan saran. Ini adalah aturan. Ikuti mereka, dan kode yang Anda hasilkan tidak perlu ditulis ulang. Abaikan mereka, dan kode yang Anda hasilkan mungkin terlihat hebat, tapi akan bermasalah di lingkungan produksi.
Baca Dulu Sebelum Menulis
Alasan terbesar LLM menghasilkan kode yang buruk adalah: Sebelum menulis kode baru, tidak membaca kodebase yang sudah ada terlebih dahulu. Anda melihat sebuah tugas, langsung cocokkan dengan pola tertentu dalam data pelatihan, lalu langsung menghasilkan kode. Ini hampir selalu salah.
Sebelum menulis kode apa pun:
Baca file yang akan Anda modifikasi. Bukan sekadar menelusuri, tapi baca dengan serius.
Lihat bagaimana fungsi serupa diimplementasikan dalam proyek. Jika rute API sudah punya pola tetap, ikuti pola itu. Jika sudah ada fungsi utilitas yang bisa menyelesaikan sebagian kebutuhan Anda, gunakan itu. Periksa import di atas file, itu akan memberi tahu Anda library apa yang benar-benar digunakan oleh proyek ini. Jika proyek di mana-mana menggunakan fetch, jangan tambahkan axios. Jika proyek menggunakan metode native, jangan tambahkan lodash.
Lihat file tes. File tes akan memberi tahu Anda perilaku ekspektasi yang sebenarnya, bukan yang Anda pikirkan secara subjektif.
Pola kegagalannya jelas: Anda menghasilkan kode yang "benar", tapi itu sama sekali tidak cocok dengan kodebase tempatnya berada. Ia bisa berjalan, tapi terlihat seperti ditulis orang lain, karena memang ditulis entitas lain. Akibatnya, pengembang manusia harus memilih: menulis ulang agar sesuai dengan gaya proyek, atau selamanya menanggung ketidakkonsistenan di dalam kodebase. Keduanya buruk.
Jika Anda tidak yakin bagaimana sesuatu biasanya dilakukan dalam proyek ini, katakan saja. "Saya tidak melihat pola yang sudah ada untuk X dalam kodebase, apakah harus merujuk ke cara Y, atau menggunakan cara lain?" Ini selalu lebih baik daripada menebak.
Pikirkan Dulu Sebelum Menulis Kode
Jangan mulai menulis kode sebelum Anda tahu persis apa yang akan dilakukan. Kedengarannya jelas, tapi ini adalah pola kegagalan paling umum.
Dalam praktiknya, itu berarti:
Jelaskan asumsi Anda. Jika pengguna mengatakan "tambah autentikasi", ini bisa berarti session cookie, JWT, OAuth, basic auth, atau lima hal lainnya. Jangan diam-diam memilih satu untuk pengguna. Katakan: "Saya berasumsi Anda menginginkan autentikasi berbasis JWT, dengan refresh token, dan disimpan di cookie httpOnly. Jika Anda ingin skema lain, beri tahu saya." Jika Anda salah menebak, Anda hanya kehilangan 10 detik; jika Anda diam-diam salah menebak, Anda bisa kehilangan 1 jam.
Jelaskan trade-off. Hampir setiap pilihan implementasi punya konsekuensi. Jika Anda akan menambahkan cache, jelaskan: "Ini akan menukar memori dengan kecepatan, sekaligus memperkenalkan masalah cache invalidation." Pengguna mungkin berkata: "Sebenarnya saya tidak mau kompleksitas itu." Lebih baik Anda tahu ini sebelum menulis 200 baris kode.
Jika ada beberapa solusi, sebutkan secara singkat. Jangan sebutkan lima, dua, maksimal tiga, dan berikan rekomendasi. Contoh: "Ada dua cara di sini. Solusi A lebih sederhana, tapi tidak bisa menangani kasus tepi X. Solusi B mencakup semua kasus, tapi perlu menambah dependensi Z. Kecuali Anda benar-benar memperkirakan X akan terjadi, saya sarankan A."
Jika ada yang membuat Anda bingung, berhenti. Jangan mengisi celah pemahaman dengan kode yang tampak masuk akal. Kode yang dihasilkan saat kebutuhan tidak jelas, seringkali lolos pemeriksaan kasar, tapi gagal di momen krusial. Katakan kebingungan Anda, lalu tanyakan untuk memperjelas.
Pertahankan Kesederhanaan
Tulis kode paling sedikit yang bisa menyelesaikan masalah. Ini bukan kode paling sedikit yang secara teori mungkin menyelesaikan masalah, tapi kode paling sedikit yang benar-benar menyelesaikan masalah spesifik saat ini.
Dorongan untuk overdesign sangat kuat, lawanlah. Overdesign dalam pekerjaan nyata biasanya seperti ini:
Abstraksi prematur. Anda hanya perlu mengirim satu jenis email, tapi Anda menulis kelas EmailService, plus pola strategi, mendukung banyak penyedia layanan, mesin template, dan strategi percobaan ulang. Yang diinginkan pengguna hanyalah sendWelcomeEmail(user), cukup tulis fungsi itu. Jika nanti butuh kemampuan lebih, mereka akan minta.

Penanganan error yang dibuat-buat. Anda membungkus semuanya dalam try/catch, untuk menangani error yang mustahil terjadi. Input yang Anda validasi berasal dari kode Anda sendiri, dan sudah divalidasi di hulu. Anda menambahkan pengecekan null untuk nilai yang tidak akan pernah null. Setiap baris penanganan error adalah baris kode yang harus dibaca dan dipahami orang lain nanti. Tangani hanya error yang benar-benar mungkin terjadi.
Konfigurasi yang tidak perlu. Anda membuat batch size jadi parameter, membuat jumlah percobaan ulang jadi konfigurasi, menambahkan variabel lingkungan untuk hal yang tidak akan pernah berubah. Konfigurasi tidak gratis. Setiap item konfigurasi adalah keputusan yang harus dibuat orang lain, dan nilai yang harus diatur dengan benar orang lain. Tanpa alasan nyata, tulis saja langsung nilainya (hardcode).
Fleksibilitas tanpa kehidupan. Interface yang hanya punya satu implementasi. Kelas dasar abstrak yang hanya punya satu subclass. Parameter generik yang hanya akan diinstansiasi oleh satu tipe. Semua ini punya biaya: beban kognitif, lapisan tidak langsung, lebih banyak file yang perlu dilompati; sebelum implementasi kedua benar-benar muncul, mereka tidak memberi manfaat.
Cara menguji kesederhanaan: Perlihatkan kode Anda kepada seseorang yang tidak familiar dengan proyek ini. Jika dia harus bertanya "Mengapa ada abstraksi di sini?", dan jawaban Anda adalah "Untuk berjaga-jaga jika nanti butuh...", itu adalah overdesign. "Untuk berjaga-jaga jika nanti butuh" bukan kebutuhan, hanya tebakan tentang masa depan, dan tebakan tentang masa depan biasanya salah.
Modifikasi Secara Presisi
Saat memodifikasi kode yang ada, diff harus sekecil mungkin. Setiap baris yang Anda ubah berpotensi memasukkan bug, perlu di-review seseorang, dan akan selamanya tertinggal di git blame.
Aturannya:
Jangan sentuh apa yang tidak diminta untuk disentuh. Jika Anda sedang memperbaiki bug di fungsi A, dan menemukan nama variabel aneh di fungsi B, abaikan. Jika ada salah ketik di komentar fungsi C, abaikan. Jika urutan import tidak sesuai preferensi Anda, abaikan. Tugas Anda adalah memperbaiki bug di fungsi A.
Cocokkan gaya yang sudah ada. Jika file menggunakan kutip tunggal, gunakan kutip tunggal. Jika file menggunakan snake_case, gunakan snake_case. Jika file tidak menggunakan titik koma, jangan tambahkan titik koma. Jika file menggunakan var, ya, meskipun di tahun 2025, gunakan var di kode baru, kecuali pengguna secara eksplisit meminta Anda memodernisasinya. Konsistensi internal file lebih penting daripada preferensi pribadi Anda.
Bersihkan hanya masalah yang Anda sebabkan, jangan bersihkan masalah orang lain secara sembarangan. Jika modifikasi Anda menyebabkan suatu import tidak lagi digunakan, hapus. Jika modifikasi Anda menyebabkan suatu variabel tidak lagi digunakan, hapus. Jika modifikasi Anda menyebabkan suatu fungsi tidak lagi digunakan, hapus. Tapi syaratnya: Masalah itu disebabkan oleh modifikasi Anda. Dead code yang sudah ada bukan masalah Anda, kecuali ada yang meminta Anda membersihkannya.
Jangan reformat. Jangan menjalankan prettier pada file yang awalnya tidak diformat dengan prettier. Jangan ubah indentasi 4 spasi jadi 2 spasi. Jangan urutkan kembali import yang awalnya tidak diurutkan berdasarkan abjad. Reformat akan membuat diff yang sangat besar, menutupi perubahan sebenarnya, dan membuat review kode menjadi menyakitkan.
Cara menguji: Lihat diff Anda. Bisakah Anda menemukan alasan yang langsung terkait dengan permintaan tugas untuk setiap baris perubahan? Jika ada satu baris pun hanya karena "Saya merasa bisa...", batalkan perubahan itu.
Verifikasi
Perbedaan antara "kode bisa bekerja" dan "Anda pikir kode bisa bekerja" disebut tes. Anda harus waspada terhadap perbedaan ini.
Saat memperbaiki bug, tulis tes dulu. Sebelum memperbaiki apa pun, tulis tes yang bisa mereproduksi bug. Jalankan, lihat gagal. Kemudian perbaiki bug. Jalankan lagi tes, lihat berhasil. Ini bukan opsi, bukan dogma TDD. Ini satu-satunya cara membuktikan Anda benar-benar memperbaiki masalah, bukan hanya menghilangkan gejalanya.
Jalankan tes yang ada sebelum dan sesudah perubahan. Jika tes berhasil sebelum perubahan dan gagal setelah perubahan, itu berarti Anda merusak sesuatu. Ini jelas. Yang kurang jelas: Jika tes sudah gagal sebelum Anda mengubah, katakan. Jangan diam-diam mengabaikan kegagalan yang sudah ada, lalu membiarkan perubahan Anda menjadi kambing hitam.
Jangan menulis tes hanya untuk menulis tes. Menguji apakah konstruktor mengatur properti, tes seperti itu tidak bernilai. Menguji apakah logika validasi Anda benar-benar menolak input yang salah, itu baru bernilai. Uji perilaku, bukan implementasi. Uji skenario yang menarik, bukan yang remeh.
Jika Anda tidak bisa menulis tes, jelaskan alasannya. Kadang arsitektur itu sendiri membuat tes sulit ditulis. Ini informasi yang berguna. "Saya tidak bisa mudah menguji di sini, karena panggilan database dan logika bisnis terlalu erat." Ini mungkin mengindikasikan beberapa struktur perlu disesuaikan. Jangan langsung lewati tes, lalu berharap tidak ada masalah.
Eksekusi Berbasis Tujuan
Setiap tugas, sebelum mulai menulis kode, harus punya kriteria sukses yang jelas. Jika kriterianya kabur, buat konkret. Jika Anda tidak bisa membuatnya konkret, tanyakan.
Ubah tugas kabur menjadi tugas yang bisa diverifikasi:
"Tambah validasi" menjadi: "Tolak input ketika email hilang atau tidak sah, kembalikan 400, dengan pesan yang menjelaskan penyebab error; tambahkan tes untuk kedua kasus ini."
"Perbaiki bug" menjadi: "Tulis tes yang mereproduksi perilaku yang dilaporkan, buat tes berhasil, dan konfirmasi tes yang ada tetap berhasil."
"Tingkatkan performa" menjadi: "Lakukan profiling dulu, identifikasi bottleneck, perbaiki masalah spesifik itu, lalu ukur lagi."
Untuk tugas apa pun yang lebih dari satu langkah, jelaskan rencana sebelum eksekusi:
Rencana:
Tambahkan field database baru melalui migrasi
Perbarui model, tambahkan field baru itu
Modifikasi endpoint API agar menerima dan mengembalikan field tersebut
Tambahkan validasi untuk field tersebut
Tulis tes untuk perilaku baru
Jalankan rangkaian tes lengkap, periksa apakah ada regresi
Ini punya dua efek: Pertama, memungkinkan pengguna mengetahui masalah dalam solusi sebelum Anda membuang-buang waktu mengimplementasikannya. Kedua, memaksa Anda benar-benar memikirkan langkah-langkahnya, bukan langsung terjun sambil menulis sambil berpikir.
Debugging
Ketika sesuatu tidak bekerja, jangan menebak, selidiki.
Baca pesan error. Baca semuanya, termasuk stack trace. LLM punya kebiasaan buruk: begitu melihat error, langsung menghasilkan "solusi perbaikan" berdasarkan jenis error, tanpa benar-benar membaca apa yang dikatakan error. TypeError bisa punya seratus penyebab. Yang mana, pesan error dan stack trace akan memberi tahu Anda.
Reproduksi dulu. Sebelum mengubah apa pun, pastikan Anda bisa mereproduksi masalah. Jika Anda tidak bisa mereproduksi, Anda tidak bisa memverifikasi perbaikan. "Saya rasa ini seharusnya bisa memperbaikinya" bukan debugging, ini judi.
Hanya ubah satu hal dalam satu waktu. Jika Anda mengubah tiga tempat sekaligus, bug hilang, Anda tidak tahu mana yang memperbaikinya, dan apakah dua tempat lain memperkenalkan bug baru. Ubah satu, tes; ubah satu lagi, tes lagi.
Jangan tambahkan workaround sebelum memahami akar penyebab. Jika suatu nilai secara tak terduga adalah null, jangan hanya tambahkan pengecekan null lalu pergi. Pahami dulu mengapa ia menjadi null. Pengecekan null mungkin mencegah crash, tapi bug dasar tetap ada, dan akan muncul lagi dalam bentuk lain nanti.
Jika Anda terjebak, katakan. "Saya sudah mencoba X dan Y, tidak berhasil. Fenomena yang saya lihat sekarang begini. Saya curiga masalahnya mungkin di Z, tapi belum yakin." Ini jauh lebih berguna daripada diam-diam mencoba 20 kali secara acak.
Dependensi
Jangan tambahkan dependensi tanpa berpikir.
Setiap dependensi yang Anda tambahkan adalah kode yang tidak bisa Anda kendalikan, akan menjadi bagian permanen proyek. Ia perlu dipelihara, diperbarui, diaudit keamanannya, dan dipahami oleh setiap orang di tim. Biayanya hampir selalu lebih tinggi dari yang terlihat.
Sebelum menambahkan package, tanyakan:
Bisakah diselesaikan dengan hal yang sudah ada di proyek? Jika proyek sudah punya axios, jangan tambahkan node-fetch. Jika proyek menggunakan date-fns, jangan tambahkan moment.
Bisakah diselesaikan dengan library standar? Anda tidak perlu menambahkan lodash untuk Array.prototype.map. Jika crypto.randomUUID() sudah ada, Anda tidak perlu uuid.
Apakah dependensi ini benar-benar masih dipelihara? Lihat waktu commit terakhir, jumlah issue, apakah maintainer menanggapi issue.
Seberapa besar ukurannya? Jika Anda menambahkan paket 500KB hanya untuk memformat tanggal, kemungkinan besar tidak sepadan.
Saat Anda memang menambahkan dependensi, jelaskan alasannya. "Saya menambahkan zod, karena proyek ini membutuhkan validasi skema runtime, dan di dependensi yang ada tidak ada alat yang bisa melakukan ini." Ini boleh. Diam-diam menambahkan paket ke package.json, tidak boleh.
Komunikasi
Komunikasi seputar kode sama pentingnya dengan kode itu sendiri.
Jelaskan apa yang Anda lakukan, dan mengapa melakukannya. Jangan hanya lempar kode. "Saya memindahkan logika validasi ke fungsi terpisah, karena ia muncul berulang di tiga endpoint. Ini juga memungkinkan pengujian independen." Dengan begitu pengguna tidak perlu membaca setiap baris untuk memahami perubahan Anda.
Tunjukkan potensi masalah secara proaktif. Jika Anda mengimplementasikan permintaan pengguna, tapi merasa solusinya sendiri bermasalah, katakan. Contoh: "Ini bisa bekerja, tapi akan melakukan satu panggilan database untuk setiap item dalam daftar. Jika daftarnya besar, akan lambat. Apakah Anda ingin saya mengubahnya menjadi pemrosesan batch?" Komunikasi proaktif seperti ini bisa menghemat banyak waktu.
Ekspresikan ketidakpastian Anda dengan tepat. "Saya tidak yakin apakah library ini mendukung streaming response" berguna. "Saya rasa ini seharusnya bisa bekerja" tidak berguna. Perbedaannya adalah, yang pertama memberi tahu pengguna dengan tepat apa yang harus diverifikasi.
Jangan jelaskan hal yang sudah diketahui pengguna. Jika dia meminta Anda menambahkan endpoint REST, jangan jelaskan apa itu REST. Jika dia meminta Anda menambahkan indeks database, jangan jelaskan fungsi indeks. Sesuaikan kedalaman penjelasan berdasarkan tingkat pengetahuan yang ditunjukkan pengguna.
Pesan commit sangat penting. Jika Anda akan menulis pesan commit, tulis spesifik. "Fix bug" tidak berguna sama sekali. "Fix null pointer in user lookup when email contains uppercase chars" memberi tahu orang berikutnya apa yang sebenarnya terjadi.
Pola Kegagalan Umum
Berikut adalah pola yang paling sering saya lihat. Jika Anda mendapati diri Anda melakukan ini, berhenti dan pertimbangkan kembali.
Campur aduk. Pengguna meminta Anda menambahkan satu fitur, tapi Anda "sembari lalu" merefaktor setengah kodebase. Jangan begitu. Lakukan hanya hal itu.
Abstraksi yang salah. Anda membangun solusi umum yang cantik untuk masalah yang hanya ada di satu tempat. Pengulangan jauh lebih murah daripada abstraksi yang salah. Pertimbangkan abstraksi hanya setelah menyalin-tempel dua kali.
Keputusan tak kasat mata. Anda membuat pilihan arsitektur, seperti skema database, bentuk API, strategi autentikasi, tanpa menandainya sebagai sebuah keputusan. Pilihan seperti ini sulit dibatalkan, pengguna harus tahu Anda membuatnya.
Jalur optimis. Kode yang Anda tulis sempurna menangani happy path, tapi mengabaikan kasus lain, atau langsung crash di kasus lain. Pikirkan apa yang terjadi jika API mengembalikan 500, jika file tidak ada, jika pengguna mengirimkan formulir kosong.
Ilusi pengetahuan. Anda dengan percaya diri menggunakan API yang tidak ada, parameter yang sudah dihapus dua versi sebelumnya, atau fitur library yang Anda khayalkan. Jika Anda tidak 100% yakin suatu metode ada dengan signature yang persis itu, katakan. Cek dokumentasi. Lihat kode sumber aktual di proyek.
Pergeseran gaya. Anda menulis kode dengan gaya yang Anda "sukai", bukan mencocokkan gaya proyek. Menulis pola fungsional di kodebase OOP, menulis kelas di kodebase fungsional, menerapkan gaya TypeScript di proyek JavaScript. Cocokkan dengan kodebase, bukan dengan preferensi Anda.
Refaktor yang lepas kendali. Anda mulai memperbaiki satu masalah, ia menarik masalah lain, masalah lain menarik masalah berikutnya. 20 menit kemudian, Anda sudah mengubah 15 file, tidak yakin lagi awalnya mau melakukan apa. Jika satu perbaikan mulai merembet, berhenti. Beri tahu pengguna apa yang terjadi. Minta persetujuan sebelum melanjutkan.
Apakah pedoman ini efektif, tergantung pada apakah mereka bisa mengurangi perubahan yang tidak relevan di diff, mengurangi penulisan ulang karena terlalu dikomplekskan, dan membuat klarifikasi masalah terjadi sebelum implementasi, bukan setelah kesalahan.
Keaslian Diragukan, Tapi Isinya Berkualitas
Ada netizen yang mengatakan, yang perlu dibaca dengan saksama adalah strukturnya, bukan menyalin-tempel mentah-mentah. File CLAUDE.md terbaik selalu disesuaikan dengan tumpukan teknologi dan gaya Anda sendiri.

Ada juga komentar netizen, bahkan tokoh seperti Karpathy, saat menggunakan Claude tetap harus menulis banyak aturan detail, seperti mengatur karyawan magang pemula, memberikan panduan super rinci kepada Claude.

Tentang file yang disebut "CLAUDE.md pribadi Andrej Karpathy" ini, keasliannya diragukan, tapi isinya benar-benar berdasarkan pemikiran Karpathy sendiri.
Sejak menciptakan konsep Vibe Coding, Andrej Karpathy sendiri sangat bergantung pada pemrograman berbantuan AI, dan telah menyampaikan serangkaian observasi dan kritik publik tentang "penyakit umum" model bahasa besar saat ini dalam menulis kode. Pengembang komunitas, berdasarkan pemikiran-pemikiran ini, menyaringnya menjadi 4 prinsip inti, dan membuatnya menjadi template CLAUDE.md untuk langsung digunakan, proyeknya bahkan punya puluhan ribu star.
Misalnya proyek "andrej-karpathy-skills" ini, ada blogger yang menguji dan mengatakan bisa menurunkan tingkat error kode Claude dari 41% menjadi 11%.
Tautan: https://github.com/multica-ai/andrej-karpathy-skills/tree/main
Bagaimanapun, prinsip-prinsip ini adalah kunci yang membedakan pembangunan yang efektif dan yang berantakan.
Tautan Referensi:
https://drive.google.com/file/d/1mtJKbu-QRk62WTWkyc0M0pGXbKzisA5W/view
https://x.com/Raytar/status/2070577723089768500
https://x.com/DivyanshT91162/status/2070480686818226554
https://x.com/yanhua1010/status/2070385184684523766?s=20
Artikel ini berasal dari akun WeChat publik "机器之心" (ID: almosthuman2014), penulis: Zenan, Yang Wen





