الرئيسية
» المجالات
»
كيفية إصلاح فقدان ذاكرة وكيل LangChain عبر المحادثات الطويلة
كيفية إصلاح فقدان ذاكرة وكيل LangChain عبر المحادثات الطويلة
إذا نسي وكيل LangChain التفاصيل أثناء محادثة طويلة، فقم بإصلاح البنية المعمارية قبل زيادة نافذة سياق النموذج. في وكلاء LangChain الحاليين بأسلوب الإصدار v1، يتم بناء استمرارية المحادثة من طبقتين منفصلتين: أداة حفظ الحالة (checkpointer) للحالة قصيرة المدى المحددة بالموضوع، ومتجر (store) للمعلومات طويلة المدى التي يجب أن تبقى عبر الموضوعات. تتطلب المحادثات الطويلة بعد ذلك اهتمامًا ثالثًا: إدارة السياق، وعادةً ما تتضمن تقليم أو تلخيص الرسائل القديمة قبل أن تطغى على النموذج.
يتبع هذا الدليل وثائق LangChain الرسمية كما تم التحقق منها في 11 سبتمبر 2026. توصي الوثائق الحالية باستخدام langchain.agents.create_agent للوكلاء الجدد وتصف استمرارية LangGraph كنظام الذاكرة الأساسي. قد تظهر الأمثلة القديمة القائمة على ConversationChain أو ConversationBufferMemory أو initialize_agent في المواد القديمة، لكن دليل ترحيل LangChain v1 نقل السلاسل القديمة والوظائف المهجورة الأخرى إلى langchain-classic. راجع دليل ترحيل LangChain v1 الرسمي.
رسم توضيحي تم إنشاؤه بالذكاء الاصطناعي: العرض بسيط: تم توفير معلومة سابقًا، لكن إجابة لاحقة لم تعد تستخدمها. الرسم التوضيحي مفاهيمي وليس واجهة LangChain ملتقطة فعليًا.
ماذا يعني "فقدان الذاكرة" فعليًا في LangChain
قبل تغيير الكود، افصل بين ثلاث مشاكل غالبًا ما تبدو متطابقة من وجهة نظر المستخدم.
العرض
السبب المحتمل
الطبقة الصحيحة للإصلاح
ينسى الوكيل بعد إعادة تشغيل الخادم
تم تخزين الحالة فقط في ذاكرة العملية
أداة حفظ حالة أو متجر دائم
ينسى الوكيل بين طلبين في نفس الدردشة
لا توجد أداة حفظ حالة، أو تم استخدام thread_id مختلف
استمرارية الموضوع
يتذكر الوكيل الأدوار المبكرة في التخزين لكنه يتوقف عن استخدامها في الدردشات الطويلة جدًا
أصبح سياق النموذج كبيرًا جدًا أو مليئًا بالضوضاء
التلخيص، التقليم، الاسترجاع
يتذكر الوكيل تفضيلًا في دردشة واحدة لكنه لا يتذكره في دردشة جديدة
توجد المعلومة فقط في حالة الموضوع
متجر طويل المدى
تعرّف وثائق الذاكرة قصيرة المدى في LangChain الذاكرة قصيرة المدى بأنها الحالة داخل موضوع واحد. وتعرّف وثائق الذاكرة طويلة المدى الذاكرة طويلة المدى بأنها المعلومات التي تستمر عبر محادثات وجلسات مختلفة.
رسم توضيحي تم إنشاؤه بالذكاء الاصطناعي: فكر في الذاكرة قصيرة المدى على أنها حالة موضوع محادثة واحد. يطبق LangChain الحالي هذه الاستمرارية من خلال أداة حفظ حالة بدلاً من فئات الذاكرة القديمة التي غالبًا ما تظهر في البرامج التعليمية القديمة.
ما تحتاجه قبل البدء
تحتاج إلى تطبيق LangChain/LangGraph حالي، وتكامل نموذج، ومكان لاستمرارية الحالة. للتجربة المحلية، يكفي InMemorySaver. للإنتاج، استخدم أداة حفظ حالة مدعومة بقاعدة بيانات. تظهر وثائق LangChain الرسمية PostgreSQL من خلال حزمة langgraph-checkpoint-postgres المنفصلة.
حافظ على وضوح أربعة معرفات:
معرّف المحادثة أو الدردشة: المعرّف الذي يعرضه تطبيقك للمستخدمين.
thread_id: مفتاح استمرارية LangGraph المستخدم لاستئناف حالة موضوع واحد.
معرّف المستخدم: الهوية الدائمة المستخدمة لتسمية مساحات أسماء الذكريات طويلة المدى.
مفتاح الذاكرة: المفتاح لعنصر دائم واحد داخل مساحة أسماء المتجر.
لا ينبغي أن تكون قيمًا متطابقة تلقائيًا. يمكن لمستخدم واحد أن يكون لديه العديد من الموضوعات، ويمكن لموضوع واحد أن يحتوي على العديد من الحقائق.
الخطوة 1: إعادة إنتاج الفشل باختبار من طلبين
ابدأ بأصغر اختبار ممكن. اطلب من الوكيل تذكر تفريد فريد، ثم استدعه مرة أخرى واطلب ذلك التفريد. لا تختبر الذاكرة باستدعاء invoke() واحد لأن النموذج يمكنه رؤية كل شيء في ذلك الطلب الواحد حتى عندما تكون الاستمرارية معطلة.
config = {"configurable": {"thread_id": "debug-thread-001"}}
agent.invoke(
{"messages": [{"role": "user", "content": "تذكر أن الاسم الرمزي لمشروعي هو Juniper."}]},
config,
)
result = agent.invoke(
{"messages": [{"role": "user", "content": "ما هو الاسم الرمزي لمشروعي؟"}]},
config,
)
إذا نسي الطلب الثاني "Juniper"، فافحص تكوين أداة حفظ الحالة وthread_id الفعلي قبل تغيير المطالبات.
الخطوة 2: أضف أداة حفظ حالة للذاكرة في نفس الموضوع
تقوم أداة حفظ الحالة (checkpointer) بحفظ لقطات من حالة رسم الوكيل. يستخدمها LangGraph للذاكرة قصيرة المدى، واستعادة الانقطاع، وتدفقات الإنسان في الحلقة، والتسامح مع الأخطاء. يصف دليل الاستمرارية الحالي أدوات حفظ الحالة بأنها محددة بالموضوع ويقول إن التطبيق يصل إلى الحالة عن طريق تمرير thread_id. راجع دليل استمرارية LangGraph الرسمي.
InMemorySaver ممتاز للتأكد من أن توصيل الموضوع الخاص بك يعمل، لكنه يخزن نقاط التفتيش في ذاكرة الوصول العشوائي (RAM). يحذر LangGraph صراحةً من أن MemorySaver/InMemorySaver لا تستمر عبر عمليات إعادة تشغيل العملية.
الخطوة 3: حافظ على نفس thread_id لنفس المحادثة
الخطأ الأكثر شيوعًا على مستوى التطبيق هو إنشاء thread_id جديد في كل طلب HTTP. قد تعمل قاعدة البيانات بشكل مثالي بينما يبدأ كل طلب موضوع LangGraph مختلفًا.
على سبيل المثال، افترض أن الواجهة الأمامية لديك تحتوي على معرّف دردشة chat_8bf4. قم بتعيين هذه القيمة بشكل حتمي إلى موضوع LangGraph وأعد استخدامها لكل دور في تلك الدردشة. يجب أن تتلقى الدردشة الجديدة معرّف موضوع جديدًا.
رسم توضيحي تم إنشاؤه بالذكاء الاصطناعي: الاستمرارية لا تزيل حد سياق النموذج. يمكن أن يحتوي الموضوع المستقر على سجل أكثر مما يجب أن يتلقاه النموذج في كل استدعاء.
لا تستخدم thread_id دائمًا واحدًا لجميع الدردشات التي تنتمي إلى نفس المستخدم. هذا يدمج محادثات غير ذات صلة في تدفق حالة واحد. إذا كنت تستخدم PostgreSQL، فإن إرشادات استكشاف الأخطاء وإصلاحها الحالية في LangGraph تقول أيضًا إن thread_id يجب أن يبقى أقل من 255 حرفًا؛ UUID أو تجزئة حتمية أكثر أمانًا من كائن متسلسل ضخم.
الخطوة 4: استبدل الاستمرارية في الذاكرة قبل الإنتاج
بمجرد نجاح اختبار الطلبين، اختبر إعادة تشغيل العملية. احفظ حقيقة، أوقف التطبيق، ابدأه مرة أخرى، ثم اطلب الحقيقة بنفس معرّف الموضوع. إذا كنت لا تزال تستخدم InMemorySaver، فإن النسيان هو سلوك متوقع.
تظهر وثائق الذاكرة قصيرة المدى الرسمية إعداد إنتاج مدعوم بـ PostgreSQL باستخدام PostgresSaver:
from langchain.agents import create_agent
from langgraph.checkpoint.postgres import PostgresSaver
DB_URI = "postgresql://user:password@db-host/app"
with PostgresSaver.from_conn_string(DB_URI) as checkpointer:
checkpointer.setup()
agent = create_agent(
model="your-provider:your-model",
tools=[],
checkpointer=checkpointer,
)
للحصول على إعداد الحزمة الموثق حاليًا بواسطة LangChain، راجع الذاكرة قصيرة المدى. لا تضع بيانات اعتماد قاعدة البيانات الحقيقية مباشرة في كود المصدر؛ استخدم نظام إدارة الأسرار العادي الخاص بك.
رسم توضيحي تم إنشاؤه بالذكاء الاصطناعي: عنصر مهم بشكل خاص هو التخزين المحلي للعملية: أداة حفظ الحالة في الذاكرة تُفقد عمدًا بعد إعادة التشغيل، لذا فإن اختبارات إعادة التشغيل تنتمي إلى مجموعة اختبارات الذاكرة.
الخطوة 5: إدارة السجلات الطويلة بدلاً من إرسال كل شيء للأبد
نافذة السياق هي كمية سياق الإدخال والإخراج التي يمكن للنموذج التعامل معها في استدعاء نموذج واحد. يمكن أن تحفظ نقاط التفتيش محادثة طويلة جدًا في التخزين، لكن هذا لا يعني أنه يجب إرسال كل رسالة تاريخية إلى النموذج للأبد.
تقول دليل الذاكرة قصيرة المدى في LangChain إن السجلات الطويلة يمكن أن تتجاوز نافذة سياق النموذج وأن النماذج القادرة على قبول السجل الكامل يمكن أن تشتت بسبب المحتوى القديم أو خارج الموضوع، مع ارتفاع زمن الاستجابة والتكلفة. الاستراتيجيات الموثقة هي التقليم، أو الحذف، أو التلخيص، أو تطبيق سياسة مخصصة.
استخدم التلخيص عندما تظل التفاصيل القديمة مهمة
SummarizationMiddleware هو الخيار المدمج الحالي لاستبدال السجل الأقدم بملخص مضغوط مع الاحتفاظ بالرسائل الحديثة. يمكن أن يعتمد مشغله على عدد الرموز، أو عدد الرسائل، أو جزء من سياق النموذج.
الأرقام أعلاه هي مثال على السياسة، وليست إعدادات عالمية. اختر العتبات بعد قياس مطالباتك الخاصة، ومخرجات الأدوات، وحدود سياق النموذج، وزمن الاستجابة، وجودة الملخص. راجع وثائق البرامج الوسيطة المدمجة في LangChain للخيارات الحالية المدعومة للمشغل والاحتفاظ.
رسم توضيحي تم إنشاؤه بالذكاء الاصطناعي: اختبر الاسترجاع بعد عدد كافٍ من الأدوار لتفعيل سياسة التقليم أو التلخيص الخاصة بك؛ يمكن أن تخفي الدردشة القصيرة أخطاء السياق الطويل.
لا تقم بتقليم رسائل الأداة بشكل أعمى
إذا قمت بتنفيذ حذف أو تقليم مخصص، فحافظ على تسلسل رسائل صالح. يحذر LangChain من أن العديد من مقدمي الخدمات يتطلبون أن يتبع رسالة المساعد التي تحتوي على استدعاءات أداة رسائل نتيجة الأداة المقابلة. يمكن أن يؤدي إزالة نصف هذا الزوج إلى أخطاء مقدم الخدمة أو سلوك نموذج محير.
الخطوة 6: انقل الحقائق الدائمة إلى متجر طويل المدى
المتجر (store) هو طبقة الاستمرارية في LangGraph لبيانات محددة من التطبيق خارج حالة رسم موضوع واحد. تستخدم وثائق LangChain الحالية المتاجر للمعلومات التي يجب أن تكون متاحة عبر المحادثات، مثل تفضيلات المستخدم، أو الحقائق، أو معرفة التطبيق المشتركة.
عناصر المتجر طويل المدى هي مستندات JSON منظمة بواسطة مساحة أسماء (namespace) ومفتاح (key). غالبًا ما تحتوي مساحة أسماء عملية على معرّف مستخدم أو منظمة:
هذا مختلف عن حفظ النص الكامل للمحادثة. قم بتخزين المعلومات التي يعاملها منتجك عمدًا على أنها دائمة. إذا كانت الحقيقة خاصة أو منظمة، فطبق سياسات الاحتفاظ، والتفويض، والتشفير، والحذف العادية الخاصة بك بدلاً من افتراض أن "ذاكرة الوكيل" معفاة منها.
رسم توضيحي تم إنشاؤه بالذكاء الاصطناعي: يستخدم هذا الرسم التوضيحي تسميات مفاهيمية واسعة بدلاً من أسماء واجهات برمجة التطبيقات الحالية الحرفية. لرمز LangChain v1 الجديد، استخدم التمييز بين أداة حفظ الحالة/المتجر الموصوف في النص والوثائق الرسمية.
استخدم متجرًا مدعومًا بقاعدة بيانات في الإنتاج
يظهر دليل الذاكرة طويلة المدى الرسمي كلًا من InMemoryStore وPostgresStore، ويشير صراحةً إلى أنه يجب استبدال التنفيذ في الذاكرة بمتجر مدعوم بقاعدة بيانات للإنتاج. كما يسرد تكاملات المتاجر خارج PostgreSQL. استخدم الخلفية التي تناسب متطلبات النشر والتشغيل الخاصة بك بدلاً من اختيار قاعدة بيانات متجهية لمجرد أن كلمة "ذاكرة" متضمنة.
أضف البحث الدلالي فقط عندما تحتاج إلى استرجاع غامض
يمكن تكوين متاجر LangGraph بفهرس بحيث يمكن لـ store.search() استرجاع العناصر حسب التشابه الدلالي. هذا مفيد عندما يكون لديك العديد من الذكريات ولا تعرف المفتاح الدقيق. لمجموعة صغيرة من التفضيلات المنظمة، غالبًا ما يكون البحث المباشر عن مساحة الأسماء/المفتاح أبسط وأكثر حتمية.
الخطوة 7: اجعل مسارات قراءة وكتابة الذاكرة صريحة
حفظ عنصر طويل المدى لا يضمن أن الوكيل سيستخدمه. لا يزال التطبيق بحاجة إلى مسار استرجاع. تسمح وكلاء LangChain الحالية للأدوات بالوصول إلى المتجر المقدم من خلال ToolRuntime.
from dataclasses import dataclass
from langchain.tools import tool, ToolRuntime
@dataclass
class Context:
user_id: str
@tool
def get_response_style(runtime: ToolRuntime[Context]) -> str:
store = runtime.store
if store is None:
return "No memory store configured"
namespace = ("users", runtime.context.user_id, "preferences")
item = store.get(namespace, "response_style")
return item.value["value"] if item else "default"
يمكنك أيضًا بناء مطالبات ديناميكية أو برامج وسيطة تقرأ الحالة والذاكرة الدائمة قبل استدعاء النموذج. القاعدة التصميمية المهمة هي أن مسار الاسترجاع يجب أن يكون قابلًا للملاحظة والاختبار. "المعلومات موجودة في مكان ما في قاعدة البيانات" لا يكفي.
رسم توضيحي تم إنشاؤه بالذكاء الاصطناعي: يطلب اختبار الانحدار المفيد حقيقة سابقة بعد العديد من الأدوار ويتحقق من أن الإجابة تأتي من طبقة الذاكرة المقصودة، وليس من نص مطالعة مكرر عن طريق الخطأ.
الخطوة 8: اختبر حدود الذاكرة الأربعة بشكل منفصل
يجب أن تغطي مجموعة اختبارات الذاكرة الموثوقة أكثر من "تذكر النموذج اسمي مرة واحدة". استخدم هذه الحالات الأربع على الأقل:
الاختبار
النتيجة المتوقعة
استدعاءان، نفس معرّف الموضوع
المعلومات المحددة بالموضوع متاحة
استدعاءان، معرّفات موضوع مختلفة
لا يتسرب سجل الموضوع قصير المدى
إعادة تشغيل التطبيق، نفس معرّف الموضوع مع أداة حفظ حالة دائمة
يمكن استئناف حالة الموضوع
موضوع جديد، نفس المستخدم مع متجر طويل المدى
يمكن استرجاع الحقائق الدائمة المخزنة عمدًا فقط
ثم أضف اختبار محادثة طويلة يتجاوز عتبة التلخيص الخاصة بك. تأكد من أن الحقائق الدائمة المهمة تبقى، وتبقى تسلسلات استدعاء الأدوات الأخيرة صالحة، ويبقى حجم المطالبة ضمن ميزانية السياق المستهدفة.
رسم توضيحي تم إنشاؤه بالذكاء الاصطناعي: تعامل مع هذا كقائمة تحقق مفاهيمية لضمان الجودة. يجب التحقق من بنية LangChain v1 الحالية مقابل واجهات برمجة التطبيقات الرسمية لأداة حفظ الحالة، والمتجر، والبرامج الوسيطة بدلاً من أمثلة فئات الذاكرة القديمة.
بنية إنتاجية دنيا
بالنسبة للعديد من تطبيقات الوكلاء، يبدو التصميم القوي على النحو التالي:
تستقبل واجهة برمجة التطبيقات user_id، وconversation_id، ورسالة المستخدم الجديدة.
يقوم التطبيق بتعيين conversation_id إلى thread_id ثابت في LangGraph.
تستعيد أداة حفظ الحالة الدائمة حالة الموضوع.
يسترجع المتجر طويل المدى فقط الحقائق الدائمة للمستخدم أو التطبيق المطلوبة للطلب.
يحافظ التلخيص أو التقليم على سجل النموذج ضمن ميزانية سياق مقاسة.
يقوم الوكيل بتشغيل الأدوات والنموذج.
تقوم أداة حفظ الحالة بإثبات حالة الموضوع المحدثة.
تُكتب الحقائق المعتمدة فقط في المتجر طويل المدى.
إذا كنت تنشر من خلال خادم وكيل LangGraph، فإن دليل الاستمرارية الحالي يقول إن الخادم يتعامل مع بنية الاستمرارية التحتية تلقائيًا، لذا لا تكرّر تلك الطبقة دون التحقق من نموذج النشر.
الأخطاء الشائعة التي تجعل الذاكرة تبدو معطلة
توليد thread_id جديد لكل طلب
هذا يخلق حالة محادثة جديدة في كل دور. سجل معرّف الموضوع بجوار معرّف دردشة التطبيق الخاص بك وتحقق من إعادة الاستخدام.
استخدام InMemorySaver في خدمة متعددة العمال أو قابلة لإعادة التشغيل
تختفي الحالة المحلية في ذاكرة الوصول العشوائي مع العملية وقد لا تكون مشتركة عبر العمال. استخدم خلفية دائمة لاستمرارية الإنتاج.
افتراض أن أداة حفظ الحالة تحل مشكلة نافذة السياق
تحفظ أداة حفظ الحالة الحالة؛ فهي لا تضمن أن السجل المتزايد باستمرار مفيد للنموذج. أضف سياسة إدارة سياق صريحة.
وضع كل حقيقة تاريخية في المطالبة
المزيد من السياق ليس بالضرورة سياقًا أفضل. استرجع المعلومات ذات الصلة بالدور الحالي وحافظ على استمرارية المحادثة الأخيرة بشكل منفصل.
معاملة الملخصات كقاعدة بيانات مثالية
الملخصات هي تمثيلات مضغوطة مولدة من النموذج. إذا كان يجب أن تكون الحقيقة دقيقة—معرّف حساب، قيد تعاقدي، تفضيل معتمد من المستخدم، أو حالة سير عمل—فقم بتخزينها كبيانات منظمة بدلاً من الأمل في أنها تبقى عبر التلخيص المتكرر.
خلط النطاقات قصيرة المدى وطويلة المدى
لا يجب أن يصبح سجل الموضوع بصمت ملف تعريف مستخدم عالميًا. وبالعكس، لا يجب أن يعيش تفضيل مستخدم مقصود أن يتبع المستخدم عبر الدردشات فقط في موضوع واحد.
نسخ برامج تعليمية للذاكرة قبل الإصدار v1 دون التحقق من الاستيرادات
إذا بدأ مثال من سلاسل قديمة أو فئات ذاكرة قديمة، فقم بمقارنته بترحيل v1 الحالي ووثائق الذاكرة قبل استخدامه في تطبيق جديد.
قائمة تحقق تصحيح الأخطاء
تأكد من إنشاء الوكيل بأداة حفظ حالة.
سجل وقارن thread_id عبر الطلبات المتتالية.
افحص حالة الموضوع المخزنة قبل إلقاء اللوم على النموذج.
أعد تشغيل العملية وكرر اختبار نفس الموضوع.
استبدل InMemorySaver بأداة حفظ حالة دائمة للإنتاج.
قِس نمو الرسائل/الرموز عبر الدردشات الطويلة.
فعّل التلخيص أو التقليم قبل أن يصبح السجل مفرطًا.
حافظ على تسلسلات استدعاء/نتيجة الأدوات صالحة عند إزالة الرسائل.
انقل الحقائق عبر الموضوعات إلى متجر طويل المدى بمساحة أسماء.
اختبر موضوعًا جديدًا لنفس المستخدم للتحقق من الاسترجاع طويل المدى المقصود.
اختبر مستخدمًا مختلفًا للتحقق من عزل الذاكرة.
تتبع عناصر الذاكرة التي تم استرجاعها لكل إجابة.
الخلاصة
نادراً ما يتم حل فقدان ذاكرة وكيل LangChain بنافذة سياق أكبر واحدة. أولاً، اجعل حالة الموضوع دائمة بأداة حفظ حالة وthread_id ثابت. ثم تحكم في السجلات الطويلة بالتقليم أو SummarizationMiddleware. أخيرًا، ضع الحقائق التي يجب أن تبقى عبر المحادثات في متجر طويل المدى بمساحة أسماء واسترجعها عمداً.
يمنحك هذا الفصل شيئًا أكثر فائدة بكثير من "الذاكرة": نظام يمكنك إعادة تشغيله، وتوسيع نطاقه، واختباره، وتدقيقه، والتفكير فيه عندما يسأل المستخدم، "لماذا نسي الوكيل؟"