نظرة عامة
يوفر CrewAI نظام ذاكرة موحد — فئةMemory واحدة تستبدل أنواع الذاكرة المنفصلة (قصيرة المدى، طويلة المدى، ذاكرة الكيانات، والخارجية) بواجهة برمجة تطبيقات ذكية واحدة. تستخدم الذاكرة LLM لتحليل المحتوى عند الحفظ (استنتاج النطاق والفئات والأهمية) وتدعم الاسترجاع متعدد العمق مع تسجيل مركب يمزج بين التشابه الدلالي والحداثة والأهمية.
يمكنك استخدام الذاكرة بأربع طرق: مستقلة (سكربتات، دفاتر ملاحظات)، مع فرق Crew، مع Agents، أو داخل التدفقات.
البدء السريع
أربع طرق لاستخدام الذاكرة
مستقلة
استخدم الذاكرة في السكربتات ودفاتر الملاحظات وأدوات سطر الأوامر أو كقاعدة معرفة مستقلة — لا حاجة لوكلاء أو فرق Crew.مع فرق Crew
مرّرmemory=True للإعدادات الافتراضية، أو مرّر مثيل Memory مُعدّ للسلوك المخصص.
memory=True، ينشئ الفريق مثيل Memory() افتراضيًا ويمرر إعداد embedder الخاص بالفريق تلقائيًا. يشترك جميع الوكلاء في الفريق في ذاكرة الفريق ما لم يكن لدى الوكيل ذاكرته الخاصة.
بعد كل مهمة، يستخرج الفريق تلقائيًا حقائق منفصلة من مخرجات المهمة ويخزّنها. قبل كل مهمة، يسترجع الوكيل السياق ذا الصلة من الذاكرة ويحقنه في موجّه المهمة.
مع Agents
يمكن للوكلاء استخدام ذاكرة الفريق المشتركة (افتراضيًا) أو تلقي عرض محدد النطاق للسياق الخاص.مع التدفقات
كل تدفق يحتوي على ذاكرة مدمجة. استخدمself.remember() و self.recall() و self.extract_memories() داخل أي دالة تدفق.
النطاقات الهرمية
ما هي النطاقات
يتم تنظيم الذكريات في شجرة هرمية من النطاقات، مشابهة لنظام الملفات. كل نطاق هو مسار مثل/ أو /project/alpha أو /agent/researcher/findings.
كيف يعمل استنتاج النطاق
عند استدعاءremember() دون تحديد نطاق، يحلل LLM المحتوى وشجرة النطاقات الحالية، ثم يقترح أفضل موضع. إذا لم يكن هناك نطاق حالي مناسب، ينشئ واحدًا جديدًا. بمرور الوقت، تنمو شجرة النطاقات عضويًا من المحتوى نفسه — لا تحتاج إلى تصميم مخطط مسبقًا.
تصوير شجرة النطاقات
MemoryScope: عروض الأشجار الفرعية
يقيّدMemoryScope جميع العمليات على فرع من الشجرة. يمكن للوكيل أو الكود الذي يستخدمه الرؤية والكتابة فقط ضمن تلك الشجرة الفرعية.
أفضل الممارسات لتصميم النطاقات
-
ابدأ بشكل مسطح، ودع LLM ينظّم. لا تبالغ في هندسة تسلسل النطاقات مسبقًا. ابدأ بـ
memory.remember(content)ودع استنتاج النطاق في LLM ينشئ الهيكل مع تراكم المحتوى. -
استخدم أنماط
/{entity_type}/{identifier}. تنشأ التسلسلات الطبيعية من أنماط مثل/project/alphaو/agent/researcherو/company/engineeringو/customer/acme-corp. -
حدد النطاق حسب الاهتمام، وليس حسب نوع البيانات. استخدم
/project/alpha/decisionsبدلاً من/decisions/project/alpha. هذا يبقي المحتوى ذا الصلة معًا. -
حافظ على العمق ضحلًا (2-3 مستويات). النطاقات المتداخلة بعمق تصبح متفرقة جدًا.
/project/alpha/architectureجيد؛/project/alpha/architecture/decisions/databases/postgresqlعميق جدًا. -
استخدم النطاقات الصريحة عندما تعرف، ودع LLM يستنتج عندما لا تعرف. إذا كنت تخزّن قرار مشروع معروف، مرّر
scope="/project/alpha/decisions". إذا كنت تخزّن مخرجات وكيل حرة الشكل، اترك النطاق ودع LLM يحدده.
أمثلة حالات الاستخدام
فريق متعدد المشاريع:شرائح الذاكرة
ما هي الشرائح
MemorySlice هو عرض عبر نطاقات متعددة، ربما متباعدة. على عكس النطاق (الذي يقيّد على شجرة فرعية واحدة)، تتيح لك الشريحة الاسترجاع من عدة فروع في وقت واحد.
متى تستخدم الشرائح مقابل النطاقات
- النطاق: استخدمه عندما يجب تقييد وكيل أو كتلة كود على شجرة فرعية واحدة. مثال: وكيل يرى فقط
/agent/researcher. - الشريحة: استخدمها عندما تحتاج إلى دمج السياق من عدة فروع. مثال: وكيل يقرأ من نطاقه الخاص بالإضافة إلى معرفة الشركة المشتركة.
شرائح القراءة فقط
النمط الأكثر شيوعًا: منح وكيل إمكانية القراءة من فروع متعددة دون السماح له بالكتابة في المناطق المشتركة.شرائح القراءة والكتابة
عند تعطيل القراءة فقط، يمكنك الكتابة في أي من النطاقات المضمّنة، لكن يجب تحديد النطاق صراحة.التسجيل المركب
يتم ترتيب نتائج الاسترجاع بواسطة مزيج مرجّح من ثلاث إشارات:- similarity =
1 / (1 + distance)من فهرس المتجهات (0 إلى 1) - decay =
0.5^(age_days / half_life_days)— اضمحلال أُسي (1.0 لليوم، 0.5 عند نصف العمر) - importance = درجة أهمية السجل (0 إلى 1)، يتم تعيينها وقت الترميز
Memory:
MemoryMatch قائمة match_reasons حتى تتمكن من رؤية سبب ترتيب نتيجة معينة في موضعها (مثل ["semantic", "recency", "importance"]).
طبقة تحليل LLM
تستخدم الذاكرة LLM بثلاث طرق:- عند الحفظ — عندما تحذف النطاق أو الفئات أو الأهمية، يحلل LLM المحتوى ويقترح النطاق والفئات والأهمية والبيانات الوصفية (الكيانات والتواريخ والموضوعات).
- عند الاسترجاع — للاسترجاع العميق/التلقائي، يحلل LLM الاستعلام (الكلمات المفتاحية، تلميحات الوقت، النطاقات المقترحة، التعقيد) لتوجيه الاسترجاع.
- استخراج الذكريات —
extract_memories(content)يقسم النص الخام (مثل مخرجات المهمة) إلى عبارات ذاكرة منفصلة. يستخدم الوكلاء هذا قبل استدعاءremember()على كل عبارة حتى يتم تخزين حقائق ذرية بدلاً من كتلة كبيرة واحدة.
توحيد الذاكرة
عند حفظ محتوى جديد، يتحقق خط أنابيب الترميز تلقائيًا من وجود سجلات مماثلة في التخزين. إذا كان التشابه أعلى منconsolidation_threshold (الافتراضي 0.85)، يقرر LLM ما يجب فعله:
- keep — السجل الحالي لا يزال دقيقًا وغير مكرر.
- update — يجب تحديث السجل الحالي بمعلومات جديدة (يوفر LLM المحتوى المدمج).
- delete — السجل الحالي قديم أو تم استبداله أو تناقضه.
- insert_new — ما إذا كان يجب إدراج المحتوى الجديد أيضًا كسجل منفصل.
إزالة التكرار داخل الدفعة
عند استخدامremember_many()، تتم مقارنة العناصر داخل نفس الدفعة مع بعضها البعض قبل الوصول إلى التخزين. إذا كان تشابه جيب التمام >= batch_dedup_threshold (الافتراضي 0.98)، يتم إسقاط العنصر الأحدث بصمت. هذا يلتقط النسخ المكررة الدقيقة أو شبه الدقيقة داخل دفعة واحدة دون أي استدعاءات LLM (رياضيات متجهات خالصة).
الحفظ غير الحاجب
remember_many() غير حاجب — يقدم خط أنابيب الترميز إلى خيط خلفي ويعود فورًا. هذا يعني أن الوكيل يمكنه المتابعة إلى المهمة التالية بينما يتم حفظ الذكريات.
حاجز القراءة
كل استدعاءrecall() يستدعي تلقائيًا drain_writes() قبل البحث، مما يضمن أن الاستعلام يرى دائمًا أحدث السجلات المستمرة. هذا شفاف — لا تحتاج أبدًا إلى التفكير فيه.
إيقاف الفريق
عند انتهاء الفريق، يستنزفkickoff() جميع عمليات حفظ الذاكرة المعلقة في كتلة finally الخاصة به، لذا لا تُفقد أي عمليات حفظ حتى لو اكتمل الفريق بينما عمليات الحفظ الخلفية قيد التنفيذ.
الاستخدام المستقل
للسكربتات أو دفاتر الملاحظات حيث لا توجد دورة حياة فريق، استدعِdrain_writes() أو close() صراحة:
المصدر والخصوصية
يمكن لكل سجل ذاكرة أن يحمل علامةsource لتتبع المصدر وعلامة private للتحكم في الوصول.
تتبع المصدر
يحدد معاملsource من أين جاءت الذاكرة:
الذكريات الخاصة
الذكريات الخاصة مرئية فقط للاسترجاع عندما يتطابقsource:
RecallFlow (الاسترجاع العميق)
يدعمrecall() عمقين:
depth="shallow"— بحث متجهي مباشر مع تسجيل مركب. سريع (~200 مللي ثانية)، بدون استدعاءات LLM.depth="deep"(افتراضي) — يشغل RecallFlow متعدد الخطوات: تحليل الاستعلام، اختيار النطاق، بحث متجهي متوازٍ، توجيه قائم على الثقة، واستكشاف متكرر اختياري عندما تكون الثقة منخفضة.
query_analysis_threshold (الافتراضي 200 حرف) تتخطى تحليل LLM للاستعلام بالكامل، حتى في الوضع العميق. الاستعلامات القصيرة مثل “ما قاعدة البيانات التي نستخدمها؟” هي بالفعل عبارات بحث جيدة — تحليل LLM يضيف قيمة قليلة. هذا يوفر ~1-3 ثوانٍ لكل استرجاع للاستعلامات القصيرة النموذجية. فقط الاستعلامات الأطول (مثل أوصاف المهام الكاملة) تمر عبر تقطير LLM إلى استعلامات فرعية مستهدفة.
إعداد المُضمِّن
تحتاج الذاكرة إلى نموذج تضمين لتحويل النص إلى متجهات للبحث الدلالي. يمكنك إعداده بثلاث طرق.التمرير إلى Memory مباشرة
عبر إعداد مُضمِّن Crew
عند استخدامmemory=True، يتم تمرير إعداد embedder الخاص بالفريق:
أمثلة المزودين
OpenAI (افتراضي)
OpenAI (افتراضي)
Ollama (محلي، خاص)
Ollama (محلي، خاص)
Azure OpenAI
Azure OpenAI
Google AI
Google AI
Google Vertex AI
Google Vertex AI
Cohere
Cohere
VoyageAI
VoyageAI
AWS Bedrock
AWS Bedrock
Hugging Face
Hugging Face
Jina
Jina
IBM WatsonX
IBM WatsonX
مُضمِّن مخصص
مُضمِّن مخصص
مرجع المزودين
| المزود | المفتاح | النموذج النموذجي | ملاحظات |
|---|---|---|---|
| OpenAI | openai | text-embedding-3-small | افتراضي. عيّن OPENAI_API_KEY. |
| Ollama | ollama | mxbai-embed-large | محلي، لا حاجة لمفتاح API. |
| Azure OpenAI | azure | text-embedding-ada-002 | يتطلب deployment_id. |
| Google AI | google-generativeai | gemini-embedding-001 | عيّن GOOGLE_API_KEY. |
| Google Vertex | google-vertex | gemini-embedding-001 | يتطلب project_id. |
| Cohere | cohere | embed-english-v3.0 | دعم قوي متعدد اللغات. |
| VoyageAI | voyageai | voyage-3 | محسّن للاسترجاع. |
| AWS Bedrock | amazon-bedrock | amazon.titan-embed-text-v1 | يستخدم بيانات اعتماد boto3. |
| Hugging Face | huggingface | all-MiniLM-L6-v2 | sentence-transformers محلي. |
| Jina | jina | jina-embeddings-v2-base-en | عيّن JINA_API_KEY. |
| IBM WatsonX | watsonx | ibm/slate-30m-english-rtrvr | يتطلب project_id. |
| Sentence Transformer | sentence-transformer | all-MiniLM-L6-v2 | محلي، لا حاجة لمفتاح API. |
| مخصص | custom | — | يتطلب embedding_callable. |
إعداد LLM
تستخدم الذاكرة LLM لتحليل الحفظ (استنتاج النطاق والفئات والأهمية)، وقرارات التوحيد، وتحليل استعلام الاسترجاع العميق. يمكنك إعداد النموذج المُستخدم.Memory() لا يفشل أبدًا في وقت الإنشاء، حتى لو لم تكن مفاتيح API مُعيّنة. تظهر الأخطاء فقط عند استدعاء LLM فعليًا (مثلاً عند الحفظ بدون نطاق/فئات صريحة، أو أثناء الاسترجاع العميق).
للتشغيل المحلي/الخاص بالكامل، استخدم نموذجًا محليًا لكل من LLM والمُضمِّن:
واجهة التخزين
- الافتراضي: LanceDB، مخزّن تحت
./.crewai/memory(أو$CREWAI_STORAGE_DIR/memoryإذا تم تعيين متغير البيئة، أو المسار الذي تمرره كـstorage="path/to/dir"). - واجهة مخصصة: نفّذ بروتوكول
StorageBackend(انظرcrewai.memory.storage.backend) ومرّر مثيلًا إلىMemory(storage=your_backend).
الاستكشاف
فحص التسلسل الهرمي للنطاقات والفئات والسجلات:سلوك الفشل
إذا فشل LLM أثناء التحليل (خطأ شبكة، حد معدل، استجابة غير صالحة)، تتدهور الذاكرة بسلاسة:- تحليل الحفظ — يتم تسجيل تحذير ولا يزال يتم تخزين الذاكرة مع النطاق الافتراضي
/، فئات فارغة، وأهمية0.5. - استخراج الذكريات — يتم تخزين المحتوى الكامل كذاكرة واحدة حتى لا يُفقد شيء.
- تحليل الاستعلام — يتراجع الاسترجاع إلى اختيار نطاق بسيط وبحث متجهي حتى تستمر في الحصول على نتائج.
ملاحظة حول الخصوصية
يتم إرسال محتوى الذاكرة إلى LLM المُعدّ للتحليل (النطاق/الفئات/الأهمية عند الحفظ، تحليل الاستعلام والاسترجاع العميق الاختياري). للبيانات الحساسة، استخدم LLM محليًا (مثل Ollama) أو تأكد من أن مزودك يلبي متطلبات الامتثال الخاصة بك.أحداث الذاكرة
جميع عمليات الذاكرة تُصدر أحداثًا معsource_type="unified_memory". يمكنك الاستماع للتوقيت والأخطاء والمحتوى.
| الحدث | الوصف | الخصائص الرئيسية |
|---|---|---|
| MemoryQueryStartedEvent | بداية الاستعلام | query, limit |
| MemoryQueryCompletedEvent | نجاح الاستعلام | query, results, query_time_ms |
| MemoryQueryFailedEvent | فشل الاستعلام | query, error |
| MemorySaveStartedEvent | بداية الحفظ | value, metadata |
| MemorySaveCompletedEvent | نجاح الحفظ | value, save_time_ms |
| MemorySaveFailedEvent | فشل الحفظ | value, error |
| MemoryRetrievalStartedEvent | بداية استرجاع الوكيل | task_id |
| MemoryRetrievalCompletedEvent | اكتمال استرجاع الوكيل | task_id, memory_content, retrieval_time_ms |
استكشاف المشاكل
الذاكرة لا تستمر؟- تأكد من أن مسار التخزين قابل للكتابة (الافتراضي
./.crewai/memory). مرّرstorage="./your_path"لاستخدام مجلد مختلف، أو عيّن متغير البيئةCREWAI_STORAGE_DIR. - عند استخدام فريق، تأكد من تعيين
memory=Trueأوmemory=Memory(...).
- استخدم
depth="shallow"لسياق الوكيل الروتيني. احتفظ بـdepth="deep"للاستعلامات المعقدة. - زد
query_analysis_thresholdلتخطي تحليل LLM لمزيد من الاستعلامات.
- لا تزال الذاكرة تحفظ/تسترجع بإعدادات افتراضية آمنة. تحقق من مفاتيح API وحدود المعدل وتوفر النموذج إذا كنت تريد تحليل LLM كاملاً.
- عمليات حفظ الذاكرة تعمل في خيط خلفي. تُصدر الأخطاء كـ
MemorySaveFailedEventلكنها لا تعطل الوكيل. تحقق من السجلات للسبب الجذري (عادة مشاكل اتصال LLM أو المُضمِّن).
- عمليات LanceDB مُتسلسلة بقفل مشترك وتُعاد تلقائيًا عند التعارض. هذا يتعامل مع مثيلات
Memoryالمتعددة التي تشير إلى نفس قاعدة البيانات (مثل ذاكرة وكيل + ذاكرة فريق). لا حاجة لإجراء.
مرجع الإعداد
جميع الإعدادات تُمرر كمعاملات كلمة مفتاحية إلىMemory(...). كل معامل له قيمة افتراضية معقولة.
| المعامل | الافتراضي | الوصف |
|---|---|---|
llm | "gpt-4o-mini" | LLM للتحليل (اسم نموذج أو مثيل BaseLLM). |
storage | "lancedb" | واجهة التخزين ("lancedb"، سلسلة مسار، أو مثيل StorageBackend). |
embedder | None (افتراضي OpenAI) | المُضمِّن (قاموس إعداد، دالة قابلة للاستدعاء، أو None لافتراضي OpenAI). |
recency_weight | 0.3 | وزن الحداثة في الدرجة المركبة. |
semantic_weight | 0.5 | وزن التشابه الدلالي في الدرجة المركبة. |
importance_weight | 0.2 | وزن الأهمية في الدرجة المركبة. |
recency_half_life_days | 30 | أيام لتنصيف درجة الحداثة (اضمحلال أُسي). |
consolidation_threshold | 0.85 | التشابه الذي يُشغّل فوقه التوحيد عند الحفظ. عيّن إلى 1.0 للتعطيل. |
consolidation_limit | 5 | أقصى عدد سجلات حالية للمقارنة أثناء التوحيد. |
default_importance | 0.5 | الأهمية المُعيّنة عندما لا تُوفَّر ويتم تخطي تحليل LLM. |
batch_dedup_threshold | 0.98 | تشابه جيب التمام لإسقاط النسخ شبه المكررة داخل دفعة remember_many(). |
confidence_threshold_high | 0.8 | ثقة الاسترجاع التي تُعاد فوقها النتائج مباشرة. |
confidence_threshold_low | 0.5 | ثقة الاسترجاع التي يُشغّل تحتها استكشاف أعمق. |
complex_query_threshold | 0.7 | للاستعلامات المعقدة، استكشف أعمق تحت هذه الثقة. |
exploration_budget | 1 | عدد جولات الاستكشاف المدفوعة بـ LLM أثناء الاسترجاع العميق. |
query_analysis_threshold | 200 | الاستعلامات الأقصر من هذا (بالأحرف) تتخطى تحليل LLM أثناء الاسترجاع العميق. |
