هذا المقال يتطلّب مستوى متوسط في AI Engineering — لازم تكون مستخدم Claude API أو OpenAI API قبل كده، وعارف Vector DB يعمل إيه على المستوى المفاهيمي.
ذاكرة AI Agents: 3 طبقات تخلّي Agent يفتكر مستخدمه بعد 6 شهور
لو Agent بتاعك بيرحّب بنفس المستخدم كأنه شايفه أول مرة بعد 80 محادثة، المشكلة مش في Claude ولا في GPT-5. المشكلة إنك بتحط كل المحادثات في الـ context window وبتعتمد على إن النموذج يلاقي اللي يهمه — وده بيفشل بعد ~32K توكن.
المشكلة باختصار
الـ context window حتى لو 200K توكن مش "ذاكرة"، هو فقط نافذة قصيرة المدى. النموذج بيقرا كل التوكنز مع كل طلب، يعني بتدفع تكلفة الـ history كاملة كل مرة. مع 50 محادثة لمستخدم واحد بتوصل للحد الأقصى، يبدأ الـ Agent ينسى التفاصيل القديمة، والفاتورة تطلع 4 أضعاف بدون قيمة مضافة.
المثال البسيط: السكرتير الجديد ضد سكرتير 5 سنين
تخيّل عندك سكرتيرين. الأول جديد، كل ما تيجي مكتبه يسألك: "حضرتك مين؟ شغلانتك إيه؟ مين زبائنك؟"، يعمل القائمة من الصفر، يخلّص شغلك في ساعتين بدل 20 دقيقة. التاني عنده 3 ملفات: ملف بيكتب فيه نقاط الاجتماع الحالي دقيقة بدقيقة، ملف بكل اجتماعات الشهر، وملف خلاصة يعرفها عنك (اسمك، أهم زبائنك، تفضيلاتك). التاني بيخلّص في 8 دقايق وانت مش حاسس إنك بتعيد كلامك.
الـ Agent اللي بيخزّن كل المحادثة في context window زي السكرتير الأول. الحل: 3 طبقات ذاكرة منفصلة لكل واحدة وظيفة محددة.
الـ 3 طبقات علميًا
التصنيف ده مأخوذ من ورقة "MemGPT: Towards LLMs as Operating Systems" (Packer et al., Berkeley, 2024) ومن نظام MIRIX (2025) اللي حقّق 99.9% recall على LOCOMO benchmark للذاكرة طويلة المدى:
- Working Memory (الذاكرة العاملة): آخر 8 إلى 16 رسالة في الـ context الحالي. زي الورقة اللي قدامك دلوقتي على المكتب — سريعة الوصول لكن محدودة.
- Episodic Memory (ذاكرة الأحداث): ملخّصات للمحادثات السابقة مخزّنة في Vector DB. بتستدعي الـ chunks المتعلقة بالسؤال الحالي عن طريق semantic search فقط لمّا تحتاجها.
- Semantic Memory (الذاكرة الدلالية): حقائق ثابتة عن المستخدم (اسمه، شغله، تفضيلاته)، مخزّنة في key-value store، بتنحقن في system prompt كل مرة لأنها صغيرة وأساسية.
كود تنفيذي شغّال — Python + ChromaDB + Anthropic SDK
from anthropic import Anthropic
import chromadb, hashlib
client = Anthropic()
chroma = chromadb.PersistentClient("./agent_memory")
episodic = chroma.get_or_create_collection("episodes")
semantic = {} # في الإنتاج: Postgres أو Redis
def chat(user_id: str, message: str) -> str:
# 1) استدعِ episodic memory المتعلقة بالسؤال
rel = episodic.query(query_texts=[message], n_results=3,
where={"user_id": user_id})
episodes = "\n".join(rel["documents"][0]) if rel["documents"] else ""
# 2) استدعِ semantic memory (حقائق ثابتة)
facts = semantic.get(user_id, {})
facts_str = "\n".join(f"- {k}: {v}" for k, v in facts.items())
# 3) ابنِ system prompt مدمج
system = f"""انت Agent يفتكر مستخدمه. حقائق ثابتة:
{facts_str}
لقطات من محادثات سابقة:
{episodes}"""
resp = client.messages.create(
model="claude-sonnet-4-6",
max_tokens=1024,
system=system,
messages=[{"role": "user", "content": message}],
)
reply = resp.content[0].text
# 4) خزّن المحادثة الحالية كـ episode
eid = hashlib.sha1(f"{user_id}:{message}".encode()).hexdigest()
episodic.add(documents=[f"User: {message}\nAI: {reply}"],
metadatas=[{"user_id": user_id}], ids=[eid])
return reply