---
read_when:
    - คุณต้องการตั้งค่า QMD เป็นแบ็กเอนด์หน่วยความจำของคุณ
    - คุณต้องการคุณสมบัติหน่วยความจำขั้นสูง เช่น การจัดอันดับใหม่หรือเส้นทางที่ทำดัชนีเพิ่มเติม
summary: ไซด์คาร์การค้นหาแบบเน้นภายในเครื่องเป็นหลักพร้อม BM25, เวกเตอร์, การจัดอันดับใหม่ และการขยายคำค้น
title: เอนจินหน่วยความจำ QMD
x-i18n:
    generated_at: "2026-04-30T09:46:44Z"
    model: gpt-5.5
    provider: openai
    source_hash: 71980e3701f9a5ddcfbbfa41497ef51d2aae2993b2326591124cc0a87f9a849f
    source_path: concepts/memory-qmd.md
    workflow: 16
---

[QMD](https://github.com/tobi/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

### เปิดใช้งาน

```json5
{
  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 โดยตรงอีกครั้ง

<Info>
การค้นหาครั้งแรกอาจช้า -- QMD ดาวน์โหลดโมเดล GGUF อัตโนมัติ (~2 GB) สำหรับ
การจัดอันดับซ้ำและการขยายคำค้นในการรัน `qmd query` ครั้งแรก
</Info>

## ประสิทธิภาพและความเข้ากันได้ของการค้นหา

OpenClaw รักษาพาธการค้นหา QMD ให้เข้ากันได้กับทั้งการติดตั้ง QMD ปัจจุบันและรุ่นเก่า

เมื่อเริ่มต้น OpenClaw จะตรวจข้อความช่วยเหลือของ QMD ที่ติดตั้งไว้หนึ่งครั้งต่อ manager หาก
ไบนารีประกาศว่ารองรับตัวกรองหลายคอลเลกชัน OpenClaw จะค้นหาคอลเลกชันแหล่งเดียวกันทั้งหมด
ด้วยคำสั่งเดียว:

```bash
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 ที่ติดตั้งไว้ด้วยตนเอง ให้รัน:

```bash
qmd --help | grep -i collection
```

ข้อความช่วยเหลือ QMD ปัจจุบันระบุว่าตัวกรองคอลเลกชันสามารถกำหนดเป้าหมายได้หนึ่งหรือหลายคอลเลกชัน
ข้อความช่วยเหลือรุ่นเก่ามักอธิบายคอลเลกชันเดียว

## การ override โมเดล

ตัวแปรสภาพแวดล้อมของโมเดล QMD จะถูกส่งผ่านแบบไม่เปลี่ยนแปลงจากโปรเซส Gateway
ดังนั้นคุณสามารถปรับ QMD แบบ global ได้โดยไม่ต้องเพิ่ม config ใหม่ของ OpenClaw:

```bash
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 ไปยังไดเรกทอรีเพิ่มเติมเพื่อให้ค้นหาได้:

```json5
{
  memory: {
    backend: "qmd",
    qmd: {
      paths: [{ name: "docs", path: "~/notes", pattern: "**/*.md" }],
    },
  },
}
```

snippet จากพาธเพิ่มเติมจะปรากฏเป็น `qmd/<collection>/<relative-path>` ใน
ผลลัพธ์การค้นหา `memory_get` เข้าใจ prefix นี้และอ่านจาก root ของคอลเลกชัน
ที่ถูกต้อง

## การทำดัชนีทรานสคริปต์เซสชัน

เปิดใช้งานการทำดัชนีเซสชันเพื่อเรียกคืนบทสนทนาก่อนหน้า:

```json5
{
  memory: {
    backend: "qmd",
    qmd: {
      sessions: { enabled: true },
    },
  },
}
```

ทรานสคริปต์จะถูกส่งออกเป็นรอบ User/Assistant ที่ sanitize แล้วไปยังคอลเลกชัน QMD
เฉพาะภายใต้ `~/.openclaw/agents/<id>/qmd/sessions/`

## ขอบเขตการค้นหา

โดยค่าเริ่มต้น ผลลัพธ์การค้นหา QMD จะแสดงในเซสชันแบบ direct และ channel
(ไม่ใช่ groups) กำหนดค่า `memory.qmd.scope` เพื่อเปลี่ยนสิ่งนี้:

```json5
{
  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

สำหรับการตั้งค่าที่เรียบง่ายกว่า [เอนจินในตัว](/th/concepts/memory-builtin) ทำงานได้ดี
โดยไม่มี 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 ไบนารีอย่างชัดเจน:

```json5
{
  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 และตัวปรับอื่นทั้งหมด ดูที่
[เอกสารอ้างอิงการกำหนดค่าหน่วยความจำ](/th/reference/memory-config)

## ที่เกี่ยวข้อง

- [ภาพรวมหน่วยความจำ](/th/concepts/memory)
- [เอนจินหน่วยความจำในตัว](/th/concepts/memory-builtin)
- [หน่วยความจำ Honcho](/th/concepts/memory-honcho)
