AI agent ลืมทุกอย่าง? เพราะ memory ผูกกับ path (worktree มีของตัวเอง)
TL;DR — AI agent memory มักถูก key ด้วย path ของโฟลเดอร์ที่เปิด. พอคุณเปิด session ใน git worktree (หรือ symlink / subfolder) มันคือ path คนละอัน → agent ได้ memory กองใหม่ที่ ว่างเปล่า ทั้งที่เป็น repo เดียวกัน. ทางแก้: ความรู้ที่ต้องอยู่รอด → ใส่ใน ไฟล์ในเรพ ไม่ใช่ memory
🌐 vendor-neutral — พฤติกรรม git worktree เป็นของ git ล้วนๆ (จริงทุกเครื่องมือ). ส่วน “memory ผูก path” ใช้กับ agent ที่เก็บ state/memory/index ต่อโปรเจกต์ (Cursor, Antigravity, Copilot, Codex, Claude Code). ป้าย 🔷 = เจาะจง Claude Code, 🌐 = มีตัวอย่างเครื่องมืออื่น
อาการ: เปิด session เดิม แต่จำอะไรไม่ได้
คุณทำโปรเจกต์กับ agent มาหลายวัน มันจำ context/decisions ไว้ใน “memory” ของมัน. อยู่ดีๆ วันหนึ่ง เปิด session ใหม่ โฟลเดอร์เดิมเป๊ะ แต่ agent เหมือน เพิ่งเจอโปรเจกต์ครั้งแรก — จำ decisions, gotchas, preferences อะไรไม่ได้เลย
หลายคนคิดว่า “memory พัง” แต่จริงๆ มันทำงานถูกต้อง — แค่คุณเผลอเปิดจาก path คนละอัน
ทำไม: memory ผูกกับ “path” ของ cwd
Agent ส่วนใหญ่เก็บ memory/context ต่อโปรเจกต์ โดย key ด้วย absolute path ของโฟลเดอร์ที่คุณเปิด มัน. พูดง่ายๆ: “โปรเจกต์” ในสายตา agent = path ของโฟลเดอร์ ไม่ใช่ “repo”
path เดียวกัน → memory กองเดียวกัน (นี่คือเหตุผลที่ resume ข้าม session ได้) path ต่างกัน → memory คนละกอง (มักว่างเปล่า)
🔷 Claude Code: memory อยู่ที่
~/.claude/projects/<path-แปลง / เป็น ->/memory/. เอา cwd มา แทน/ด้วย-เป็นชื่อโฟลเดอร์ — เห็นชัดว่าผูกกับ path ตรงๆ🌐 ทั่วไป: Cursor เก็บ index/rules/memories ต่อ workspace, Antigravity/Copilot ก็ผูก context กับ workspace ที่เปิด, Codex พึ่งไฟล์ในเรพ. ตัวที่มี state ต่อโปรเจกต์ทั้งหมดนี้ = ผูก กับโฟลเดอร์ที่เปิดทั้งนั้น
git worktree = path ใหม่ = memory กองใหม่ (ว่าง)
git worktree ให้คุณ checkout หลาย branch พร้อมกันในหลายโฟลเดอร์ (จาก repo เดียว). ประโยชน์คือ
รันหลาย session ขนานกันแบบไม่ชน. แต่ worktree อยู่คนละ path เช่น:
~/app ← main working tree
~/app/.worktrees/feature-x ← worktree (path ใหม่!)
พอเปิด agent ใน ~/app/.worktrees/feature-x → path เปลี่ยน → memory namespace ใหม่ = ว่างเปล่า.
agent เลย “จำอะไรไม่ได้” ทั้งที่เป็น repo เดียวกับ ~/app
🔷 Claude Code: ตอนสร้าง session ถ้าติ๊ก “worktree” มันจะเปิดใน
.claude/worktrees/<name>= path ใหม่ = memory ว่าง. อยากได้ memory เดิม → อย่าติ๊ก worktree (เปิดโฟลเดอร์จริง)🌐 ทั่วไป: เครื่องมือไหนก็ตามที่คุณเปิดจากโฟลเดอร์ worktree — Cursor/Antigravity/Copilot/Codex — ก็เห็นมันเป็น “โปรเจกต์ใหม่” (workspace ใหม่) เพราะ path ต่าง. index/memory/settings ต่อ workspace จะเริ่มใหม่หมด
symlink กับ subfolder ก็โดนเหมือนกัน
เพราะมันดูที่ string ของ path เป๊ะๆ ไม่ใช่ “repo ไหน”:
- เปิดผ่าน symlink (
~/proj-link→~/proj) vs path จริง → คนละ path → คนละ memory - เปิดจาก subfolder (
~/proj/packages/api) → ก็คนละ path อีก
กฎจำง่าย: อยากได้ memory เดิม → เปิดจาก path เป๊ะเดิมทุกครั้ง
โบนัส: concurrency — 1 working tree = 1 branch
เปิดหลาย session โฟลเดอร์เดียวแต่คนละ branch ไม่ได้ — 1 โฟลเดอร์ checkout ได้ทีละ branch จะรัน ขนานกันก็ตีกัน. รันขนานจริงต้องใช้ git worktree (แต่ละ session มีโฟลเดอร์+branch ของตัวเอง แต่ได้ memory namespace ใหม่). ส่วน memory ตาม path ไม่ตาม branch → สลับ branch ในโฟลเดอร์เดิม memory คงเดิม.
รายละเอียด + วิธีเลือก parallel worktree vs สลับ branch อยู่ในบทความแยก → รัน AI agent หลายตัวขนานกันด้วย git worktree
กฎที่ได้: durable knowledge → repo files
นี่คือบทเรียนหลัก:
memory เป็น local + ผูก path → ไม่เดินทางข้าม worktree / เครื่อง / คนอื่น / เครื่องมือ. ไฟล์ในเรพเดินทางผ่าน git → ทุกที่เห็นเหมือนกัน
เพราะงั้น อะไรที่ ต้องอยู่รอด (decisions, conventions, gotchas, สถานะโปรเจกต์) → ใส่ใน ไฟล์ ในเรพ ไม่ใช่ memory ของเครื่องมือ (ดูระบบ handoff ที่เก็บสถานะโปรเจกต์ให้ resume ได้)
🔷 Claude Code:
CLAUDE.md,HANDOFF.md,PROGRESS.md. memory ใช้เก็บของ local ส่วนตัว ที่ไม่อยากใส่เรพ (preference, rule ส่วนตัว)🌐 ทั่วไป: ไฟล์ instructions ที่ commit ลงเรพ — Copilot
.github/copilot-instructions.md· Codex/AntigravityAGENTS.md· Cursor.cursor/rules/*.mdc. พวกนี้ worktree/เพื่อนร่วมทีม/ CI ได้ครบเพราะอยู่ใน git
ตัวอย่างเนื้อไฟล์ — durable knowledge เขียนประมาณนี้ (ไฟล์ชื่อ AGENTS.md หรือ CLAUDE.md /
.github/copilot-instructions.md เนื้อหาเดียวกัน แค่เปลี่ยนชื่อ):
# Project knowledge (durable — อยู่ในเรพ ไม่ใช่ memory ของเครื่องมือ)
## Conventions
- API ทุกตัว = vertical slice: core → service → data → route
## Gotchas (เจอแล้ว)
- build OOM (exit 137) = RAM ไม่ใช่ disk → ลด jest maxWorkers
- migrate ด้วย `make migrate` เท่านั้น (prisma ตรงๆ พัง)
เขียนในเรพครั้งเดียว → ทุก worktree / เพื่อนร่วมทีม / CI / เครื่องมืออื่น เห็นเหมือนกัน — ต่างจาก memory ที่ผูก path (worktree ใหม่ = ว่าง)
อีก 2 กฎที่เจ็บมาแล้ว (อัปเดตจากการใช้จริง):
- อย่าจด “layout/โครงสร้าง repo” ลง memory — repo อธิบายตัวเองผ่านไฟล์ในเรพอยู่แล้ว จดซ้ำ = stale ทันทีที่โครงขยับ · memory ไว้จด “ฉันทำงานยังไง” ไม่ใช่ “อะไรอยู่ไหน”
- memory ไม่มี git undo — ก่อนให้ agent แก้ memory เป็นชุด (migration/rewrite หลายไฟล์)
ให้ backup ก่อน:
cp -R <memory-dir> <memory-dir>-backup-<วันที่>· เสร็จ+ตรวจแล้วค่อยลบ
เมื่อไรควรใช้ worktree / เมื่อไรไม่ควร
| สถานการณ์ | ใช้ worktree? |
|---|---|
| อยากได้ memory เดิม, ทำ session เดียว | ❌ เปิดโฟลเดอร์จริง |
| ต้องรันหลาย session ขนานกันจริง (แยกไม่ชน) | ✅ worktree (ยอมรับ memory ใหม่ → พึ่งไฟล์ในเรพ) |
| แค่สลับ branch ไปมา ทีละอัน | ❌ โฟลเดอร์เดียว, สลับ branch (memory คงเดิม) |
สรุป
- memory ผูกกับ path ของ cwd — path เดียวกัน = จำได้, path ต่าง = memory ใหม่ (ว่าง)
- git worktree / symlink / subfolder = path ใหม่ → agent “ลืม” ทั้งที่ repo เดียวกัน
- 1 working tree = 1 branch — จะขนานจริงต้องใช้ worktree; memory ตาม path ไม่ตาม branch
- durable knowledge → repo files (เดินทางผ่าน git) ไม่ใช่ memory (local + ผูก path)
รู้ทันข้อนี้ = เลิกงงว่าทำไม agent ลืม และวางความรู้ให้ถูกที่ตั้งแต่แรก 🚀

