الذاكرة والتوليد المعزّز بالاسترجاع (RAG)
خريطة دقيقة وموثّقة بالمراجع المصدرية لأنظمة الذاكرة الفرعية في كاظمة — بما في ذلك ملاحظات الحالة الصادقة حول ما هو موصول فعليًا مقابل ما تصفه الوثائق القديمة.
1. أنظمة الذاكرة الفرعية الثلاثة (اقرأ هذا أولًا)
Section titled “1. أنظمة الذاكرة الفرعية الثلاثة (اقرأ هذا أولًا)”يحتوي الإطار كاظمة على ثلاثة أنظمة ذاكرة فرعية متمايزة وغير متكاملة. تاريخيًا كانت الوثائق تدمجها في «خط أنابيب من أربع طبقات». يفصل هذا القسم بينها بصدق:
| النظام الفرعي | الخلفية (Backing) | التضمين | هل يستخدمه وكيل الدردشة؟ | الكود |
|---|---|---|---|---|
| أ. VectorMemory (أدوات RAG) | chromadb.PersistentClient | all-MiniLM-L6-v2 (384-أبعاد) | فقط عندما يستدعي نموذج اللغة memory_search / memory_store | kazma_core/memory/vector_store.py |
ب. SQLiteMemoryBackend (وكيل self.memory) | SQLite + FTS5 (porter unicode61) | لا يوجد | لا يُستعلم أثناء استرجاع الدردشة | kazma_memory/search_backend.py |
| ج. UnifiedMemoryAdapter (الأربع طبقات) | ChromaDB + NetworkX + FTS5 + sqlite-vec، ممزوجة عبر RRF | all-MiniLM-L6-v2 | لا — فقط self_improvement.py + phonebook.py | kazma_core/swarm/memory/adapter.py |
الخلاصة: في مسار الدردشة الافتراضي، الاسترجاع الوحيد للذاكرة الذي يحدث هو استعلام ChromaDB واحد خلف أداة اختيارية يستدعيها نموذج اللغة. لا يوجد حقن تلقائي للسياق المسترجَع إلى الموجّه (prompt)، ولا توجد عملية دمج من المدى القصير إلى الدائم.
2. النظام الفرعي أ — VectorMemory (أدوات RAG)
Section titled “2. النظام الفرعي أ — VectorMemory (أدوات RAG)”هذا هو ما تستخدمه أدوات memory_search / memory_store فعليًا.
2.1 التهيئة
Section titled “2.1 التهيئة”kazma-ui/kazma_ui/app.py:444-462:
vector_memory = VectorMemory( path=KAZMA_VECTOR_PATH, # default ~/.kazma/vector_memory collection_name=KAZMA_VECTOR_COLLECTION, # default "agent_memory" model_name=KAZMA_VECTOR_MODEL, # default "all-MiniLM-L6-v2")set_vector_memory(vector_memory)VectorMemory (memory/vector_store.py):
- التخزين:
chromadb.PersistentClient(path=...)(السطر 57). - التضمين:
SentenceTransformerEmbeddingFunctionمرتبط عند إنشاء المجموعة (الأسطر 58-63) — جميع عمليات التضمين تعمل محليًا، دون أي استدعاءات لواجهات برمجية خارجية (سطر وثائق الوحدة 5). - اسم المجموعة الافتراضي:
agent_memory(السطر 42). - الأبعاد: 384 (
all-MiniLM-L6-v2). ملاحظة: القيمةstorage.vector_dim: 1536فيkazma.yamlلا تتطابق ولا يتم فرضها هنا.
2.2 الاسترجاع (قائم على الأدوات، وليس تلقائيًا)
Section titled “2.2 الاسترجاع (قائم على الأدوات، وليس تلقائيًا)”يحدث الاسترجاع فقط عندما يختار نموذج اللغة استدعاء memory_search (agent/tool_registry.py:591-605):
async def memory_search(query: str, limit: int = 5) -> str: mem = get_vector_memory() results = mem.search(query=query, n_results=limit) return json.dumps(results, ...)الدالة VectorMemory.search() (vector_store.py:136-180) عبارة عن استدعاء ChromaDB واحد:
self._collection.query(query_texts=[query], n_results=..., where=tenant_filter)تعود النتيجة إلى نموذج اللغة كملاحظة أداة عادية في حلقة ReAct. لا توجد خطوة FTS، ولا إعادة ترتيب، ولا حقن تلقائي.
2.3 التخزين (قائم على الأدوات)
Section titled “2.3 التخزين (قائم على الأدوات)”يحدث التخزين فقط عندما يستدعي نموذج اللغة memory_store (tool_registry.py:607-624): mem.add(text, metadata) ← VectorMemory.add() ← self._collection.add(documents, metas, ids).
لا توجد استراتيجية تجزئة (chunking). كل استدعاء
add()يمثّل مستندًا واحدًا. عمليات البحث عنchunk، وtext_splitter، وchunk_size، وoverlapلم تجد أي تطبيق لتقسيم المستندات.
2.4 النسخة الوحيدة (singleton) المشتركة للتضمين
Section titled “2.4 النسخة الوحيدة (singleton) المشتركة للتضمين”يعرّض swarm/memory/vector.py:27-46 الدالة get_encoder() التي تحمّل SentenceTransformer("all-MiniLM-L6-v2") مرة واحدة. تعيد الطبقة 4 (sqlite_vec.py:141) استخدام هذه النسخة الوحيدة.
3. النظام الفرعي ب — SQLiteMemoryBackend (FTS5)
Section titled “3. النظام الفرعي ب — SQLiteMemoryBackend (FTS5)”kazma_memory/search_backend.py — خلفية هجينة FTS5 + متجهات (مقصودة).
3.1 المخطط (Schema)
Section titled “3.1 المخطط (Schema)”- قاعدة البيانات:
kazma-data/memory.db(السطر 32)، توجيهات PRAGMAjournal_mode=WAL،synchronous=NORMAL(الأسطر 52-53). - الجدول
memories(الأسطر 63-75):id, content, content_arabic, metadata, timestamp, source, relevance, embedding BLOB, tenant_id(يُهاجَر المستأجر تلقائيًا، الأسطر 78-81). - جدول FTS5 المسمى
memories_fts(الأسطر 86-113) يُبقى متزامنًا عبر محفّزاتAFTER INSERT/DELETE/UPDATE، بأعمدةmemory_id, content, content_arabic.
3.2 البحث
Section titled “3.2 البحث”الدالة search() (الأسطر 170-320) تُشغّل FTS5 عبر MATCH + bm25(memories_fts) أولًا، ثم اختياريًا بحثًا متجهيًا إذا كان semantic_search=True وتوفّر embedding. الدرجة المجمّعة: -bm25*0.7 + relevance*0.3 (الأسطر 310-318).
3.3 ملاحظة الحالة الصادقة: هذه الخلفية لا تُستعلم في الدردشة
Section titled “3.3 ملاحظة الحالة الصادقة: هذه الخلفية لا تُستعلم في الدردشة”- موصولة كـ
self.memoryالخاصة بالوكيل (agent_runner.py:220). - لا يستدعي أحدٌ في مسار الدردشة الدالة
search()أثناء الاسترجاع. - لذا هي فعليًا خاملة للاسترجاع. قد تُكتب فيها بيانات عبر مسارات أخرى، لكنها لا تغذّي حلقة الدردشة.
4. النظام الفرعي ج — المحوّل UnifiedMemoryAdapter رباعي الطبقات
Section titled “4. النظام الفرعي ج — المحوّل UnifiedMemoryAdapter رباعي الطبقات”«ذاكرة الأربع طبقات» المُشار إليها في README.md وswarm/memory/__init__.py. الطبقات الأربع كلها موجودة ككود تحت kazma_core/swarm/memory/:
| الطبقة | الملف | الخلفية (Backing) |
|---|---|---|
| 1. المتجهات | vector.py | ChromaDB (PersistentClient أو في الذاكرة)؛ المجموعة الافتراضية kazma_global. |
| 2. الرسم البياني | graph.py | networkx.MultiDiGraph، يُحفظ بصيغة JSON في kazma-data/knowledge_graph.json. يتتبّع تبعيات الكود، وسلالة العمّال، والمهمة→المُخرجات، والتسليمات. |
| 3. المعجمية | fts5.py | غلاف FTS5LexicalStore. |
| 4. sqlite-vec | sqlite_vec.py | جداول vec0 الافتراضية (FLOAT[384])، WHERE embedding MATCH ? ORDER BY distance. قاعدة البيانات في kazma-data/vector.db. |
4.1 المزج عبر RRF
Section titled “4.1 المزج عبر RRF”الدالة UnifiedMemoryAdapter.query() (adapter.py:78) تتوزّع على الطبقات الأربع بالتوازي (asyncio.gather، السطر 116) وتدمجها عبر دمج الرتبة العكسية (Reciprocal Rank Fusion)، حيث _RRF_K = 60 (السطر 26): مساهمة الدرجة 1.0 / (_RRF_K + rank) (السطر 237). تُزال التكرارات بالاعتماد على uid.
4.2 أين يُستخدم فعليًا
Section titled “4.2 أين يُستخدم فعليًا”مستدعِيان غير اختباريَّين فقط:
kazma_core/skills/self_improvement.py:131,194(get_adapter())kazma_core/swarm/phonebook.py:69(get_adapter()) — يحقن سياق «PREVIOUS_SUCCESSFUL_STRATEGIES» قبل الإرسال.
لا يُستخدم من قبل agent_runner.py، أو مسار بوابة الدردشة، أو tool_registry.py، أو majlis.py. وكيل الدردشة الافتراضي لا يلمسه إطلاقًا.
5. المُجزِّئ العربي
Section titled “5. المُجزِّئ العربي”kazma-memory/kazma_memory/arabic_tokenizer.py — يغذّي عمود FTS5 المسمى content_arabic.
5.1 خط أنابيب التطبيع (normalize، الأسطر 132-165)
Section titled “5.1 خط أنابيب التطبيع (normalize، الأسطر 132-165)”تُطبَّق بالترتيب التالي:
- إزالة التشكيل (
_remove_diacritics، الأسطر 193-204): التعبير النمطي[\u064B-\u065F\u0670](الحركات + ألف الخنجرية). - تطبيع الألف (
_normalize_alef، الأسطر 206-218):أ،إ،آ←ا. - تاء مربوطة ← هاء:
ة←ه(السطر 148). - تطبيع الياء (
_normalize_yeh، الأسطر 220-232):ئ،ؤ،إي،ى←ي. - واو/ياء الهمزة:
ؤ←و،ئ←ي(ملاحظة: هذه تتداخل مع القاعدة 4 — تعارف ثانوي معروف). - إزالة التطويل/الكشيدة:
text.replace("ـ", "")(السطر 160). موجودة. - طيّ المسافات البيضاء.
5.2 كلمات الإيقاف (الأسطر 35-102)
Section titled “5.2 كلمات الإيقاف (الأسطر 35-102)”نحو 40 مدخلًا مكتوبًا برمجيًا: أدوات (في، من، على)، وضمائر (أنا/انا، هو، هي)، وأدوات ربط (و، أو/او، ثم)، إضافة إلى مصطلحات اللهجة الكويتية (يلا، شلون، عشان، مو، ليه، ماكو، فد). أُضيفت تكرارات مطبّعة (مجرّدة من الهمزة) ضمن «إصلاح BUG-023».
5.3 المُجدِّع (Stemmer) (_init_stemmer، الأسطر 104-130)
Section titled “5.3 المُجدِّع (Stemmer) (_init_stemmer، الأسطر 104-130)”تجريد اللواحق والبادئات قائم على التعبيرات النمطية (اللواحق: ات، ون، ين، ة، ان، نا؛ البادئات: ال، بـ، كـ). تصِف وثائق الدالة عملها بأنه «Basic stemming» — أي تجذيع أساسي وليس مُؤَلِّفًا كاملًا للقاموس (lemmatizer).
5.4 الأصناف
Section titled “5.4 الأصناف”ArabicTokenizer.tokenize()← تُعيد سلسلة نصية (الأسطر 167-191).ArabicTantivyTokenizer.tokenize()← تُعيد قائمة (الأسطر 243-266)، مع تصفيةlen(word) > 1.
6. تكثيف السياق
Section titled “6. تكثيف السياق”عندما يطول المحادثة نحو حدود نافذة السياق، يقوم ContextAuthority بتلخيصها. هذه هي الوحيدة من بين عمليات إدارة السياق التلقائية التي تعمل في مسار الدردشة.
6.1 المكوّنات
Section titled “6.1 المكوّنات”| المكوّن | الملف | الدور |
|---|---|---|
CompactionEngine | compaction.py (287 سطرًا) | المُلخِّص. |
ContextAuthority | authority.py (94 سطرًا) | الحارس الذي يقرّر متى يُكثَّف. |
TokenCounter | token_counter.py | عدّ الرموز + العتبة. |
6.2 الاستراتيجية (compaction.py:63 compact)
Section titled “6.2 الاستراتيجية (compaction.py:63 compact)”- حفظ نقطة تفتيش (الأسطر 87-92) — مقصود؛ انظر ملاحظة الحالة.
- تلخيص بنموذج اللغة (السطر 95) — يستخدم
_SUMMARY_SYSTEM(الأسطر 20-30): الحفاظ على هدف المهمة، والقرارات الرئيسية، ونتائج الأدوات، وقيود المستخدم؛ بسقف 2000 رمز، وقصّ محرفي عند 8000 (السطر 160). - استرجاع أعلى 5 ذكريات (السطر 98) — مقصود؛ انظر ملاحظة الحالة.
- بناء رسالة نظام جديدة تحتوي الملخص + الذكريات (
_build_compacted_system، الأسطر 231-259). - إرجاع حالة جديدة مع
messages = [رسالة نظام واحدة]،context_tokens = 0.
6.3 العتبة
Section titled “6.3 العتبة”قيمة مكتوبة برمجيًا int(window * 0.8) (token_counter.py:23). مع القيمة الافتراضية memory.max_context_tokens: 128000، يُطلَق التكثيف عند 102,400 رمز. هذا مقصودٌ ألا يكون قابلًا للضبط من قِبل المستخدم (authority.py:5، compaction.md:178)؛ الإعداد القابل للضبط الوحيد هو النافذة نفسها.
6.4 نقطة الإطلاق
Section titled “6.4 نقطة الإطلاق”داخل عقدة المشرف (graph_builder.py:167): ينفّذ compacted_state = await authority.check_and_enforce(state_for_check) قبل استدعاء نموذج اللغة. إذا حصل تكثيف، تعود السيطرة إلى SUPERVISOR لإعادة التشغيل (السطر 174).
6.5 الاحتياطي الاستدلالي (Heuristic fallback)
Section titled “6.5 الاحتياطي الاستدلالي (Heuristic fallback)”إن لم يتوفّر نموذج لغة، تبني الدالة _summarize_heuristic (السطر 168) ملخصًا من عدد الرسائل + آخر رسالة للمستخدم (500 محرف) + آخر 5 مُخرجات أدوات (200 محرف لكل منها).
6.6 عدّ الرموز
Section titled “6.6 عدّ الرموز”يستخدم TokenCounter مكتبة tiktoken إن كانت مثبّتة، وإلّا يلجأ إلى تقدير محارف/4 (token_counter.py:44-46). مكتبة tiktoken ليست تبعية مُعلَنة — التقدير الاستدلالي هو الافتراضي ما لم تُثبّتها بنفسك.
7. ملاحظات الحالة الصادقة (اقرأها قبل الاعتماد على ميزات الذاكرة)
Section titled “7. ملاحظات الحالة الصادقة (اقرأها قبل الاعتماد على ميزات الذاكرة)”هذه هي الفجوات التي كشفها التدقيق. وُثّقت هنا كي لا يعتمد المشغّلون على سلوك غير مُفعّل فعلًا.
-
دمج المدى القصير→الدائم غير موجود. لم يُعثَر على أيٍّ من
consolidat*، أوpromote، أوpersist.*memory، أو منطق ترقية خلفي. تُكتَب الذاكرة الدائمة فقط عندما يستدعي نموذج اللغة صراحةًmemory_store. التكثيف لا يكتب الرسائل المُهمَلة فيVectorMemory— هو فقط يحفظ نقطة تفتيش (مقصود) ويُلخِّص. -
استرجاع الذكريات وحفظ نقطة التفتيش أثناء التكثيف عمليتان فارغتان في التوصيل الافتراضي. يستدعي
agent_runner.py:162-166الدالةcreate_authority(...)دون تمريرmemory_storeأوcheckpoint_manager(كلاهما افتراضيNone). النتائج:- تُعيد
retrieve_memories()القائمة[](compaction.py:220-221) — خطوة «استرجاع أعلى 5 ذكريات» خاملة. - تُتجاوز خطوة «حفظ نقطة تفتيش قبل التكثيف».
- الذي يعمل فعلًا هو تلخيص نموذج اللغة فقط. الوثائق الأقدم (
compaction.md، README) التي تصف تكثيفًا غنيًّا بالذاكرة ومُزوَّدًا بنقاط تفتيش تصف التصميم المقصود، لا زمن التشغيل الفعلي.
- تُعيد
-
المحوّل رباعي الطبقات غير موصول في الدردشة. هو موجود ويعمل، لكنه لا يُ reachable إلا من
self_improvement.pyوphonebook.py. -
اكتشاف sqlite-vec في
search_backend.pyعملية فارغة. تشغّل الأسطر 55-60 الاستعلامSELECT sqlite_version()(ينجح دائمًا) ولا تستدعيload_extensionأبدًا، لذا فالقيمة_vec_availableغير موثوقة. -
يستخدم
search_backend.pyالدالة_vector_searchبصيغةdistance(embedding, ?)(الأسطر 343، 354)، وهي ليست دالة sqlite-vec صالحة (يُستعلم عن جداول vec0 عبرMATCH/k، كما هو منفّذ بشكل صحيح فيswarm/memory/sqlite_vec.py:215-217). هذا المسار سيُطلق استثناءً عند التشغيل ويُعيد[]من كتلةexcept. عمليًا لا يُبلَغ إليه لأن المستدعين لا يمرّرونsemantic_search=Trueمعembedding. -
sqlite-vecليست تبعية مُعلَنة. تظهر فيuv.lockفقط كتبعية انتقالية لـlanggraph-checkpoint-sqlite. إنها متاحة عند التشغيل كأثر جانبي، لا لأن كاظمة تطلبها. -
ثلاثة أنظمة ذاكرة فرعية متباينة تتعايش دون تكامل: (أ) أدوات RAG عبر ChromaDB، (ب)
self.memoryعبر FTS5 (خامل للاسترجاع)، (ج) محوّل RRF رباعي الطبقات (للتطوير الذاتي/دفتر الهاتف فقط). -
خط الأنابيب الموثّق «embed → vector → FTS → re-rank → inject» لا يوجد كتدفّق متّصل. الاسترجاع هو استعلام ChromaDB واحد خلف أداة اختيارية يستدعيها نموذج اللغة.
ملاحظات تدقيق الوثائق
Section titled “ملاحظات تدقيق الوثائق”- تصحيح نسبة الفرضية: ادعاء «ذاكرة الأربع طبقات» موجود في
README.md:313وswarm/memory/__init__.py:1، وليس فيAGENTS.md. - فجوة التوصيل في
agent_runner.py:162-166هي أهم نتيجة واحدة لأي من يخطط للاعتماد على RAG أثناء المحادثات الطويلة. حتى تُمرَّرmemory_store/checkpoint_managerإلىcreate_authority()، يبقى التكثيف تلخيصًا فقط. - عدم التطابق بين
storage.vector_dim: 1536والأبعاد الفعلية 384 موثّق في الإعدادات (Configuration). - عدم وجود تجزئة يعني أن المستندات الطويلة المخزَّنة عبر
memory_storeتُضمَّن كاملة — يُستحسن التقسيم المسبق في مهارتك/أداتك إن احتجت استرجاعًا أدقّ.