𝟯 LangGraph રીરાઈટ્સ: પ્રોડક્શન ચેકપોઈન્ટિંગે મને શું શીખવ્યું
ત્રણ અઠવાડિયા સુધી, અમારા ઓનબોર્ડિંગ એજન્ટે તે દરેક જોબ ગુમાવી દીધી જે તેણે સેવ કરવાની હતી. લોગ્સમાં કંઈ દેખાતું નહોતું. કોઈ એરર નહીં. કોઈ વોર્નિંગ નહીં. ચેકપોઈન્ટરે સફળતા દર્શાવી, પરંતુ રિઝ્યુમ (resume) કરતી વખતે સ્ટેટ (state) ગાયબ થઈ ગયું.
સત્ય સમજતા પહેલા મેં એક જ LangGraph પાઇપલાઇનને ત્રણ વાર ફરીથી લખી. ફ્રેમવર્ક એ જ કરી રહ્યું હતું જે મેં તેને કરવાનું કહ્યું હતું. હું ફક્ત તેને ખોટા નિર્દેશો આપી રહ્યો હતો.
જો તમે પ્રોડક્શન માટે સ્ટેટફુલ (stateful) એજન્ટ્સ બનાવો છો, તો એવું ન માનો કે ડિફોલ્ટ સેટિંગ્સ તમને બચાવી લેશે. અહીં શું તૂટ્યું અને મેં તેને કેવી રીતે સુધાર્યું તે છે.
𝗧𝗵𝗲 𝗙𝗶𝗿𝘀𝘁 𝗕𝗿𝗲𝗮𝗸: 𝗦𝗶𝗹𝗲𝗻𝘁 𝗦𝘁𝗮𝘁𝗲 𝗟𝗼𝘀𝘀
મારો એજન્ટ પાંચ-સ્ટેપના ઓનબોર્ડિંગ ફ્લોને હેન્ડલ કરતો હતો. મેં પ્રોગ્રેસ સેવ કરવા માટે Postgres નો ઉપયોગ કર્યો જેથી યુઝર્સ પછીથી રિઝ્યુમ કરી શકે. પરંતુ દરેક રિઝ્યુમ સ્ટેપ વનથી જ શરૂ થતું હતું.
તેનું કારણ મારું સ્ટેટ સ્કીમા (state schema) હતું. LangGraph માં, દરેક નોડ એક અપડેટ રિટર્ન કરે છે જે સ્ટેટમાં મર્જ થાય છે. જો તમે કેવી રીતે મર્જ કરવું તે સ્પષ્ટ ન કરો, તો ડિફોલ્ટ રીતે તે ઓવરરાઈટ (overwrite) થઈ જાય છે.
મને લાગ્યું કે મારી મેસેજ લિસ્ટમાં નવા મેસેજ ઉમેરાશે (append થશે). તેના બદલે, દરેક નવા નોડે આખી હિસ્ટ્રીને બદલીને માત્ર એક જ મેસેજ કરી દીધો. ચેકપોઈન્ટરે ખોટો ડેટા બરાબર રીતે સેવ કરી લીધો હતો.
ઉકેલ: સ્પષ્ટ રિડ્યુસર્સ (reducers) સાથે Annotated ફીલ્ડ્સનો ઉપયોગ કરો.
• મેસેજ લિસ્ટ માટે add ઓપરેટરનો ઉપયોગ કરો. • ડિક્શનરીઝ માટે કસ્ટમ મર્જ ફંક્શનનો ઉપયોગ કરો. • "step" જેવા સિંગલ વેલ્યુઝ માટે જ ડિફોલ્ટ ઓવરરાઈટનો ઉપયોગ કરો.
𝗧𝗵𝗲 𝗦𝗲𝗰𝗼𝗻𝗱 𝗕𝗿𝗲𝗮𝗸: 𝗗𝗲𝘀𝗲𝗿𝗶𝗮𝗹𝗶𝘇𝗮𝘁𝗶𝗼𝗻 𝗮𝗻𝗱 𝗖𝗼𝗻𝗰𝘂𝗿𝗿𝗲𝗻𝗰𝘆
બીજા રીરાઈટમાં બે નવી સમસ્યાઓ આવી:
- કરપ્ટ રોઝ (Corrupt rows): મેં સ્ટેટમાં કસ્ટમ ઓબ્જેક્ટ્સ સ્ટોર કર્યા હતા. સિરિયલાઈઝર તેને હેન્ડલ કરી શકતું નહોતું. આના કારણે એવી રોઝ (rows) બની જે અસ્તિત્વમાં તો હતી પણ ઉપયોગી નહોતી.
- ડુપ્લીકેટ કીઝ (Duplicate keys): જો તમે ઝડપથી જવાબ ન આપો તો WhatsApp વેબહુક્સ (webhooks) ને ફરીથી ટ્રાય કરે છે. જો એકસાથે બે મેસેજ આવે, તો ગ્રાફના બે રન એક જ થ્રેડમાં લખવાનો પ્રયાસ કરે છે. આના કારણે ડેટાબેઝ કોલિઝન (collisions) થાય છે.
ઉકેલો: • કસ્ટમ ઓબ્જેક્ટ્સ દૂર કરો. ફક્ત પ્લેન ડિક્ટ્સ (dicts) અને સ્ટાન્ડર્ડ LangChain પ્રકારોનો જ ઉપયોગ કરો. • વેબહુક્સને ગ્રાફની બહાર હેન્ડલ કરો. ડુપ્લીકેટ્સને રોકવા માટે ક્યુ (queue) અને આઈડેમપોટન્સી કી (idempotency key) નો ઉપયોગ કરો. • ડેટાબેઝ લોક ઉમેરો. ખાતરી કરો કે એક સમયે એક થ્રેડ દીઠ માત્ર એક જ રન થાય.
𝗧𝗵𝗲 𝗧𝗵𝗶𝗿𝗱 𝗥𝗲𝘄𝗿𝗶𝘁𝗲: 𝗧𝗵𝗲 𝗦𝘁𝗮𝗯𝗹𝗲 𝗣𝗮𝘁𝘁𝗲𝗿𝗻
અંતિમ વર્ઝન ત્રણ સિદ્ધાંતો પર કેન્દ્રિત હતું:
• નાના ગ્રાફ્સ: મેં એક વિશાળ ગ્રાફને ત્રણ નાના સબ-ગ્રાફ્સમાં વિભાજિત કર્યો. આનાથી બગ્સની અસરનું ક્ષેત્ર (blast radius) ઘટી ગયું. • સ્પષ્ટ ચેકપોઈન્ટ્સ: મેં દરેક નોડ પછી ચેકપોઈન્ટિંગ કરવાનું બંધ કરી દીધું. હું ફક્ત અર્થપૂર્ણ રિઝ્યુમ પોઈન્ટ્સ પર જ ચેકપોઈન્ટ કરું છું. આનાથી ડેટાબેઝ રાઈટ્સમાં 60% નો ઘટાડો થયો. • આઈડેમપોટન્ટ (Idempotent) નોડ્સ: આ અત્યંત મહત્વપૂર્ણ છે. જો કોઈ નોડ બે વાર ચાલે, તો તેણે સમાન પરિણામ આપવું જોઈએ. જો કોઈ નોડ જોવે કે સ્ટેટમાં કોઈ કાર્ય પહેલેથી જ પૂર્ણ થઈ ગયું છે, તો તેણે તરત જ રિટર્ન કરી દેવું જોઈએ. આ મોંઘા મોડેલ કોલ્સ માટે ડબલ ચાર્જ થતો અટકાવે છે.
તમારા માટે શીખવા જેવી બાબતો:
- કોડ લખતા પહેલા રિડ્યુસર સેમેન્ટિક્સ (reducer semantics) વાંચો.
- સ્ટેટમાં કસ્ટમ ઓબ્જેક્ટ્સ સ્ટોર કરશો નહીં.
- કન્કરન્સી કંટ્રોલ (concurrency control) ને ગ્રાફની બહાર લઈ જાઓ.
- દરેક નોડને આઈડેમપોટન્ટ (idempotent) બનાવો.
ફ્રેમવર્ક નિષ્ફળ ગયું નથી. મારી ધારણાઓ નિષ્ફળ ગઈ હતી.
વૈકલ્પિક લર્નિંગ કમ્યુનિટી: https://t.me/GyaanSetuAi