SSD Nodes Learn Hosting plans →
Panduan Matt ConnorOleh Matt Connor · Dikemas kini 2026-08-29

Cara Guna AGENTS.md Bersarang dalam Monorepo

Fail AGENTS.md tunggal di root sering menjadi lapuk dan membuang konteks. Gunakan struktur bersarang untuk memastikan ejen AI hanya membaca arahan khusus bagi setiap servis.

Apakah maksud AGENTS.md bersarang dalam monorepo

AGENTS.md bersarang dalam monorepo bermaksud satu fail kecil di root repositori dan satu lagi fail di dalam setiap direktori servis. Fail root menyimpan beberapa peraturan yang terpakai di mana-mana, serta peta lokasi fail lain. Setiap fail servis menyimpan arahan dan konvensyen untuk direktori itu sahaja. Ejen yang menyunting services/worker/queue.py kemudian membaca fail root dan fail pekerja, dan tidak menggunakan sebarang konteks pada bahagian front end yang tidak akan disentuhnya.

Tiada apa-apa yang perlu dipasang. AGENTS.md hanyalah satu konvensyen, dan projek huluan menyatakan perkara ini dengan jelas:

AGENTS.md hanyalah Markdown standard. Gunakan sebarang tajuk yang anda suka; ejen hanya menghuraikan teks yang anda sediakan.

Itulah sebabnya teknik ini berbaloi untuk dipelajari dengan betul. Formatnya tidak akan berubah. Perkara yang boleh terjejas ialah penempatan dan penyelenggaraan, dan kedua-duanya adalah tanggungjawab anda.

Mengapa satu fail AGENTS.md induk di root berhenti berfungsi?

Satu fail AGENTS.md sepanjang 600 baris di root repositori yang menempatkan aplikasi web, pekerja latar belakang, dan direktori Terraform gagal dalam empat cara berbeza.

Ia menjadi lapuk kerana tiada siapa yang memilikinya. Jurutera yang menamakan semula skrip ujian dalam apps/web sedang menyunting fail di bawah apps/web. Fail AGENTS.md di root tidak termasuk dalam diff tersebut, jadi tiada penyemak yang melihat ketidakpadanan itu. Enam minggu kemudian, fail tersebut menerangkan langkah binaan yang tidak lagi wujud, dan individu yang merosakkannya telah melupakan perubahan tersebut.

Ia memakan konteks pada setiap tugasan. Fail-fail ini dimuatkan pada permulaan sesi, sebelum ejen mengetahui apa yang anda akan tanya. Dokumentasi Claude Code meletakkan had padanya: "sasarkan bawah 200 baris bagi setiap fail CLAUDE.md. Fail yang lebih panjang menggunakan lebih banyak konteks dan mengurangkan pematuhan." Codex berhenti menggabungkan fail arahan sebaik sahaja saiz gabungannya mencapai 32 KiB, iaitu project_doc_max_bytes lalai. Fail root yang mendokumentasikan empat servis membelanjakan bajet tersebut untuk tiga daripadanya bagi setiap tugasan tunggal.

Arahan mula bercanggah antara satu sama lain. Direktori web mahukan pnpm test. Pekerja mahukan pytest -q. Apabila ditulis dalam satu fail, setiap peraturan hanya betul pada waktu tertentu, jadi ejen terpaksa meneka yang mana satu terpakai. Dokumentasi Claude Code menerangkan hasilnya: "jika dua peraturan bercanggah antara satu sama lain, Claude mungkin memilih salah satu secara sewenang-wenangnya." Fail bagi setiap direktori menghapuskan tekaan tersebut, kerana hanya satu daripada dua peraturan itu yang berada dalam konteks. Apabila peraturan yang anda pasti anda tulis dengan jelas tetap dilangkau, menyemak sebab arahan tidak pernah dilaksanakan adalah lebih baik daripada menulis semula ayat tersebut buat kali keempat.

Ia dipenuhi dengan fakta yang ejen boleh baca daripada kod. Pepohon direktori, senarai dependensi, ringkasan apa yang dilakukan oleh setiap pakej. Semakan /doctor Claude Code wujud untuk membuang perkara ini. Ia "memotong kandungan yang Claude boleh peroleh daripada pangkalan kod, seperti susun atur direktori, senarai dependensi, dan gambaran keseluruhan seni bina" serta mengekalkan "perangkap, rasional, dan konvensyen yang berbeza daripada lalai alat." Ayat itu adalah ujian terbaik yang saya tahu untuk menentukan sama ada sesuatu baris itu patut berada dalam fail tersebut atau tidak.

Adakah ejen membaca fail root, atau hanya fail yang paling hampir?

Di sinilah kebanyakan orang tersalah faham tentang model ini, jadi adalah wajar untuk memetik konvensyen huluan (upstream) daripada membuat parafrasa:

Letakkan satu lagi AGENTS.md di dalam setiap pakej. Ejen secara automatik membaca fail yang paling hampir dalam pepohon direktori, jadi fail yang paling dekat akan diutamakan dan setiap subprojek boleh menghantar arahan yang disesuaikan.

Dan mengenai konflik:

Fail AGENTS.md yang paling hampir dengan fail yang disunting akan menang; gesaan sembang pengguna secara eksplisit mengatasi segala-galanya.

"Diutamakan" (takes precedence) dibaca oleh ramai orang sebagai "fail root diabaikan". Ia tidak diabaikan. Dalam alatan yang melaksanakan konvensyen ini, setiap fail pada laluan dari root repositori turun ke direktori kerja akan dibaca dan digabungkan. Fail yang paling hampir hanya menang apabila dua fail menyatakan perkara yang berbeza mengenai subjek yang sama.

Codex menyatakan mekanisme ini dengan jelas: "Codex mencantumkan fail dari root ke bawah, menyambungkannya dengan baris kosong. Fail yang lebih dekat dengan direktori semasa anda mengatasi panduan sebelumnya." Claude Code mengikuti laluan yang sama untuk nama failnya sendiri. Fail dalam hierarki direktori di atas direktori kerja "dimuatkan sepenuhnya semasa pelancaran", dan "Semua fail yang ditemui dicantumkan ke dalam konteks dan bukannya mengatasi satu sama lain." Direktori di bawah direktori kerja berkelakuan berbeza: Claude Code memuatkan fail tersebut atas permintaan, "apabila Claude membaca fail dalam direktori tersebut."

Dua akibat praktikal timbul daripada perkara ini. Fail root adalah awalan (prefix) pada setiap sesi dalam repositori, jadi anggap setiap baris di sana sebagai baris yang anda bayar seratus kali seminggu. Fail per-direktori tidak menelan kos apabila ejen bekerja di tempat lain, yang bermaksud perincian adalah murah di sana dan sepatutnya diletakkan di sana.

Kelakuan ini telah disemak berbanding dokumentasi Codex dan Claude Code pada Ogos 2026. Alatan melaksanakan konvensyen ini dengan sedikit perbezaan dan ia memang berubah, jadi sahkan peraturan pemuatan untuk mana-mana ejen yang dijalankan oleh pasukan anda.

Susun atur yang berfungsi untuk repositori dengan tiga servis

repo/
  AGENTS.md                   rules true everywhere, plus the map
  apps/web/AGENTS.md          TypeScript client, Vite, Vitest
  services/worker/AGENTS.md   Python queue consumer, pytest
  infra/AGENTS.md             Terraform and the deploy scripts

Fail akar sengaja dibuat ringkas. Ia menyatakan lokasi untuk mencari fail lain dan hanya mengandungi peraturan yang terpakai dalam setiap direktori.

# AGENTS.md

This is a monorepo. Each top-level directory ships its own AGENTS.md.
Read this file and the AGENTS.md nearest the code you are editing
before you change anything.

- `apps/web` browser client
- `services/worker` queue consumer
- `infra` Terraform and deploy scripts

## Rules for the whole repository

- The package manager is `pnpm`. `npm install` writes a second lockfile
  that CI ignores, so the install you tested is not the install that ships.
- Any `generated/` directory is build output. Edit the schema in
  `schemas/` and run `pnpm codegen` instead.
- `.env.local` holds real credentials. Do not read it and do not print it.
- If you change code in a directory, update that directory's AGENTS.md
  in the same commit.

Fail per-direktori ialah tempat perincian diletakkan, dan ia boleh menjadi sepanjang yang diperlukan oleh direktori tersebut.

# apps/web

Browser client. Vite and React, TypeScript with `strict` on.

## Commands

- `pnpm dev` serves on port 5173.
- `pnpm test` runs Vitest once and exits.
- `pnpm typecheck` runs `tsc --noEmit`.

## Conventions

- One component per file under `src/components/`.
- All HTTP goes through `src/api/client.ts`. Do not call `fetch` directly,
  because the client attaches the auth header and retries on 429.

## Traps

- `pnpm build` does not type check. Vite strips the types instead of
  checking them, so a broken type still produces a green build.
  Run `pnpm typecheck` as a separate step.

Fail pekerja mempunyai bentuk yang sama dengan kandungan yang berbeza: arahan pemasangan, pytest -q, sebab mengapa pengguna mesti kekal idempoten, dan migrasi yang perlu dijalankan sebelum ujian berjaya. Fail infra ialah tempat anda menulis peraturan yang menghalang ejen daripada melakukan kerosakan. Jangan sekali-kali jalankan terraform apply. Jalankan terraform plan dan berhenti di situ, serta namakan backend keadaan yang telah dikonfigurasikan supaya ejen tidak cuba memulakan yang baharu.

Perhatikan perkara yang tiada dalam fail-fail ini: penerangan tentang tujuan setiap servis. Itu adalah untuk manusia. Upstream melukis garis yang sama, menyatakan "fail README.md adalah untuk manusia: permulaan pantas, penerangan projek, dan garis panduan sumbangan", manakala AGENTS.md membawa "konteks tambahan yang kadangkala terperinci yang diperlukan oleh ejen pengekodan: langkah binaan, ujian, dan konvensyen." pemisahan antara AGENTS.md dan README yang menghadap manusia meneliti sempadan tersebut ayat demi ayat, dan DESIGN.md yang merekodkan sebab kod dibentuk sedemikian meliputi fail ketiga, iaitu fail yang menjelaskan keputusan dan bukannya arahan.

Siapa yang mengemas kini fail apabila kod berubah?

Satu peraturan, dan ia diletakkan dalam fail root: sesiapa yang menukar kod dalam sesuatu direktori perlu mengemas kini AGENTS.md direktori tersebut dalam commit yang sama.

Ini berfungsi atas sebab mekanikal, bukan budaya. Fail per-direktori berada dalam diff yang sama dengan kod, jadi penyemak pull request dapat melihat kedua-duanya sekali gus. Fail root adalah milik semua orang, yang bermaksud ia milik sesiapa pun, dan ia tidak pernah berada dalam diff yang sedang dibaca oleh sesiapa.

Sokong peraturan ini dengan semakan pada pull request. Ia mencari AGENTS.md terdekat di atas setiap fail yang diubah, kemudian melaporkan apabila fail tersebut tidak disentuh.

#!/usr/bin/env bash
# Warn when code changed but the nearest AGENTS.md above it did not.
changed=$(git diff --name-only origin/main...HEAD)

nearest_doc() {
  d=$(dirname "$1")
  while [ "$d" != "." ]; do
    if [ -f "$d/AGENTS.md" ]; then echo "$d/AGENTS.md"; return; fi
    d=$(dirname "$d")
  done
  echo "AGENTS.md"
}

printf '%s\n' "$changed" | while read -r f; do
  [ -n "$f" ] || continue
  case "$f" in AGENTS.md|*/AGENTS.md) continue ;; esac
  doc=$(nearest_doc "$f")
  printf '%s\n' "$changed" | grep -Fqx "$doc" && continue
  echo "note: $f changed but $doc was not updated"
done

Pada cawangan yang mengubah suai API client tanpa menyentuh dokumentasi, outputnya kelihatan seperti ini:

note: apps/web/src/api/client.ts changed but apps/web/AGENTS.md was not updated

Jadikannya sebagai amaran dan bukannya kegagalan. Sekatan keras akan mengajar orang untuk menambah baris kosong pada fail supaya CI menjadi hijau, dan fail yang disunting untuk memuaskan robot adalah lebih tidak bernilai daripada tiada fail langsung. Amaran memberikan penyemak soalan untuk ditanya, yang merupakan bahagian yang sebenarnya berkesan.

Bagaimanakah cara mengesan AGENTS.md yang sudah lapuk?

Terdapat dua pemeriksaan yang boleh anda jalankan hari ini, dan satu simptom yang akan anda lihat di dalam sesi.

Bandingkan usia setiap fail dengan usia kod yang diterangkannya. %cs mencetak tarikh komit sebagai YYYY-MM-DD.

for f in $(git ls-files '*AGENTS.md'); do
  d=$(dirname "$f")
  printf '%s  doc:%s  code:%s\n' "$f" \
    "$(git log -1 --format=%cs -- "$f")" \
    "$(git log -1 --format=%cs -- "$d")"
done
apps/web/AGENTS.md          doc:2026-02-11  code:2026-08-07
services/worker/AGENTS.md   doc:2026-07-29  code:2026-08-09
infra/AGENTS.md             doc:2026-08-01  code:2026-08-01

Tarikh dokumen yang enam bulan ketinggalan berbanding tarikh kod tidak membuktikan fail tersebut salah. Ia hanya memberitahu anda fail mana yang perlu dibaca dahulu, dan itu sahaja yang anda perlukan daripada pemeriksaan yang mengambil masa satu saat.

Cari laluan yang tidak lagi wujud. Dokumentasi menjadi usang dalam satu cara yang sangat khusus: ia terus menerangkan kod yang telah dipadamkan. Setiap laluan dalam fail ini ditulis dalam backtick, jadi ia mudah untuk dikeluarkan dan diuji.

grep -o '`[^`]*`' apps/web/AGENTS.md | tr -d '`' | grep '/' | while read -r p; do
  [ -e "$p" ] || [ -e "apps/web/$p" ] || echo "missing: $p"
done

Baca output tersebut daripada menyambungkan proses ini ke dalam CI. Ia juga menandakan glob seperti src/**/*.ts dan mana-mana URL yang anda petik, kerana kedua-duanya mengandungi garis miring dan bukan fail pada cakera.

Simptom dalam satu sesi. Ejen membaca fail tersebut, cuba membuka src/api/client.ts kerana fail itu mengarahkannya berbuat demikian, dan alat tersebut mengembalikan:

No such file or directory

Jadi, ia melakukan perkara yang munasabah dan menulis pembungkus fetch miliknya sendiri. Itulah kos sebenar fail yang lapuk. Ejen tidak mengabaikan dokumentasi anda. Ia mengikuti dokumentasi tersebut, mendarat pada laluan yang telah dipadamkan tiga bulan lalu, dan membina semula kod yang sudah anda miliki. Kemahiran seperti Ponytail, yang mengekalkan ejen pada perubahan terkecil yang berfungsi, menjadikan naluri membina semula itu lebih jarang berlaku, tetapi ia tidak dapat mencari pembantu yang ditunjukkan oleh fail anda di tempat yang salah.

Adakah Claude Code membaca fail AGENTS.md?

Tidak, dan perkara ini perlu ditegaskan kerana susun atur bersarang bergantung kepadanya. Setakat Ogos 2026, dokumentasi menyatakan: "Claude Code membaca CLAUDE.md, bukan AGENTS.md." Corak ini masih berfungsi, anda hanya perlu meletakkan CLAUDE.md di sebelah setiap AGENTS.md.

Bentuk import adalah tepat apabila anda mahukan baris khusus alat di atas baris yang dikongsi. Letakkan ini dalam services/worker/CLAUDE.md:

@AGENTS.md

## Claude Code

Use plan mode for changes under `services/worker/migrations/`.

Bentuk symlink adalah tepat apabila tiada perkara khusus alat yang perlu ditambah.

git ls-files '*AGENTS.md' | while read -r f; do
  ln -s AGENTS.md "$(dirname "$f")/CLAUDE.md"
done
ls -l apps/web/CLAUDE.md

ln tidak mencetak apa-apa apabila berjaya, jadi semak senarai: apps/web/CLAUDE.md -> AGENTS.md. Kemudian mulakan sesi dan jalankan /context, di mana fail yang dimuatkan akan muncul di bawah Memory files. Pada Windows, symlink memerlukan hak Administrator atau Developer Mode, jadi gunakan import @AGENTS.md di sana.

Satu perangkap berkaitan dengan perkara ini. Selepas /compact, fail akar dibaca semula daripada cakera, tetapi fail bersarang dalam subdirektori tidak disuntik semula. Fail tersebut akan kembali pada kali seterusnya ejen membaca fail dalam direktori itu. Jika peraturan per-direktori kelihatan berhenti berfungsi di tengah-tengah sesi yang panjang, itulah puncanya, dan menyentuh mana-mana fail dalam direktori tersebut akan mengaktifkannya semula.

Tetapan yang menghalakan ejen lain ke AGENTS.md

Codex membaca AGENTS.md secara natif. Pada setiap tahap, ia menyemak AGENTS.override.md terlebih dahulu, yang memberikan satu direktori penggantian tempatan tanpa perlu menyunting fail yang dikongsi. Ia berhenti menggabungkan sebaik sahaja saiz gabungan mencapai 32 KiB, iaitu project_doc_max_bytes lalai, yang merupakan satu lagi sebab untuk memastikan fail akar kekal kecil.

Aider mengambilnya melalui .aider.conf.yml dengan baris read: AGENTS.md.

Gemini CLI mengambilnya melalui .gemini/settings.json dengan { "context": { "fileName": "AGENTS.md" } }.

Dokumentasi hulu (upstream) mendokumenkan penamaan semula yang serasi ke belakang untuk repositori yang masih menggunakan nama tunggal yang lama: mv AGENT.md AGENTS.md && ln -s AGENTS.md AGENT.md.

Dalam monorepo yang sangat besar, tetapan claudeMdExcludes Claude Code melangkau fail leluhur mengikut laluan atau glob, yang berguna apabila direktori pasukan lain berada di atas direktori anda.

Bagaimanakah ini berbeza daripada memori ejen, atau kemahiran?

Mekanisme ini kelihatan serupa tetapi gagal dengan cara yang berbeza, jadi adalah penting untuk menentukan dengan tepat mekanisme mana yang anda perlukan.

AGENTS.md ditulis oleh anda, dikomit ke git, disemak dalam pull request, dan adalah sama untuk sesiapa sahaja yang mengklon repositori tersebut. Memori ejen ditulis oleh ejen, disimpan di luar repositori, dan bersifat setempat pada satu mesin. Dokumentasi Claude Code menetapkan garis yang sama: CLAUDE.md mengandungi "Arahan dan peraturan" yang anda tulis, memori automatik mengandungi "Pembelajaran dan corak" yang ditulis oleh Claude, dan direktori memori tidak dikongsi merentas mesin. Ujiannya mudah. Jika sesuatu fakta perlu benar untuk rakan sekerja pada klon baharu, ia tidak boleh berada dalam memori. Bagaimana memori ejen dikekalkan antara sesi merangkumi separuh daripada gambaran tersebut.

Kemahiran adalah perkara ketiga. AGENTS.md ialah konteks yang dimuatkan setiap sesi; kemahiran ialah prosedur yang dimuatkan apabila ia diperlukan. Dokumentasi Claude Code memberikan peraturan yang boleh digunakan: "Jika entri ialah prosedur berbilang langkah atau hanya penting untuk satu bahagian pangkalan kod, pindahkannya ke kemahiran atau peraturan yang diskopkan mengikut laluan." Separuh kedua ayat itu adalah tepat apa yang diselesaikan oleh AGENTS.md bersarang. Separuh pertama adalah tujuan kemahiran ejen, dan apabila prosedur yang sama diperlukan dalam lebih daripada satu repositori, kongsi kemahiran tersebut merentas repo daripada menampal perenggan yang sama ke dalam sepuluh fail AGENTS.md yang berbeza.

Pihak hulu menyatakan bahawa "pada masa penulisan, repositori utama OpenAI mempunyai 88 fail AGENTS.md". Nombor itu adalah hujah keseluruhannya. Repositori yang besar tidak memerlukan fail yang lebih besar. Ia memerlukan lebih banyak fail kecil, setiap satunya terletak bersebelahan dengan kod yang diterangkannya, dan setiap satunya dimiliki oleh sesiapa sahaja yang terakhir mengubah kod tersebut.

FAQ

Adakah AGENTS.md bersarang menggantikan fail akar atau menambah kepadanya?

Ia menambah kepadanya. Pihak hulu menyatakan "yang paling hampir diutamakan", yang menerangkan perkara yang berlaku apabila terdapat konflik, bukannya perkara yang dimuatkan. Codex "mencantumkan fail dari akar ke bawah, menyambungkannya dengan baris kosong", dan Claude Code mencantumkan setiap fail yang ditemui semasa menyusuri direktori kerja ke atas dan bukannya mengatasi fail tersebut. Fail yang paling hampir hanya menang apabila dua fail memberikan arahan berbeza mengenai subjek yang sama. Tulis peraturan kongsi di akar sekali sahaja, dan jangan ulanginya dalam setiap direktori.

Berapa besarkah AGENTS.md akar sepatutnya?

Cukup kecil supaya anda tidak keberatan jika ia ditampal pada setiap permintaan yang anda buat dalam repositori tersebut, kerana itulah yang berlaku. Dokumentasi Claude Code mencadangkan sasaran di bawah 200 baris setiap fail dan memberi amaran bahawa fail yang lebih panjang "mengurangkan pematuhan". Codex berhenti menggabungkan fail arahan pada 32 KiB secara gabungan secara lalai. Jika fail akar anda mendokumenkan empat servis, kebanyakan daripadanya adalah beban yang tidak perlu bagi mana-mana tugasan tunggal. Pindahkan perincian ke bawah ke dalam fail setiap direktori dan tinggalkan peta di belakang.

Bagaimanakah cara saya menghalang fail ini daripada menjadi lapuk?

Letakkan satu peraturan dalam fail akar: sesiapa yang menukar kod dalam sesuatu direktori perlu mengemas kini AGENTS.md direktori tersebut dalam commit yang sama. Meletakkan fail di sebelah kod adalah perkara yang menjadikan peraturan itu kekal, kerana perubahan tersebut kemudiannya akan masuk ke dalam diff pull request yang sama yang sedang dibaca oleh manusia. Tambahkan amaran CI yang memetakan setiap laluan yang ditukar kepada AGENTS.md terdekat di atasnya, dan sekali-sekala bandingkan git log -1 --format=%cs pada setiap fail dengan arahan yang sama yang dijalankan pada direktori yang didokumenkannya.

Adakah Claude Code membaca fail AGENTS.md?

Tidak. Setakat Ogos 2026, dokumentasi menyatakan "Claude Code membaca CLAUDE.md, bukan AGENTS.md." Cipta CLAUDE.md dalam direktori yang sama dengan @AGENTS.md pada baris pertama, yang memuatkan fail kongsi dan membolehkan anda menambah arahan khusus Claude di bawahnya. Pautan simbolik (symlink) yang dicipta dengan ln -s AGENTS.md CLAUDE.md berfungsi apabila tiada perkara tambahan untuk ditambah, walaupun pada Windows ia memerlukan hak Pentadbir atau Mod Pembangun. Jalankan /context dalam sesi dan sahkan fail tersebut muncul di bawah fail Memori.

Di manakah saya perlu meletakkan peraturan yang hanya penting pada waktu tertentu?

Bukan dalam AGENTS.md. Fail tersebut dimuatkan dalam setiap sesi, jadi setiap baris di dalamnya bersaing untuk mendapatkan perhatian dengan permintaan yang sebenarnya anda taip. Prosedur dengan beberapa langkah yang diperlukan sekali-sekala tergolong dalam kemahiran (skill), yang dimuatkan atas permintaan. Peraturan yang terpakai pada satu direktori tergolong dalam AGENTS.md direktori tersebut. Fakta yang boleh dibaca oleh ejen terus daripada kod, seperti pepohon direktori atau senarai dependensi, tidak tergolong dalam kedua-duanya.