Monorepo Yapısında İç İçe AGENTS.md Kullanımı
Monorepo içinde tek bir AGENTS.md dosyası bağlam kaybına neden olur. Servis bazlı iç içe yerleşim ile aracıların sadece ilgili dizine odaklanmasını sağlayan yöntemi öğrenin.
Bir monorepo içinde iç içe geçmiş AGENTS.md dosyalarının anlamı
Bir monorepo içinde iç içe geçmiş AGENTS.md dosyaları, depo kök dizininde küçük bir dosya ve her servis dizininin içinde birer dosya daha bulunması anlamına gelir. Kök dizindeki dosya, her yerde geçerli olan birkaç kuralı ve diğer dosyaların nerede bulunduğuna dair bir haritayı barındırır. Her servis dosyası ise yalnızca o dizine özel komutları ve kuralları içerir. services/worker/queue.py dosyasını düzenleyen bir aracı, kök dizindeki dosyayı ve ilgili servis dosyasını okur; böylece asla dokunmayacağı bir ön yüz (front end) için bağlam (context) harcamaz.
Kurulacak herhangi bir şey yoktur. AGENTS.md bir gelenektir ve yukarı akış (upstream) projesi bunu açıkça belirtir:
AGENTS.md sadece standart bir Markdown dosyasıdır. İstediğiniz başlıkları kullanabilirsiniz; aracı, sağladığınız metni basitçe ayrıştırır.
Bu teknik, doğru şekilde öğrenilmeye değerdir. Format sizin üzerinizde değişmeyecektir. Bozulacak olan şey yerleşim ve bakımdır; bunların her ikisi de sizin sorumluluğunuzdadır.
Kök dizindeki tek bir büyük AGENTS.md dosyası neden çalışmayı durdurur?
Bir web uygulaması, bir arka plan çalışanı ve bir Terraform dizini içeren bir deponun kök dizinindeki 600 satırlık tek bir AGENTS.md dosyası, dört farklı şekilde başarısız olur.
Sahiplenilmediği için güncelliğini yitirir. apps/web içindeki bir test betiğini yeniden adlandıran mühendis, apps/web altındaki dosyaları düzenlemektedir. Kök dizindeki AGENTS.md bu fark (diff) içinde yer almadığından, hiçbir gözden geçiren kişi uyumsuzluğu görmez. Altı hafta sonra dosya artık var olmayan bir derleme adımını tarif eder ve onu bozan kişi değişikliği unutmuştur.
Her görevde bağlam maliyeti yaratır. Bu dosyalar, oturumun başında, ajan size ne soracağınızı bilmeden önce yüklenir. Claude Code belgeleri buna bir sayı koyar: "CLAUDE.md dosyası başına 200 satırın altını hedefleyin. Daha uzun dosyalar daha fazla bağlam tüketir ve uyumu azaltır." Codex, talimat dosyalarının toplam boyutu varsayılan project_doc_max_bytes olan 32 KiB değerine ulaştığında bunları birleştirmeyi durdurur. Dört servisi belgeleyen bir kök dosya, her görev için bu bütçeyi diğer üç servis üzerinde harcar.
Talimatlar birbiriyle çelişmeye başlar. Web dizini pnpm test ister. Çalışan ise pytest -q ister. Tek bir dosyaya yazıldığında, her kural yalnızca bazen doğrudur, bu yüzden ajan hangisinin geçerli olduğunu tahmin etmek zorunda kalır. Claude Code belgeleri sonucu şöyle tarif eder: "iki kural birbiriyle çelişirse, Claude bunlardan birini rastgele seçebilir." Dizin bazlı bir dosya bu tahmini ortadan kaldırır, çünkü iki kuraldan yalnızca biri bağlam içindedir.
Ajanın koddan okuyabileceği gerçeklerle dolar. Bir dizin ağacı, bağımlılık listesi, her paketin ne yaptığına dair bir özet. Claude Code'un /doctor denetimi tam olarak bunu ayıklamak için vardır. "Claude'un kod tabanından çıkarabileceği dizin düzenleri, bağımlılık listeleri ve mimari genel bakışlar gibi içerikleri keser" ve "araç varsayılanlarından farklı olan tuzakları, mantığı ve kuralları" tutar. Bu cümle, bir satırın dosyaya ait olup olmadığını anlamak için bildiğim en iyi testtir.
Ajan kök dizindeki dosyayı mı okur, yoksa yalnızca en yakındakini mi?
Çoğu kişinin modeli yanlış anladığı nokta burasıdır; bu nedenle, kendi sözlerimizle ifade etmek yerine yukarı akış (upstream) kuralını doğrudan alıntılamakta fayda var:
Her paketin içine bir AGENTS.md yerleştirin. Ajanlar, dizin ağacındaki en yakın dosyayı otomatik olarak okur; bu sayede en yakın olan öncelik kazanır ve her alt proje kendine özel talimatlar sunabilir.
Çakışmalar konusunda ise:
Düzenlenen dosyaya en yakın olan AGENTS.md geçerli olur; açık kullanıcı sohbet istemleri ise her şeyin önüne geçer.
"Öncelik kazanır" ifadesi birçok kişi tarafından "kök dizindeki dosya yok sayılır" şeklinde yorumlanır. Ancak durum böyle değildir. Bu kuralı uygulayan araçlarda, depo kökünden çalışma dizinine kadar olan yol üzerindeki her dosya okunur ve birleştirilir. En yakın dosya, yalnızca iki dosya aynı konu hakkında farklı şeyler söylediğinde geçerli olur.
Codex, mekanizma konusunda oldukça açıktır: "Codex, dosyaları kökten aşağıya doğru birleştirir ve aralarına boş satırlar ekler. Mevcut dizininize daha yakın olan dosyalar, önceki yönlendirmeleri geçersiz kılar." Claude Code, kendi dosya adı için de aynı yolu izler. Çalışma dizininin üzerindeki dizin hiyerarşisinde yer alan dosyalar "başlatma sırasında tamamen yüklenir" ve "keşfedilen tüm dosyalar birbirini geçersiz kılmak yerine bağlama (context) dahil edilerek birleştirilir." Çalışma dizininin altındaki dizinler ise farklı davranır: Claude Code bu dosyaları talep üzerine, "Claude bu dizinlerdeki dosyaları okuduğunda" yükler.
Buradan iki pratik sonuç çıkar. Kök dizindeki dosya, depodaki her oturumun bir ön ekidir; bu nedenle oradaki her satırı, haftada yüzlerce kez ödeme yaptığınız bir satır olarak değerlendirin. Dizin bazlı bir dosya ise ajan başka bir yerde çalışırken hiçbir maliyet oluşturmaz; bu da detayların orada ucuz olduğu ve oraya ait olduğu anlamına gelir.
Bu davranış, Ağustos 2026 itibarıyla Codex ve Claude Code belgeleri üzerinden doğrulanmıştır. Araçlar bu kuralı biraz farklı şekillerde uygular ve zamanla değişiklik gösterebilirler; bu nedenle ekibinizin kullandığı ajan için yükleme kurallarını teyit edin.
Üç servisli bir depo için çalışma düzeni
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 scriptsKök dizindeki dosya bilinçli olarak kısa tutulmuştur. Hangi dizinlere bakılması gerektiğini belirtir ve yalnızca her dizin için geçerli olan kuralları içerir.
# 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.Dizin bazlı dosya, detayların yer aldığı yerdir ve dizinin gerektirdiği uzunlukta olabilir.
# 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.Worker dosyası, farklı içeriklerle aynı yapıya sahiptir: kurulum komutu, pytest -q, tüketicinin neden idempotent kalması gerektiği ve testlerin geçmesi için çalıştırılması gereken migrasyon. Infra dosyası, bir ajanın hasar vermesini engelleyen kuralları yazdığınız yerdir. Asla terraform apply çalıştırmayın. terraform plan komutunu çalıştırıp orada durun ve ajanın yeni bir tane başlatmaya çalışmaması için halihazırda yapılandırılmış olan durum arka ucunu (state backend) belirtin.
Bu dosyaların hiçbirinde neyin yer almadığına dikkat edin: her servisin ne işe yaradığına dair bir açıklama. Bu, insanların sorumluluğundadır. Upstream aynı sınırı çizer ve şunu belirtir: "README.md dosyaları insanlar içindir: hızlı başlangıçlar, proje açıklamaları ve katkı kılavuzları", AGENTS.md ise "kodlama ajanlarının ihtiyaç duyduğu ek, bazen ayrıntılı bağlamı taşır: derleme adımları, testler ve kurallar." AGENTS.md ile insan odaklı README arasındaki ayrım, bu sınırı cümle cümle ele alır ve kodun neden bu şekilde yapılandırıldığını kaydeden bir DESIGN.md, komutlardan ziyade kararları açıklayan üçüncü dosyayı kapsar.
Kod değiştiğinde dosyayı kim günceller?
Tek bir kural vardır ve bu kural kök dizindeki dosyada yer alır: Bir dizindeki kodu değiştiren kişi, aynı commit içerisinde o dizinin AGENTS.md dosyasını da günceller.
Bu yöntem kültürel bir nedenden değil, mekanik bir zorunluluktan dolayı işe yarar. Dizin bazlı dosya, kod ile aynı diff içerisinde yer alır; bu sayede pull request incelemesini yapan kişi her ikisini de aynı anda görür. Kök dizindeki bir dosya ise herkese ait olduğu için aslında kimseye ait değildir ve kimsenin okumakta olduğu diff içerisinde yer almaz.
Bu kuralı, pull request üzerinde bir denetim mekanizması ile destekleyin. Bu denetim, değiştirilen her dosyanın üst dizinindeki en yakın AGENTS.md dosyasını bulur ve dosyanın güncellenmediği durumlarda raporlama yapar.
#!/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"
doneAPI istemcisini dokümantasyona dokunmadan yeniden düzenleyen bir branch üzerinde çıktı şu şekilde görünür:
note: apps/web/src/api/client.ts changed but apps/web/AGENTS.md was not updatedBunu bir hata (failure) yerine uyarı (warning) olarak tutun. Katı bir engel, insanların CI sürecini yeşile döndürmek için dosyaya boş bir satır eklemesine neden olur; bir robotu tatmin etmek için düzenlenen bir dosyanın değeri, hiç olmamasından daha düşüktür. Uyarı, incelemeyi yapan kişiye sorması gereken soruyu hatırlatır; asıl işe yarayan kısım da budur.
AGENTS.md dosyasının güncelliğini yitirdiği nasıl anlaşılır?
Bugün uygulayabileceğiniz iki kontrol ve bir oturum sırasında karşılaşacağınız bir belirti bulunmaktadır.
Her dosyanın yaşını, tanımladığı kodun yaşıyla karşılaştırın. %cs, commit tarihini YYYY-MM-DD olarak yazdırır.
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")"
doneapps/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-01Kod tarihinden altı ay geride olan bir doküman tarihi, dosyanın hatalı olduğunu kanıtlamaz. Bu durum size yalnızca ilk olarak hangi dosyayı okumanız gerektiğini söyler; bir saniye süren bir kontrolden beklediğiniz tek şey de budur.
Artık mevcut olmayan yolları arayın. Dokümantasyon çok belirli bir şekilde eskir: silinmiş olan kodları tanımlamaya devam eder. Bu dosyalardaki her yol ters tırnak (backtick) içinde yazıldığından, bunları ayıklamak ve test etmek kolaydır.
grep -o '`[^`]*`' apps/web/AGENTS.md | tr -d '`' | grep '/' | while read -r p; do
[ -e "$p" ] || [ -e "apps/web/$p" ] || echo "missing: $p"
doneBu komutu CI sürecine dahil etmek yerine çıktısını okuyun. Bu işlem ayrıca src/**/*.ts gibi glob ifadelerini ve alıntıladığınız tüm URL'leri işaretler; çünkü her ikisi de eğik çizgi içerir ve disk üzerinde bir dosya değildir.
Oturumdaki belirti. Ajan dosyayı okur, dosya talimat verdiği için src/api/client.ts yolunu açmaya çalışır ve araç şu hatayı döndürür:
No such file or directoryBunun üzerine ajan mantıklı olanı yapar ve kendi fetch sarmalayıcısını (wrapper) yazar. Güncelliğini yitirmiş bir dosyanın gerçek maliyeti budur. Ajan dokümantasyonunuzu görmezden gelmez. Dokümantasyonu takip eder, üç ay önce silinmiş bir yola ulaşır ve halihazırda sahip olduğunuz kodu yeniden oluşturur. Ajani çalışan en küçük değişikliğe zorlayan Ponytail gibi bir yetenek, bu yeniden oluşturma içgüdüsünü nadirleştirir ancak dosyanızın yanlış bir yere işaret ettiği yardımcı bir aracı bulamaz.
Claude Code, AGENTS.md dosyalarını okur mu?
Hayır, iç içe geçmiş yapının buna bağlı olması nedeniyle bunu açıkça belirtmek gerekir. Ağustos 2026 itibarıyla belgeler şunu belirtmektedir: "Claude Code, CLAUDE.md dosyasını okur, AGENTS.md dosyasını değil." Bu model hala çalışmaktadır, sadece her AGENTS.md dosyasının yanında bir CLAUDE.md dosyasına sahip olmanız yeterlidir.
İçe aktarma (import) biçimi, paylaşılan satırların üzerine araca özel satırlar eklemek istediğinizde doğrudur. Bunu services/worker/CLAUDE.md içine yerleştirin:
@AGENTS.md
## Claude Code
Use plan mode for changes under `services/worker/migrations/`.Sembolik bağlantı (symlink) biçimi, eklenecek araca özel bir şey olmadığında doğrudur.
git ls-files '*AGENTS.md' | while read -r f; do
ln -s AGENTS.md "$(dirname "$f")/CLAUDE.md"
done
ls -l apps/web/CLAUDE.mdln başarılı olduğunda hiçbir çıktı vermez, bu yüzden listeyi kontrol edin: apps/web/CLAUDE.md -> AGENTS.md. Ardından bir oturum başlatın ve yüklenen dosyaların Memory files altında göründüğü /context komutunu çalıştırın. Windows üzerinde bir sembolik bağlantı, Yönetici hakları veya Geliştirici Modu gerektirir, bu nedenle orada @AGENTS.md içe aktarma yöntemini kullanın.
Bununla ilgili bir tuzak bulunmaktadır. /compact komutundan sonra kök dosya diskten yeniden okunur, ancak alt dizinlerdeki iç içe geçmiş dosyalar yeniden enjekte edilmez. Bu dosyalar, ajan o dizindeki bir dosyayı bir sonraki okuyuşunda geri gelir. Eğer dizine özel bir kural uzun bir oturumun ortasında uygulanmayı bırakmış gibi görünüyorsa, bunun nedeni genellikle budur ve dizindeki herhangi bir dosyaya dokunmak kuralı geri getirir.
Diğer ajanları AGENTS.md dosyasına yönlendiren ayarlar
Codex, AGENTS.md dosyasını yerel olarak okur. Her seviyede önce AGENTS.override.md dosyasını kontrol eder; bu, paylaşılan dosyayı düzenlemeden bir dizine yerel bir geçersiz kılma (override) sağlar. Birleştirilmiş boyut, varsayılan project_doc_max_bytes değeri olan 32 KiB'a ulaştığında birleştirmeyi durdurur; bu, kök dosyayı küçük tutmak için bir başka nedendir.
Aider, bunu read: AGENTS.md satırı ile .aider.conf.yml üzerinden alır.
Gemini CLI, bunu { "context": { "fileName": "AGENTS.md" } } ile .gemini/settings.json üzerinden alır.
Upstream, hala eski tekil ismi kullanan depolar için geriye dönük uyumlu bir yeniden adlandırma belgelemiştir: mv AGENT.md AGENTS.md && ln -s AGENTS.md AGENT.md.
Çok büyük bir monorepo içinde, Claude Code'un claudeMdExcludes ayarı, başka bir ekibin dizini sizinkinin üzerinde yer aldığında kullanışlı olan yol veya glob ile üst dizin dosyalarını atlar.
Bunun ajan belleğinden veya bir yetenekten farkı nedir?
Bu mekanizmalar birbirine benzer görünse de tamamen farklı şekillerde başarısız olurlar; bu nedenle hangisine ihtiyaç duyduğunuz konusunda kesin olmakta fayda vardır.
AGENTS.md dosyası sizin tarafınızdan yazılır, git deposuna commit edilir, bir pull request ile gözden geçirilir ve depoyu klonlayan herkes için aynıdır. Ajan belleği ise ajan tarafından yazılır, depo dışında saklanır ve tek bir makineye özgüdür. Claude Code belgeleri de aynı ayrımı yapar: CLAUDE.md sizin yazdığınız "Talimatlar ve kurallar"ı içerir, otomatik bellek Claude'un yazdığı "Öğrenilenler ve kalıplar"ı tutar ve bellek dizini makineler arasında paylaşılmaz. Test basittir. Eğer bir bilginin yeni bir klon üzerinde çalışan bir iş arkadaşı için de geçerli olması gerekiyorsa, bu bilgi bellekte barındırılamaz. Ajan belleğinin oturumlar arasında nasıl kalıcı hale geldiği konunun bu kısmını ele alır.
Yetenek ise üçüncü bir unsurdur. AGENTS.md her oturumda yüklenen bir bağlamdır; yetenek ise ihtiyaç duyulduğunda yüklenen bir prosedürdür. Claude Code belgeleri kullanışlı bir kural sunar: "Eğer bir girdi çok adımlı bir prosedürse veya kod tabanının yalnızca bir bölümü için önemliyse, onu bir yeteneğe veya yol kapsamlı bir kurala taşıyın." Bu cümlenin ikinci yarısı, iç içe geçmiş AGENTS.md dosyalarının tam olarak çözdüğü sorundur. İlk yarısı ise ajan yetenekleri içindir ve aynı prosedür birden fazla depoda gerektiğinde, aynı paragrafları on farklı AGENTS.md dosyasına yapıştırmak yerine yeteneği depolar arasında paylaşın.
Upstream, "bu yazının yazıldığı sırada ana OpenAI deposunda 88 adet AGENTS.md dosyası bulunduğunu" belirtmektedir. Bu sayı, argümanın tamamını oluşturur. Büyük bir depo, daha büyük bir dosyaya ihtiyaç duymaz. Daha fazla küçük dosyaya ihtiyaç duyar; her biri tanımladığı kodun yanında durur ve her biri o kodu en son değiştiren kişi tarafından sahiplenilir.
FAQ
İç içe geçmiş bir AGENTS.md dosyası kök dizindeki dosyanın yerini mi alır yoksa ona ekleme mi yapar?
Ekleme yapar. Upstream kaynaklar "en yakındaki önceliklidir" ifadesini kullanır; bu, bir çakışma durumunda ne olacağını açıklar, neyin yükleneceğini değil. Codex "dosyaları kökten aşağıya doğru boş satırlarla birleştirerek" okur; Claude Code ise dosyaları geçersiz kılmak yerine, çalışma dizininden yukarı doğru yürüyerek bulduğu her dosyayı birleştirir. En yakın dosya, yalnızca iki dosya aynı konu hakkında farklı talimatlar verdiğinde kazanır. Paylaşılan kuralları bir kez kök dizine yazın ve bunları her dizinde tekrarlamayın.
Kök dizindeki AGENTS.md dosyası ne kadar büyük olmalıdır?
O depoda yaptığınız her isteğin tepesine yapıştırıldığında sizi rahatsız etmeyecek kadar küçük olmalıdır, çünkü olan tam olarak budur. Claude Code belgeleri, dosya başına 200 satırın altında kalınmasını önerir ve daha uzun dosyaların "uyumu azalttığını" belirtir. Codex, varsayılan olarak 32 KiB birleşik boyuta ulaşıldığında talimat dosyalarını birleştirmeyi durdurur. Kök dosyanız dört servisi belgeliyorsa, bunun büyük bir kısmı tek bir görev için gereksiz yük oluşturur. Detayları dizin bazlı dosyalara taşıyın ve kök dizinde bir harita bırakın.
Bu dosyaların güncelliğini yitirmesini nasıl engellerim?
Kök dosyaya bir kural ekleyin: Bir dizindeki kodu değiştiren kişi, aynı commit içerisinde o dizinin AGENTS.md dosyasını da günceller. Dosyayı kodun yanına yerleştirmek kuralın kalıcı olmasını sağlar, çünkü değişiklik bir insanın zaten okumakta olduğu aynı pull request farkına (diff) düşer. Her değiştirilen yolu üzerindeki en yakın AGENTS.md dosyasıyla eşleştiren bir CI uyarısı ekleyin ve belirli aralıklarla her dosya üzerindeki git log -1 --format=%cs komutunu, belgelendirdiği dizinde çalıştırılan aynı komutla karşılaştırın.
Claude Code AGENTS.md dosyalarını okur mu?
Hayır. Ağustos 2026 itibarıyla belgeler "Claude Code AGENTS.md dosyasını değil, CLAUDE.md dosyasını okur" ifadesini içermektedir. Aynı dizinde, ilk satırında @AGENTS.md bulunan bir CLAUDE.md oluşturun; bu, paylaşılan dosyayı yükler ve altına Claude'a özel talimatlar eklemenize olanak tanır. ln -s AGENTS.md CLAUDE.md ile oluşturulan bir sembolik bağlantı (symlink), eklenecek ekstra bir şey olmadığında çalışır; ancak Windows üzerinde yönetici hakları veya Geliştirici Modu gerektirir. Bir oturumda /context komutunu çalıştırın ve dosyanın Memory dosyaları altında göründüğünü doğrulayın.
Sadece bazen geçerli olan bir kuralı nereye koymalıyım?
AGENTS.md dosyasına değil. Bu dosya her oturumda yüklendiği için, içindeki her satır aslında yazdığınız istekle dikkat çekmek için yarışır. Ara sıra ihtiyaç duyulan birkaç adımlı bir prosedür, talep üzerine yüklenen bir yeteneğe (skill) aittir. Tek bir dizin için geçerli olan bir kural, o dizinin AGENTS.md dosyasına aittir. Dizin ağacı veya bağımlılık listesi gibi ajanın doğrudan koddan okuyabileceği bir bilgi ise ikisine de ait değildir.