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.

التمكين

json5
{  memory: {    backend: "qmd",  },}

ينشئ OpenClaw مجلدًا رئيسيًا مستقلاً لـ QMD ضمن ~/.openclaw/agents/<agentId>/qmd/ ويدير دورة حياة المحرك الجانبي تلقائيًا - إذ يتولى المجموعات والتحديثات وعمليات التضمين نيابةً عنك. ويفضّل الأشكال الحالية لمجموعات QMD واستعلامات MCP، لكنه يرجع إلى أعلام أنماط المجموعات البديلة وأسماء أدوات 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 في جميع المجموعات ذات المصدر نفسه باستخدام أمر واحد:

bash
qmd search "router notes" --json -n 10 -c memory-root-main -c memory-dir-main

يتجنب ذلك بدء عملية QMD فرعية لكل مجموعة ذاكرة دائمة. وتبقى مجموعات نصوص الجلسات في مجموعة مصدر مستقلة، لذا تظل عمليات البحث المختلطة بين memory وsessions تمنح أداة تنويع النتائج مدخلات من كلا المصدرين.

لا تقبل إصدارات QMD الأقدم سوى عامل تصفية واحد للمجموعات. وعندما يكتشف OpenClaw أحد هذه الإصدارات، يحتفظ بمسار التوافق ويبحث في كل مجموعة على حدة قبل دمج النتائج وإزالة التكرارات منها.

لفحص العقد المثبّت يدويًا، شغّل:

bash
qmd --help | grep -i collection

تشير مساعدة QMD الحالية إلى استهداف مجموعة واحدة أو أكثر. أما المساعدة الأقدم فعادةً ما تصف مجموعة واحدة.

تجاوزات النماذج

تمر متغيرات بيئة نماذج QMD دون تغيير من عملية Gateway، بحيث يمكنك ضبط QMD على المستوى العام دون إضافة إعداد جديد إلى 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"

بعد تغيير نموذج التضمين، أعد تشغيل التضمينات كي يتطابق الفهرس مع فضاء المتجهات الجديد.

فهرسة مسارات إضافية

وجّه QMD إلى أدلة إضافية لجعلها قابلة للبحث:

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

تظهر المقتطفات من المسارات الإضافية بالصيغة qmd/<collection>/<relative-path> في نتائج البحث. ويفهم memory_get هذه البادئة ويقرأ من جذر المجموعة الصحيح.

فهرسة نصوص الجلسات

فعّل فهرسة الجلسات لاستدعاء المحادثات السابقة. يحتاج QMD إلى مصدر الجلسات العام memorySearch وإلى مُصدّر نصوص QMD معًا:

json5
{  agents: {    defaults: {      memorySearch: {        experimental: { sessionMemory: true },        sources: ["memory", "sessions"],      },    },  },  memory: {    backend: "qmd",    qmd: {      sessions: { enabled: true },    },  },}

تُصدّر النصوص على هيئة أدوار منقّحة للمستخدم والمساعد إلى مجموعة QMD مخصصة ضمن ~/.openclaw/agents/<id>/qmd/sessions/. ولا يؤدي تعيين memorySearch.experimental.sessionMemory وحده إلى تصدير النصوص إلى QMD.

تظل نتائج الجلسات خاضعة للتصفية حسب tools.sessions.visibility. ولا تكشف الرؤية الافتراضية tree جلسات غير مرتبطة تابعة للوكيل نفسه. وإذا كان ينبغي أن تكون جلسة أرسلها Gateway قابلة للاستدعاء من جلسة رسالة مباشرة منفصلة، فعيّن tools.sessions.visibility: "agent" عمدًا.

نطاق البحث

افتراضيًا، لا تظهر نتائج بحث QMD إلا في الجلسات المباشرة (وليس في محادثات المجموعات أو القنوات). اضبط memory.qmd.scope لتغيير ذلك:

json5
{  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 مختلف عن صدفتك التفاعلية. ثبّت مسار الملف التنفيذي صراحةً:

json5
{  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.*) وأوضاع البحث وفواصل التحديث وقواعد النطاق وجميع الخيارات الأخرى، راجع مرجع إعداد الذاكرة.

ذو صلة

Was this useful?
On this page

On this page