യഥാർത്ഥ ബാക്ക്പ്രഷറുമായി (Backpressure) Claude ബ്രൗസറിലേക്ക് സ്ട്രീം ചെയ്യുക

LLM ടോക്കണുകൾ സ്ട്രീം ചെയ്യുന്നത് 80% ശരിയായി ചെയ്യാൻ എളുപ്പമാണ്. എന്നാൽ ബാക്കിയുള്ള 20% കാര്യങ്ങളിലാണ് മിക്ക ഡെവലപ്പർമാരും പരാജയപ്പെടുന്നത്. സാധാരണ രീതിയിലുള്ള സെറ്റപ്പുകൾ നിങ്ങളുടെ ലോക്കൽ മെഷീനിൽ പ്രവർത്തിക്കും, എന്നാൽ സ്ലോ കണക്ഷനുകളിലോ വേഗതയേറിയ മോഡലുകളിലോ അവ തകരാറിലാകുന്നു.

നിങ്ങൾക്ക് പ്രൊഡക്ഷൻ-ഗ്രേഡ് (production-grade) സ്ട്രീമിംഗ് വേണമെന്നുണ്ടെങ്കിൽ, നിങ്ങൾ രണ്ട് പ്രത്യേക പ്രശ്നങ്ങൾ പരിഹരിക്കേണ്ടതുണ്ട്.

1. Nginx ബഫർ പ്രശ്നം (The Nginx Buffer Problem)

മിക്ക ഡെവലപ്പർമാരും X-Accel-Buffering ഹെഡർ മറന്നുപോകുന്നു. ഇത് no എന്ന് സെറ്റ് ചെയ്തില്ലെങ്കിൽ, Nginx നിങ്ങളുടെ സ്ട്രീം ബഫർ ചെയ്യും. മറുപടി പൂർണ്ണമായും ലഭിക്കുന്നത് വരെ ഉപയോക്താവിന് ഒന്നും കാണാൻ കഴിയില്ല. ഇത് സ്ട്രീമിംഗിന്റെ ഉദ്ദേശ്യത്തെ തന്നെ ഇല്ലാതാക്കുന്നു.

2. ഉപേക്ഷിക്കപ്പെട്ട സ്ട്രീം പ്രശ്നം (The Abandoned Stream Problem)

ഇതാണ് ഏറ്റവും വലിയ സാമ്പത്തിക നഷ്ടമുണ്ടാക്കുന്ന തെറ്റ്. മോഡൽ ജനറേറ്റ് ചെയ്തുകൊണ്ടിരിക്കുമ്പോൾ ഒരു ഉപയോക്താവ് ടാബ് ക്ലോസ് ചെയ്യുകയോ കണക്ഷൻ നഷ്ടപ്പെടുകയോ ചെയ്താൽ, സെർവർ പ്രവർത്തിച്ചുകൊണ്ടേയിരിക്കും. നിങ്ങളുടെ ലൂപ്പ് Claude-ൽ നിന്ന് ടോക്കണുകൾ വലിച്ചെടുച്ചുകൊണ്ടേയിരിക്കും. ആരും കാണാത്ത ഔട്ട്പുട്ടിനായി നിങ്ങൾ പണം നൽകേണ്ടി വരും.

പരിഹാരം: എൻഡ്-ടു-എൻഡ് അബോർട്ട്സ് (End-to-End Aborts)

നിങ്ങൾ റിക്വസ്റ്റ് സിഗ്നലിനെ Claude സ്ട്രീമുമായി ബന്ധിപ്പിക്കണം. ക്ലയന്റ് ഡിസ്കണക്ട് ചെയ്യുമ്പോൾ, സെർവർ ഉടൻ തന്നെ ജനറേഷൻ നിർത്തണം.

നിങ്ങളുടെ Next.js റൂട്ടിൽ, റിക്വസ്റ്റ് സിഗ്നൽ Anthropic SDK-ലേക്ക് പാസ്സ് ചെയ്യുക:

  • നിങ്ങളുടെ SDK കോളിൽ { signal: request.signal } ഉപയോഗിക്കുക.
  • അബോർട്ട് സിഗ്നലിനായി ഒരു ഇവന്റ് ലിസണർ (event listener) ചേർക്കുക.
  • ഒരു അബോർട്ട് സംഭവിക്കുമ്പോൾ llm.abort() ഉം controller.close() ഉം വിളിക്കുക.

ഇത് ജനറേഷൻ നിർത്തുകയും നിങ്ങളുടെ ബില്ല് വർദ്ധിക്കുന്നത് തടയുകയും ചെയ്യുന്നു.

ഫ്രണ്ട് എൻഡിൽ (On the Frontend)

ബ്രൗസർ ചങ്ക്സ് (chunks) ലഭിക്കുന്നത് ക്രമരഹിതമായ അതിർവരമ്പുകളിലാണ്. നിങ്ങൾ ഈ ചങ്ക്സ് ബഫർ ചെയ്യുകയും SSE ഡെലിമിറ്റർ (delimiter) ഉപയോഗിച്ച് അവയെ വിഭജിക്കുകയും വേണം.

  • നിങ്ങളുടെ fetch കോളിൽ ഒരു AbortController ഉപയോഗിക്കുക.
  • ആ കൺട്രോളർ നിങ്ങളുടെ React കമ്പോണന്റിലേക്ക് തിരികെ നൽകുക.
  • കമ്പോണന്റ് ക്ലീനപ്പ് ഫങ്ക്ഷനിൽ (cleanup function) controller.abort() വിളിക്കുക.

ഇത് അബോർട്ട് സിഗ്നൽ UI-ൽ നിന്ന് നിങ്ങളുടെ സെർവർ വരെ എത്തുന്നുണ്ടെന്ന് ഉറപ്പാക്കുന്നു.

പെർഫോമൻസിനായുള്ള ഒരു അവസാന ടിപ്പ്: വേഗതയേറിയ മോഡലുകൾ DOM റീപെയിന്റ് (repaint) ചെയ്യുന്നതിനേക്കാൾ വേഗത്തിൽ ടോക്കണുകൾ പുറപ്പെടുവിക്കുന്നു. ഓരോ ടോക്കണിനും വേണ്ടി React സ്റ്റേറ്റ് അപ്ഡേറ്റ് ചെയ്യുന്നത് നിങ്ങളുടെ UI ലാഗ് (lag) ഉണ്ടാക്കും. ടോക്കണുകൾ ബഫർ ചെയ്യുകയും ബാച്ചുകളായി (batches) അപ്ഡേറ്റ് ചെയ്യുകയും ചെയ്യുക. ഇത് നിങ്ങളുടെ ഇന്റർഫേസ് സുഗമമായി നിലനിർത്തും.

ഡെമോയ്ക്ക് മാത്രമുള്ള സ്ട്രീമുകൾ നിർമ്മിക്കുന്നത് നിർത്തുക. പണം ലാഭിക്കാനും കരുത്തുറ്റ ആപ്പുകൾ നിർമ്മിക്കാനും പ്രോക്സി ബഫറിംഗ് (proxy buffering) ഒഴിവാക്കുകയും അബോർട്ടുകൾ പ്രൊപ്പഗേറ്റ് (propagate) ചെയ്യുകയും ചെയ്യുക.

Source: https://dev.to/pavelespitia/streaming-claude-to-the-browser-with-backpressure-that-actually-works-4oaf

Optional learning community: https://t.me/GyaanSetuAi