ลำดับชั้น CLAUDE.md: user, project, directory
แนวคิด
CLAUDE.md คือไฟล์ instruction ที่ Claude Code อ่านตอนเริ่มทุก session และมันวางได้หลายที่ตามลำดับชั้น exam guide เน้นสามระดับ คือ user-level ที่ ~/.claude/CLAUDE.md, project-level ที่ ./CLAUDE.md หรือ ./.claude/CLAUDE.md, และ directory-level คือไฟล์ CLAUDE.md ใน subdirectory เอกสารจริงเพิ่มอีกสองระดับที่ควรรู้ คือ managed policy ระดับองค์กร และ ./CLAUDE.local.md สำหรับความชอบส่วนตัวใน project ที่ควรใส่ .gitignore
หัวใจที่ต้องเข้าใจคือทุกไฟล์ที่พบจะถูก concatenate เข้า context รวมกัน ไม่ใช่ทับกัน ลำดับการโหลดไล่จากขอบเขตกว้างสุดไปแคบสุด คือ managed แล้ว user แล้ว project แล้ว local ดังนั้น instruction ของ project จึงปรากฏใน context หลัง instruction ของ user และ instruction ที่ใกล้ที่ที่เรารัน Claude จะถูกอ่านทีหลังสุด
จุดที่มักพลาดคือ directory-level ไม่ได้โหลดตอน launch เหมือน project-level ไฟล์ CLAUDE.md ใน subdirectory จะถูกดึงเข้ามาแบบ on demand ก็ต่อเมื่อ Claude อ่านไฟล์ในโฟลเดอร์นั้นจริง ๆ ทำให้ context ไม่บวมด้วยกฎที่ยังไม่เกี่ยว
ทำไมสำคัญ
เหตุผลที่ต้องรู้ว่ากฎแต่ละข้ออยู่ระดับไหน เพราะมันตอบคำถามว่า "ใครจะได้รับ instruction นี้บ้าง" ~/.claude/CLAUDE.md เป็นของเราคนเดียวทุก project บนเครื่อง มันไม่ถูกแชร์ผ่าน version control กรณีคลาสสิกที่ exam guide ยกคือ สมาชิกใหม่ในทีมไม่ได้รับ instruction เพราะกฎนั้นถูกเขียนไว้ที่ user-level ของคนเขียน ไม่ใช่ที่ project-level ที่ commit ลง repo ทางแก้คือย้ายกฎที่ทีมต้องใช้ร่วมกันไปไว้ที่ ./CLAUDE.md หรือ ./.claude/CLAUDE.md แล้ว commit เพื่อให้ทุกคนที่ clone ได้เหมือนกัน
อีกทักษะที่ต้องมีคือการ diagnose ว่าไฟล์ใดถูกโหลดจริง คำสั่ง /memory จะแสดงรายการ CLAUDE.md, CLAUDE.local.md, และไฟล์ rules ทั้งหมดที่โหลดใน session ปัจจุบัน ถ้าไฟล์ไม่ปรากฏในรายการ แปลว่า Claude มองไม่เห็นมัน นี่เป็นก้าวแรกเวลาพฤติกรรมไม่สม่ำเสมอข้าม session เพราะบางทีปัญหาไม่ใช่เนื้อหาของกฎ แต่เป็นเพราะกฎนั้นอยู่ในตำแหน่งที่ session นี้ไม่ได้โหลด
ตัวอย่าง
# โหลดเต็มตอน launch (ไล่จากกว้างไปแคบ)
~/.claude/CLAUDE.md # user — ของเราคนเดียว ไม่ commit
./CLAUDE.md หรือ ./.claude/CLAUDE.md # project — commit แชร์ทั้งทีม
./CLAUDE.local.md # local — ส่วนตัวใน project นี้ (ใส่ .gitignore)
# โหลดแบบ on demand เมื่อ Claude แตะไฟล์ในโฟลเดอร์นั้น
./packages/api/CLAUDE.md # directory — เฉพาะเวลาแก้ไฟล์ใน api/
ถ้ากฎ "รันเทสต์ก่อน commit" อยู่ใน ~/.claude/CLAUDE.md ของเรา เพื่อนร่วมทีมจะไม่เห็นมัน ย้ายไป ./CLAUDE.md แล้ว commit จึงจะแชร์ได้ ใช้ /memory ยืนยันว่าไฟล์ถูกโหลดจริง
เช็คความเข้าใจ
ทำไมสมาชิกใหม่ในทีมอาจไม่ได้รับ instruction ที่เราตั้งไว้ และแก้อย่างไร
directory-level CLAUDE.md ต่างจาก project-level อย่างไรในเรื่องการโหลด