Sessions and memory
เอนจินหน่วยความจำ QMD
QMD คือไซด์คาร์ค้นหาแบบ local-first ที่ทำงาน ควบคู่กับ OpenClaw โดยรวม BM25, การค้นหาเวกเตอร์ และการจัดอันดับซ้ำไว้ใน ไบนารีเดียว และสามารถทำดัชนีเนื้อหานอกเหนือจากไฟล์หน่วยความจำในเวิร์กสเปซของคุณได้
สิ่งที่เพิ่มจากระบบในตัว
- การจัดอันดับซ้ำและการขยายคำค้น เพื่อให้เรียกคืนผลลัพธ์ได้ดีขึ้น
- ทำดัชนีไดเรกทอรีเพิ่มเติม -- เอกสารโปรเจกต์, โน้ตของทีม, หรืออะไรก็ตามบนดิสก์
- ทำดัชนีทรานสคริปต์ของเซสชัน -- เรียกคืนบทสนทนาก่อนหน้า
- ทำงานในเครื่องทั้งหมด -- ทำงานด้วยแพ็กเกจรันไทม์ node-llama-cpp ที่เป็นทางเลือก และ ดาวน์โหลดโมเดล GGUF อัตโนมัติ
- ** fallback อัตโนมัติ** -- หาก QMD ใช้งานไม่ได้ OpenClaw จะถอยกลับไปใช้ เอนจินในตัวได้อย่างไร้รอยต่อ
เริ่มต้นใช้งาน
ข้อกำหนดเบื้องต้น
- ติดตั้ง QMD:
npm install -g @tobilu/qmdหรือbun install -g @tobilu/qmd - บิลด์ SQLite ที่อนุญาตส่วนขยาย (
brew install sqliteบน macOS) - QMD ต้องอยู่ใน
PATHของ Gateway - macOS และ Linux ใช้งานได้ทันที Windows รองรับได้ดีที่สุดผ่าน WSL2
เปิดใช้งาน
{
memory: {
backend: "qmd",
},
}
OpenClaw จะสร้างโฮม QMD แบบครบในตัวภายใต้
~/.openclaw/agents/<agentId>/qmd/ และจัดการวงจรชีวิตของไซด์คาร์
โดยอัตโนมัติ -- คอลเลกชัน, การอัปเดต และการรัน embedding จะถูกจัดการให้คุณ
ระบบจะเลือกใช้รูปแบบคอลเลกชันและคำค้น MCP ของ QMD ปัจจุบันก่อน แต่ยังถอยกลับไปใช้
แฟล็กรูปแบบคอลเลกชันทางเลือกและชื่อเครื่องมือ MCP รุ่นเก่าเมื่อจำเป็น
การปรับให้ตรงกันตอนบูตยังสร้างคอลเลกชันที่จัดการไว้แต่ค้างเก่ากลับไปเป็น
รูปแบบ canonical อีกครั้ง เมื่อยังมีคอลเลกชัน QMD รุ่นเก่าที่มีชื่อเดียวกัน
อยู่
วิธีทำงานของไซด์คาร์
- OpenClaw สร้างคอลเลกชันจากไฟล์หน่วยความจำในเวิร์กสเปซและ
memory.qmd.pathsที่กำหนดค่าไว้ จากนั้นรันqmd updateเมื่อเปิดตัวจัดการ QMD และรันเป็นระยะหลังจากนั้น (ค่าเริ่มต้นทุก 5 นาที) การรีเฟรชเหล่านี้ ทำงานผ่าน subprocess ของ QMD ไม่ใช่การ crawl ระบบไฟล์ในโปรเซสเดียวกัน โหมด semantic จะรันqmd embedด้วย - คอลเลกชันเวิร์กสเปซเริ่มต้นติดตาม
MEMORY.mdพร้อมกับทรีmemory/ส่วนmemory.mdตัวพิมพ์เล็กจะไม่ถูกทำดัชนีเป็นไฟล์หน่วยความจำราก - สแกนเนอร์ของ QMD เองจะละเว้นพาธที่ซ่อนอยู่และไดเรกทอรี dependency/build
ทั่วไป เช่น
.git,.cache,node_modules,vendor,distและbuildการเริ่ม Gateway จะไม่เริ่มต้น QMD โดยค่าเริ่มต้น ดังนั้น cold boot จะหลีกเลี่ยงการนำเข้ารันไทม์หน่วยความจำหรือสร้าง watcher อายุยาวก่อน มีการใช้หน่วยความจำครั้งแรก - หากยังต้องการรีเฟรชตอนเริ่ม Gateway ให้ตั้ง
memory.qmd.update.startupเป็นidleหรือimmediateการรีเฟรชตอนเริ่ม แบบ opt-in จะใช้พาธ subprocess ของ QMD แบบครั้งเดียว แทนการสร้าง watcher ในโปรเซสแบบเต็มที่มีอายุยาว - การค้นหาใช้
searchModeที่กำหนดค่าไว้ (ค่าเริ่มต้น:search; ยังรองรับvsearchและquery)searchเป็น BM25 เท่านั้น ดังนั้น OpenClaw จะข้าม การ probe ความพร้อมของเวกเตอร์ semantic และการบำรุงรักษา embedding ในโหมดนั้น หากโหมดใดล้มเหลว OpenClaw จะลองใหม่ด้วยqmd query - เมื่อใช้ QMD รุ่นที่ประกาศตัวกรองหลายคอลเลกชัน OpenClaw จะรวม คอลเลกชันแหล่งเดียวกันไว้ในการเรียกค้นหา QMD ครั้งเดียว QMD รุ่นเก่าจะ ใช้ fallback แบบต่อคอลเลกชันที่เข้ากันได้ต่อไป
- หาก QMD ล้มเหลวทั้งหมด OpenClaw จะถอยกลับไปใช้เอนจิน SQLite ในตัว
ความพยายามซ้ำในแต่ละรอบแชตจะ back off สั้น ๆ หลังเปิดล้มเหลว เพื่อไม่ให้
ไบนารีที่ขาดหายหรือ dependency ของไซด์คาร์ที่เสียสร้างพายุการลองซ้ำ;
openclaw memory statusและการ probe CLI แบบครั้งเดียวยังคงตรวจ QMD โดยตรงอีกครั้ง
ประสิทธิภาพและความเข้ากันได้ของการค้นหา
OpenClaw รักษาพาธการค้นหา QMD ให้เข้ากันได้กับทั้งการติดตั้ง QMD ปัจจุบันและรุ่นเก่า
เมื่อเริ่มต้น OpenClaw จะตรวจข้อความช่วยเหลือของ QMD ที่ติดตั้งไว้หนึ่งครั้งต่อ manager หาก ไบนารีประกาศว่ารองรับตัวกรองหลายคอลเลกชัน OpenClaw จะค้นหาคอลเลกชันแหล่งเดียวกันทั้งหมด ด้วยคำสั่งเดียว:
qmd search "router notes" --json -n 10 -c memory-root-main -c memory-dir-main
วิธีนี้หลีกเลี่ยงการเริ่ม subprocess ของ QMD หนึ่งตัวสำหรับทุกคอลเลกชัน durable-memory
คอลเลกชันทรานสคริปต์เซสชันจะอยู่ในกลุ่มแหล่งของตัวเอง ดังนั้นการค้นหาแบบผสม
memory + sessions ยังคงให้ input สำหรับตัวกระจายผลลัพธ์จากทั้งสองแหล่ง
บิลด์ QMD รุ่นเก่ารับตัวกรองคอลเลกชันได้เพียงหนึ่งรายการ เมื่อ OpenClaw ตรวจพบบิลด์ เหล่านั้น ระบบจะคงพาธความเข้ากันได้ไว้และค้นหาแต่ละคอลเลกชัน แยกกันก่อนรวมและลบผลลัพธ์ซ้ำ
หากต้องการตรวจ contract ที่ติดตั้งไว้ด้วยตนเอง ให้รัน:
qmd --help | grep -i collection
ข้อความช่วยเหลือ QMD ปัจจุบันระบุว่าตัวกรองคอลเลกชันสามารถกำหนดเป้าหมายได้หนึ่งหรือหลายคอลเลกชัน ข้อความช่วยเหลือรุ่นเก่ามักอธิบายคอลเลกชันเดียว
การ override โมเดล
ตัวแปรสภาพแวดล้อมของโมเดล QMD จะถูกส่งผ่านแบบไม่เปลี่ยนแปลงจากโปรเซส Gateway ดังนั้นคุณสามารถปรับ QMD แบบ global ได้โดยไม่ต้องเพิ่ม config ใหม่ของ OpenClaw:
export QMD_EMBED_MODEL="hf:Qwen/Qwen3-Embedding-0.6B-GGUF/Qwen3-Embedding-0.6B-Q8_0.gguf"
export QMD_RERANK_MODEL="/absolute/path/to/reranker.gguf"
export QMD_GENERATE_MODEL="/absolute/path/to/generator.gguf"
หลังจากเปลี่ยนโมเดล embedding ให้รัน embedding อีกครั้งเพื่อให้ดัชนีตรงกับ vector space ใหม่
การทำดัชนีพาธเพิ่มเติม
ชี้ QMD ไปยังไดเรกทอรีเพิ่มเติมเพื่อให้ค้นหาได้:
{
memory: {
backend: "qmd",
qmd: {
paths: [{ name: "docs", path: "~/notes", pattern: "**/*.md" }],
},
},
}
snippet จากพาธเพิ่มเติมจะปรากฏเป็น qmd/<collection>/<relative-path> ใน
ผลลัพธ์การค้นหา memory_get เข้าใจ prefix นี้และอ่านจาก root ของคอลเลกชัน
ที่ถูกต้อง
การทำดัชนีทรานสคริปต์เซสชัน
เปิดใช้งานการทำดัชนีเซสชันเพื่อเรียกคืนบทสนทนาก่อนหน้า:
{
memory: {
backend: "qmd",
qmd: {
sessions: { enabled: true },
},
},
}
ทรานสคริปต์จะถูกส่งออกเป็นรอบ User/Assistant ที่ sanitize แล้วไปยังคอลเลกชัน QMD
เฉพาะภายใต้ ~/.openclaw/agents/<id>/qmd/sessions/
ขอบเขตการค้นหา
โดยค่าเริ่มต้น ผลลัพธ์การค้นหา QMD จะแสดงในเซสชันแบบ direct และ channel
(ไม่ใช่ groups) กำหนดค่า memory.qmd.scope เพื่อเปลี่ยนสิ่งนี้:
{
memory: {
qmd: {
scope: {
default: "deny",
rules: [{ action: "allow", match: { chatType: "direct" } }],
},
},
},
}
เมื่อ scope ปฏิเสธการค้นหา OpenClaw จะบันทึกคำเตือนพร้อม channel และ ประเภทแชตที่อนุมานได้ เพื่อให้ debug ผลลัพธ์ว่างได้ง่ายขึ้น
การอ้างอิง
เมื่อ memory.citations เป็น auto หรือ on snippet การค้นหาจะมี footer
Source: <path#line> ตั้ง memory.citations = "off" เพื่อละเว้น footer
แต่ยังส่งพาธให้ agent ภายใน
ควรใช้เมื่อใด
เลือก QMD เมื่อคุณต้องการ:
- การจัดอันดับซ้ำเพื่อผลลัพธ์คุณภาพสูงขึ้น
- ค้นหาเอกสารโปรเจกต์หรือโน้ตนอกเวิร์กสเปซ
- เรียกคืนบทสนทนาเซสชันที่ผ่านมา
- การค้นหาในเครื่องทั้งหมดโดยไม่ต้องใช้คีย์ API
สำหรับการตั้งค่าที่เรียบง่ายกว่า เอนจินในตัว ทำงานได้ดี โดยไม่มี dependency เพิ่มเติม
การแก้ไขปัญหา
ไม่พบ QMD? ตรวจสอบให้แน่ใจว่าไบนารีอยู่ใน PATH ของ Gateway หาก OpenClaw
ทำงานเป็นบริการ ให้สร้าง symlink:
sudo ln -s ~/.bun/bin/qmd /usr/local/bin/qmd
หาก qmd --version ทำงานใน shell ของคุณ แต่ OpenClaw ยังรายงาน
spawn qmd ENOENT โปรเซส Gateway น่าจะมี PATH แตกต่างจาก
interactive shell ของคุณ ให้ pin ไบนารีอย่างชัดเจน:
{
memory: {
backend: "qmd",
qmd: {
command: "/absolute/path/to/qmd",
},
},
}
ใช้ command -v qmd ในสภาพแวดล้อมที่ติดตั้ง QMD แล้วตรวจซ้ำ
ด้วย openclaw memory status --deep
การค้นหาครั้งแรกช้ามาก? QMD ดาวน์โหลดโมเดล GGUF เมื่อใช้งานครั้งแรก ให้ pre-warm
ด้วย qmd query "test" โดยใช้ XDG dirs เดียวกับที่ OpenClaw ใช้
มี subprocess ของ QMD จำนวนมากระหว่างการค้นหา? อัปเดต QMD หากทำได้ OpenClaw ใช้
โปรเซสเดียวสำหรับการค้นหาหลายคอลเลกชันแหล่งเดียวกัน เฉพาะเมื่อ QMD ที่ติดตั้งไว้
ประกาศว่ารองรับตัวกรอง -c หลายรายการ มิฉะนั้นจะคง fallback รุ่นเก่า
แบบต่อคอลเลกชันไว้เพื่อความถูกต้อง
QMD แบบ BM25 เท่านั้นยังพยายาม build llama.cpp? ตั้ง
memory.qmd.searchMode = "search" OpenClaw ถือว่าโหมดนั้นเป็น lexical-only,
ไม่รันการ probe สถานะเวกเตอร์ QMD หรือการบำรุงรักษา embedding และปล่อยให้
การตรวจความพร้อม semantic เป็นของการตั้งค่า vsearch หรือ query
การค้นหา timeout? เพิ่ม memory.qmd.limits.timeoutMs (ค่าเริ่มต้น: 4000ms)
ตั้งเป็น 120000 สำหรับฮาร์ดแวร์ที่ช้ากว่า
ผลลัพธ์ว่างในแชตกลุ่ม? ตรวจ memory.qmd.scope -- ค่าเริ่มต้นอนุญาตเฉพาะ
เซสชัน direct และ channel
การค้นหาหน่วยความจำรากกว้างเกินไปกะทันหัน? รีสตาร์ท Gateway หรือรอ
การปรับให้ตรงกันตอนเริ่มครั้งถัดไป OpenClaw จะสร้างคอลเลกชันที่จัดการไว้แต่ค้างเก่า
กลับไปเป็นรูปแบบ canonical MEMORY.md และ memory/ เมื่อพบความขัดแย้ง
ชื่อเดียวกัน
repo ชั่วคราวที่มองเห็นได้ในเวิร์กสเปซทำให้เกิด ENAMETOOLONG หรือการทำดัชนีเสีย?
ขณะนี้ traversal ของ QMD ใช้พฤติกรรมสแกนเนอร์ QMD พื้นฐาน แทนกฎ symlink
ในตัวของ OpenClaw ให้เก็บ checkout monorepo ชั่วคราวไว้ภายใต้
ไดเรกทอรีที่ซ่อน เช่น .tmp/ หรือนอก root QMD ที่ทำดัชนีไว้ จนกว่า QMD จะเปิดเผย
การ traversal ที่ปลอดภัยต่อ cycle หรือการควบคุมการยกเว้นที่ชัดเจน
การกำหนดค่า
สำหรับพื้นผิว config ทั้งหมด (memory.qmd.*), โหมดการค้นหา, ช่วงเวลาการอัปเดต,
กฎ scope และตัวปรับอื่นทั้งหมด ดูที่
เอกสารอ้างอิงการกำหนดค่าหน่วยความจำ