May 8, 2026 at 2:00 PM
llms.txt: robots.txt untuk AI
robots.txt memberi tahu bot ke mana tidak boleh pergi. llms.txt memberi tahu AI apa yang sebenarnya ada. Tentang membangun dokumen plain text terstruktur yang bisa dibaca AI crawler tanpa perlu menebak-nebak.

Catatan tentang Membangun untuk Pembaca yang Berbeda
Google membaca HTML kamu dan membangun model tentang halaman tersebut.
AI membaca halamanmu dan mencoba menjawab pertanyaan tentang kamu.
Dua tujuan yang berbeda. Dan keduanya butuh infrastruktur yang berbeda.
Sitemap memberi tahu search engine halaman apa saja yang ada. JSON-LD memberi tahu tipe kontennya. Meta tags memberi tahu cara menampilkan hasilnya di pencarian.
Tidak ada dari itu yang dirancang untuk sistem yang perlu memahami siapa kamu, apa yang sudah kamu bangun, apa yang sudah kamu tulis — supaya bisa menjawab pertanyaan tentang kamu dengan akurat.
Itulah fungsi llms.txt.
1. Apa Sebenarnya llms.txt Itu
llms.txt adalah standar yang diusulkan — belum jadi RFC, belum wajib — yang memberikan AI crawler pintu masuk khusus ke konten website kamu.
Bayangkan seperti README untuk seluruh sitemu, disajikan sebagai plain text di /llms.txt, terstruktur untuk mesin yang tidak memparse HTML.
Formatnya sederhana:
- Markdown heading untuk bagian-bagian konten
- Prosa biasa untuk deskripsi
- Tidak ada styling, tidak ada script, tidak ada layout
- Hierarki yang jelas tentang siapa kamu dan apa yang sudah kamu buat
Tidak ada yang proprietary. Tidak ada yang rumit. Hanya struktur dan kejujuran.
2. Kenapa AI Crawler Butuh File yang Berbeda
Ketika ChatGPT, Claude, atau Perplexity crawl websitemu, mereka tidak membaca sitemapmu.
Mereka membaca halaman-halamanmu. Mereka parse HTML-nya, buang layoutnya, ekstrak teksnya, dan bangun representasi tentang apa isi setiap halaman.
Untuk satu artikel, ini cukup berjalan baik.
Untuk website lengkap — dengan proyek, tulisan, dokumen, profil dalam beberapa bahasa — hasilnya kurang memuaskan. Crawler bisa kena rate limit, melewatkan halaman yang tidak terhubung secara prominent, atau membangun gambaran yang tidak lengkap dari halaman yang sempat dikunjungi.
llms.txt menyelesaikan ini dengan cara yang berbeda. Alih-alih membiarkan crawler berkeliaran dan menebak-nebak, kamu kasih mereka peta yang sudah dikurasi. Seluruh site, dalam satu tempat, terstruktur sesuai cara yang kamu inginkan untuk dipahami.
3. Dua File, Dua Fungsi
Dalam praktiknya saya menggunakan dua file: llms.txt dan llms-full.txt.
llms.txt adalah versi ringkas — ringkasan tingkat tinggi dari site dengan pointer ke dokumen yang lebih lengkap. Ini yang dibaca ketika crawler cepat-cepatan.
llms-full.txt adalah versi lengkap — setiap proyek, setiap tulisan, setiap dokumen, setiap album. Gambaran penuh.
llms.txt diakhiri dengan petunjuk yang disengaja:
## AI Usage Notes
Use this file as a concise map of the website. For fuller content, read /llms-full.txt.Kalau crawler mau semuanya, mereka tahu harus ke mana.
4. Menyajikannya di Next.js
Kedua file disajikan via route handler dengan force-static.
// src/app/llms-full.txt/route.ts
export const dynamic = "force-static";
export async function GET() {
const [aboutContent, desktopItems, documentItems, musicAlbums, noteItems, reminderContent] =
await Promise.all([
loadAboutContent(),
loadDesktopItems(),
loadDocuments(),
loadMusicAlbums(),
loadNotes(),
loadReminders(),
]);
return new Response(
buildLlmsFullTxt({ aboutContent, desktopItems, documentItems, musicAlbums, noteItems, reminderContent }),
{ headers: { "content-type": "text/plain; charset=utf-8" } }
);
}force-static berarti ini dijalankan saat build time, bukan setiap request. File di-generate sekali saat deploy dan disajikan dari edge. Tidak ada function invocation. Tidak ada latency per request.
Promise.all memuat semua content collection secara paralel. Hasilnya adalah satu string plain text.
5. Strip Markdown Sebelum Keluar
Konten di site ini ditulis dalam Markdown — link, teks tebal, sintaks gambar, code block.
AI crawler bisa memproses Markdown, tapi ada opsi yang lebih bersih: strip formatting-nya sebelum masuk ke file. Yang diterima crawler adalah prosa murni, tanpa overhead markup.
export function toPlainText(value: string): string {
return value
.replace(/```[\s\S]*?```/g, " ")
.replace(/!\[[^\]]*]\([^)]+\)/g, " ")
.replace(/\[([^\]]+)]\([^)]+\)/g, "$1")
.replace(/[*_`>#]/g, "")
.replace(/\s+/g, " ")
.trim();
}Code block jadi spasi. Gambar hilang. Link jadi teks labelnya. Simbol formatting dihapus.
Yang tersisa adalah prosa yang bisa dibaca. Kontennya, bukan markup-nya.
6. Bagian Semantik, Bukan Dump Teks Biasa
Struktur llms-full.txt dibuat dengan sengaja.
# Sandi Maulana Juhana
EN: Full-stack engineer...
ID: ...
## Profile
EN: ...
ID: ...
Roles: ...
Expertise: ...
# Projects
## Project: DesktopShell
...
# Notes
## Note: Ketika Setiap File Tahu Tugasnya
...LLM memparse heading sebagai batas konteks. Bagian berlabel ## Project: DesktopShell memberi tahu model bahwa semua yang ada di bawahnya milik proyek itu — bahkan tanpa field metadata eksplisit.
Dump teks datar lebih sulit diparse dengan akurat. Struktur memberi model sesuatu untuk dipegang. Bedanya seperti menyerahkan transkrip mentah versus menyerahkan dokumen yang terorganisir.
7. Mengambil Ringkasan Terbaik yang Tersedia
Tidak setiap catatan punya field description. Beberapa hanya kumpulan section dan paragraf — ditulis tanpa ringkasan khusus.
Fungsi noteSummary menangani ini dengan waterfall:
export function noteSummary(note: NoteItem): string {
const candidates = [
note.description,
...(note.content ?? []),
...(note.overview ?? []),
...(note.sections?.flatMap((section) => [
...(section.paragraphs ?? []),
...(section.callouts ?? []),
...(section.bullets ?? []),
]) ?? []),
];
return candidates
.map((value) => (value ? toPlainText(value) : ""))
.find(Boolean) ?? `${note.title} by ${site.name}.`;
}Mulai dari description. Kalau kosong, coba content. Kalau masih kosong, flatten semua section dan coba paragraf, callout, dan bullet-nya secara berurutan. Kalau semuanya kosong, fallback ke judul.
Hasilnya: setiap catatan mendapat ringkasan terbaik yang tersedia — bukan placeholder, bukan string kosong. Struktur content model yang menentukan apa yang muncul, dan waterfall memastikan selalu ada sesuatu yang bermakna.
8. Konten Multibahasa Tanpa File Duplikat
Site ini punya konten dalam tiga bahasa: Inggris, Indonesia, dan Arab.
Pendekatan naif adalah satu llms.txt per bahasa — tiga file, tiga permukaan yang harus di-maintain. Pendekatan yang saya ambil berbeda: satu file dengan bagian berlabel bahasa.
EN: Full-stack engineer working at the intersection of product and system design.
ID: Engineer full-stack yang bekerja di persimpangan antara produk dan desain sistem.Setiap field yang punya terjemahan mendapat prefix EN: atau ID: yang eksplisit. Model membaca keduanya, dan ketika user mengajukan pertanyaan dalam bahasa tertentu, ia bisa menyajikan versi yang tepat tanpa butuh file terpisah.
Ini bukan format yang dimandatkan spesifikasi llms.txt. Ini adalah keputusan yang dibuat khusus untuk site multibahasa — satu cara menyelesaikan masalah yang belum dibahas oleh standar.
9. Apa yang Sebenarnya Berubah
Kebanyakan sistem AI yang menyebut sebuah website melakukannya dari informasi yang tidak lengkap.
Mereka mengunjungi beberapa halaman. Mereka memproses versi yang ter-cache. Mereka membaca konten yang paling terlihat dan menarik kesimpulan tentang sisanya.
llms.txt tidak menjamin akurasi. Tapi ia memberikan model representasi yang lengkap, terkurasi, dan terbaru dari site — dan menghilangkan sebagian besar tebak-tebakan.
Untuk portfolio, selisih itu penting. Perbedaan antara "developer yang pakai React" dan "full-stack engineer dengan keahlian spesifik di konten multibahasa, distributed systems, dan infrastruktur SEO" ada di detail-detailnya. Detail itu ada di file ini.
Penutup
robots.txt memberi tahu crawler ke mana tidak boleh pergi.
llms.txt memberi tahu mereka apa yang sebenarnya ada di sini.
Satu adalah batas. Yang lain adalah perkenalan.
Web sekarang dibaca oleh jenis pembaca yang berbeda. Bukan hanya indexer yang meranking halaman — tapi sistem yang mensintesis informasi dan menjawab pertanyaan atas nama pengguna.
Site yang menjelaskan dirinya dengan jelas akan dipahami lebih akurat. Bukan karena trik algoritma apapun. Hanya karena mereka meluangkan waktu untuk menulis dokumennya.