الذاكرة في الذكاء الاصطناعي: لماذا ينسى الـ API المحادثات السابقة وكيف نعالج ذلك؟
ما المقصود بذاكرة النماذج اللغوية ولماذا تبدو وكأنها “تنسى”؟
عند بناء تطبيق يعتمد على LLM API يظن كثير من المطورين أن النموذج يحتفظ تلقائياً بكل ما قيل سابقاً، لكن هذا غير صحيح في أغلب واجهات البرمجة. النموذج لا يملك “ذاكرة دائمة” داخلية لكل مستخدم، بل يستقبل في كل طلب حزمة نصية جديدة تحتوي على التعليمات والسياق والرسائل السابقة التي تقرر أنت إرسالها. إذا لم تُرسل هذا السياق مرة أخرى، فسيتصرف النموذج كما لو أنه يراك لأول مرة.
لفهم ذلك برمجياً، من المفيد الرجوع إلى مقال مدخل إلى هندسة الذكاء الاصطناعي التوليدي: كيف تعمل نماذج اللغة الكبيرة (LLMs) برمجياً؟. فالنموذج يعمل وفق آلية next-token prediction داخل نافذة سياق محدودة تسمى context window. أي أن “الذاكرة” في التطبيق ليست خاصية سحرية داخل النموذج، بل هي طبقة هندسية خارجية تقوم أنت بإدارتها.
كيف يتدفق الطلب داخل التطبيق ولماذا يحدث النسيان؟
هندسياً، مسار البيانات في تطبيق محادثة بسيط يمر غالباً بالمراحل التالية:
- المستخدم يرسل رسالة جديدة.
- الخادم يستقبل الرسالة مع
session_idأو هوية المستخدم. - التطبيق يقرر هل سيسترجع تاريخ المحادثة أم لا.
- يُبنى
promptالنهائي بإضافة الرسائل السابقة أو ملخصها أو السياق المسترجع. - يُرسل الطلب إلى
API. - يعيد النموذج الرد اعتماداً فقط على ما وُضع داخل الطلب الحالي.
إذا أرسلت الرسالة الأخيرة فقط، فسيغيب تاريخ الحوار تماماً. لذلك لا يوجد “نسيان” بالمعنى البيولوجي، بل يوجد فقدان للسياق لأن التطبيق لم يمرر الذاكرة للنموذج. كما أن هناك سبباً ثانياً مهماً: حتى لو أرسلت كل التاريخ، فإن حجم الرموز أو tokens محدود. عند تجاوز النافذة، ستضطر إلى حذف أجزاء من الماضي أو تلخيصها.
الفرق بين ذاكرة الجلسة وذاكرة التطبيق طويلة الأمد
1) ذاكرة قصيرة الأمد Short-Term Memory
هي الرسائل الحديثة داخل نفس الجلسة. هذا النوع مناسب للمحادثات المتتابعة مثل خدمة العملاء أو المساعد الشخصي أثناء جلسة واحدة. غالباً يُخزن في Redis أو قاعدة بيانات تقليدية أو حتى قائمة مؤقتة داخل الخادم.
2) ذاكرة طويلة الأمد Long-Term Memory
هي معلومات يجب استحضارها بعد أيام أو أسابيع: تفضيلات المستخدم، ملخصات جلسات سابقة، ملفات مرفوعة، أو حقائق شخصية مسموح بتخزينها. هنا نستخدم عادةً قواعد بيانات تقليدية للحقائق المنظمة، أو أدوات مثل LangChain مع Vector DB عندما تكون الذاكرة نصية أو دلالية.
أشهر استراتيجيات معالجة النسيان في تطبيقات API
تمرير تاريخ المحادثة كاملاً
أبسط حل هو إعادة إرسال جميع الرسائل السابقة في كل طلب. هذا مفيد في البدايات، لكنه مكلف ويستهلك tokens بسرعة.
استخدام نافذة متحركة Sliding Window
بدلاً من كامل التاريخ، نرسل آخر N رسائل فقط. هذا يحافظ على السياق الحديث ويخفض التكلفة.
تلخيص الماضي Conversation Summarization
عندما تكبر المحادثة، يمكن ضغط الأجزاء القديمة في ملخص منظم ثم ضمّه مع آخر الرسائل. هذه طريقة فعالة جداً لأنك تحول 200 سطر مثلاً إلى فقرة أو نقاط مركزة.
استرجاع الذاكرة دلالياً Semantic Retrieval
في التطبيقات المتقدمة، لا تحتاج إلى كل التاريخ، بل إلى الأجزاء ذات الصلة فقط. هنا تظهر قيمة التمثيلات الدلالية Embeddings وأنماط RAG. تخزن الرسائل أو الملخصات داخل Vector DB ثم تسترجع المقاطع الأقرب دلالياً لسؤال المستخدم الحالي.
نمط معماري موصى به لبناء ذاكرة موثوقة
أفضل تصميم عملي غالباً ليس حلاً واحداً، بل مزيج طبقات:
- طبقة جلسة فورية: آخر 6 إلى 12 رسالة.
- طبقة تلخيص: ملخص تراكمي يتم تحديثه كل عدة رسائل.
- طبقة معرفة طويلة الأمد: حقائق أو تفضيلات محفوظة بشكل منظم.
- طبقة استرجاع دلالي: مقاطع ذات صلة من سجل قديم أو وثائق خارجية.
هذا الأسلوب يقلل التكلفة، ويحسن الدقة، ويمنع إغراق النموذج بمعلومات غير لازمة.
مثال برمجي بسيط لإدارة ذاكرة المحادثة
إذا كنت قد أعددت بيئة التطوير مسبقاً وفق مقال إعداد بيئة العمل الذكية: تثبيت مكتبات Python الأساسية للتعامل مع الذكاء الاصطناعي، فيمكنك البدء بمخزن ذاكرة بسيط داخل التطبيق:
from openai import OpenAI
client = OpenAI()
memory_store = {}
def get_messages(session_id, user_message):
history = memory_store.get(session_id, [])
messages = [
{"role": "system", "content": "You are a helpful assistant with conversational memory."}
]
messages.extend(history[-8:])
messages.append({"role": "user", "content": user_message})
return messages
def chat(session_id, user_message):
messages = get_messages(session_id, user_message)
response = client.chat.completions.create(
model="gpt-4o-mini",
messages=messages,
temperature=0.3
)
assistant_reply = response.choices[0].message.content
memory_store.setdefault(session_id, []).append(
{"role": "user", "content": user_message}
)
memory_store[session_id].append(
{"role": "assistant", "content": assistant_reply}
)
return assistant_reply
هذا المثال يطبق session memory فقط. لكنه غير كافٍ للإنتاج، لأن الذاكرة ستضيع عند إعادة تشغيل الخادم، ولا يوجد فيه تلخيص أو استرجاع دلالي.
مثال على التلخيص الدوري لتقليل استهلاك tokens
def summarize_history(client, history):
prompt = f"""
Summarize this conversation into persistent facts, user preferences,
unresolved questions, and important decisions:
{history}
"""
response = client.chat.completions.create(
model="gpt-4o-mini",
messages=[{"role": "user", "content": prompt}],
temperature=0.2
)
return response.choices[0].message.content
بعد إنشاء الملخص، يمكنك تخزينه في قاعدة بيانات وإرساله لاحقاً ضمن system prompt أو كرسالة سياقية. ولتحسين صياغة هذه التعليمات، راجع مقال هندسة الأوامر (Prompt Engineering) داخل الكود: قوالب النصوص المتغيرة (F-Strings).
احتفظ بآخر 8 رسائل كما هي، ثم أضف ملخصاً قصيراً للرسائل الأقدم يحتوي على: اسم المستخدم، تفضيلاته، القرارات السابقة، والمهام المفتوحة. إذا لم تكن المعلومة مؤكدة فلا تتعامل معها كحقيقة دائمة.
كيف يساعد LangChain في هذا السيناريو؟
يمكن عبر LangChain بناء سلاسل تتضمن إدخال المستخدم، استرجاع الذاكرة، وإرسال السياق تلقائياً. وإذا كنت قد قرأت إنشاء أول سلسلة (Chain) باستخدام LangChain لتمرير البيانات تلقائياً فستفهم كيف يمكن إدراج الذاكرة كخطوة وسطية داخل مسار التنفيذ. كذلك يمكن دمج retriever دلالي لاستحضار الرسائل الأكثر ارتباطاً بالسؤال الحالي، لا كل الرسائل السابقة.
أخطاء شائعة يقع فيها المطورون
- الاعتماد على النموذج نفسه لتذكر كل شيء دون تخزين خارجي.
- إرسال تاريخ كامل ضخم في كل مرة مما يرفع التكلفة ويقلل الجودة.
- تخزين معلومات حساسة دون سياسة خصوصية أو تنقيح.
- خلط الحقائق الدائمة مع رسائل عابرة لا تستحق الحفظ.
- عدم فرض بنية منظمة للملخصات أو المخرجات، رغم إمكانية استخدام مخرجات
JSONالمهيكلة.
الخلاصة الهندسية
سبب “نسيان” API للمحادثات السابقة ليس قصوراً غامضاً في LLM بقدر ما هو قرار معماري في تطبيقك. النموذج يرى فقط ما ترسله له داخل الطلب الحالي، ومع حدود context window يصبح تصميم الذاكرة ضرورة لا ميزة اختيارية. الحل الاحترافي يجمع بين ذاكرة جلسة قصيرة، ملخصات تراكمية، واسترجاع دلالي عبر Vector DB أو قواعد منظمة. بهذه البنية يتحول التطبيق من واجهة ترد على أسئلة منفصلة إلى مساعد يفهم الاستمرارية والسياق ويقدم تجربة أقرب لما يتوقعه المستخدم من الأنظمة الذكية الحديثة.
9 comments