حصل وكلاء LangGraph أخيراً على طريقة موثوقة للحفاظ على حالتهم بعد أسابيع من فقدان البيانات الصامت. فبعد ثلاث حيل فاشلة لحفظ نقاط التحقق (checkpointing)—وهي SQLite، وتخزين الكائنات الخام (raw object storage)، ونسخة معطلة من كل منهما—استقر المؤلف على نمط التحديث الذري (atomic-update pattern) الذي يمنع الوكلاء من البدء من الصفر في كل مرة يصل فيها طلب.
لماذا تهم عملية حفظ نقاط التحقق (checkpointing) في LangGraph
يتيح LangGraph للمطورين ربط استدعاءات LLM معاً في "وكلاء" (agents) قابلين لإعادة الاستخدام، يمكنهم تذكر ما حدث سابقاً في المحادثة. يقوم هؤلاء الوكلاء بتقسيم طلب المستخدم إلى مهام فرعية، وتخزين النتائج الوسيطة، ثم الاستئناف من حيث توقفوا في الاستدعاء التالي. إذا اختفت الحالة المخزنة، يقوم الوكيل بإعادة حساب كل شيء، مما يؤدي إلى إهدار موارد الحوسبة، وزيادة زمن الاستجابة (latency)، وتقديم تجربة مستخدم سيئة. وفي حالة بوت إنتاجي يتعامل مع رسائل Telegram، أدى فقدان البيانات إلى محو تاريخ المحادثات لأسابيع.
الإصلاح الأول: SqliteSaver
يعمل SqliteSaver المدمج بشكل جيد عندما تقوم نسخة واحدة فقط بتشغيل الوكيل. فهو يكتب كل نقطة تحقق ككتلة JSON في ملف SQLite محلي. بدأت المشاكل عندما أضاف المطور حقلاً جديداً إلى نوع AgentState وأعاد النشر. كانت نقاط التحقق الموجودة، والتي تم إنشاؤها قبل تغيير المخطط (schema)، تفتقر إلى الحقل الجديد. ولأن SqliteSaver لا يقوم أبداً بعملية ترحيل (migration)، قام LangGraph بتحميل ملف JSON غير المكتمل، وتجاهل البيانات المفقودة، مما جعل الوكيل يبدأ من البداية.
نقطة رئيسية: تخزين SQLite هو أداة للعروض التجريبية (demo)، وليس حلاً جاهزاً للإنتاج عندما يتطلب الأمر تطور المخطط (schema evolution).
الإصلاح الثاني: تخزين الكائنات (Object storage)
للحصول على تحكم أكبر في تنسيق التسلسل (serialization format)، كتب المؤلف منقذاً مخصصاً يقوم برفع نقطة تحقق JSON إلى Oracle Cloud Object Storage. منحت هذه الخطوة مرونة في إصدار المخطط يدوياً، لكنها أدخلت نمط فشل جديداً. فعندما يصل طلبان إلى نفس سلسلة المحادثة في وقت واحد، يحاول كلاهما الكتابة فوق الكائن نفسه. تم تحسين خدمات تخزين الكائنات لأنماط "الكتابة مرة واحدة، والقراءة مرات عديدة"؛ فهي لا توفر دلالات الكتابة الذرية (atomic overwrite semantics). أدت حالة التسابق (race condition) إلى إنتاج ملفات JSON مشوهة أو مبتورة، وفقد الوكيل سياقه مرة أخرى.
نقطة رئيسية: عمليات الكتابة المباشرة في تخزين الكائنات ليست آمنة عندما يمكن لعدة عمال (workers) الوصول إلى نفس المفتاح في نفس الوقت.
الإصلاح الثالث: التحديثات الذرية مع الإصدارات
يجمع التصميم النهائي المستقر بين فكرتين: أرقام إصدارات صريحة وعمليات كتابة مشروطة بناءً على معرف ETag الخاص بالكائن (وهو معرف المجموع التدقيقي لخدمة التخزين).
- اقرأ نقطة التحقق الحالية والتقط معرف ETag الخاص بها.
- زد حقل الإصدار داخل غلاف نقطة التحقق.
- اكتب نقطة التحقق المحدثة باستخدام طلب مشروط ينجح فقط إذا تطابق ETag مع المعرف الذي تمت قراءته سابقاً.
- أعد محاولة حلقة (القراءة-الزيادة-الكتابة) كاملة إذا فشلت الكتابة المشروطة بسبب قيام عملية أخرى بتغيير الكائن.
بما أن الكتابة تنجح فقط عندما لا تكون أي عملية أخرى قد غيرت الملف، يمكن لعامل واحد فقط اعتماد حالة جديدة في كل مرة. كما يسهل حقل الإصدار اكتشاف نقاط التحقق القديمة وترحيلها للأمام عند تغيير المخطط.
يعمل هذا النمط مع تخزين الكائنات الذي يدعم عمليات الكتابة المشروطة القائمة على ETag.
دروس لمهندسي الذكاء الاصطناعي
- استخدم SQLite للنماذج الأولية فقط. يحتاج وكلاء الإنتاج إلى مخزن يمكنه التعامل مع تغييرات المخطط وعمليات الكتابة المتزامنة.
- خطط لعمليات ترحيل المخطط (schema migrations) بنفسك. تصف القواميس المحددة النوع (Typed dictionaries) الأشكال للتحليل الساكن ولكنها لا تفرض الهيكل في وقت التشغيل.
- عامل الحالة كمورد مشترك. تظهر أخطاء التزامن على شكل فقدان صامت للبيانات؛ وهي أصعب في التصحيح من الاستثناءات الصريحة.
- استخدم المكونات الأساسية للسحابة. توفر عمليات الكتابة المشروطة القائمة على ETag قفلاً متفائلاً (optimistic locking) منخفض التكلفة دون الحاجة إلى خدمة قفل منفصلة.
- سجل كل خطوة. الفشل الصامت — مثل حقل مفقود يتجاهله LangGraph — هو الأصعب في التتبع.
ما التالي لعملية حفظ نقاط التحقق في LangGraph؟
بالنسبة للفرق التي واجهت نفس العقبات بالفعل، توفر وصفة التحديث الذري حلاً سريعاً ومنخفض التكلفة. وهي تظهر أن خط إنتاج موثوق للإنتاج لا يتطلب مخزن حالة ضخمًا، بل يتطلب فقط تعاملاً دقيقاً مع التزامن والإصدارات.
الخلاصة: غلاف بسيط مع إصدارات بالإضافة إلى عمليات كتابة مشروطة يحول نظاماً غير مستقر إلى نظام موثوق، مما يسمح لمهندسي الذكاء الاصطناعي بالتركيز على منطق الوكيل بدلاً من التصحيح اللامتناهي لفقدان البيانات.
