AI agent ลืมทุกอย่าง? เพราะ memory ผูกกับ path (worktree มีของตัวเอง)

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 จะเริ่มใหม่หมด

เพราะมันดูที่ 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/Antigravity AGENTS.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 กฎที่เจ็บมาแล้ว (อัปเดตจากการใช้จริง):

  1. อย่าจด “layout/โครงสร้าง repo” ลง memory — repo อธิบายตัวเองผ่านไฟล์ในเรพอยู่แล้ว จดซ้ำ = stale ทันทีที่โครงขยับ · memory ไว้จด “ฉันทำงานยังไง” ไม่ใช่ “อะไรอยู่ไหน”
  2. 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 คงเดิม)

สรุป

  1. memory ผูกกับ path ของ cwd — path เดียวกัน = จำได้, path ต่าง = memory ใหม่ (ว่าง)
  2. git worktree / symlink / subfolder = path ใหม่ → agent “ลืม” ทั้งที่ repo เดียวกัน
  3. 1 working tree = 1 branch — จะขนานจริงต้องใช้ worktree; memory ตาม path ไม่ตาม branch
  4. durable knowledge → repo files (เดินทางผ่าน git) ไม่ใช่ memory (local + ผูก path)

รู้ทันข้อนี้ = เลิกงงว่าทำไม agent ลืม และวางความรู้ให้ถูกที่ตั้งแต่แรก 🚀

Supawut Thomas

Supawut Thomas

Software Developer

มีประสบการณ์พัฒนา Software ระดับ Enterprise มากกว่า 10 ปี ผ่านงานจริงหลากหลายโปรเจกต์องค์กร — เชื่อว่าความรู้ที่ดีที่สุดคือความรู้ที่มาจากประสบการณ์จริง และอยากแบ่งปันสิ่งเหล่านั้นให้เพื่อน Developer ทุกคนได้นำไปพัฒนาตัวเองได้ดีขึ้นในทุกๆ วัน