เขียน CLAUDE.md เหมือนเป็นรัฐธรรมนูญ: ข้อห้าม กฎพฤติกรรม การตัดสินใจเริ่มต้น. 92 commits ใน 5 วัน ไม่หลงทาง.
ภายใน 5 วันผมส่ง 92 commits และนำผลิตภัณฑ์ขึ้น production (github.com/defi-io/smarts) ไม่มีการพังกลางทาง ไม่มี rollback ไม่มี refactor ก้อนใหญ่ เหตุผลไม่ใช่เพราะ Claude เป็นอัจฉริยะ แต่เป็นเพราะไฟล์ CLAUDE.md 565 บรรทัดที่อยู่ที่รากของโปรเจกต์
บทความนี้พูดถึงวิธีเขียน CLAUDE.md ให้ทำงานเหมือนรัฐธรรมนูญ และสิ่งที่เกิดขึ้นหลังจากนั้น
หลายคนเขียน CLAUDE.md คล้าย README — โปรเจกต์คืออะไร รันยังไง นั่นเสียของ
README เขียนเพื่อมนุษย์อ่าน CLAUDE.md เขียนเพื่อ Claude อ่าน Claude จะโหลดอัตโนมัติทุกครั้งที่เปิด session นั่นหมายความว่าทุกบรรทัดที่คุณใส่ลงไป จะกลายเป็นเงื่อนไขนำหน้าของทุกการตัดสินใจที่ Claude ทำหลังจากนั้น
เขียนแบบ README จะได้แบบนี้: Claude พอรู้ว่าโปรเจกต์คืออะไร รู้วิธีรันเทสต์ แต่ทุกการตัดสินใจทางเทคนิคเริ่มจากศูนย์
เขียนแบบรัฐธรรมนูญจะได้แบบนี้: Claude รู้ว่าทางไหนปิดอยู่ ข้อตกลงไหนบังคับ จุดแยกไหนค่าเริ่มต้นเลือกทางไหน และเมื่อไหร่ต้องหยุดถาม
ความต่าง: แบบแรกจะ "ในเมื่อทำอยู่แล้ว" ลาก dependency ใหม่เข้ามา เพิ่มชั้น abstraction แก้ Gemfile แบบที่สองจะไม่ทำ
โปรเจกต์ที่ผมทำอยู่ชื่อ smarts.md — แพลตฟอร์มที่สร้าง live docs และ MCP server สำหรับ smart contract ไฟล์ CLAUDE.md ของมันยาว 565 บรรทัด แบ่งเป็นส่วนๆ:
1. ตัวตนของโปรเจกต์ (5 บรรทัด)
2. แก่นของผลิตภัณฑ์ (นิยามหนึ่งบรรทัด + ความต่างเชิงโครงสร้างจากคู่แข่ง)
3. Tech stack (ข้อจำกัดแข็ง รูปแบบ YAML)
4. รายการข้อห้าม (รายการ ❌ ที่ชัดเจน)
5. ขอบเขต (ขอบของ MVP ที่ตายตัว)
6. สถาปัตยกรรม (พร้อมแผนภาพ ASCII)
7. โครงสร้างไดเรกทอรี (ความรับผิดชอบของแต่ละไฟล์)
8. คอนเวนชันโค้ด Ruby (พร้อมตัวอย่างควร/ไม่ควร)
9. กลยุทธ์ cache (เป็นตาราง)
10. ข้อกำหนดเทสต์
11. รายละเอียด deploy
12. Git workflow
13. กฎการใช้ Claude Code (คำสั่งเชิงพฤติกรรม)
14. หมุดหมายภายใน 90 วัน
15. หลักการแก่น
ไม่มีส่วนไหนเป็นแค่การประดับ ด้านล่างผมจะหยิบบางส่วนมาอธิบายว่าทำไมถึงต้องเขียนแบบนี้
ของผมหน้าตาประมาณนี้:
❌ ห้ามใส่บริการ TypeScript / Node.js
❌ ห้ามใส่ ethers.js / web3.js
❌ ห้ามใส่ Sidekiq (ใช้ Solid Queue)
❌ ห้ามใส่ React / Vue / Svelte (ใช้ Hotwire)
❌ ห้ามใส่ Redis (Solid Cache / Solid Queue / Solid Cable คลุมทุกอย่าง)
❌ ไม่ทำสัญญาที่ยังไม่ verified (รับเฉพาะที่ verified บน Etherscan)
❌ ไม่ทำ Solana / Bitcoin / Move (เฉพาะ EVM)
นี่คือโปรเจกต์ Web3 ค่าเริ่มต้นในวงการ Web3 คือ TypeScript + ethers.js + Redis + React ผมเดินสวน เหตุผลผมมี แต่ Claude ไม่รู้ ถ้าไม่มีรายการข้อห้าม Claude จะแนะนำตาม "สามัญสำนึกของอุตสาหกรรม" ที่ฝังในข้อมูลฝึก — ซึ่งเกือบจะแน่นอนว่าเป็นเส้นทาง TypeScript
มีรายการข้อห้ามแล้ว Claude จะเลิกถามว่า "เพิ่มบริการ Node ไว้รัน web3.js ดีไหม?" เส้นทางนั้นปิดตามค่าเริ่มต้น
จุดสำคัญ: ทุกข้อต้อง ชัดเจน และ เด็ดขาด อย่าเขียน "พยายามเลี่ยง TypeScript" ให้เขียน "ห้ามใส่ TypeScript" สิ่งที่กำกวม Claude จะอ่านว่าต่อรองได้
บล็อกใหญ่ก้อนสุดท้ายของ CLAUDE.md คือ "กฎการใช้ Claude Code":
### เมื่อผมพูดว่า "เริ่มทำ X"
1. เช็กก่อนว่าข้อจำกัดของ CLAUDE.md อนุญาตวิธีนี้ไหม
2. เช็กในโค้ดเดิมว่ามีการ implement ที่เกี่ยวข้องอยู่แล้วไหม (อย่าประดิษฐ์ล้อใหม่)
3. ก่อนเขียนโค้ด ให้เปิด branch ใหม่
4. หลัง implement เสร็จ ให้รันเทสต์
5. ห้าม commit อัตโนมัติ — เมื่อโค้ดเขียนเสร็จและเทสต์เขียว ให้หยุดและรายงาน
รอจนผมพูดว่า "commit" ชัดเจนค่อย commit
### เมื่อผมพูดว่า "ผมมีไอเดีย"
อย่าเขียนโค้ดทันที ก่อนอื่น:
1. ยืนยันความเข้าใจ (พูดทวนด้วยคำพูดของตัวเอง)
2. ประเมินกับข้อจำกัดของ CLAUDE.md
3. ชี้ปัญหาที่อาจเกิดหรือทางเลือกที่ดีกว่า
4. รอผมยืนยันก่อนค่อยลงมือ
### เมื่อเจอจุดแยกทางเทคนิค
เมื่อ CLAUDE.md ไม่ระบุ:
1. ค่าเริ่มต้น: เลือกแบบที่ "Rails-native มากกว่า"
2. ค่าเริ่มต้น: เลือกแบบที่มี dependency น้อยกว่า
3. ค่าเริ่มต้น: เลือกแบบที่ทำให้ solo dev iterate ได้เร็วกว่า
4. ไม่แน่ใจ ให้หยุดและถาม
ส่วนนี้สำคัญกว่า "ตั้งชื่อแบบ snake_case" สิบเท่า
style โค้ด Claude อ่านโค้ดก็เรียนได้ แต่ "เมื่อไหร่ควรหยุดถาม", "ได้ยิน 'ผมมีไอเดีย' ให้พูดทวนก่อนแทนที่จะเขียนโค้ดทันที" — เหล่านี้คือรูปแบบพฤติกรรม อ่านโค้ดอย่างเดียวเรียนไม่ได้
บรรทัดที่สำคัญที่สุด: ที่จุดแยก ค่าเริ่มต้นเลือกทางไหน กฎข้อเดียวนี้กำหนดว่า Claude จะทำอะไรเมื่อคุณไม่อยู่ในห้อง (เมื่อคุณแค่บอก "เริ่มทำ X" แล้วเดินจากไป) เขียนข้อนี้ให้ชัด คุณก็กล้าปล่อยให้มันทำงานเองโดยไม่ต้องคุม
หัวของ CLAUDE.md มีบรรทัดนี้:
เอกสารนี้คือ "ต้นทาง" ของโปรเจกต์ จะถูกโหลดอัตโนมัติเมื่อเริ่มทุก session ของ Claude Code เมื่อจะเปลี่ยนการตัดสินใจทางเทคนิค ให้แก้ที่นี่ก่อน โค้ดตามมาทีหลัง
นี่คือสัญญาเรื่อง workflow เมื่อผมตัดสินใจสลับตัวเลือกทางเทคนิค — เช่น อัปเกรดโมเดล AI หลักจาก gpt-5-mini เป็น gpt-5 — ก้าวแรกไม่ใช่การไปแก้ initializer ก้าวแรกคือแก้ส่วนนี้ใน CLAUDE.md:
ai:
fast: gpt-5-mini # ก่อน
fast: gpt-5 # หลัง
จากนั้นค่อยให้ Claude อ่าน CLAUDE.md อีกครั้งและปรับโค้ดให้ตรงกัน
ทำไม? เพราะถ้าคุณเปลี่ยนค่าในโค้ดแล้ว CLAUDE.md ตามไม่ทัน คราวต่อไปที่ Claude อ่าน CLAUDE.md มันจะเห็นค่าเก่า แล้ว "ใจดี" rollback โค้ดของคุณกลับ ต้นเหตุของความขัดแย้งคือจุดล้มเดี่ยว — CLAUDE.md ที่หลุด sync รัฐธรรมนูญที่ตามความเป็นจริงไม่ทันคือจุดเริ่มต้นของสงครามกลางเมือง
ปฏิบัติกับ CLAUDE.md แบบรัฐธรรมนูญหมายถึง: มันต้องวิ่งนำหน้าโค้ดเสมอ
smarts.md, 5 วัน, 92 commits:
อายุเฉลี่ยของ PR: 30 นาที ไม่มี refactor ใหญ่ ไม่มี "เดี๋ยว ทิศทางผิด rollback"
ไม่ใช่เพราะ Claude มีเวทมนตร์ แต่เพราะทุก session มันวิ่งบนรางยาว 565 บรรทัด มันรู้ว่าต้องไม่ลาก TypeScript เข้ามา รู้ว่า Solid Queue คือ queue ค่าเริ่มต้น รู้ว่าฟังก์ชัน view cache 60 วินาที รู้ว่าทุก service ต้อง implement class method call รู้ว่าก่อน commit ต้องรอผมยืนยัน
ลอกข้อจำกัดเหล่านี้ออกครึ่งหนึ่ง คุณจะได้: 30 นาทีต่อวันอธิบาย "ทำไมเราไม่ใช้ X", 5 นาทีรีวิว dependency ที่มันเพิ่ม "เผื่อเรียก", และ Gemfile ที่ค่อยๆ พังลง
อย่าเริ่มจากไฟล์เปล่า เริ่มจากการตัดสินใจล่าสุดที่เจ็บปวด
ถ้าช่วงนี้ Claude "ลาก dependency ใหม่ตลอด" ให้เขียนรายการข้อห้าม
ถ้าเป็น "เปลี่ยนสถาปัตยกรรมตามใจ" ให้เขียนแผนภาพสถาปัตยกรรม + "เพิ่ม microservice เปลี่ยน DB ฯลฯ ต้องยืนยัน"
ถ้าเป็น "ไม่เขียนเทสต์" ให้เขียน "ส่วนไหนต้องมี unit test แน่นอน"
ถ้าเป็น "commit ดุเดือดเกินไป" ให้เขียน "ห้าม commit อัตโนมัติ รอคำสั่งชัดเจน"
เจ็บแต่ละครั้ง เพิ่มหนึ่งข้อ ที่เหลือยังไม่ต้องเขียน
3 เดือนต่อมาคุณจะมี CLAUDE.md ยาว 500 บรรทัด ซึ่งทุกบรรทัดมี "ผมไม่อยากให้มันทำแบบนี้อีก" ที่เป็นรูปธรรมหนุนหลัง เอกสารนี้เอาชนะเทมเพลตใดๆ เพราะมันถูกปรับให้ตรงกับโปรเจกต์ของคุณ workflow ของคุณ ทีมของคุณ (แม้คนเดียว) อย่างแม่นยำ
รัฐธรรมนูญไม่ได้เขียนทีเดียวเสร็จ มันก่อร่างขึ้นจากความขัดแย้งคอนกรีตทีละอัน
ซอร์ส: github.com/defi-io/smarts