แนวทางปฏิบัติที่ดีที่สุดสำหรับ Memory
วิธีจัดโครงสร้าง memory เพื่อ recall ที่มีประสิทธิภาพ — category, key, tag, priority
แนวทางปฏิบัติที่ดีที่สุดสำหรับ Memory
วิธีที่คุณจัดโครงสร้าง memory กำหนดว่ามันจะมีประโยชน์แค่ไหน คู่มือนี้ครอบคลุมรูปแบบสำหรับจัด category, tag และกำหนด priority ของ memory เพื่อให้ LLM recall ข้อมูลที่ถูกต้องในเวลาที่เหมาะสม
Category: เลือกอันที่เฉพาะเจาะจงที่สุด
| Category | ใช้สำหรับ | ตัวอย่าง |
|---|---|---|
identity |
ชื่อผู้ใช้, role, ข้อมูลติดต่อ | "user_name": "Michael Schäfer" |
preference |
สิ่งที่ชอบ/ไม่ชอบ, สไตล์การทำงาน | "communication": "Prefers concise responses" |
fact |
fact ที่ตรวจสอบได้ | "office_location": "Berlin, Germany" |
project |
สถานะโปรเจกต์, การตัดสินใจ | "project_synapse": "v1.5.0 deployed" |
skill |
ทักษะผู้ใช้ | "skill_python": "Advanced, 10+ years" |
mistake |
error ในอดีตที่ต้องหลีกเลี่ยง | "mistake_npm_version": "Always bump version" |
context |
context ที่เกี่ยวข้องกับ session | "current_focus": "Working on docs system" |
note |
note อื่น ๆ | "note_idea": "Try Redis for caching" |
เมื่อไม่แน่ใจ ใช้ `fact` สำหรับข้อมูลที่ตรวจสอบได้ และ `note` สำหรับทุกอย่างอื่น อย่า categorize มากเกินไป — `fact` ที่ชัดเจนดีกว่า `context` ที่สับสน
Key: identifier ที่มีความหมาย
ฟิลด์ key เป็น identifier ของ memory ใช้ key ที่มีความหมายและคงที่:
Key ที่ดี:
user_nameproject_synapse_statuspreference_communication_stylemistake_npm_version_bump
Key ที่ไม่ดี:
mem_001(ไม่มีความหมาย)temp(ไม่บรรยาย)2026-06-27-note(วันที่ไม่ช่วย recall)
หลักการตั้งชื่อ key
snake_case(ตัวพิมพ์เล็กด้วย underscore)- นำหน้าด้วย category:
preference_*,project_*,mistake_* - ใช้คำนามที่บรรยาย ไม่ใช่กริยา
- ความยาวไม่เกิน 50 ตัวอักษร
Tag: สำหรับการค้นหาและกรอง
Tag เปิดใช้งานการกรองและค้นหาที่รวดเร็ว เพิ่ม 2-5 tag ต่อ memory:
{
"category": "project",
"key": "project_synapse_status",
"content": "Synapse v1.5.0 deployed. Next: v1.6.0 with docs system.",
"tags": ["synapse", "deployment", "status", "v1.5.0"]
}รูปแบบ tag
- ชื่อโปรเจกต์:
synapse,synapse-mcp,synapse-chat - หัวข้อ:
deployment,ci,database,auth - สถานะ:
active,completed,blocked - ตัวบ่งชี้ priority:
urgent,long-term
tag ไม่ sensitive ต่อตัวพิมพ์เล็ก/ใหญ่ ใช้ตัวพิมพ์เล็กเพื่อความสม่ำเสมอ
Priority: สมจริง
| Priority | ใช้สำหรับ | % ของ Memory |
|---|---|---|
critical |
ตัวตนผู้ใช้, ข้อมูลทางกฎหมาย, การตัดสินใจย้อนกลับไม่ได้ | ~5% |
high |
โปรเจกต์ที่ใช้งาน, ค่ากำหนดสำคัญ | ~20% |
normal |
fact, note, context ส่วนใหญ่ | ~65% |
low |
ชั่วคราว, รู้ไว้ก็ดี | ~10% |
อย่าทำเครื่องหมายทุกอย่างเป็น `critical` ถ้าทุกอย่าง critical ก็ไม่มีอะไร critical เลย สงวน `critical` สำหรับสิ่งที่จะก่อให้เกิดอันตรายจริงหากลืม
เมื่อใดเก็บ vs ไม่เก็บ
เก็บเสมอ
- ตัวตนผู้ใช้ (ชื่อ, email, role)
- ค่ากำหนดระยะยาว
- การตัดสินใจและเหตุผลของโปรเจกต์
- mistake และบทเรียนในอดีต
- คำมั่นสัญญาที่ให้กับผู้ใช้
ไม่เก็บ
- state ชั่วคราว (ใช้ variable แทน)
- ประวัติการสนทนาแบบ verbatim (ระบบแช็ตจัดการสิ่งนี้)
- ข้อมูล sensitive (รหัสผ่าน, API key)
- fact ที่ derive ง่าย (วันที่ปัจจุบัน, เนื้อหาไฟล์)
- context ชั่วคราว (ใช้ category
contextพร้อม priority ต่ำ)
การอัปเดต Memory
POST /memory ด้วย category + key เดิมจะอัปเดต memory ที่มีอยู่:
# Initial store
store("project", "project_synapse_status", "v1.4.0 deployed", priority="high")
# Later: update with same key
store("project", "project_synapse_status", "v1.5.0 deployed. CI green.", priority="high")ใช้ key ที่คงที่เพื่อให้อัปเดตได้โดยไม่สร้างซ้ำ LLM ควร POST ซ้ำ key เดิมเมื่อข้อมูลเปลี่ยน ไม่ใช่สร้าง memory ใหม่
วงจรชีวิต Memory
Create → Active → Stale → Archive → Delete- Create: POST /memory พร้อม context เต็ม
- Active: recall บ่อย, อัปเดตตามต้องการ
- Stale: ยังเกี่ยวข้องแต่ไม่ได้ใช้งาน (priority ต่ำกว่า?)
- Archive: ตั้ง priority เป็น
low, เก็บเพื่ออ้างอิงทางประวัติศาสตร์ - Delete: DELETE /memory/:id เมื่อไม่เกี่ยวข้องอีก
การทำความสะอาดเป็นคาบ
# Find memories not updated in 90 days
old_memories = requests.get(
f"{URL}/memory/search?q=*",
headers={"Authorization": f"Bearer {KEY}"}
)
for mem in old_memories["results"]:
if is_stale(mem, days=90):
# Either delete or lower priority
if is_obsolete(mem):
delete_memory(mem["id"])
else:
update_memory(mem["id"], priority="low")รูปแบบ: การสืบทอด Memory
สำหรับ context แบบลำดับชั้น (โปรเจกต์ → โปรเจกต์ย่อย → task):
# Parent project
store("project", "project_synapse", "Main Synapse project",
tags=["synapse", "parent"], priority="high")
# Sub-project (tags link to parent)
store("project", "project_synapse_docs", "Docs system for Synapse",
tags=["synapse", "docs", "synapse-parent"], priority="high")
# Specific task (tags link to sub-project)
store("project", "task_docs_loader", "Implement docs-loader.ts",
tags=["synapse", "docs", "task"], priority="normal")LLM สามารถค้นหา q=synapse+docs เพื่อหา memory ที่เกี่ยวข้องทั้งหมด
รูปแบบ: Decision Log
เก็บการตัดสินใจพร้อมเหตุผลเพื่อให้ LLM ไม่ต้องถกเถียงใหม่:
store("fact", "decision_postgres_over_sqlite",
"Chose PostgreSQL over SQLite for production. Reason: concurrent writes, "
"FTS5 native support, better backup story. Date: 2026-06-15. Decided by: Michael.",
tags=["decision", "database", "postgres", "sqlite"],
priority="high")รูปแบบ: การหลีกเลี่ยง Mistake
เก็บ mistake พร้อมคำแนะนำการหลีกเลี่ยงเฉพาะ:
store("mistake", "mistake_forget_version_bump",
"Forgot to bump package.json version after changes. npm publish failed. "
"FIX: Always run `npm version patch` before pushing. "
"CI fails with 'version already exists' if you forget.",
tags=["npm", "ci", "publish", "version"],
priority="high")