Sessions and memory
เอนจินหน่วยความจำ QMD
QMD คือบริการเสริมสำหรับการค้นหาแบบเน้นการทำงานภายในเครื่อง ซึ่งทำงาน ควบคู่กับ OpenClaw โดยรวม BM25 การค้นหาแบบเวกเตอร์ และการจัดอันดับซ้ำไว้ใน ไบนารีเดียว และสามารถจัดทำดัชนีเนื้อหานอกเหนือจากไฟล์หน่วยความจำในพื้นที่ทำงานของคุณได้
สิ่งที่เพิ่มเข้ามาเหนือกว่าเอนจินในตัว
- การจัดอันดับซ้ำและการขยายคำค้น เพื่อเพิ่มความครอบคลุมของผลการค้นหา
- จัดทำดัชนีไดเรกทอรีเพิ่มเติม - เอกสารโครงการ บันทึกของทีม หรือทุกสิ่งบนดิสก์
- จัดทำดัชนีบทถอดความเซสชัน - เรียกคืนบทสนทนาก่อนหน้า
- ทำงานภายในเครื่องอย่างสมบูรณ์ - ทำงานร่วมกับ Plugin ผู้ให้บริการ llama.cpp อย่างเป็นทางการ และ ดาวน์โหลดโมเดล GGUF โดยอัตโนมัติ
- การย้อนกลับอัตโนมัติ - หาก 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/ และจัดการวงจรชีวิตของบริการเสริม
โดยอัตโนมัติ ทั้งคอลเลกชัน การอัปเดต และการเรียกใช้การฝังข้อมูลจะได้รับการจัดการให้คุณ
ระบบจะให้ความสำคัญกับรูปแบบคอลเลกชันและคำค้น MCP ของ QMD ปัจจุบัน แต่จะย้อนกลับไปใช้
แฟล็กรูปแบบคอลเลกชันทางเลือกและชื่อเครื่องมือ MCP รุ่นเก่าเมื่อจำเป็น
การปรับสถานะให้สอดคล้องกันเมื่อเริ่มต้นยังสร้างคอลเลกชันที่จัดการอยู่ซึ่งล้าสมัยขึ้นใหม่ให้กลับเป็น
รูปแบบมาตรฐาน เมื่อยังมีคอลเลกชัน QMD รุ่นเก่าที่ใช้ชื่อเดียวกันอยู่
วิธีการทำงานของบริการเสริม
- OpenClaw สร้างคอลเลกชันจากไฟล์หน่วยความจำในพื้นที่ทำงานของคุณและ
memory.qmd.pathsที่กำหนดค่าไว้ จากนั้นเรียกใช้qmd updateเมื่อผู้จัดการ QMD เปิดทำงาน และเรียกเป็นระยะหลังจากนั้น (memory.qmd.update.intervalค่าเริ่มต้นคือ5m) การรีเฟรชทำงานผ่านกระบวนการย่อยของ QMD ไม่ใช่การไล่สำรวจระบบไฟล์ ภายในกระบวนการ โหมดการค้นหาเชิงความหมายจะเรียกใช้qmd embedด้วย (memory.qmd.update.embedIntervalค่าเริ่มต้นคือ60m) - คอลเลกชันพื้นที่ทำงานเริ่มต้นติดตาม
MEMORY.mdรวมถึงโครงสร้างไดเรกทอรีmemory/โดยจะไม่จัดทำดัชนีmemory.mdตัวพิมพ์เล็กในฐานะไฟล์หน่วยความจำราก - ตัวสแกนของ QMD จะละเว้นพาธที่ซ่อนอยู่และไดเรกทอรีการพึ่งพา/การบิลด์ทั่วไป
เช่น
.git,.cache,node_modules,vendor,distและbuildโดยค่าเริ่มต้น การเริ่มต้น Gateway จะไม่เตรียม QMD (memory.qmd.update.startupมีค่าเริ่มต้นเป็นoff) ดังนั้นการเริ่มระบบแบบเย็นจึงหลีกเลี่ยง การนำเข้ารันไทม์หน่วยความจำหรือการสร้างตัวเฝ้าดูระยะยาวก่อนที่จะมีการใช้ หน่วยความจำเป็นครั้งแรก - ตั้งค่า
memory.qmd.update.startupเป็นidleหรือimmediateเพื่อเตรียม QMD เมื่อ Gateway เริ่มทำงานอยู่ดีmemory.qmd.update.onBootมีค่าเริ่มต้นเป็นtrueและ เรียกใช้การรีเฟรชครั้งแรกเมื่อเริ่มต้น ตั้งค่าเป็นfalseเพื่อข้าม การรีเฟรชทันทีนั้น (ผู้จัดการระยะยาวยังคงเปิดเมื่อมีการกำหนดค่าช่วงเวลาอัปเดตหรือฝังข้อมูล ดังนั้น QMD ยังคงเป็นผู้ดูแลตัวเฝ้าดู/ตัวจับเวลาตามรอบของตน) - การค้นหาใช้
searchModeที่กำหนดค่าไว้ (ค่าเริ่มต้น:search; รองรับvsearchและqueryด้วย)searchใช้เฉพาะ BM25 ดังนั้น OpenClaw จึงข้าม การตรวจสอบความพร้อมของเวกเตอร์เชิงความหมายและการบำรุงรักษาการฝังข้อมูลในโหมดนั้น หากโหมดใด ล้มเหลว OpenClaw จะลองใหม่ด้วยqmd query - เมื่อ
searchModeเป็นqueryให้ตั้งค่าmemory.qmd.rerankเป็นfalseเพื่อใช้ เส้นทางคำค้นแบบผสมของ QMD โดยไม่มีตัวจัดอันดับซ้ำ (ต้องใช้ QMD 2.1 หรือใหม่กว่า) OpenClaw ส่ง--no-rerankไปยังเส้นทาง CLI ของ QMD โดยตรง และส่งrerank: falseไปยังเครื่องมือคำค้น MCP ของ QMD - สำหรับ QMD รุ่นที่ประกาศรองรับตัวกรองหลายคอลเลกชัน OpenClaw จะจัดกลุ่ม คอลเลกชันจากแหล่งเดียวกันไว้ในการเรียกค้นหา QMD ครั้งเดียว ส่วน QMD รุ่นเก่า จะใช้การย้อนกลับที่เข้ากันได้แบบแยกคอลเลกชัน
- หาก QMD ล้มเหลวทั้งหมด OpenClaw จะย้อนกลับไปใช้เอนจิน SQLite ในตัว
ความพยายามซ้ำในแต่ละรอบการสนทนาจะเว้นช่วงสั้น ๆ หลังจากเปิดไม่สำเร็จ เพื่อไม่ให้
ไบนารีที่หายไปหรือการพึ่งพาของบริการเสริมที่เสียหายก่อให้เกิดการลองใหม่ถี่เกินไป
openclaw memory statusและการตรวจสอบ CLI แบบครั้งเดียวยังคงตรวจสอบ QMD โดยตรงอีกครั้ง
ประสิทธิภาพและความเข้ากันได้ของการค้นหา
OpenClaw รักษาเส้นทางการค้นหาของ QMD ให้เข้ากันได้ทั้งกับการติดตั้ง QMD รุ่นปัจจุบันและรุ่นเก่า
เมื่อเริ่มต้น OpenClaw จะตรวจสอบข้อความช่วยเหลือของ QMD ที่ติดตั้งไว้หนึ่งครั้งต่อผู้จัดการ หาก ไบนารีประกาศว่ารองรับตัวกรองหลายคอลเลกชัน OpenClaw จะ ค้นหาคอลเลกชันทั้งหมดจากแหล่งเดียวกันด้วยคำสั่งเดียว:
qmd search "router notes" --json -n 10 -c memory-root-main -c memory-dir-mainวิธีนี้หลีกเลี่ยงการเริ่มกระบวนการย่อย QMD หนึ่งกระบวนการต่อคอลเลกชันหน่วยความจำถาวร
คอลเลกชันบทถอดความเซสชันจะอยู่ในกลุ่มแหล่งข้อมูลของตนเอง ดังนั้นการค้นหาแบบผสม
memory + sessions ยังคงส่งข้อมูลจากทั้งสองแหล่งให้ตัวกระจายความหลากหลายของผลลัพธ์
บิลด์ QMD รุ่นเก่ารองรับตัวกรองคอลเลกชันเพียงหนึ่งตัว เมื่อ OpenClaw ตรวจพบบิลด์ เหล่านั้น ระบบจะคงเส้นทางความเข้ากันได้ไว้และค้นหาแต่ละคอลเลกชัน แยกกัน ก่อนรวมและตัดผลลัพธ์ที่ซ้ำกันออก
หากต้องการตรวจสอบสัญญาของรุ่นที่ติดตั้งด้วยตนเอง ให้เรียกใช้:
qmd --help | grep -i collectionข้อความช่วยเหลือของ QMD ปัจจุบันกล่าวถึงการระบุเป้าหมายเป็นหนึ่งคอลเลกชันหรือหลายคอลเลกชัน ส่วนข้อความช่วยเหลือ รุ่นเก่ามักอธิบายเพียงคอลเลกชันเดียว
การแทนที่โมเดล
ตัวแปรสภาพแวดล้อมของโมเดล QMD จะถูกส่งผ่านจากกระบวนการ Gateway โดยไม่เปลี่ยนแปลง ดังนั้นคุณจึงปรับแต่ง QMD โดยรวมได้โดยไม่ต้องเพิ่มการกำหนดค่า 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"หลังจากเปลี่ยนโมเดลการฝังข้อมูล ให้เรียกใช้การฝังข้อมูลอีกครั้งเพื่อให้ดัชนีสอดคล้องกับ ปริภูมิเวกเตอร์ใหม่
การจัดทำดัชนีพาธเพิ่มเติม
กำหนดให้ QMD ชี้ไปยังไดเรกทอรีเพิ่มเติมเพื่อให้ค้นหาได้:
{ memory: { backend: "qmd", qmd: { paths: [{ name: "docs", path: "~/notes", pattern: "**/*.md" }], }, },}ข้อความตัดตอนจากพาธเพิ่มเติมจะปรากฏเป็น qmd/<collection>/<relative-path> ใน
ผลการค้นหา memory_get เข้าใจคำนำหน้านี้และอ่านจาก
รากคอลเลกชันที่ถูกต้อง
การจัดทำดัชนีบทถอดความเซสชัน
เปิดใช้การจัดทำดัชนีเซสชันเพื่อเรียกคืนบทสนทนาก่อนหน้า QMD ต้องใช้ทั้ง
แหล่งเซสชัน memorySearch ทั่วไปและตัวส่งออกบทถอดความของ QMD:
{ agents: { defaults: { memorySearch: { experimental: { sessionMemory: true }, sources: ["memory", "sessions"], }, }, }, memory: { backend: "qmd", qmd: { sessions: { enabled: true }, }, },}บทถอดความจะถูกส่งออกเป็นรอบการสนทนา User/Assistant ที่ผ่านการทำให้ปลอดภัยแล้ว ไปยังคอลเลกชัน QMD
เฉพาะภายใต้ ~/.openclaw/agents/<id>/qmd/sessions/ การตั้งค่าเฉพาะ
memorySearch.experimental.sessionMemory จะไม่ส่งออกบทถอดความไปยัง
QMD
ผลลัพธ์จากเซสชันยังคงถูกกรองด้วย
tools.sessions.visibility ค่าเริ่มต้น
tree จะไม่เปิดเผยเซสชันอื่นที่ไม่เกี่ยวข้องของเอเจนต์เดียวกัน หากต้องการให้
เซสชันที่ Gateway ส่งต่อมาสามารถถูกเรียกคืนจากเซสชันข้อความส่วนตัวอีกเซสชันหนึ่งได้
ให้ตั้งค่า tools.sessions.visibility: "agent" อย่างตั้งใจ
ขอบเขตการค้นหา
โดยค่าเริ่มต้น ผลการค้นหาของ QMD จะแสดงเฉพาะในเซสชันโดยตรงเท่านั้น (ไม่รวม
การสนทนากลุ่มหรือช่อง) กำหนดค่า memory.qmd.scope เพื่อเปลี่ยนพฤติกรรมนี้:
{ memory: { qmd: { scope: { default: "deny", rules: [{ action: "allow", match: { chatType: "direct" } }], }, }, },}ส่วนย่อยด้านบนคือกฎเริ่มต้นจริง เมื่อขอบเขตปฏิเสธการค้นหา OpenClaw จะบันทึกคำเตือนพร้อมช่องและประเภทการสนทนาที่อนุมานได้ เพื่อให้ แก้จุดบกพร่องของผลลัพธ์ว่างได้ง่ายขึ้น
การอ้างอิงแหล่งที่มา
เมื่อ memory.citations เป็น auto หรือ on ข้อความตัดตอนจากผลการค้นหาจะได้รับ
ส่วนท้าย Source: <path>#L<line> (หรือ #L<start>-L<end>) ต่อท้าย ในโหมด auto
ส่วนท้ายจะถูกเพิ่มเฉพาะสำหรับเซสชันการสนทนาโดยตรง ตั้งค่า
memory.citations = "off" เพื่อละเว้นส่วนท้าย ขณะที่ยังคงส่งพาธให้
เอเจนต์ภายใน
เมื่อใดควรใช้
เลือก QMD เมื่อคุณต้องการ:
- การจัดอันดับซ้ำเพื่อผลลัพธ์ที่มีคุณภาพสูงขึ้น
- ค้นหาเอกสารโครงการหรือบันทึกที่อยู่นอกพื้นที่ทำงาน
- เรียกคืนบทสนทนาจากเซสชันที่ผ่านมา
- การค้นหาภายในเครื่องอย่างสมบูรณ์โดยไม่ใช้คีย์ API
สำหรับการตั้งค่าที่เรียบง่ายกว่า เอนจินในตัว ทำงานได้ดี โดยไม่ต้องมีการพึ่งพาเพิ่มเติม
การแก้ไขปัญหา
ไม่พบ QMD? ตรวจสอบให้แน่ใจว่าไบนารีอยู่ใน PATH ของ Gateway หาก OpenClaw
ทำงานเป็นบริการ ให้สร้างลิงก์เชิงสัญลักษณ์:
sudo ln -s ~/.bun/bin/qmd /usr/local/bin/qmd
หาก qmd --version ทำงานในเชลล์ของคุณ แต่ OpenClaw ยังคงรายงาน
spawn qmd ENOENT กระบวนการ Gateway น่าจะมี PATH แตกต่างจาก
เชลล์แบบโต้ตอบของคุณ ให้ระบุไบนารีอย่างชัดเจน:
{ memory: { backend: "qmd", qmd: { command: "/absolute/path/to/qmd", }, },}ใช้ command -v qmd ในสภาพแวดล้อมที่ติดตั้ง QMD จากนั้นตรวจสอบอีกครั้ง
ด้วย openclaw memory status --deep
การค้นหาครั้งแรกช้ามาก? QMD ดาวน์โหลดโมเดล GGUF ในการใช้งานครั้งแรก เตรียมระบบล่วงหน้า
ด้วย qmd query "test" โดยใช้ไดเรกทอรี XDG เดียวกับที่ OpenClaw ใช้
มีกระบวนการย่อย QMD จำนวนมากระหว่างค้นหา? อัปเดต QMD หากทำได้ OpenClaw
ใช้กระบวนการเดียวสำหรับการค้นหาหลายคอลเลกชันจากแหล่งเดียวกัน เฉพาะเมื่อ
QMD ที่ติดตั้งประกาศว่ารองรับตัวกรอง -c หลายตัว มิฉะนั้นระบบจะ
คงการย้อนกลับแบบแยกคอลเลกชันรุ่นเก่าไว้เพื่อความถูกต้อง
QMD แบบ BM25 เท่านั้นยังคงพยายามบิลด์ llama.cpp? ตั้งค่า
memory.qmd.searchMode = "search" OpenClaw ถือว่าโหมดนั้นใช้
การค้นหาเชิงคำศัพท์เท่านั้น ข้ามการตรวจสอบสถานะเวกเตอร์ของ QMD และการบำรุงรักษาการฝังข้อมูล และ
ปล่อยให้การตรวจสอบความพร้อมเชิงความหมายเป็นหน้าที่ของการตั้งค่า vsearch หรือ query
การค้นหาหมดเวลา? เพิ่ม memory.qmd.limits.timeoutMs (ค่าเริ่มต้น:
4000ms) ตั้งค่าให้สูงขึ้น เช่น 120000 สำหรับฮาร์ดแวร์ที่ช้ากว่า
ผลลัพธ์ว่างในการสนทนากลุ่มหรือช่อง? นี่เป็นพฤติกรรมที่คาดไว้เมื่อใช้
memory.qmd.scope เริ่มต้น ซึ่งอนุญาตเฉพาะเซสชันโดยตรง เพิ่มกฎ
allow สำหรับประเภทการสนทนา group หรือ channel หากคุณต้องการผลลัพธ์ QMD
ในบริบทเหล่านั้น
การค้นหาหน่วยความจำรากกว้างเกินไปอย่างกะทันหัน? เริ่ม Gateway ใหม่หรือรอ
การปรับสถานะให้สอดคล้องกันครั้งถัดไปเมื่อเริ่มต้น OpenClaw จะสร้างคอลเลกชันที่จัดการอยู่ซึ่งล้าสมัย
ขึ้นใหม่ให้กลับเป็นรูปแบบมาตรฐาน MEMORY.md และ memory/ เมื่อ
ตรวจพบความขัดแย้งของชื่อเดียวกัน
ที่เก็บชั่วคราวที่มองเห็นได้จากพื้นที่ทำงานทำให้เกิด ENAMETOOLONG หรือการจัดทำดัชนีเสียหาย?
การไล่สำรวจของ QMD ใช้ตัวสแกน QMD พื้นฐานแทนกฎลิงก์เชิงสัญลักษณ์
ในตัวของ OpenClaw เก็บเช็กเอาต์ monorepo ชั่วคราวไว้ในไดเรกทอรีที่ซ่อนอยู่
เช่น .tmp/ หรือภายนอกราก QMD ที่จัดทำดัชนี จนกว่า QMD จะรองรับ
การไล่สำรวจที่ปลอดภัยจากวงวนหรือตัวควบคุมการยกเว้นอย่างชัดเจน
การกำหนดค่า
สำหรับพื้นผิวการกำหนดค่าทั้งหมด (memory.qmd.*) โหมดการค้นหา ช่วงเวลาการอัปเดต
กฎขอบเขต และตัวเลือกอื่นทั้งหมด โปรดดู
ข้อมูลอ้างอิงการกำหนดค่าหน่วยความจำ