LangGraph एजंट्सना आठवड्यांच्या अदृश्य डेटा गळतीनंतर (silent data loss) त्यांचा 'स्टेट' (state) टिकवून ठेवण्यासाठी अखेर एक विश्वसनीय मार्ग सापडला आहे. तीन अयशस्वी चेकपॉइंटिंग पद्धती—SQLite, रॉ ऑब्जेक्ट स्टोरेज आणि त्यातील प्रत्येक पद्धतीचे दोषपूर्ण प्रकार—नंतर लेखकाला एका 'ॲटॉमिक-अपडेट पॅटर्न'वर (atomic-update pattern) मात करता आली, ज्यामुळे प्रत्येक विनंती आल्यावर एजंट्सना पुन्हा शून्यापासून सुरुवात करावी लागणार नाही.

LangGraph साठी चेकपॉइंटिंग का महत्त्वाचे आहे

LangGraph डेव्हलपर्सना LLM कॉल्स एकत्र करून पुन्हा वापरण्यायोग्य "एजंट्स" तयार करण्यास मदत करते, जे संभाषणात आधी काय झाले होते ते लक्षात ठेवू शकतात. हे एजंट्स वापरकर्त्याच्या विनंतीचे उप-कार्यांमध्ये (sub-tasks) विभाजन करतात, मध्यवर्ती निकाल साठवतात आणि पुढच्या कॉलवर जिथे थांबले होते तिथूनच पुन्हा सुरू करतात. जर साठवलेला 'स्टेट' गायब झाला, तर एजंट सर्व काही पुन्हा मोजतो (recomputes), ज्यामुळे कॉम्प्युट वाया जातो, लॅटन्सी (latency) वाढते आणि वापरकर्त्याचा अनुभव खराब होतो. टेलिग्राम मेसेज हाताळणाऱ्या प्रोडक्शन बॉटमध्ये, या डेटा गळतीमुळे आठवड्यांचा संभाषणाचा इतिहास पुसला गेला होता.

पहिला उपाय: SQLite सेव्हर

जेव्हा एखादा सिंगल इन्स्टन्स एजंट चालवतो, तेव्हा इन-बिल्ट SqliteSaver व्यवस्थित काम करते. हे प्रत्येक चेकपॉइंट एका स्थानिक SQLite फाईलमध्ये JSON ब्लब (blob) म्हणून लिहिते. समस्या तेव्हा सुरू झाली जेव्हा डेव्हलपरने AgentState प्रकारामध्ये नवीन फील्ड जोडले आणि पुन्हा डिप्लॉय (redeploy) केले. स्कीमा बदलापूर्वी तयार केलेले अस्तित्वातचे चेकपॉइंट्स त्या नवीन फील्डशिवाय होते. SqliteSaver कधीही मायग्रेशन रन करत नसल्यामुळे, LangGraph ने अपूर्ण JSON लोड केले, गहाळ डेटा काढून टाकला आणि एजंटने सुरुवातीपासून पुन्हा सुरुवात केली.

महत्त्वाचा मुद्दा: जेव्हा स्कीमा इव्होल्यूशनची (schema evolution) आवश्यकता असते, तेव्हा SQLite स्टोरेज हे केवळ डेमो टूल आहे, प्रोडक्शन-रेडी सोल्यूशन नाही.

दुसरा उपाय: ऑब्जेक्ट स्टोरेज

सिरियलायझेशन फॉरमॅटवर (serialization format) नियंत्रण मिळवण्यासाठी, लेखकाने एक कस्टम सेव्हर लिहिला जो JSON चेकपॉइंट Oracle Cloud Object Storage वर अपलोड करत असे. या बदलामुळे स्कीमा मॅन्युअली व्हर्जन करण्याची लवचिकता मिळाली, परंतु यामुळे एक नवीन त्रुटी निर्माण झाली. जेव्हा दोन विनंत्या एकाच वेळी एकाच कन्वर्सेशन थ्रेडवर आल्या, तेव्हा दोन्ही विनंत्यांनी एकाच ऑब्जेक्टवर ओव्हरराईट करण्याचा प्रयत्न केला. ऑब्जेक्ट स्टोरेज सेवा 'write-once, read-many' पॅटर्नसाठी ऑप्टिमाइझ केलेल्या असतात; त्या ॲटॉमिक ओव्हरराईट सिमेंटिक्स प्रदान करत नाहीत. या रेस कंडिशनमुळे (race condition) चुकीच्या किंवा अपूर्ण JSON फाईल्स तयार झाल्या आणि एजंटने पुन्हा आपला संदर्भ (context) गमावला.

महत्त्वाचा मुद्दा: जेव्हा एकाच वेळी अनेक वर्कर्स एकाच की (key) वर काम करू शकतात, तेव्हा ऑब्जेक्ट स्टोरेजमधील साधे ओव्हरराईट्स सुरक्षित नसतात.

तिसरा उपाय: व्हर्जनिंगसह ॲटॉमिक अपडेट्स

अंतिम आणि स्थिर डिझाइन दोन कल्पनांचे मिश्रण आहे: स्पष्ट व्हर्जन नंबर आणि ऑब्जेक्टच्या ETag (स्टोरेज सर्व्हिसचा चेकसम आयडेंटिफायर) वर आधारित कंडिशनल राइट्स (conditional writes).

  1. वाचा (Read) सध्याचा चेकपॉइंट आणि त्याचा ETag कॅप्चर करा.
  2. वाढवा (Increment) चेकपॉइंट एनव्हलपमधील एक व्हर्जन फील्ड.
  3. लिहा (Write) अपडेटेड चेकपॉइंट एका कंडिशनल रिक्वेस्टचा वापर करून लिहा, जी केवळ तेव्हाच यशस्वी होईल जर ETag आधी वाचलेल्या ETag शी जुळत असेल.
  4. पुन्हा प्रयत्न करा (Retry) जर कंडिशनल राइट अयशस्वी झाले (कारण दुसऱ्या प्रक्रियेने ऑब्जेक्ट बदलला आहे), तर संपूर्ण 'रीड-इन्क्रिमेंट-राईट' लूप पुन्हा करा.

कारण ही प्रक्रिया केवळ तेव्हाच यशस्वी होते जेव्हा इतर कोणत्याही प्रक्रियेने फाईलमध्ये बदल केलेला नसतो, त्यामुळे एका वेळी फक्त एकच वर्कर नवीन स्टेट कमिट करू शकतो. व्हर्जन फील्डमुळे जुने (stale) चेकपॉइंट्स शोधणे आणि स्कीमा बदलल्यावर ते पुढे मायग्रेट करणे देखील सोपे होते.

ही पद्धत ETag-आधारित कंडिशनल राइट्सला सपोर्ट करणाऱ्या ऑब्जेक्ट स्टोरेजसोबत काम करते.

AI इंजिनिअर्ससाठी धडे

  • SQLite चा वापर फक्त प्रोटोटाइपसाठी करा. प्रोडक्शन एजंट्सना अशा स्टोअरची गरज असते जे स्कीमा बदल आणि कन्करंट राइट्स हाताळू शकेल.
  • स्कीमा मायग्रेशन स्वतः प्लॅन करा. टायप्ड डिक्शनरीज (Typed dictionaries) स्टॅटिक अनालिसिससाठी आकार दर्शवतात पण रनटाइम स्ट्रक्चर लागू करत नाहीत.
  • स्टेटला एक सामायिक संसाधन (shared resource) म्हणून पहा. कन्करन्सी बग्स अदृश्य डेटा गळती म्हणून समोर येतात; ते थेट एररपेक्षा शोधणे अधिक कठीण असतात.
  • क्लाउड प्रिमिटिव्हजचा (cloud primitives) वापर करा. ETag-आधारित कंडिशनल राइट्स वेगळ्या लॉक सर्व्हिसशिवाय स्वस्त 'ऑप्टिमिस्टिक लॉकिंग' प्रदान करतात.
  • प्रत्येक पायरी लॉग करा. अदृश्य त्रुटी—जसे की एखादे गहाळ फील्ड ज्याकडे LangGraph दुर्लक्ष करते—त्यांचा मागोवा घेणे सर्वात कठीण असते.

LangGraph चेकपॉइंटिंगसाठी पुढे काय?

ज्या टीम्सना आधीच अशाच अडचणींचा सामना करावा लागला आहे, त्यांच्यासाठी हे 'ॲटॉमिक-अपडेट' रेसिपी एक जलद आणि कमी खर्चाचा उपाय आहे. हे दर्शवते की एका विश्वसनीय प्रोडक्शन पाईपलाईनसाठी हेवीवेट स्टेट स्टोअरची गरज नसते—केवळ कन्करन्सी आणि व्हर्जनिंगचे काळजीपूर्वक व्यवस्थापन आवश्यक आहे.

निष्कर्ष: एक साधे व्हर्जन केलेले एनव्हलप आणि कंडिशनल राइट्स एका अस्थिर सिस्टीमला विश्वसनीय सिस्टीममध्ये बदलू शकतात, ज्यामुळे AI इंजिनिअर्सना डेटा लॉसच्या डीबगिंगऐवजी एजंट लॉजिकवर लक्ष केंद्रित करणे सोपे जाते.