تُعدّ إحدى أبرز القيود في نماذج اللغة الكبيرة (LLMs) الحديثة هي افتقارها إلى الدوام. ورغم إتقان هذه النماذج للاستدلال السياقي ضمن جلسة واحدة، إلا أنها تنسى كل شيء بمجرد إغلاق نافذة السياق. بالنسبة للمطوّرين الذين يبنيون وكلاء ذكاء اصطناعي مستقلين، تُشكّل هذه "الزهايمر" عنق زجاجة حرجًا. لإنشاء أنظمة مستقلة مفيدة حقًا، يجب علينا تنفيذ بنيات ذاكرة متطورة تتيح للوكلاء تذكّر التفاعلات السابقة، والتعلّم من الملاحظات، والحفاظ على الحالة طويلة المدى.
تُصنَّف ذاكرة الوكلاء عمومًا إلى نوعين: الذاكرة قصيرة المدى والذاكرة طويلة المدى. عادةً ما تقيم الذاكرة قصيرة المدى ضمن نافذة السياق الفورية لنموذج اللغة، حيث تُدير تدفق المحادثة الحالية. ومع ذلك، تتطلب الذاكرة طويلة المدى أنظمة تخزين خارجية للحفاظ على البيانات عبر الجلسات. يركّز هذا المنشور على تنفيذ نظام ذاكرة طويلة المدى قوي باستخدام التضمينات المتجهية واستراتيجيات الاسترجاع الهجين.
بنية ذاكرة الوكلاء
تعتمد ذاكرة الوكلاء الفعالة على خط أنابيب من ثلاث مراحل: الاستهلاك، والتخزين، والاسترجاع. عندما يتفاعل الوكيل مع مستخدم أو بيئة، يتم استخراج نقاط بيانات رئيسية. ثم تُحوَّل هذه النقاط إلى تضمينات متجهية، وهي تمثيلات رقمية عالية الأبعاد للبيانات. أخيرًا، عندما يحتاج الوكيل إلى استرجاع المعلومات، يولّد متجه استعلام ويبحث عن التضمينات المشابهة في قاعدة بيانات المتجهات.
إن مجرد تخزين كل كلمة في المحادثة غير كفء وغالبًا ما يُدخل ضوضاء. وبدلاً من ذلك، يجب على الوكلاء استخدام استراتيجية "التكامل". في نهاية الجلسة، أو على فترات منتظمة، يلخّص الوكيل المحادثة ويستخرج الحقائق البارزة. تقلّل هذه العملية من حجم البيانات مع الحفاظ على المعنى الدلالي.
تنفيذ الذاكرة طويلة المدى القائمة على المتجهات
للتخزين طويل المدى، تُعدّ قواعد بيانات المتجهات مثل Pinecone وWeaviate أو ChromaDB مثالية. تتيح هذه قواعد البيانات البحث عن التشابه، مما يمكّن الوكيل من إيجاد ذكريات سابقة ذات صلة بناءً على التشابه الدلالي بدلاً من المطابقة الدقيقة للكلمات المفتاحية. أدناه مثال عملي باستخدام Python ومكتبة ChromaDB لتنفيذ مخزن ذاكرة أساسي.
import chromadb
from chromadb.utils import embedding_functions
# Initialize the ChromaDB client
client = chromadb.Client()
# Define an embedding function using a lightweight model
# In production, use a more robust model like Sentence Transformers
embed_function = embedding_functions.SentenceTransformerEmbeddingFunction(model_name="all-MiniLM-L6-v2")
# Create a persistent collection for agent memory
# Persistence ensures data survives between script runs
memory_collection = client.get_or_create_collection(
name="agent_long_term_memory",
embedding_function=embed_function,
metadata={"hnsw:space": "cosine"}
)
def store_memory(agent, memory_text, metadata=None):
"""
Stores a specific memory into the vector database.
Args:
agent: The agent ID associated with the memory.
memory_text: The text representation of the memory.
metadata: Additional metadata like timestamp or importance score.
"""
# Ensure metadata includes the agent ID for filtering
if metadata is None:
metadata = {}
metadata["agent_id"] = agent
# Generate a unique ID based on hash or use UUID
import uuid
doc_id = str(uuid.uuid4())
memory_collection.add(
ids=[doc_id],
documents=[memory_text],
metadatas=[metadata]
)
return doc_id
def retrieve_memories(agent, query, n_results=5):
"""
Retrieves the most relevant memories for a given query.
Args:
agent: The agent ID to filter by.
query: The current context or question.
n_results: Number of memories to retrieve.
Returns:
List of relevant memory documents.
"""
# Perform a similarity search filtered by agent ID
results = memory_collection.query(
query_texts=[query],
n_results=n_results,
where={"agent_id": agent}
)
# Extract documents and distances for analysis
memories = results["documents"][0]
distances = results["distances"][0]
# Filter out low-relevance memories (optional threshold)
relevant_memories = []
for mem, dist in zip(memories, distances):
if dist < 0.5: # Cosine distance threshold
relevant_memories.append(mem)
return relevant_memories
# Example Usage
# 1. Storing a memory after a conversation
store_memory("Agent_Alpha", "The user prefers dark mode in their dashboard settings.")
# 2. Retrieving memory when user asks about UI settings
query = "How should I configure the theme for my profile?"
relevant_context = retrieve_memories("Agent_Alpha", query)
print("Retrieved Context:", relevant_context)
الاسترجاع الهجين للدقة
على الرغم من تفوق البحث المتجهي في الفهم الدلالي، إلا أنه قد يفشل أحيانًا في المطابقات الدقيقة، مثل الأسماء المحددة، أو التواريخ، أو المعرّفات التقنية. للتخفيف من هذا، تستخدم أنظمة الوكلاء المتقدمة الاسترجاع الهجين، الذي يجمع بين البحث عن التشابه المتجهي والبحث التقليدي بالكلمات المفتاحية (مثل BM25). تضمن هذه الطريقة أن يسترجع الوكيل المعلومات ذات الصلة المفاهيمية والتفاصيل الواقعية الدقيقة معًا.
عند تصميم الموجه (Prompt) لنموذج اللغة، يجب حق الذكريات المسترجعة في الموجه النظامي أو نافذة السياق الفورية. من الضروري ترتيب هذه الذكريات حسب الصلة والحداثة. يجب أن تكون الذكريات الأقدم ذات وزن أقل أو ملخّصة لمنع تلوث السياق. على سبيل المثال، قد تتضمن أعلى ثلاث ذكريات حديثة ذات صلة وملخصًا لجميع التفاعلات الأقدم.
إدارة حدود نافذة السياق
حتى مع الاسترجاع الكفء، فإن نماذج اللغة الكبيرة لها نوافذ سياق محدودة. إذا كان الوكيل نشطًا لفترة طويلة، فقد تقترب ذاكرته قصيرة المدى (سجل المحادثة) من الحد. تشمل استراتيجيات إدارة ذلك ما يلي:
- نافذة المنزلقات: الاحتفاظ فقط بآخر N رسائل في السياق النشط.
- التلخيص: طلب تلخيص المحادثة حتى الآن من نموذج اللغة بشكل دوري واستبدال السجل الكامل بالملخص.
- تفريغ الذاكرة: نقل السجل التفصيلي إلى التخزين المتجهي طويل المدى والاحتفاظ بالملخص فقط في السياق قصير المدى.
من خلال دمج هذه التقنيات، يمكنك بناء وكلاء يشعرون بالاستمرارية والوعي بتاريخهم، مما يحسّن تجربة المستخدم ومعدلات إتمام المهام بشكل كبير.
الخلاصة
إن تنفيذ ذاكرة الوكلاء لا يتعلق فقط بتخزين البيانات؛ بل يتعلق بتنسيق السياق. تتيح أنظمة الذاكرة المصممة جيدًا للوكلاء سد الفجوة بين نماذج اللغة غير الدائمة والمساعدين الدائمين والذكيين. ابدأ بمخزن متجهات بسيط للحقائق طويلة المدى، ودمج البحث الهجين للدقة، وإدارة نافذة السياق بصرامة. ومع تطور النماذج والأدوات، ستبقى القدرة على إدارة الذاكرة بفعالية كفاءة أساسية لبناء وكلاء ذكاء اصطناعي متقدمين.