ثلاث أسطر: search قبل الرد، add بعده
الفكرة كلها بثلاث استدعاءات:
الـ user_id هو مفتاح كل شي: ذاكرة لكل مستخدم لحاله، وما بتختلط.
Python. في نسخة JavaScript بنفس الأسماء (npm install mem0ai).
التركيب: pip أو Docker أو المستضاف
المكتبة (الأسهل، كل شي على جهازك):
pip install mem0ai anthropic
بتحتاج مفتاحين بالبيئة: ANTHROPIC_API_KEY للرد والاستخلاص، وOPENAI_API_KEY لأن الـ embeddings الافتراضية (تحويل النص لأرقام للبحث) من OpenAI. بدك تستغني عن OpenAI؟ شوف القسم 3.
خادم كامل بواجهة (للفريق أو أكثر من تطبيق):
git clone https://github.com/mem0ai/mem0.git
cd mem0/server
make bootstrap
أمر واحد بيشغّل الحزمة بـ Docker، بيعمل حساب أدمن، وبيعطيك أول مفتاح API. الواجهة على http://localhost:3000. (البديل اليدوي: docker compose up -d من نفس المجلد وبتكمّل الإعداد من المتصفح.)
مستضاف عندهم (بدون تركيب):
حساب على app.mem0.ai ومفتاح API، وبتستعمل MemoryClient بدل Memory بنفس الفكرة. فيه خطة مجانية وخطط مدفوعة. الكود تحت للنسخة المفتوحة المصدر.
الكود الكامل: مساعد Claude بذاكرة
احفظه باسم memory_chat.py وشغّله. المرة الثانية بيتذكّر القهوة والمتجر بدون ما تعيد:
memory_chat.py
import os
from anthropic import Anthropic
from mem0 import Memory
# needs ANTHROPIC_API_KEY (replies + memory extraction) and OPENAI_API_KEY (default embeddings)
config = {
"llm": {
"provider": "anthropic",
"config": {"model": "claude-sonnet-5-5", "temperature": 0.1, "max_tokens": 2000},
}
}
memory = Memory.from_config(config)
client = Anthropic()
def chat(user_id: str, message: str) -> str:
# 1) before replying: what do we know about this user that relates to the message?
found = memory.search(query=message, filters={"user_id": user_id}, top_k=3)
notes = "\n".join(f"- {m['memory']}" for m in found.get("results", []))
system = "أنت مساعد ودود. ذكريات عن المستخدم:\n" + (notes or "- لا شيء بعد")
# 2) the reply from Claude
reply = client.messages.create(
model="claude-sonnet-5-5",
max_tokens=600,
system=system,
messages=[{"role": "user", "content": message}],
).content[0].text
# 3) after replying: let Mem0 keep what matters from this exchange
memory.add(
[{"role": "user", "content": message}, {"role": "assistant", "content": reply}],
user_id=user_id,
)
return reply
print(chat("ahmad", "اسمي أحمد وبشتغل على متجر إلكتروني للقهوة"))
print(chat("ahmad", "اقترح لي اسم لحملة رمضان")) # remembers the coffee store
| السطر | شو بيعمل |
|---|---|
Memory.from_config(config) | ذاكرة بتستعمل Claude للاستخلاص بدل الافتراضي (OpenAI). بدون config، Memory() بتشتغل بس كلها على OpenAI. |
memory.search(query=…, filters={"user_id": …}, top_k=3) | أقرب 3 ذكريات لهالمستخدم. الصيغة الحالية بتاخد filters، مش user_id مباشرة (الإصدارات القديمة كانت تقبلها). |
found["results"] | قائمة، كل عنصر فيه memory (النص) وscore (درجة التشابه) وتاريخ الإنشاء. |
system = … | الذكريات بتروح بالـ system prompt، مش برسالة المستخدم، حتى Claude يعاملها كمعلومات مش كطلب. |
memory.add([...], user_id=…) | بتعطيه الرسالتين. هو بيستخلص الحقائق (مش الكلام كله)، وبيحدّث الموجود لو تغيّر. |
جرّب بعدها: memory.get_all(filters={"user_id": "ahmad"}) وشوف شو حفظ بالضبط.
خلّي Claude هو اللي بيستخلص الذكريات
Mem0 بيستعمل نموذجين: LLM بيقرأ المحادثة وبيقرر شو يحفظ، وembedder بيحوّل النص لأرقام للبحث. الـ config اللي بالكود بيحط Claude بالدور الأول:
Anthropic as the LLM
config = {
"llm": {
"provider": "anthropic",
"config": {
"model": "claude-sonnet-5-5",
"temperature": 0.1,
"max_tokens": 2000,
}
}
}
memory = Memory.from_config(config)
- الـ embedder: الافتراضي OpenAI (text-embedding-3-small) وبده OPENAI_API_KEY. Mem0 بيدعم بدائل بنفس مكان الـ config تحت مفتاح "embedder": Ollama (محلي ومجاني)، Hugging Face، Google، Vertex، Bedrock وغيرهم. القائمة والصيغة بالضبط على docs.mem0.ai/components/embedders.
- التخزين: افتراضياً Qdrant على القرص بمجلد مؤقت. للإنتاج حط "vector_store" بالـ config على Qdrant أو Postgres (pgvector) أو غيرهم.
- الموديل: claude-sonnet-5-5 توازن سعر وذكاء للاستخلاص. للرد نفسه بتختار اللي بدك بسطر messages.create.
ما تعيد كتابته. خلّي Claude Code يدخّل Mem0 فيه باختبارات.
ربطه بمشروع موجود من Claude Code
Mem0 ناشر skills رسمية لمساعدات البرمجة (Claude Code، Codex، Cursor…) بمجلد skills/ بالريبو. ركّبهم بأمرين من مجلد مشروعك:
npx skills add https://github.com/mem0ai/mem0 --skill mem0-integrate
npx skills add https://github.com/mem0ai/mem0 --skill mem0-test-integration
بعدها افتح claude بنفس المجلد:
- إنت /mem0-integrate (للنسخة المفتوحة المصدر ضيف --product oss؛ الافتراضي المنصة المستضافة).
- Claude بيقرأ مشروعك، بيلاقي وين المحادثة بتصير، بيكتب اختبار أول، وبعدها بيضيف search قبل الرد وadd بعده بنفس أسلوب كودك.
- إنت /mem0-test-integration بيتحقق إن الذاكرة بتنحفظ وبترجع فعلاً.
- إنت راجع الـ diff قبل ما تعمل commit، خصوصاً مكان الـ user_id: لازم يكون معرّف المستخدم الحقيقي عندك مش قيمة ثابتة.
- أول مرة تستعمل npx skills بيسألك لأي أداة تركّب: اختار Claude Code (أو ضيف
-a claude-codeللأمر). - ما بتحب أدوات طرف ثالث؟ انسخ مجلد skills/mem0-integrate من الريبو لـ
.claude/skills/بمشروعك، ونفس الأمر بيشتغل. تفاصيل الـ skills عموماً: دليل الـ skills. - شي ثاني بنفس الاسم: في plugin رسمي لـ Claude Code اسمه mem0 بيعطي Claude Code نفسه ذاكرة عن جلساتك (/mem0:remember، /mem0:search…) وبيحتاج مفتاح منصة Mem0. هذا لذاكرة Claude Code، مش لتطبيقك.
أخطاء شائعة
| الغلطة | الصح |
|---|---|
| بتمرّر user_id= لـ search | الإصدار الحالي بيرفضها: filters={"user_id": user_id}. وlimit= بتتجاهل بصمت، الصح top_k=. |
| نفس الـ user_id لكل الناس | بتختلط ذكريات المستخدمين. استعمل معرّف المستخدم من نظام الدخول عندك. |
| بتحفظ بعد كل رسالة وبتدوّر بكل الذاكرة | الحفظ بعد الرد صح، بس top_k=3 أو 5 بيكفي. ذكريات أكثر بالـ system prompt ما بتعني رد أحسن. |
| بتتوقع يحفظ كل الكلام | Mem0 بيحفظ حقائق مستخلصة («بيحب القهوة المختصة») مش النص كامل. بدك السجل الحرفي؟ احفظه بقاعدة بياناتك عادي. |
| بتنسى مفتاح الـ embeddings | الخطأ الأول اللي بيطلع لكل واحد. إما OPENAI_API_KEY بالبيئة، أو embedder محلي بالـ config. |
| Qdrant بالمجلد المؤقت بالإنتاج | بينمسح مع إعادة التشغيل. حط vector_store على قاعدة دائمة قبل ما تطلّع التطبيق. |