أحد أكثر الأخطاء شيوعاً في تطوير وكلاء الذكاء الاصطناعي المستقلين هو "مشكلة سمكة الذهب". بدون آلية للحفاظ على المعلومات، يعود الوكيل إلى نقطة الصفر مع كل تفاعل جديد. بينما تتميز نماذج اللغات الكبيرة (LLMs) بقدرتها الهائلة على معالجة السياق داخل نافذة طلب واحدة، إلا أنها تفتقر بشكل جوهري إلى الاستمرارية طويلة المدى. لبناء وكلاء يمكنها حقاً التعلم، وتذكر التفضيلات، والحفاظ على الحالة عبر الجلسات، يجب علينا تنفيذ هندسات ذاكرة قوية.
أنواع ذاكرة الوكلاء
نادراً ما تكون ذاكرة الوكيل الفعالة بنية أحادية متجانسة. بدلاً من ذلك، تتكون عادةً من ثلاث طبقات مميزة، يخدم كل منها غرضاً مختلفاً:
- الذاكرة قصيرة المدى (نافذة السياق): هذا هو السياق الفوري الذي يتم تمريره إلى نموذج اللغة الكبيرة (LLM) أثناء الاستدلال. يتضمن تاريخ المحادثة الحالي والتعليمات النظامية. وعلى الرغم من محدوديتها بقيود الرموز (Tokens)، إلا أنها حاسمة للاستدلال الفوري.
- الذاكرة طويلة المدى (مخزن المتجهات): تعمل هذه كقرص صلب خارجي للوكيل. من خلال تضمين المستندات أو التفاعلات السابقة في فضاءات المتجهات، يمكن للوكيل استرجاع المعلومات التاريخية ذات الصلة عند الحاجة، متجاوزاً بذلك حدود الرموز فعلياً.
- الذاكرة العرضية (الذاكرة العاملة): هذه هي الحالة المحددة والعابرة للوكيل أثناء تنفيذ مهمة، مثل قائمة تسوق يتم بناؤها أو مقطع كود يتم تصحيح الأخطاء فيه.
تنفيذ الذاكرة طويلة المدى باستخدام RAG
أكثر النهج عملية لمنح الوكيل ذاكرة طويلة المدى هو التوليد المعزز بالاسترجاع (RAG). بدلاً من إغراق نافذة السياق بجميع التفاعلات السابقة (وهو أمر مكلف وغير كفؤ)، نسترجع فقط المقاطع الأكثر صلة. يتطلب هذا تحويل النص إلى متجهات عالية الأبعاد باستخدام نموذج التضمين (Embedding Model).
فيما يلي مثال عملي باستخدام Python ومكتبة LangChain لإعداد نظام ذاكرة بسيط يخزن تاريخ المحادثات ويسترجعه عند الضرورة.
from langchain_community.vectorstores import Chroma
from langchain_community.embeddings import OpenAIEmbeddings
from langchain.memory import ConversationBufferMemory
from langchain.chains import ConversationalRetrievalChain
# تهيئة نموذج التضمين
embeddings = OpenAIEmbeddings()
# إنشاء مخزن للمتجهات لحفظ التفاعلات السابقة
# في التطبيق الفعلي، ستقوم بحفظ هذا على القرص أو في قاعدة بيانات
vectorstore = Chroma(embedding_function=embeddings, persist_directory="./db")
# إعداد الذاكرة الحوارية لتتبع الأدوار الأخيرة
memory = ConversationBufferMemory(
memory_key="chat_history",
return_messages=True,
output_key="answer"
)
# دمج المسترجع مع نموذج اللغة الكبيرة
retriever = vectorstore.as_retriever(search_kwargs={"k": 2})
# يجمع السلسلة بين الاسترجاع والتوليد
chat_chain = ConversationalRetrievalChain.from_llm(
llm,
retriever=retriever,
memory=memory
)
اعتبارات عملية: الاسترجاع والصيانة
بينما يعد إعداد البنية التحتية أمراً مباشراً، تكمن التحدي الهندسي في الصيانة. الذاكرة ليست ثابتة؛ فهي تتطلب التقليم. فحفظ كل تفاعل على حدة يؤدي في النهاية إلى الضوضاء وزيادة زمن الاستجابة. يجب عليك تنفيذ استراتيجيات مثل:
- التلخيص: قم بتلخيص المحادثات القديمة بانتظام إلى حقائق مجردة بدلاً من الحفاظ على النص الخام.
- الإقصاء: نفذ سياسة إقصاء (مثل الأقل استخداماً مؤخراً) لإزالة البيانات القديمة من مخزن المتجهات.
- التصفية: استخدم البيانات الوصفية (Metadata) لتصفية الذكريات بناءً على الصلة، مما يضمن أن ينظر الوكيل فقط في البيانات ذات الصلة بالمستخدم الحالي أو المهمة.
الخاتمة
الذاكرة هي أساس الذكاء الحقيقي في وكلاء الذكاء الاصطناعي. بدونها، تكون الوكلاء مجرد روبوتات محادثة متطورة ليس لها أي إحساس بالاستمرارية. من خلال تنفيذ استراتيجية ذاكرة متعددة الطبقات تجمع بين السياق قصير المدى والتخزين المستمر للمتجهات، يمكن للمطورين إنشاء وكلاء تبدو شخصية حقاً، ومفيدة، وقادرة على الاستدلال المعقد متعدد الخطوات. مع تطور المجال، من المرجح أن نرى المزيد من هندسات الذاكرة المتطورة التي تحاكي العمليات المعرفية البشرية، ولكن في الوقت الحالي، يعد إتقان RAG وقواعد بيانات المتجهات الخطوة الأولى الأساسية.