บทเรียน 121 · Rails · Day 3

prompts/ และ CLAUDE.md — คู่มือพนักงานใหม่ที่แนบให้ AI ทุกครั้ง

~20 นาที · ควรผ่าน บทเรียน 120 (เริ่ม Day 3) มาก่อน · ใช้ของจาก บท 86–89 (Claude Code · prompt ที่ดี) และ บท 118 (checklist 8 ข้อ) · บทนี้ไม่มีโค้ด Ruby

ทุกบล็อกของ Day 3 จบด้วยการเขียนคำสั่งงานให้ AI ลงไฟล์ แล้วเก็บไว้ในโฟลเดอร์ prompts/ · และมีไฟล์ชื่อ CLAUDE.md ที่ Claude Code เปิดอ่านเองทุกครั้งที่เริ่มคุย
อ่านจบแล้วคุณจะ: รู้ว่าทำไมต้องเก็บ prompt เป็นไฟล์ · อ่านไฟล์ prompts/00-context.md ของจริงออก · รู้ว่ากฎไหนควรอยู่ไฟล์ไหน (ของทีม vs ของส่วนตัว) · และเข้าใจว่าทำไมกฎในไฟล์พวกนี้เป็นแค่คำแนะนำ ไม่ใช่สิ่งที่บังคับ AI ได้

🔁 ทวนก่อนเริ่ม — คำพวกนี้จะโผล่ในบทนี้

🧰 เวอร์ชันที่ใช้ตรวจ: Claude Code 2.1.318 · ไฟล์ทุกไฟล์ในบทก็อปจาก repo ของคอร์ส branch day3-start ตรง ๆ (เครื่องตรวจใช้ Ruby 4.0.9 · Rails 8.1.4 ส่วนไฟล์ใน repo เขียน 4.0.5 · 8.1.3 — บทนี้ไม่ได้รัน Rails เลย จึงไม่มีผล)

📍 บทนี้เริ่มจาก: โปรเจกต์ wongnok-blog-all-in-one ที่เปิดไว้ในบท 120 (branch my-day3 ที่แตกจาก day3-start + seeds 30 บทความที่ commit แล้ว) · ตามไม่ทันให้ทำบท 120 ก่อน · บทนี้อ่านไฟล์เป็นหลัก · ที่ลองแก้ในบท จะบอกวิธีคืนค่าทุกครั้ง

ปัญหา: AI คือพนักงานใหม่ที่จำบทสนทนาเมื่อวานไม่ได้

ใน Lab 2 (บท 119) เราเขียน prompt ยาว 12 ข้อ เพื่อให้ AI สร้างหมวดอาหารได้ถูกกฎของร้านในรอบเดียว · ปัญหาคือพรุ่งนี้เปิดแชทใหม่ AI ไม่เห็นข้อความแชทของเมื่อวาน ต้องแปะใหม่ทั้งก้อน

ทางแก้ของคอร์สนี้คือเขียน prompt ลงไฟล์ แล้วเก็บไว้ในโฟลเดอร์ prompts/ ใน repo · อยากใช้เมื่อไหร่ก็เรียกไฟล์นั้น · เจอ AI ทำพลาดก็แก้ไฟล์ให้ดีขึ้น · และไฟล์เข้า git ไปพร้อมโค้ด เพื่อนในทีมได้ใช้ด้วย

เทียบกับ React: ข้อความในแชทเหมือน useState (บท 73) ที่หายเมื่อรีเฟรชหน้า · ไฟล์ใน prompts/ เหมือนของที่เขียนลงดิสก์ — ปิดเปิดใหม่กี่รอบก็ยังอยู่

📒 เทียบให้เห็นภาพ — แฟ้มคู่มือพนักงานใหม่ที่แนบไปทุกกะ

นึกถึงร้านอาหารที่ได้พนักงานพาร์ตไทม์คนใหม่ทุกกะ · เก่ง ทำงานไว แต่ไม่รู้ว่ากะก่อนคุยอะไรกันไว้ · ถ้าหัวหน้าต้องยืนอธิบายกฎร้านปากเปล่าทุกกะ วันไหนลืมพูดข้อไหน ข้อนั้นก็พลาด
ร้านที่ฉลาดจะทำแฟ้มคู่มือวางไว้ให้อ่านก่อนเริ่มงาน: หน้าแรกเป็นกฎถาวรของร้าน (00-context.md) · หน้าถัด ๆ ไปเป็นคู่มือของแต่ละงาน (01-views.md · 02-styling.md …) · เจอใครทำพลาดก็เติมหน้าคู่มือ

ที่ไม่เหมือนกัน: พนักงานจริงที่อ่านคู่มือแล้วไม่เข้าใจจะถามกลับ · AI ส่วนใหญ่ไม่ถาม มันเดาแล้วทำต่อด้วยความมั่นใจ · และพนักงานจริงที่ฝ่าฝืนกฎร้านโดนเตือนได้ แต่ AI ที่อ่านคู่มือแล้วก็ยังทำผิดได้ — เรื่องนี้สำคัญมาก เดี๋ยวมีหัวข้อของมันเอง

สไลด์หน้า 4 บอกว่าโฟลเดอร์นี้จะโตไปทีละไฟล์ตลอดคอร์ส · ตอนนี้ (หลังบท 120) ใน repo มีแค่ไฟล์แรก:

ไฟล์เรื่องเกิดตอนไหน
00-context.mdstack + กฎถาวรของโปรเจกต์มีแล้ว — อ่านกันในบทนี้
01-views.mdบล็อก A · Viewบท 126 (Lab Vibe 1)
02-styling.mdบล็อก B · CSSบท 129 (Lab Vibe 2)
03-hotwire.mdบล็อก C · Hotwireบท 135 (Lab Vibe 3)
04-content.md · 05-jobs.md · 06-caching.mdrich text · งานเบื้องหลัง · cacheDay 3 Part 2 (ยังไม่มาในชุดนี้)
07-auth.md · 08-testing.mdlogin · การเขียนเทสDay 4
FINAL.mdเอาทุกไฟล์มาต่อกันท้ายคอร์ส

สไลด์เล่าว่าท้ายคอร์สจะเอาทุกไฟล์มาต่อเป็น FINAL.md แล้วสั่ง AI สร้างแอปใหม่ทั้งแอป · ไฟล์นั้นจึงเป็นความรู้ทั้งคอร์สที่เขียนออกมาเป็นตัวหนังสือ — ไฟล์จะดีได้เท่าที่เราเข้าใจเรื่องที่เรียนเท่านั้น

🗣 ศัพท์ที่เพิ่งเรียนไป
session · context
session = บทสนทนาหนึ่งรอบกับ Claude Code (ปิดแล้วเปิดใหม่ = session ใหม่) · context = ทุกอย่างที่ AI "เห็น" ใน session นั้น (ข้อความแชท · ไฟล์ที่อ่าน · กฎที่โหลดมา) · ถาม senior ได้ว่า "กฎนี้ควรอยู่ในไฟล์ที่โหลดทุก session หรือพิมพ์บอกเฉพาะงานนี้"
prompt file
prompt ที่เขียนเก็บเป็นไฟล์ .md ใน repo แทนการพิมพ์ใหม่ทุกครั้ง · แก้ได้ · เข้า git ได้ · ทั้งทีมใช้ร่วมกันได้ · ถามทีมได้ว่า "เรามีโฟลเดอร์ prompt ที่ใช้ร่วมกันไหม หรือทุกคนพิมพ์เอง"

ทุกไฟล์รายบล็อกมี 4 ส่วนเหมือนกัน

ไฟล์ 01–08 ใช้แม่แบบเดียวกันหมด (สไลด์หน้า 4) · เป็น Markdown ธรรมดา มี 4 หัวข้อ · ข้างล่างคือแม่แบบ ยังไม่ใช่ไฟล์จริงใน repo (ไฟล์จริงไฟล์แรกเกิดในบท 126):

## เป้าหมาย
ฟีเจอร์ที่อยากได้ เขียนเป็นภาษาคน

## ข้อกำหนด
- มาจากคำศัพท์ที่เพิ่งเรียนในบล็อกนี้
- ...

## ห้าม
- มาจากกับดักที่เพิ่งเจอในบล็อกนี้

## เกณฑ์ตรวจรับ
- [ ] คือ checklist ของบล็อกนี้
- [ ] ...

ทั้ง 4 ส่วนไม่ใช่ของใหม่ · เป้าหมายกับข้อกำหนดคือ "บอกให้ชัด" ของบท 88 · ห้ามคือ "บอกสิ่งที่ห้ามแตะ" ของบท 89 · เกณฑ์ตรวจรับคือขั้น Evaluate ของบท 87 · ต่างกันแค่ว่าครั้งนี้จัดลงช่องเดิมทุกครั้ง

สไลด์พูดไว้ดีมาก: สามส่วนล่าง (ข้อกำหนด · ห้าม · เกณฑ์ตรวจรับ) ไม่ใช่งานเพิ่ม — มันคือเนื้อหาที่เพิ่งเรียนในบล็อกนั้น แค่เขียนลงไฟล์ · ถ้าเขียนส่วนไหนไม่ออก แปลว่าเรื่องในบล็อกนั้นยังไม่เข้าใจ ให้ย้อนกลับไปอ่าน ไม่ใช่ไปถาม AI ให้เขียนแทน

🧾 เทียบให้เห็นภาพ — ใบสั่งงานครัวที่พิมพ์ช่องไว้ตายตัว

ใบสั่งงานที่พิมพ์ช่องไว้แล้ว "เมนู · วิธีทำ · ห้ามใส่ (ลูกค้าแพ้) · ชิมผ่านเมื่อ…" · คนเขียนเห็นทันทีว่าลืมกรอกช่องไหน · และช่อง "ชิมผ่านเมื่อ…" คือสิ่งที่หัวหน้าใช้ตรวจจานก่อนเสิร์ฟ

ที่ไม่เหมือนกัน: ใบสั่งงานจริงเขียนครั้งเดียวทิ้ง · ไฟล์ prompt ของเราถูกแก้ซ้ำเรื่อย ๆ ทุกครั้งที่ AI พลาดแบบใหม่ · และคนที่ต้องติ๊กเกณฑ์ตรวจรับทีละข้อคือเรา ไม่ใช่ AI

🗣 ศัพท์ของ 4 ส่วน
goal · requirements · constraints
ชื่อภาษาอังกฤษของ เป้าหมาย · ข้อกำหนด · ห้าม · constraint = "ข้อจำกัด/สิ่งที่ห้ามทำ" · พิมพ์บอก AI ได้ว่า "Goal: … Requirements: … Constraints: do NOT add a migration"
acceptance criteria
"งานนี้ถือว่าเสร็จเมื่อ…" เขียนเป็นข้อที่ตรวจได้จริง (เคยเจอในบท 119) · ถาม senior ได้ว่า "acceptance criteria ของ ticket นี้คืออะไร ผมจะได้รู้ว่าเสร็จเมื่อไหร่"

เปิด prompts/00-context.md ของจริง

ไฟล์ 00 ต่างจากไฟล์อื่น: มันไม่ใช่งานของบล็อกไหน แต่เป็น "หน้าแรกของคู่มือ" ที่ใช้ทุกงาน จึงไม่มี 4 ส่วนข้างบน · เปิดในโฟลเดอร์โปรเจกต์ด้วย cat prompts/00-context.md (หรือเปิดใน VS Code) · ผมแบ่งดูเป็นสองครึ่ง

ครึ่งบน — บอก AI ว่าร้านเราใช้อุปกรณ์อะไร

# บริบทของโปรเจค wongnok_blog

## Stack

- Ruby 4.0.5 / Rails 8.1.3 / PostgreSQL 18
- Propshaft + importmap  (ห้ามใช้ Sprockets, ห้ามแนะนำ npm หรือ node_modules)
- tailwindcss-rails (Tailwind v4) + daisyUI 5 ผ่าน @plugin ในไฟล์ CSS
  ห้ามสร้าง tailwind.config.js — Tailwind v4 ไม่อ่านไฟล์นั้น
- Solid Queue / Solid Cache / Solid Cable
- Active Storage -> MinIO (S3-compatible)
- Minitest (ไม่ใช่ RSpec)

## รูปแบบโค้ด

- ข้อความที่ผู้ใช้เห็นเป็นภาษาไทย ผ่าน i18n
- ใช้ params.expect ไม่ใช่ params.require(...).permit(...)
- ตั้งชื่อตาม convention ของ Rails เสมอ
- ห้ามมี `<script>` ใน view

ครึ่งล่าง — checklist 8 ข้อของ Day 2 ย้ายมาอยู่ตรงนี้

## กฎที่ห้ามลืม  (จากวันก่อน)

1. validates uniqueness ต้องมี unique index ที่ DB คู่เสมอ
2. validates presence ต้องมี NOT NULL ที่ DB คู่เสมอ
3. คอลัมน์ที่ใช้ค้นหาหรือเป็น foreign key ต้องมี index
4. ระบุ dependent: ของทุก association เสมอ และเลือกจากกฎธุรกิจ
5. ตรงที่วน each ต้องมี includes
6. index action ต้องมี limit หรือ pagination
7. migration ต้องไม่ล็อกตารางที่มีข้อมูลเยอะ — ใช้ expand-contract
8. strong parameters ไม่ใช่ authorization — แยกให้ออก

## รูปแบบการตอบ

- บอกชื่อไฟล์ทุกไฟล์ที่แก้หรือสร้าง
- ถ้าต้องมี migration ให้เขียนมาด้วย
- อย่าเพิ่ง refactor อย่างอื่นที่ไม่ได้ขอ

8 ข้อนี้คือchecklist ตรวจงาน AI ของบท 118 ทั้งชุด แค่เปลี่ยนจาก "คำถามที่เราถามตอนตรวจ" มาเป็น "กฎที่บอก AI ก่อนเริ่มงาน" · ถ้าข้อไหนอ่านแล้วไม่แน่ใจ ย้อนไปบทนั้น:

ข้อแปลเป็นภาษาคนเรียนในบท
1–2กฎใน model (validation) ต้องมีกฎที่ตัวตู้ (constraint ของ DB) คู่กันเสมอ เพราะกันคนละรู 110 · 111
3ช่องที่ใช้ค้นหา และช่อง …_id ต้องมีป้ายแท็บ (index) ไม่งั้นไล่หาทีละแผ่น 109
4ลบแม่แล้วลูกไปไหน ต้องเลือกเองจากกฎของธุรกิจ 116
5วนลูปแล้วแตะของที่ผูกกัน ต้องหยิบทีเดียวทั้งตะกร้า (N+1) 114
6หน้ารายการห้ามดึงทุกแถว ต้องจำกัดจำนวนหรือแบ่งหน้า 113
7migration ห้ามปิดลิ้นชักนานจนแอปค้าง 109
8strong params คัดช่องที่รับ · ไม่ได้ตรวจว่าใครมีสิทธิ์ (เรื่องคนคือ Day 4) 117

## รูปแบบการตอบ = บอกว่าอยากได้คำตอบหน้าตาแบบไหน — คือหลักข้อ 5 "บอกรูปแบบผลลัพธ์" ของบท 89 · ข้อสุดท้าย "อย่าเพิ่ง refactor (ปรับโค้ดส่วนอื่นให้สวยขึ้น) อย่างอื่นที่ไม่ได้ขอ" กัน AI แก้ไฟล์เกินงานจนเราตรวจไม่ไหว

ไฟล์นี้ยาว 35 บรรทัด (ผมนับด้วย wc -l prompts/00-context.md) · ตลอด Day 3 จะมีกฎเพิ่มอีก 4 ข้อในบท 135 · สไลด์หน้า 6 พูดถึง "กฎทั้ง 12 ข้อ" ไว้ล่วงหน้า — ตอนนี้ในไฟล์ยังมี 8

CLAUDE.md — ป้ายหน้าห้องพนักงานที่ Claude Code อ่านเองทุกครั้ง

แฟ้มคู่มือจะมีประโยชน์ก็ต่อเมื่อพนักงานได้อ่าน · ถ้าเราต้องพิมพ์ว่า "อ่าน 00-context.md ก่อนนะ" ทุกครั้ง วันไหนลืมก็เหมือนไม่มีไฟล์
Claude Code แก้ปัญหานี้ด้วยไฟล์ชื่อ CLAUDE.md · เอกสารบอกว่ามันอ่านไฟล์นี้เองตอนเริ่มทุก session โดยเราไม่ต้องสั่ง

เปิดดูของจริงที่ root ของโปรเจกต์ (ระดับเดียวกับ Gemfile):

$ cat CLAUDE.md
# wongnok_blog

@prompts/00-context.md

## คำสั่งที่ใช้บ่อย

- bin/dev                 รัน web + tailwind watch
- bin/rails test          รัน test ทั้งหมด
- bin/rails db:prepare    เตรียมฐานข้อมูล
- bin/rails routes        ดู route ทั้งหมด
- docker compose up -d    postgres + minio

เทียบกับ TypeScript: @ คล้าย import (บท 71) ที่ดึงของจากไฟล์อื่นมาใช้ · ต่างกันตรงที่ @ เอาเนื้อทั้งไฟล์มาวางให้ AI อ่านเลย ไม่ได้เลือกหยิบเฉพาะชิ้น

🪧 เทียบให้เห็นภาพ — ป้ายหน้าห้องพนักงาน + แฟ้มที่แขวนข้างป้าย

CLAUDE.md คือป้ายหน้าห้องพนักงานที่ทุกคนต้องอ่านก่อนเข้างาน · บนป้ายเขียนสั้น ๆ ว่า "อ่านแฟ้มกฎถาวรที่แขวนข้างป้ายด้วย" (บรรทัด @) · พนักงานใหม่ทุกกะเลยได้อ่านกฎครบโดยหัวหน้าไม่ต้องพูดสักคำ

ที่ไม่เหมือนกัน: พนักงานคนจริงอ่านป้ายแล้วอาจข้ามแฟ้ม · Claude Codeโหลดทั้งป้ายและแฟ้มเข้ามาให้เองทุกครั้ง (ไม่ได้ขึ้นกับความขยัน) · แต่ "ได้อ่าน" ไม่ได้แปลว่า "ทำตามทุกข้อ" — ยังเป็นเรื่องเดียวกับที่ค้างไว้

🗣 ศัพท์ของ CLAUDE.md
CLAUDE.md · project instructions
ไฟล์คำสั่งประจำโปรเจกต์ที่ Claude Code โหลดเองตอนเริ่ม session · เอกสารเรียกว่า project instructions หรือ memory files · ถาม senior ได้ว่า "repo นี้มี CLAUDE.md ไหม มีกฎอะไรที่ทีมตกลงกันไว้"
import (@path)
@ที่อยู่ไฟล์ ใน CLAUDE.md = ดึงไฟล์นั้นมาโหลดด้วย · ถ้าแค่อยากเขียนชื่อที่ขึ้นต้นด้วย @ เฉย ๆ ไม่ให้ import เอกสารบอกให้ครอบด้วย backtick (`…`) · พิมพ์บอก AI ได้ว่า "our CLAUDE.md imports @prompts/00-context.md — follow those rules"

CLAUDE.md กับ AGENTS.md — ไฟล์เดียวกัน สองชื่อ

ใน repo ของคอร์ส CLAUDE.md ไม่ใช่ไฟล์ธรรมดา · ลองสั่ง ls -l (ดูรายละเอียดไฟล์) กับสองไฟล์นี้:

$ ls -l CLAUDE.md AGENTS.md
-rw-r--r--@ 1 tuwanon  wheel  389 Nov  7 09:14 AGENTS.md
lrwxr-xr-x@ 1 tuwanon  wheel    9 Nov  7 11:18 CLAUDE.md -> AGENTS.md

ไฟล์ link แบบนี้เรียกว่า symlink (symbolic link) · ทำไมไม่ตั้งชื่อ CLAUDE.md ไปเลย? เพราะ AGENTS.md เป็นชื่อที่ไม่ผูกกับยี่ห้อ · เอกสารของ Claude Code อธิบาย AGENTS.md ว่าเป็นไฟล์คำสั่งที่เขียนให้ AI coding agent ทั่วไป · ท่า symlink นี้เป็นหนึ่งในสองท่าที่เอกสารให้ไว้สำหรับ repo ที่อยากให้เครื่องมือหลายตัวใช้ไฟล์เดียวกัน (อีกท่าคือ CLAUDE.md ที่มีบรรทัด @AGENTS.md แบบที่เจอในบท 86)

🚪 เทียบให้เห็นภาพ — ป้ายสองภาษาบนประตูห้องเดียว

ห้องพนักงานห้องเดียว แต่ประตูติดป้ายสองแผ่น: "ห้องพนักงาน" กับ "Staff Room" · พนักงานคนไทยมองหาป้ายแรก คนต่างชาติมองหาป้ายที่สอง · ใครเดินเข้าป้ายไหนก็เจอห้องเดียวกัน ของข้างในชุดเดียวกัน · AGENTS.md คือตัวห้อง · CLAUDE.md คือป้ายแผ่นที่สอง

ที่ไม่เหมือนกัน: เขียนอะไรลงบนป้ายจริง ตัวหนังสือก็อยู่บนป้าย · แต่เขียนลง symlink ของจะไปลงในไฟล์ปลายทาง (ลองในกล่องทายผลข้างล่าง) · และถ้าลบตัวห้อง (AGENTS.md) ป้ายจะชี้ไปที่ว่าง เปิดไม่ได้ · (บน Windows บางเครื่อง ป้ายกลายเป็นกระดาษที่เขียนชื่อห้องไว้เฉย ๆ — ดูตารางอาการในภารกิจ)

เพิ่มบรรทัดใหม่ต่อท้าย CLAUDE.md ด้วยคำสั่งนี้ (echo '…' >> ไฟล์ = เขียนข้อความต่อท้ายไฟล์) แล้วถาม git ว่ามีไฟล์ไหนเปลี่ยน (git status --short = git status แบบย่อ บรรทัดละไฟล์):

$ echo '- bin/rails console    เปิดครัวทดลอง' >> CLAUDE.md
$ git status --short

git จะบอกว่าไฟล์ไหนถูกแก้ — CLAUDE.md · AGENTS.md · หรือทั้งสองไฟล์?

$ git status --short
 M AGENTS.md

git บอกว่าไฟล์ที่ถูกแก้คือ AGENTS.md (M = modified) · CLAUDE.md ไม่โผล่เลย · เพราะเราเขียนผ่านป้าย แต่ของไปลงในห้อง · ตัวป้ายเองยังชี้ไปที่เดิม ไม่ได้เปลี่ยนอะไร
เอกสารของ Claude Code บอกด้วยว่า ถ้าสั่ง Claude แก้ CLAUDE.md ที่เป็น symlink มันจะไม่เขียนผ่านป้าย แต่จะถูกบอกให้ไปแก้ AGENTS.md ตรง ๆ แทน — ปลายทางคือไฟล์เดียวกับที่เราเพิ่งเห็น

คืนค่าก่อนไปต่อ: git restore AGENTS.md แล้ว git status --short อีกรอบ ต้องไม่มี AGENTS.md โผล่

คืนค่าด้วย git restore AGENTS.md ระบุชื่อไฟล์เสมอ · ถ้าคุณข้ามขั้น commit db/seeds.rb ในบท 120 แล้วใช้ git restore . (คืนทุกไฟล์) seeds จะกลับเป็นไฟล์เดิมที่มีแค่ comment (ข้อมูลตัวอย่าง 30 บทความหายไปจากไฟล์)

🗣 ศัพท์เรื่องไฟล์สองชื่อ
symlink (symbolic link)
ไฟล์ที่เก็บแค่ "ที่อยู่ของไฟล์อื่น" · เปิดแล้วระบบพาไปไฟล์ปลายทางให้เอง · สร้างด้วย ln -s ปลายทาง ชื่อป้าย · ถาม senior ได้ว่า "CLAUDE.md ใน repo นี้เป็น symlink ไป AGENTS.md ใช่ไหม ถ้าจะแก้กฎต้องแก้ไฟล์ไหน"
AGENTS.md
ไฟล์คำสั่งสำหรับ AI coding agent ที่ไม่ผูกกับเครื่องมือตัวใดตัวหนึ่ง · Claude Code อ่านได้ (เอกสารมีหัวข้อแยกให้) · พิมพ์บอก AI ได้ว่า "project rules live in AGENTS.md; CLAUDE.md is a symlink to it"

กฎ 3 ชั้น — ของทีมเข้า git ของส่วนตัวไม่เข้า

CLAUDE.md ไม่ได้มีแค่ไฟล์เดียว · ที่เราใช้บ่อยมีสามที่ และ Claude Codeอ่านทุกไฟล์ที่เจอแล้วเอามาต่อกัน ไม่มีไฟล์ไหนทับไฟล์ไหน (สไลด์หน้า 6 + เอกสาร):

ไฟล์ใส่อะไรใครเห็นเข้า git ไหม
~/.claude/CLAUDE.mdนิสัยของเราเองที่ใช้กับทุกโปรเจกต์ เช่น "อธิบายเป็นภาษาไทย"เราคนเดียว ไม่ — อยู่ในโฟลเดอร์บ้านของเรา (~) ไม่ได้อยู่ใน repo ไหน
./CLAUDE.mdกฎของโปรเจกต์นี้ที่ทั้งทีมต้องทำตามทุกคนในทีมเข้า — commit ไปพร้อมโค้ด
./CLAUDE.local.mdของส่วนตัวที่ใช้กับโปรเจกต์นี้เท่านั้น เช่น URL ของ DB ทดลองในเครื่องเราเราคนเดียว ไม่ — ต้องใส่ชื่อไว้ใน .gitignore
🎒 เทียบให้เห็นภาพ — สมุดในกระเป๋า · ป้ายหน้าห้อง · โน้ตในล็อกเกอร์

พนักงานพาร์ตไทม์คนหนึ่งไปทำหลายร้าน · สมุดในกระเป๋า (~/.claude/CLAUDE.md) พกไปทุกร้าน จดนิสัยการทำงานของตัวเอง · ป้ายหน้าห้องพนักงาน (./CLAUDE.md) เป็นของร้าน ทุกคนเห็นเหมือนกัน · โพสต์อิทในล็อกเกอร์ของตัวเองที่ร้านนี้ (CLAUDE.local.md) ใช้เฉพาะร้านนี้ คนอื่นไม่เห็น

ที่ไม่เหมือนกัน: คนจริงรู้ว่าป้ายร้าน "ใหญ่กว่า" โน้ตส่วนตัว ถ้าขัดกันก็เชื่อป้าย · Claude Code ไม่มีลำดับใหญ่-เล็กแบบนั้น — อ่านต่อกันหมดแล้วต้องเลือกเอง · และล็อกเกอร์จริงล็อกได้เลย แต่ CLAUDE.local.md "ไม่เข้า git" ได้ก็เพราะ .gitignore เท่านั้น ลืมใส่ = หลุดขึ้น GitHub

เอาไปใช้ที่โปรเจกต์อื่นที่มีแค่ AGENTS.md (ไม่มี CLAUDE.md): เอกสารเตือนว่าสร้าง CLAUDE.local.md เพิ่มแล้ว Claude Code จะเลิกอ่าน AGENTS.md · repo ของคอร์สมี symlink CLAUDE.md อยู่แล้ว จึงไม่เจอปัญหานี้

🗣 ศัพท์เรื่องชั้นของกฎ
user · project · local scope
ขอบเขตของไฟล์คำสั่ง: ทุกโปรเจกต์ของเรา · โปรเจกต์นี้ทั้งทีม · โปรเจกต์นี้แค่เรา · ถาม senior ได้ว่า "กฎข้อนี้ควรอยู่ project scope ให้ทั้งทีมใช้ หรือ local scope แค่ผม"
.gitignore
รายชื่อไฟล์ที่ git ไม่สนใจ (ไม่โผล่ใน git status · ไม่ถูก commit) · ตรวจว่าไฟล์ไหนโดนกันด้วย git check-ignore -v ชื่อไฟล์ · พิมพ์บอก AI ได้ว่า "make sure CLAUDE.local.md is in .gitignore before I add secrets to it"

คำแนะนำ ไม่ใช่การบังคับ

นี่คือประโยคที่สไลด์หน้า 6 บอกว่า "ต้องพูดให้ตรง": CLAUDE.md คือคำแนะนำ · Claude พยายามทำตาม แต่ไม่รับประกัน · เอกสารของ Claude Code พูดแบบเดียวกัน — ไฟล์พวกนี้คือข้อมูลประกอบ ไม่ใช่การตั้งค่าที่บังคับได้

ดูหลักฐานใน repo เดียวกันเลย · กฎข้อ 6 ใน 00-context.md บอกว่า "index action ต้องมี limit หรือ pagination" แต่โค้ดตอนนี้คือ:

# app/controllers/posts_controller.rb (branch day3-start)
  # GET /posts or /posts.json
  def index
    @posts = Post.all
  end

Post.all ไม่มี limit · กฎในไฟล์ไม่ได้แก้โค้ดให้เอง และไม่ได้ห้ามใครเขียนโค้ดผิดกฎ (โค้ดนี้มาจาก scaffold — เราจะแก้ด้วยการแบ่งหน้าในบท 126) · AI ก็เหมือนกัน: อ่านกฎแล้ว ส่วนใหญ่ทำตาม แต่บางครั้งยังพลาด

แล้วกฎที่พลาดไม่ได้จริง ๆ ไปอยู่ไหน? สไลด์ตอบว่า test หรือ CI · repo นี้มีของพวกนี้อยู่แล้วบางส่วน:

เทียบกับ TypeScript: comment ที่เขียนว่า // ห้ามส่ง null มาตรงนี้ คือคำแนะนำ — คนอ่านอาจข้าม · ส่วน type ที่ไม่รับ null แล้ว tsc ฟ้อง error (บท 63–68) คือการบังคับ · CLAUDE.md อยู่ฝั่ง comment · test/CI อยู่ฝั่ง type

🚰 เทียบให้เห็นภาพ — ป้าย "กรุณาล้างมือ" กับประตูครัวที่ต้องสแกนมือก่อนเปิด

ป้าย "กรุณาล้างมือก่อนเข้าครัว" ช่วยได้เยอะ คนส่วนใหญ่ทำตาม · แต่วันที่ยุ่ง ๆ ก็มีคนลืม · ถ้าเรื่องนี้พลาดไม่ได้จริง ร้านจะติดประตูที่เปิดเมื่อสแกนมือที่ล้างแล้วเท่านั้น — ใครจะลืมก็เข้าไม่ได้
CLAUDE.md = ป้าย · test/CI/gem ที่ดัก = ประตูที่ล็อก

ที่ไม่เหมือนกัน: ประตูจริงกันได้ทันทีที่หน้าครัว · test/CI ส่วนใหญ่จับได้หลังโค้ดถูกเขียนแล้ว (ตอนรัน test · ตอน push) ไม่ได้หยุด AI ตอนพิมพ์ · และประตูจริงตรวจได้แค่เรื่องเดียว (ล้างมือ) — test ตรวจได้เฉพาะเรื่องที่เราเขียน test ไว้ เรื่องที่ไม่มี test ก็กลับไปพึ่งป้ายเหมือนเดิม

🗣 ศัพท์เรื่องคำแนะนำกับการบังคับ
guidance vs enforcement
guidance = คำแนะนำที่หวังให้ทำตาม (CLAUDE.md · comment) · enforcement = กลไกที่ไม่ผ่านก็ไปต่อไม่ได้ (test · CI · type checker · gem ที่ดัก) · ถาม senior ได้ว่า "กฎนี้สำคัญพอจะต้องมี test/CI จับไหม หรือแค่เขียนไว้ใน CLAUDE.md พอ"
CI (continuous integration)
ระบบที่รันตรวจโค้ดอัตโนมัติทุกครั้งที่ push หรือเปิด pull request · repo นี้ใช้ GitHub Actions (บริการ CI ของ GitHub · ตั้งค่าใน .github/workflows/ci.yml) · พิมพ์บอก AI ได้ว่า "this rule must not regress — write a test for it so CI fails if someone breaks it"

4 อย่างที่จะใช้ทั้งวันใน Claude Code

สไลด์หน้า 7 สรุปไว้ 4 อย่าง · ทุกอย่างพิมพ์ในช่องแชทของ Claude Code ที่เปิดจากโฟลเดอร์โปรเจกต์ (ผมตรวจคำสั่งกับเอกสารทางการแล้ว แต่ไม่ได้แคปหน้าจอมา — หน้าตาของคุณให้ยึดตามที่เห็นจริง)

1 · @ไฟล์ ในช่องพิมพ์ — ยื่นคู่มือหน้านั้นให้ตอนสั่งงาน

> @prompts/03-hotwire.md ทำตามไฟล์นี้

2 · /context — เช็กว่ากฎโหลดมาจริงไหม

context (ของทั้งหมดที่ AI เห็นใน session) มีที่จำกัด เหมือนโต๊ะทำงานที่วางแฟ้มได้จำนวนหนึ่ง · /context แสดงว่าตอนนี้อะไรวางอยู่บนโต๊ะบ้าง · ให้หาหัวข้อ Memory files · สไลด์บอกว่าควรเห็น CLAUDE.md และ prompts/00-context.md ที่ถูก import เข้ามา (ผมไม่ได้เปิดหน้าจอนี้เอง ชื่อที่โชว์ของคุณอาจไม่ตรงเป๊ะ) · ถ้ารายการถูกพับไว้ เอกสารบอกให้พิมพ์ /context all
ไม่เห็น = เปิด claude ผิดโฟลเดอร์ หรือที่อยู่ไฟล์หลัง @ สะกดผิด · สไลด์บอกว่าเช็ก 5 วินาทีแต่กันงงได้ครึ่งชั่วโมง

3 · เติมกฎใหม่หลังเจอ AI พลาด — พิธีกรรมท้ายทุกบล็อก

> เพิ่มกฎนี้ลง prompts/00-context.md:
  ...กฎที่เพิ่งเจอ...

4 · ของที่ควรรู้ไว้

เรื่องภาษาคน
เก็บไฟล์ให้สั้น (≤ ~200 บรรทัด) ทุกบรรทัดกินพื้นที่ความจำของ AI ทุก session · เอกสารบอกว่าไฟล์ยาว = ทำตามได้แย่ลง และไฟล์ที่ import ก็นับรวมด้วย · ตอนนี้ CLAUDE.md 11 บรรทัด + 00-context 35 บรรทัด ยังสบาย
/compact สรุปบทสนทนายาว ๆ ให้สั้นลงเพื่อคืนพื้นที่ · หลังสรุป CLAUDE.md ที่ root ถูกอ่านใหม่จากดิสก์ แต่คำสั่งที่พิมพ์ในแชทอาจหายไป — กฎที่อยากให้อยู่ถาวรต้องอยู่ในไฟล์
อย่า import ไฟล์รายบล็อกเข้า CLAUDE.md ถ้าใส่ @prompts/01-views.md ไว้ใน CLAUDE.md มันจะโหลดทุก session แม้กำลังทำเรื่องอื่น · เปลืองพื้นที่ และกฎของงานหนึ่งไปปนอีกงาน · ไฟล์รายบล็อกให้เรียกด้วย @ ในช่องพิมพ์ตอนจะใช้
claude --version พิมพ์ใน terminal (ไม่ใช่ในแชท) · เครื่องผมได้ 2.1.318 (Claude Code) ของคุณเป็นเลขอื่นได้ · เอกสารบางหัวข้อเขียนว่า "ต้องเวอร์ชันนี้ขึ้นไป"

ถ้าจะใช้กับโปรเจกต์ที่ทำงาน: เปิด claude ในโฟลเดอร์โปรเจกต์ แล้วพิมพ์ /init · เอกสารบอกว่ามันจะสแกน repo แล้วร่าง CLAUDE.md ให้ (ถ้ามีอยู่แล้วจะเสนอแก้แทนการเขียนทับ) · ร่างที่ได้คือจุดเริ่ม — กฎที่ AI เดาจากโค้ดไม่ได้ (เช่นกฎธุรกิจ) เรายังต้องเติมเอง

🗣 ศัพท์ของคำสั่งที่ใช้ทั้งวัน
@-mention (file reference)
@ไฟล์ ในช่องพิมพ์ = ใส่เนื้อไฟล์เข้าบทสนทนานี้ · ต่างจาก import ใน CLAUDE.md ที่โหลดทุก session · พิมพ์บอก AI ได้ว่า "follow @prompts/01-views.md and report against its acceptance criteria"
compaction · /compact
การย่อบทสนทนาให้สั้นลงเมื่อพื้นที่ใกล้เต็ม · ของในไฟล์โหลดกลับมา ของในแชทอาจหาย · ถาม senior ได้ว่า "หลัง compact แล้ว AI ลืมกฎ ควรย้ายกฎนั้นไปไว้ใน CLAUDE.md ไหม"

ภารกิจ

🎯 ภารกิจ (~10 นาที) — ฝึก 4 ส่วน + กฎส่วนตัวไฟล์แรก

ทำในโฟลเดอร์โปรเจกต์ wongnok-blog-all-in-one (ต่อจากบท 120):

  1. ดูของจริงสองอย่าง — พิมพ์ทีละบรรทัด:
    ls -l CLAUDE.md AGENTS.md
    wc -l prompts/00-context.md
    ควรเห็นบรรทัดของ CLAUDE.md ขึ้นต้นด้วย l และมี -> AGENTS.md · และเลข 35 หน้าชื่อไฟล์ 00-context.md
  2. ร่าง 4 ส่วน (เขียนในโน้ต ยังไม่ต้องสร้างไฟล์) — ตอนนี้หน้า /posts โชว์หมวดเป็นตัวเลข เพราะ app/views/posts/_post.html.erb เขียน <%= post.category_id %> · ร่างคำสั่งงานให้ AI แก้เป็นชื่อหมวด โดยมีครบ 4 หัวข้อ: เป้าหมาย · ข้อกำหนด · ห้าม · เกณฑ์ตรวจรับ (อย่างน้อยหัวข้อละ 1 ข้อ) · ใบ้: กฎข้อ 5 ของ 00-context เกี่ยวตรง ๆ
  3. สร้างกฎส่วนตัวไฟล์แรก — ใน VS Code สร้างไฟล์ใหม่ชื่อ CLAUDE.local.md ที่ root (ระดับเดียวกับ Gemfile) แล้วใส่ของที่ใช้เฉพาะโปรเจกต์นี้ และเฉพาะคุณ 1 ข้อ เช่น:
    # กฎส่วนตัวของฉัน (ไม่เข้า git)
    
    - โปรเจกต์นี้ฉันใช้เรียน Rails Day 3 — ก่อนแก้ไฟล์ ให้บอกว่าจะแก้บรรทัดไหนและทำไม
    ส่วนนิสัยที่ใช้ทุกโปรเจกต์ (เช่น "ตอบเป็นภาษาไทย") ควรไปอยู่ ~/.claude/CLAUDE.md แทน · ไม่ต้องใส่เลขข้อ — เลข 9–12 จะเป็นของกฎทีมใน 00-context.md (บท 135)
  4. พิสูจน์ว่า git ไม่เห็นไฟล์นี้:
    git check-ignore -v CLAUDE.local.md
    git status --short
  5. (ไม่บังคับ ถ้ามี Claude Code) เปิด claude ในโฟลเดอร์นี้ พิมพ์ /context แล้วดูว่า Memory files มีครบสามไฟล์ไหม: CLAUDE.md · prompts/00-context.md · CLAUDE.local.md

ควรเห็น (ข้อ 4): บรรทัดแรกพิมพ์ออกมาว่า .gitignore:40:CLAUDE.local.md ตามด้วยชื่อไฟล์อีกรอบ = "ถูกกันไว้โดยบรรทัด 40 ของ .gitignore" · บรรทัดที่สอง ไม่มี CLAUDE.local.md โผล่

ถ้าเจออาการนี้ แปลว่า…

เห็นอะไรแปลว่า
git check-ignore -v เงียบ ไม่พิมพ์อะไรเลย · และ git status --short โชว์ ?? CLAUDE.local.md .gitignore ไม่ได้กันไฟล์นี้ (เช่นโปรเจกต์อื่นที่ไม่ใช่ของคอร์ส) · ?? = "ไฟล์ใหม่ที่ git ยังไม่เคยเก็บ" ถ้า git add . จะหลุดเข้า commit · แก้: เพิ่มบรรทัด CLAUDE.local.md ท้าย .gitignore แล้วรันข้อ 4 ซ้ำ · ผมลองลบบรรทัดนั้นทิ้งดูแล้ว ได้อาการนี้จริงทั้งสองอย่าง
ls -l ได้ CLAUDE.md ขึ้นต้นด้วย - และไม่มีลูกศร CLAUDE.md เป็นไฟล์ธรรมดา ไม่ใช่ symlink — มักเกิดบน Windows ที่ไม่ได้เปิดการรองรับ symlink · เปิดดูด้วย cat CLAUDE.md ถ้าเห็นแค่คำว่า AGENTS.md บรรทัดเดียว แปลว่าเป็นอาการนี้ (Claude Code จะไม่เห็นกฎเลย) · แก้ในเครื่องตัวเอง: เปลี่ยนบรรทัดนั้นเป็น @AGENTS.md ซึ่งเป็นท่าที่เอกสารแนะนำสำหรับ Windows
No such file or directory ไม่ได้อยู่ในโฟลเดอร์โปรเจกต์ → cd เข้าโฟลเดอร์ wongnok-blog-all-in-one ก่อน

ข้อ 1 และ 4 — ผลรันจริง (ชื่อเจ้าของและวันเวลาของคุณจะต่าง):

$ ls -l CLAUDE.md AGENTS.md
-rw-r--r--@ 1 tuwanon  wheel  389 Nov  7 09:14 AGENTS.md
lrwxr-xr-x@ 1 tuwanon  wheel    9 Nov  7 11:18 CLAUDE.md -> AGENTS.md
$ wc -l prompts/00-context.md
      35 prompts/00-context.md
$ git check-ignore -v CLAUDE.local.md
.gitignore:40:CLAUDE.local.md	CLAUDE.local.md
$ git status --short
$

บรรทัด git status --short ไม่พิมพ์อะไรเลย = ไม่มีไฟล์ไหนเปลี่ยน และ CLAUDE.local.md ถูกซ่อนไว้แล้ว (ถ้าคุณยังไม่ได้ commit db/seeds.rb จากบท 120 จะเห็นบรรทัด M db/seeds.rb — ปกติ)

ข้อ 2 — ตัวอย่างร่างหนึ่งแบบ (ผมเขียนเอง ไม่ได้ส่งให้ AI ทำ · ของคุณใช้คำอื่นได้ ขอแค่ครบ 4 ส่วนและตรวจได้จริง):

## เป้าหมาย
หน้ารายการบทความ (/posts) บอกชื่อหมวดของแต่ละบทความ เช่น "ของหวาน" แทนตัวเลข

## ข้อกำหนด
- แก้ app/views/posts/_post.html.erb ให้แสดง post.category.name
- PostsController#index ต้อง includes(:category)

## ห้าม
- แก้ไฟล์อื่นนอกจากสองไฟล์ข้างบน
- เปลี่ยนโครงตาราง (ไม่ต้องมี migration)

## เกณฑ์ตรวจรับ
- [ ] เปิด /posts แล้วเห็นชื่อหมวดเป็นภาษาไทย ไม่มีตัวเลข category_id
- [ ] log ของการโหลด /posts ครั้งเดียว ไม่มี SELECT ตาราง categories ซ้ำทีละบทความ
  • ข้อกำหนด includes(:category) มาจากกฎข้อ 5 · ถ้าไม่บอก AI อาจเขียน post.category.name เฉย ๆ แล้วได้ N+1 (บท 114)
  • เกณฑ์ตรวจรับข้อ 2 คือวิธีพิสูจน์ด้วยตาตัวเอง — ไม่ใช่เชื่อที่ AI บอกว่า "แก้แล้ว" · การนับ query จาก log ทำจริงในบท 125
  • งานนี้ (และมากกว่านี้) จะทำจริงใน Lab Vibe 1 บท 126 พร้อมไฟล์ prompts/01-views.md ฉบับเต็ม

เก็บกวาด: CLAUDE.local.md เก็บไว้ได้เลย (เป็นของส่วนตัว ไม่กระทบโค้ดบทต่อไป) · ถ้าไม่อยากเก็บ rm CLAUDE.local.md · ถ้าเผลอแก้ AGENTS.md หรือ 00-context.md ระหว่างทาง คืนค่าด้วย git restore AGENTS.md prompts/00-context.md

ทดสอบความเข้าใจ

1. อยากให้ Claude Code รู้ว่า DB ทดลองในเครื่องคุณอยู่พอร์ต 55432 (เพื่อนในทีมใช้พอร์ตอื่น) ควรเขียนไว้ที่ไหน?

ตัวเลือกที่ 3 ถูก · ค่านี้เป็นของโปรเจกต์นี้ และเป็นของเราคนเดียว — ตรงกับ CLAUDE.local.md พอดี · และ repo ของคอร์สกันไว้ใน .gitignore บรรทัด 40

ตัวเลือกที่ 1 และ 2 ผิด — สองไฟล์นี้เข้า git · พอร์ตของเราจะไปปนกับของเพื่อน AI ในเครื่องเพื่อนจะต่อผิดพอร์ต · ตัวเลือกที่ 4 ผิด — ไม่หลุดเข้า git จริง แต่ไฟล์นี้ใช้กับทุกโปรเจกต์ โปรเจกต์อื่นไม่ได้ใช้พอร์ตนี้

จุดที่ต้องจำ: ถามสองคำถาม — ใช้กับโปรเจกต์ไหน (ทุกอัน/อันนี้) · ใครต้องรู้ (ทั้งทีม/เราคนเดียว) · แล้วจะรู้เองว่าไฟล์ไหน

2. เครื่องหมาย @ ในสองที่นี้ต่างกันยังไง: บรรทัด @prompts/00-context.md ใน CLAUDE.md กับการพิมพ์ @prompts/01-views.md ทำตามไฟล์นี้ ในช่องแชท?

ตัวเลือกที่ 2 ถูก · @ ใน CLAUDE.md คือ import — เนื้อไฟล์ถูกโหลดตอนเริ่มทุก session · @ ในช่องแชทคือยื่นไฟล์ให้ดูเฉพาะงานนี้

ตัวเลือกที่ 1 ผิด — @ ในช่องแชทไม่ได้แก้ไฟล์ไหน จึงไม่มีอะไรติดไปถึง session หน้า เปิดแชทใหม่ก็ต้องพิมพ์ใหม่ · ตัวเลือกที่ 3 ผิด — เอกสารบอกว่าไฟล์ที่ import ถูกโหลดเข้ามาพร้อม CLAUDE.md เลย ไม่ได้รอ AI ตัดสินใจเปิด · ตัวเลือกที่ 4 ผิด — การพิมพ์ในแชทไม่ได้แก้ไฟล์ CLAUDE.md ให้ ถ้าอยากให้ถาวรต้องสั่งหรือแก้ไฟล์เอง

จุดที่ต้องจำ: ของที่ใช้ทุกงาน → import ใน CLAUDE.md · ของที่ใช้บางงาน → @ ในช่องแชทตอนจะใช้

3. 00-context.md มีกฎ "index action ต้องมี limit หรือ pagination" แต่ AI ยังเขียน @posts = Post.all มาให้ ข้อสรุปไหนถูกที่สุด?

ตัวเลือกที่ 1 ถูก · ทั้งสไลด์และเอกสารพูดตรงกันว่าไฟล์พวกนี้เป็นคำแนะนำ ไม่ใช่การบังคับ · หน้าที่ของเราคือติ๊กเกณฑ์ตรวจรับเอง และเรื่องที่พลาดไม่ได้ให้ test/CI จับ

ตัวเลือกที่ 2 ผิด — โหลดแล้วก็ยังพลาดได้ (เช็กว่าโหลดไหมด้วย /context ไม่ใช่เดาจากผลงาน) · ตัวเลือกที่ 3 ผิด — 46 บรรทัดยังห่างจาก ~200 มาก ลบกฎดี ๆ ทิ้งไม่ได้แก้ปัญหา · ตัวเลือกที่ 4 ผิด — เอกสารบอกว่าไฟล์ต่าง ๆ ถูกเอามาต่อกัน ไม่มีไฟล์ไหนชนะไฟล์ไหน และกฎทีมควรอยู่ที่ทีมเห็น

จุดที่ต้องจำ: CLAUDE.md = ป้าย · test/CI = ประตูที่ล็อก · AI ทำผิดกฎ = เรื่องปกติที่ต้องตรวจเจอ ไม่ใช่ระบบพัง

4. เพื่อนเสนอให้ใส่ @prompts/01-views.md · @prompts/02-styling.md · @prompts/03-hotwire.md ลงใน CLAUDE.md "AI จะได้รู้ทุกอย่างตลอด" ทำไมไม่ควรทำ?

ตัวเลือกที่ 4 ถูก · import = โหลดทุก session · ไฟล์รายบล็อกใช้เฉพาะตอนทำบล็อกนั้น จึงควรเรียกด้วย @ ในช่องแชทตอนจะใช้ · ไฟล์ที่ import ยังนับรวมในงบ ~200 บรรทัดด้วย

ตัวเลือกที่ 1 ผิด — import ได้หลายไฟล์ และไฟล์ถูกเอามาต่อกัน ไม่ทับกัน · ตัวเลือกที่ 2 ผิด — prompts/ เข้า git อยู่แล้วโดยตั้งใจ (ทีมใช้ร่วมกัน) · ตัวเลือกที่ 3 ผิด — ไฟล์ที่โหลดเป็นข้อมูลประกอบ AI ไม่ได้ลงมือทำเองจนกว่าเราจะสั่งงาน

จุดที่ต้องจำ: CLAUDE.md เก็บเฉพาะของที่จริงทุกงาน (stack · กฎถาวร · คำสั่งที่ใช้บ่อย) · ที่เหลือเรียกเมื่อใช้

ถามกลับได้เลย

ถ้าไม่แน่ใจว่ากฎข้อหนึ่งควรอยู่ไฟล์ไหน ให้ก็อปกฎข้อนั้นมาถาม พร้อมบอกว่า "ใช้กับโปรเจกต์ไหน · ใครต้องรู้" · หรือถ้า /context ไม่เห็นไฟล์ที่ควรเห็น ให้ก็อปผล ls -l CLAUDE.md AGENTS.md กับ pwd (โฟลเดอร์ที่เปิดอยู่) มาด้วย — สองอย่างนี้ตอบได้เกือบทุกครั้ง

ถ้าเปิดสไลด์ดูประกอบ

หน้าสไลด์เขียนของจริง (repo branch day3-start)ต้องสนใจไหม
4"ท้ายวันอังคาร" รวมเป็น FINAL.md · "ความรู้ 16 ชั่วโมง" FINAL.md ยังไม่มีใน repo (เกิดท้ายคอร์ส) · ตัวเลขชั่วโมงเป็นคำของสไลด์ ไม่ต้อง
5Stack: Ruby 4.0.6 / Rails 8.1.3 / PostgreSQL 17 · tailwindcss-rails 4.6 ไฟล์จริงเขียน Ruby 4.0.5 / Rails 8.1.3 / PostgreSQL 18 · ไม่ระบุเลขรุ่น tailwindcss-rails · มีบรรทัด "ห้ามสร้าง tailwind.config.js" เพิ่ม ไม่ต้อง — ยึดไฟล์ใน repo
5รูปแบบโค้ด 3 ข้อ · รูปแบบการตอบ 2 ข้อ · หัวข้อ "(จากวันพฤหัส)" มี "ห้ามมี <script> ใน view" และ "อย่าเพิ่ง refactor อย่างอื่นที่ไม่ได้ขอ" เพิ่ม · หัวข้อเขียน "(จากวันก่อน)" · ถ้อยคำกฎ 8 ข้อต่างเล็กน้อย ความหมายเดิม ไม่ต้อง
6CLAUDE.md มีคำสั่งที่ใช้บ่อย 3 บรรทัด CLAUDE.md เป็น symlink ไป AGENTS.md · มีคำสั่ง 5 บรรทัด (เพิ่ม bin/rails routes · docker compose up -d) รู้ไว้ — แก้กฎให้แก้ AGENTS.md
6"กฎทั้ง 12 ข้อของเรา" ตอนนี้มี 8 ข้อ · ข้อ 9–12 เพิ่มในบท 135 รู้ไว้
7/context แล้วดูหัวข้อ Memory files เอกสารบอกว่าบางโหมดแสดงผล /context จะพับรายการไว้ ต้องพิมพ์ /context all รู้ไว้ ถ้าไม่เห็นรายการ

อ้างอิง