หยุดอธิบายโปรเจกต์ซ้ำทุกครั้ง ด้วย CLAUDE.md ใน Claude Code
เวลาที่เราเริ่ม Claude Code ในโปรเจกต์ใหม่ เรามักต้องอธิบายเรื่องเดิมซ้ำ ๆ เช่น โปรเจกต์นี้ใช้คำสั่งอะไรสำหรับรัน Test ใช้ npm หรือ pnpm โครงสร้าง API อยู่ตรงไหน ห้ามแก้ไฟล์ใด หรือก่อนส่งงานต้องตรวจสอบอะไรบ้าง
ใน Session แรก Claude อาจเข้าใจกติกาเหล่านี้ดี แต่เมื่อเริ่ม Session ใหม่ Context ของบทสนทนาเดิมไม่ได้ติดตามมาทั้งหมด เราจึงต้องพิมพ์คำแนะนำเดิมอีกครั้ง
ปัญหานี้แก้ได้ด้วยไฟล์ชื่อ CLAUDE.md
ไฟล์นี้ทำหน้าที่คล้ายคู่มือการทำงานประจำโปรเจกต์ เมื่อ Claude Code เริ่ม Session มันจะอ่านคำแนะนำจากไฟล์ดังกล่าวและนำไปใช้เป็น Context ตั้งแต่เริ่มต้น
แทนที่จะบอก Claude ทุกครั้งว่า
โปรเจกต์นี้ใช้ pnpm ห้ามใช้ npm หลังแก้ TypeScript ต้องรัน typecheck ก่อน commit ต้องรัน test ที่เกี่ยวข้อง อย่าแก้ database migration โดยไม่ได้รับอนุญาต
เราสามารถเขียนข้อมูลเหล่านี้ไว้ใน CLAUDE.md เพียงครั้งเดียว แล้วให้ Claude Code อ่านในการทำงานครั้งต่อ ๆ ไป
CLAUDE.md คืออะไร
CLAUDE.md คือไฟล์ Markdown สำหรับบันทึกคำแนะนำถาวรที่ต้องการให้ Claude Code รับรู้ในแต่ละ Session
ข้อมูลที่เหมาะกับไฟล์นี้ ได้แก่
- คำสั่ง Build, Test, Lint และ Typecheck
- Coding Convention ที่แตกต่างจากค่ามาตรฐาน
- โครงสร้างสำคัญของโปรเจกต์
- ข้อจำกัดในการแก้ไขไฟล์
- Workflow ก่อน Commit หรือเปิด Pull Request
- Architectural Decision ที่ Claude ไม่สามารถเดาได้จากโค้ด
- ปัญหาหรือข้อควรระวังเฉพาะของโปรเจกต์
ตัวอย่างเช่น โปรเจกต์อาจดูเหมือนใช้ npm เพราะมี package.json แต่ทีมงานกำหนดให้ใช้ pnpm เท่านั้น หรือ Test บางชุดอาจต้องเปิด Redis ในเครื่องก่อน เรื่องเหล่านี้ Claude อาจไม่สามารถรู้ได้จากการอ่านโค้ดเพียงอย่างเดียว
CLAUDE.md จึงไม่ควรเป็นเอกสารอธิบายทุกอย่างในระบบ แต่ควรเป็นรายการข้อมูลสำคัญที่ถ้า Claude ไม่รู้แล้วจะมีโอกาสทำงานผิด
เริ่มต้นสร้าง CLAUDE.md ด้วยคำสั่ง /init
เมื่อเปิด Claude Code ภายในโปรเจกต์ สามารถเริ่มต้นด้วยคำสั่ง
/init
Claude Code จะสำรวจโครงสร้างของโปรเจกต์ ตรวจดูระบบ Build, Test Framework, รูปแบบโค้ด และคำสั่งที่เกี่ยวข้อง จากนั้นสร้างร่าง CLAUDE.md ให้
ถ้าโปรเจกต์มี CLAUDE.md อยู่แล้ว คำสั่ง /init จะเสนอแนวทางปรับปรุงไฟล์เดิม แทนที่จะเขียนทับทันทีโดยไม่ตรวจสอบ
อย่างไรก็ตาม ไม่ควรถือว่าไฟล์ที่ /init สร้างขึ้นสมบูรณ์แล้ว เพราะ Claude วิเคราะห์ได้เฉพาะสิ่งที่พบใน Repository เท่านั้น
กติกาที่ไม่ได้เขียนอยู่ในโค้ด เช่น
ห้ามเปลี่ยน Public API โดยไม่ได้รับอนุมัติ ใช้ข้อมูลจำลองเท่านั้นเมื่อทดสอบ Payment ทุกการเปลี่ยนแปลงใน Billing ต้องเพิ่ม Integration Test ห้าม Push ไปยัง main โดยตรง
ยังต้องให้มนุษย์เพิ่มเติมเอง
วิธีใช้งานที่เหมาะสมจึงเป็น
รัน /init ตรวจสอบสิ่งที่ Claude สร้าง ลบข้อมูลที่ไม่จำเป็น เพิ่มกติกาที่ Claude เดาไม่ได้ ทดลองใช้งานจริง ปรับแก้เมื่อพบข้อผิดพลาด
ตัวอย่าง CLAUDE.md ที่นำไปใช้ได้จริง
สมมติว่าเป็นโปรเจกต์ Web Application ที่ใช้ TypeScript, React และ Node.js ไฟล์เริ่มต้นอาจเขียนได้ดังนี้
# Project overview - This is a TypeScript monorepo. - Frontend code is in `apps/web`. - Backend code is in `apps/api`. - Shared packages are in `packages`. # Package manager - Use `pnpm`. - Do not use `npm` or `yarn`. - Install dependencies from the repository root. # Commands - Development: `pnpm dev` - Typecheck: `pnpm typecheck` - Lint: `pnpm lint` - Unit tests: `pnpm test` - Run one test file: `pnpm vitest <path>` # Code style - Use TypeScript for new source files. - Prefer named exports. - Do not introduce `any` unless the reason is documented. - Reuse existing components before creating new ones. # Testing - Add or update tests when changing business logic. - Prefer running the relevant test file during development. - Run typecheck and related tests before declaring the task complete. # Database safety - Do not modify migration files without explicit approval. - Do not run destructive database commands. - Use test data only when testing locally. # Git workflow - Review `git diff` before committing. - Do not push directly to `main`. - Keep commits focused on one logical change.
จุดสำคัญคือต้องเขียนเป็นคำแนะนำที่ตรวจสอบได้
คำว่า
เขียนโค้ดให้ดี
คลุมเครือเกินไป เพราะแต่ละคนตีความคำว่า “ดี” ไม่เหมือนกัน
ควรเปลี่ยนเป็น
ห้ามใช้ any ใน TypeScript เว้นแต่เขียนเหตุผลไว้ใน Comment
แทนที่จะเขียนว่า
ตรวจสอบงานให้เรียบร้อย
ควรเขียนว่า
หลังแก้ Source Code ให้รัน pnpm typecheck และ Test ที่เกี่ยวข้อง
ยิ่งกฎเฉพาะเจาะจง Claude ก็ยิ่งมีโอกาสปฏิบัติตามได้สม่ำเสมอขึ้น
วาง CLAUDE.md ไว้ตรงไหน
ตำแหน่งของไฟล์มีผลต่อขอบเขตการใช้งาน
ใช้กับทุกโปรเจกต์ของคุณ
วางไว้ที่
~/.claude/CLAUDE.md
ตำแหน่งนี้เหมาะกับความชอบส่วนตัวที่ใช้ในทุกโปรเจกต์ เช่น
# Personal preferences - Explain important architectural decisions before implementing them. - Keep responses concise. - Prefer small focused commits. - Ask before installing a major dependency.
ไม่ควรใส่รายละเอียดเฉพาะโปรเจกต์ไว้ในไฟล์ระดับผู้ใช้ เพราะอาจทำให้ Claude นำกติกาของโปรเจกต์หนึ่งไปใช้กับอีกโปรเจกต์โดยไม่เหมาะสม
ใช้ร่วมกันทั้งทีม
วางไว้ที่ Root ของโปรเจกต์
./CLAUDE.md
หรือ
./.claude/CLAUDE.md
ไฟล์นี้ควร Commit เข้า Git เพื่อให้สมาชิกทุกคนในทีมใช้คำแนะนำชุดเดียวกัน
ตัวอย่างสิ่งที่ควรอยู่ในไฟล์ระดับโปรเจกต์ ได้แก่ โครงสร้างระบบ คำสั่ง Test รูปแบบ Branch ข้อกำหนดด้าน Security และ Workflow ของทีม
ใช้เฉพาะคุณในโปรเจกต์นั้น
ใช้ไฟล์
./CLAUDE.local.md
ไฟล์นี้เหมาะกับข้อมูลส่วนตัวที่ไม่ควรถูก Commit เช่น URL ของ Sandbox ชุดข้อมูลทดสอบเฉพาะเครื่อง หรือ Workflow ส่วนตัว
ควรเพิ่มไฟล์นี้ไว้ใน .gitignore
CLAUDE.local.md
อย่าใส่ Secret, Password, API Key หรือ Credential ลงในไฟล์คำแนะนำ แม้ไฟล์นั้นจะถูก Ignore จาก Git เพราะ Claude ยังสามารถอ่านข้อมูลในไฟล์ได้เมื่อทำงาน
Claude โหลด CLAUDE.md หลายระดับได้
Claude Code สามารถอ่าน CLAUDE.md ตามลำดับโฟลเดอร์ได้
สมมติว่าโปรเจกต์มีโครงสร้างดังนี้
company/
├── CLAUDE.md
└── ecommerce/
├── CLAUDE.md
├── frontend/
│ └── CLAUDE.md
└── backend/
└── CLAUDE.md
ถ้าเปิด Claude Code จากโฟลเดอร์ ecommerce Claude จะอ่านกฎจากระดับด้านบนและกฎของโปรเจกต์ปัจจุบัน
ส่วน CLAUDE.md ที่อยู่ใน frontend หรือ backend จะถูกนำมาใช้เมื่อ Claude เข้าไปอ่านไฟล์ในพื้นที่เหล่านั้น
แนวทางนี้มีประโยชน์มากกับ Monorepo เพราะสามารถกำหนดกฎกลางของบริษัท กฎกลางของโปรเจกต์ และกฎเฉพาะแต่ละ Module แยกจากกันได้
อย่างไรก็ตาม ต้องระวังกฎที่ขัดแย้งกัน เช่น ไฟล์ระดับบนกำหนดให้ใช้ Named Export แต่ไฟล์ใน Subdirectory กำหนดให้ใช้ Default Export โดยไม่มีเหตุผลชัดเจน
Claude ไม่ได้มีระบบแก้ความขัดแย้งของกฎเหมือน Compiler หากมีคำสั่งขัดกัน มันอาจเลือกทำตามคำสั่งใดคำสั่งหนึ่งอย่างไม่สม่ำเสมอ
อย่ายัดทุกอย่างไว้ในไฟล์เดียว
เมื่อใช้ไปนาน ๆ CLAUDE.md มักขยายใหญ่ขึ้น เพราะทุกครั้งที่ Claude ทำผิด เราอาจเพิ่มกฎใหม่เข้าไปเรื่อย ๆ
ผลคือไฟล์กลายเป็นคู่มือหลายร้อยบรรทัด มีทั้ง Coding Style, API Design, Testing, Security, Deployment และข้อมูลอธิบายระบบทั้งหมด
ไฟล์ที่ยาวเกินไปใช้พื้นที่ Context มากขึ้น และกฎสำคัญอาจถูกกลบด้วยรายละเอียดที่ไม่จำเป็น
แนวทางที่ดีกว่าคือเก็บเฉพาะกฎที่ต้องใช้เกือบทุก Session ไว้ใน CLAUDE.md ส่วนกฎเฉพาะด้านให้แยกไว้ใน
.claude/rules/
ตัวอย่างโครงสร้างคือ
.claude/
├── CLAUDE.md
└── rules/
├── testing.md
├── api-design.md
├── database.md
└── frontend.md
แต่ละไฟล์ควรรับผิดชอบหนึ่งหัวข้อ เพื่อลดความสับสนและทำให้ทีมตรวจสอบกฎได้ง่ายขึ้น
โหลดกฎเฉพาะเมื่อ Claude ทำงานกับไฟล์ที่เกี่ยวข้อง
กฎใน .claude/rules/ สามารถกำหนดขอบเขตด้วย paths
ตัวอย่างเช่น ต้องการให้กฎด้าน API ใช้เฉพาะไฟล์ TypeScript ภายใต้ src/api
สร้างไฟล์
.claude/rules/api-design.md
แล้วเขียนว่า
--- paths: - "src/api/**/*.ts" --- # API rules - Validate all external input. - Use the shared error response format. - Do not expose internal error messages to clients. - Add tests for success and failure cases.
กฎนี้จะเกี่ยวข้องเมื่อ Claude อ่านหรือทำงานกับไฟล์ที่ตรงกับ Pattern ที่กำหนด
อีกตัวอย่างหนึ่งคือกฎสำหรับ React Component
---
paths:
- "src/components/**/*.{ts,tsx}"
---
# Component rules
- Reuse components from the design system.
- Keep data fetching outside presentational components.
- Include loading, empty, and error states.
วิธีนี้ช่วยให้กฎด้าน Frontend ไม่รบกวน Context ตอน Claude กำลังทำงานกับ Database และกฎด้าน Database ไม่รบกวนตอนกำลังแก้ UI
นำเอกสารเดิมมาใช้ด้วย @import
หากโปรเจกต์มีเอกสารอยู่แล้ว ไม่จำเป็นต้อง Copy เนื้อหาทั้งหมดมาใส่ CLAUDE.md
สามารถอ้างอิงไฟล์ด้วยรูปแบบ
See @README.md for the project overview. Read @package.json for available commands. Follow the Git workflow in @docs/git-workflow.md.
Claude Code จะนำเนื้อหาจากไฟล์ที่อ้างอิงเข้ามาใน Context
แต่ต้องเข้าใจว่า Import ช่วยจัดระเบียบเอกสาร ไม่ได้ช่วยลด Context โดยอัตโนมัติ เพราะเนื้อหาที่ Import ยังถูกโหลดเข้ามา
ดังนั้นไม่ควร Import เอกสารขนาดใหญ่ทั้งชุดเพียงเพราะสะดวก ควรอ้างอิงเฉพาะไฟล์ที่จำเป็นต่อการทำงานเกือบทุก Session
ตรวจสอบว่า Claude โหลดกฎจริงหรือไม่ด้วย /memory
หลังสร้างหรือแก้ไข CLAUDE.md อย่าเพิ่งสรุปว่า Claude เห็นไฟล์แล้ว
ให้เปิด Claude Code และใช้คำสั่ง
/memory
คำสั่งนี้ใช้ดูว่า Session ปัจจุบันโหลดไฟล์คำแนะนำใดบ้าง เช่น
CLAUDE.md CLAUDE.local.md .claude/rules/testing.md .claude/rules/api-design.md
ถ้าไฟล์ไม่ปรากฏในรายการ แสดงว่า Claude ไม่ได้โหลดไฟล์นั้นใน Session ปัจจุบัน อาจเกิดจากวางไฟล์ผิดตำแหน่ง เปิด Claude จาก Working Directory คนละระดับ หรือกฎแบบ Path-specific ยังไม่ถูก Trigger
การใช้ /memory จึงเป็นวิธีตรวจสอบที่ดีกว่าการถาม Claude ว่า
คุณเห็น CLAUDE.md หรือไม่
เพราะเราตรวจสอบจากรายการไฟล์ที่ระบบโหลดได้โดยตรง
ทดสอบ CLAUDE.md เหมือนทดสอบโค้ด
หลังตั้งค่าแล้ว ควรทดลองมอบหมายงานเล็ก ๆ ที่เกี่ยวข้องกับกฎ
ตัวอย่างเช่น ถ้าเขียนไว้ว่า
Use pnpm. Do not use npm.
ให้ลองสั่ง Claude เพิ่ม Dependency หนึ่งรายการ แล้วตรวจสอบว่าคำสั่งที่ Claude เลือกใช้คือ pnpm add หรือไม่
ถ้ากำหนดว่า
Run typecheck after changing TypeScript files.
ให้ลองมอบหมายงานแก้ไฟล์ TypeScript แล้วตรวจสอบว่า Claude รันคำสั่ง Typecheck ก่อนสรุปงานหรือไม่
หาก Claude ไม่ทำตาม ให้ตรวจสอบตามลำดับดังนี้
ตรวจสอบว่าไฟล์ถูกโหลดหรือไม่
ใช้
/memory
ตรวจสอบว่ากฎคลุมเครือหรือไม่
เปลี่ยนจาก
Test changes carefully.
เป็น
After changing TypeScript source files, run `pnpm typecheck` and the nearest related test file.
ตรวจสอบว่ามีกฎขัดแย้งกันหรือไม่
ค้นหาใน
CLAUDE.md CLAUDE.local.md .claude/rules/
ว่าอาจมีคำแนะนำคนละชุดเกี่ยวกับเรื่องเดียวกัน
ตรวจสอบว่าไฟล์ยาวเกินไปหรือไม่
ลบเนื้อหาที่ Claude สามารถค้นพบได้เองจาก Repository และเก็บเฉพาะสิ่งที่จำเป็นจริง ๆ
CLAUDE.md ไม่ใช่ระบบบังคับความปลอดภัย
ข้อควรเข้าใจที่สำคัญที่สุดคือ CLAUDE.md เป็นคำแนะนำที่ถูกส่งเข้า Context ไม่ใช่ข้อบังคับระดับระบบ
การเขียนว่า
ห้ามแก้ไฟล์ migration
ช่วยลดโอกาสที่ Claude จะเข้าไปแก้ไฟล์ดังกล่าว แต่ไม่ได้รับประกันว่าจะไม่มีการแก้ไขในทุกสถานการณ์
ถ้าเป็นข้อห้ามที่ต้องบังคับจริง เช่น
- ห้ามเขียนไฟล์ใน Production Configuration
- ห้ามรันคำสั่ง Deploy
- ห้ามแก้ Database Migration
- ต้องรัน Formatter หลังแก้ไฟล์
- ต้องตรวจสอบบางอย่างก่อน Commit
ควรใช้ Permissions, Sandbox หรือ Hooks ให้เหมาะสม
หลักการง่าย ๆ คือ
CLAUDE.md ใช้บอกว่า Claude ควรทำงานอย่างไร Permissions ใช้กำหนดว่า Claude ได้รับอนุญาตให้ทำอะไร Hooks ใช้กำหนดว่าเมื่อเกิดเหตุการณ์หนึ่ง ต้องรันขั้นตอนอะไร
ตัวอย่างเช่น การเขียนใน CLAUDE.md ว่าให้รัน ESLint หลังแก้ไฟล์เป็นคำแนะนำ แต่การสร้าง Hook ให้รัน ESLint หลังการแก้ไขเป็นกลไกที่แน่นอนกว่า
กฎที่ดีควรเกิดจากข้อผิดพลาดจริง
ไม่จำเป็นต้องพยายามเขียน CLAUDE.md ให้สมบูรณ์ตั้งแต่วันแรก
เริ่มจากข้อมูลพื้นฐาน เช่น
คำสั่ง Build คำสั่ง Test Package Manager โครงสร้างสำคัญ ข้อห้ามที่จำเป็น
จากนั้นเมื่อ Claude ทำผิดซ้ำหรือทีมต้องอธิบายเรื่องเดิมอีก ให้เพิ่มกฎเฉพาะเรื่องนั้น
ตัวอย่างเช่น Claude สร้าง Component ใหม่ทั้งที่มี Component เดิมอยู่แล้ว อาจเพิ่มว่า
Search the existing design system before creating a new UI component.
หาก Claude รัน Test ทั้งระบบทุกครั้งจนเสียเวลามาก อาจเพิ่มว่า
During development, run the nearest relevant test file. Run the full suite only when requested or before release.
หาก Claude แก้ไฟล์นอกขอบเขตงานบ่อย อาจเพิ่มว่า
Before editing, identify the minimum set of files required. Do not perform unrelated refactoring.
ไฟล์ที่มีประโยชน์ที่สุดจึงไม่ใช่ไฟล์ที่ยาวที่สุด แต่คือไฟล์ที่สะสมบทเรียนจากการทำงานจริงของทีม
จาก Prompt ที่ต้องพิมพ์ซ้ำ สู่ระบบการทำงานของทีม
เมื่อมี CLAUDE.md ที่ออกแบบดี Prompt สำหรับเริ่มงานจะสั้นลงอย่างมาก
จากเดิมที่ต้องเขียนว่า
ช่วยเพิ่มระบบเปลี่ยนรหัสผ่าน โปรเจกต์ใช้ pnpm API อยู่ใน apps/api ต้องใช้รูปแบบ error เดิม ต้องเขียน test ห้ามแก้ migration หลังทำเสร็จให้รัน typecheck
สามารถเหลือเพียง
เพิ่มระบบเปลี่ยนรหัสผ่านตาม Convention ของโปรเจกต์ เริ่มจากสำรวจโค้ดที่เกี่ยวข้องและเสนอแผนก่อนแก้ไข
กฎพื้นฐานถูกเก็บไว้ในโปรเจกต์แล้ว Prompt จึงเหลือเฉพาะเป้าหมายและขอบเขตของงานปัจจุบัน
นี่คือความแตกต่างระหว่างการใช้ Claude Code เป็นครั้ง ๆ กับการสร้างสภาพแวดล้อมที่ Claude Code สามารถทำงานร่วมกับทีมได้อย่างต่อเนื่อง
CLAUDE.md ไม่ได้ทำให้ Claude รู้ทุกอย่าง และไม่ได้รับประกันว่า Claude จะทำตามทุกคำสั่งเสมอไป
แต่เมื่อใช้ร่วมกับ /memory, .claude/rules/, Permissions และ Hooks อย่างเหมาะสม มันช่วยลดการอธิบายซ้ำ ลดข้อผิดพลาดเดิม และเปลี่ยนความรู้ที่เคยอยู่ในหัวของนักพัฒนาให้กลายเป็นกติกาที่ Claude และทีมสามารถใช้ร่วมกันได้