Computer >> कंप्यूटर ट्यूटोरियल >  >> प्रोग्रामिंग >> Redis

सर्वर-सेंट इवेंट्स (SSE) का उपयोग करके नेक्स्ट.जेएस में रियल-टाइम LLM स्ट्रीमिंग

AI-संचालित एप्लिकेशन जो तेजी से प्रतिक्रिया देते हैं, यूजर एक्सपीरियंस को तत्काल सुना और देखा महसूस कराकर बढ़ाते हैं। स्ट्रीमिंग के साथ, आप ऐसे चैटबॉट बना सकते हैं जो क्वेरी को तुरंत संबोधित करते हैं या रियल-टाइम में व्यक्तिगत सिफारिशें प्रदान करते हैं। यह केवल गति के बारे में नहीं है - यह यूजर की जरूरतों को तुरंत पूरा करने के बारे में है, इसके कथित मूल्य को बढ़ाता है।

स्ट्रीमिंग में डेटा को एक बड़े ब्लॉक के बजाय छोटे, निरंतर चंक्स में भेजना शामिल है। AI एप्लिकेशन के संदर्भ में, जैसे चैटबॉट या सिफारिश सिस्टम, स्ट्रीमिंग का अर्थ है आंशिक प्रतिक्रियाओं को यूजर्स को भेजना जैसे ही वे उपलब्ध होती हैं, पूरे प्रतिक्रिया को संकलित और वितरित करने की प्रतीक्षा करने के बजाय। यह दृष्टिकोण सुनिश्चित करता है कि यूजर्स को तत्काल फीडबैक या जानकारी प्राप्त हो, जिससे अधिक गतिशील और प्रतिक्रियाशील यूजर एक्सपीरियंस बनता है।

इस गाइड में, आप सीखेंगे कि सर्वर-सेंट इवेंट्स (SSE) का उपयोग करके नेक्स्ट.जेएस एंडपॉइंट्स में LangChain और OpenAI के भाषा मॉडल के साथ स्ट्रीमिंग को कैसे लागू किया जाए। इसके अलावा, आप अपस्टैश के साथ स्ट्रीमिंग प्रतिक्रियाओं को कैश करना सीखेंगे।

पूर्वापेक्षाएँ

आपको निम्नलिखित की आवश्यकता होगी:

  • Node.js 18 या बाद का संस्करण
  • एक OpenAI खाता
  • एक Upstash खाता
  • एक Vercel खाता

टेक स्टैक

प्रौद्योगिकीविवरण
Upstashसर्वरलेस डेटाबेस प्लेटफॉर्म। आप OpenAI API प्रतिक्रियाओं को कैश करने के लिए Upstash Redis का उपयोग करेंगे।
OpenAIउन्नत AI प्रौद्योगिकियों के विकास पर केंद्रित एक कृत्रिम बुद्धिमत्ता अनुसंधान प्रयोगशाला।
LangChainभाषा मॉडल द्वारा संचालित एप्लिकेशन विकसित करने के लिए फ्रेमवर्क।
Next.jsवेब के लिए रिएक्ट फ्रेमवर्क।
Vercelवेब एप्लिकेशन को तैनात और स्केल करने के लिए क्लाउड प्लेटफॉर्म।

OpenAI टोकन जनरेट करें

OpenAI API का उपयोग करके, आप AI का उपयोग करके चैटबॉट प्रतिक्रियाएं बनाने में सक्षम हैं। OpenAI API के किसी भी अनुरोध के लिए एक प्राधिकरण टोकन की आवश्यकता होती है। टोकन प्राप्त करने के लिए, अपने OpenAI खाते में API Keys पर जाएं, और Create new secret key बटन पर क्लिक करें। बाद में उपयोग के लिए OPENAI_API_KEY एनवायरनमेंट वेरिएबल के रूप में इस टोकन को कॉपी और सुरक्षित रूप से स्टोर करें।

Upstash Redis सेट करना

एक बार जब आप एक Upstash खाता बना लेते हैं और लॉग इन हो जाते हैं, तो आप Redis टैब पर जाएंगे और एक डेटाबेस बनाएंगे।

सर्वर-सेंट इवेंट्स (SSE) का उपयोग करके नेक्स्ट.जेएस में रियल-टाइम LLM स्ट्रीमिंग

सर्वर-सेंट इवेंट्स (SSE) का उपयोग करके नेक्स्ट.जेएस में रियल-टाइम LLM स्ट्रीमिंग

नीचे स्क्रॉल करें जब तक आपको REST API सेक्शन न मिल जाए और .env बटन चुनें। सामग्री को कॉपी करें और इसे कहीं सुरक्षित रखें।

सर्वर-सेंट इवेंट्स (SSE) का उपयोग करके नेक्स्ट.जेएस में रियल-टाइम LLM स्ट्रीमिंग

एक नया Next.js एप्लिकेशन बनाएं

आइए एक नया Next.js प्रोजेक्ट बनाकर शुरू करें। अपना टर्मिनल खोलें और निम्न कमांड चलाएं:

npx create-next-app@latest my-app

जब संकेत दिया जाए, तो चुनें:

  • TypeScript का उपयोग करने के लिए Yes।
  • ESLint का उपयोग करने के लिए No।
  • Tailwind CSS का उपयोग करने के लिए Yes।
  • src/ डायरेक्टरी का उपयोग करने के लिए No।
  • App Router का उपयोग करने के लिए Yes।
  • डिफ़ॉल्ट आयात उपनाम (@/*) को कस्टमाइज़ करने के लिए No।

एक बार यह हो जाने के बाद, प्रोजेक्ट डायरेक्टरी में जाएं और निम्न कमांड निष्पादित करके ऐप को डेवलपमेंट मोड में शुरू करें:

cd my-app
npm run dev

ऐप localhost:3000 पर चलना चाहिए। LangChain निर्भरताओं को एप्लिकेशन में इंस्टॉल करने के लिए डेवलपमेंट सर्वर को रोकें:

npm install @langchain/openai @langchain/community

कमांड ने निम्न लाइब्रेरी इंस्टॉल की:

  • @langchain/openai: OpenAI मॉडल की श्रृंखला के साथ इंटरफेस करने के लिए एक LangChain पैकेज।
  • @langchain/community: LangChain कोर के साथ प्लग-एन-प्ले के लिए थर्ड-पार्टी इंटीग्रेशन का एक संग्रह।

अब, अपने प्रोजेक्ट के रूट पर एक .env फाइल बनाएं। आप पहले प्राप्त OPENAI_API_KEY जोड़ेंगे।

यह कुछ इस तरह दिखना चाहिए:

# .env
# OpenAI Environment Variable
OPENAI_API_KEY="..."
# Upstash Redis Environment Variables
UPSTASH_REDIS_REST_URL="..."
UPSTASH_REDIS_REST_TOKEN="..."

Next.js में API एंडपॉइंट बनाने के लिए, आप Next.js Route Handlers का उपयोग करेंगे जो आपको वेब रिक्वेस्ट और रिस्पॉन्स APIs पर प्रतिक्रियाएं सर्व करने की अनुमति देते हैं। Next.js में एक API रूट बनाना शुरू करने के लिए जो यूजर को प्रतिक्रियाएं स्ट्रीम करता है, निम्न कमांड निष्पादित करें:

mkdir -p app/api/stream/completion/chat
mkdir app/lib

-p फ्लैग chat डायरेक्टरी के लिए पैरेंट डायरेक्टरी बनाता है यदि वे गायब हैं।

यह हमारे Next.js प्रोजेक्ट को सेट करता है। अब, आइए Upstash के साथ एक कैश हैंडलर बनाने पर आगे बढ़ें।

Upstash Redis कैश क्लाइंट इंस्टेंटिएट करें

UpstashRedisCache क्लास के साथ, आप OpenAI API प्रतिक्रियाओं को कैश करने के लिए कुछ ही लाइनों में एक Redis कैश क्लाइंट इनिशियलाइज़ कर सकते हैं। app/lib डायरेक्टरी के अंदर upstashCache.tsx नामक एक फाइल बनाएं:

कैश हैंडलर का उपयोग करके, OpenAI API द्वारा जनरेट की गई बातचीत या पूर्ण प्रतिक्रियाओं को कैश करना सुपर आसान हो जाता है। आइए समझते हैं कि आप Next.js में सर्वर-सेंट इवेंट्स का उपयोग कैसे शुरू कर सकते हैं।

Next.js App Router में सर्वर-सेंट इवेंट्स API बनाना

सर्वर-सेंट इवेंट्स (SSE) आपको निरंतर पोलिंग की आवश्यकता के बिना सर्वर से क्लाइंट को रियल-टाइम डेटा अपडेट देने की अनुमति देते हैं। SSE एकल, लंबे समय तक चलने वाले HTTP कनेक्शन पर डेटा के एकदिशात्मक प्रवाह को सक्षम करता है।

app/api/stream डायरेक्टरी में निम्न कोड के साथ route.ts नामक एक फाइल बनाएं ताकि सर्वर-सेंट इवेंट्स का उपयोग करके प्रतिक्रियाओं को स्ट्रीम करने के लिए आवश्यक न्यूनतम सेटअप को समझा जा सके:

// File: app/api/stream/route.ts
// इस रूट की प्रतिक्रिया को Vercel पर कैश होने से रोकता है
export const dynamic = "force-dynamic";
export async function POST(request: Request) {
  const encoder = new TextEncoder()
  // एक स्ट्रीमिंग प्रतिक्रिया बनाएं
  const customReadable = new ReadableStream({
    start(controller) {
      const message = "A sample message."
      controller.enqueue(encoder.encode(`data: ${message}\n\n`))
    },
  })
  // स्ट्रीम प्रतिक्रिया लौटाएं और कनेक्शन को जीवित रखें
  return new Response(customReadable, {
    // सर्वर-सेंट इवेंट्स (SSE) के लिए हेडर सेट करें
    headers: {
      Connection: "keep-alive",
      "Content-Encoding": "none",
      "Cache-Control": "no-cache, no-transform",
      "Content-Type": "text/event-stream; charset=utf-8",
    },
  })
}

उपरोक्त कोड निम्न कार्य करता है:

  • dynamic कॉन्स्टेंट को force-dynamic पर सेट किया गया है, जो Vercel प्लेटफॉर्म पर प्रतिक्रियाओं के कैशिंग को रोकता है। यह सुनिश्चित करता है कि SSE स्ट्रीम के लिए प्रत्येक अनुरोध को ताजा डेटा मिले और कैश से सर्व न किया जाए।
  • क्लाइंट को भेजे जाने वाले डेटा की एक स्ट्रीम उत्पन्न करने के लिए एक ReadableStream बनाया जाता है। स्ट्रीम के start मेथड में, एक मैसेज एन्कोड किया जाता है और स्ट्रीम के कंट्रोलर में एन्क्यू किया जाता है। यह मैसेज SSE स्ट्रीम के हिस्से के रूप में क्लाइंट को भेजा जाएगा।
  • Response ऑब्जेक्ट को सर्वर-सेंट इवेंट्स के लिए विशिष्ट हेडर्स के साथ बनाया जाता है। इन हेडर्स में निम्न शामिल हैं:
    • Connection: keep-alive स्ट्रीमिंग के लिए कनेक्शन को खुला रखने के लिए।
    • Cache-Control: no-cache, no-transform ब्राउज़र में कैशिंग को रोकने के लिए।
    • Content-Type: text/event-stream; charset=utf-8 कंटेंट टाइप को सर्वर-सेंट इवेंट्स के रूप में निर्दिष्ट करने के लिए।
  • कस्टम ReadableStream वाला Response ऑब्जेक्ट एंडपॉइंट से लौटाया जाता है। यह प्रतिक्रिया SSE स्ट्रीम का अनुरोध करने वाले क्लाइंट्स को भेजी जाएगी।

इसके साथ, आपने एक एंडपॉइंट बनाया है जो प्रतिक्रियाओं को स्ट्रीम करने में सक्षम है। अगले सेक्शन में, आप समझेंगे कि LangChain कॉलबैक्स के साथ OpenAI से Completion और Chat Completion API प्रतिक्रियाओं को कैसे स्ट्रीम किया जाए।

LangChain कॉलबैक्स के साथ OpenAI Completion API प्रतिक्रियाओं को स्ट्रीम करना

OpenAI Completion API दिए गए प्रॉम्प्ट(एस) के आधार पर टेक्स्ट जनरेट करने के लिए एक शक्तिशाली उपकरण प्रदान करता है, जो कंटेंट जनरेशन और भाषा अनुवाद जैसे विभिन्न वास्तविक जीवन परिदृश्यों में उपयोगी है। LangChain कॉलबैक्स को एकीकृत करने से प्रतिक्रियाओं की रियल-टाइम स्ट्रीमिंग सक्षम होती है, जिससे एप्लिकेशन में कथित प्रतिक्रियाशीलता बढ़ जाती है।

app/lib डायरेक्टरी में completionModel.tsx नामक एक फाइल बनाएं, जो एक फंक्शन को परिभाषित करती है जो स्ट्रीमिंग सक्षम और LangChain कॉलबैक्स के साथ एक OpenAI इंस्टेंस को इनिशियलाइज़ करती है, जो रियल-टाइम में टेक्स्ट जनरेट करती है।

// File: app/lib/completionModel.tsx
import { OpenAI } from "@langchain/openai";
export const completionModel = (
  controller: ReadableStreamDefaultController,
  encoder: TextEncoder
) => new OpenAI({
  streaming: true,
  callbacks: [
    {
      handleLLMNewToken(token) {
        controller.enqueue(encoder.encode(`data: ${token}\n\n`));
      },
      async handleLLMEnd(output) {
        controller.close();
      },
    },
  ],
});

उपरोक्त कोड निम्न कार्य करता है:

  • @langchain/openai पैकेज से OpenAI क्लास आयात करता है।
  • completionModel नामक एक फंक्शन एक्सपोर्ट करता है जो दो पैरामीटर लेता है:
    • controller: एक ReadableStreamDefaultController ऑब्जेक्ट जो आपको स्ट्रीम में मैसेजेस एन्क्यू करने की अनुमति देता है।
    • encoder: एक TextEncoder ऑब्जेक्ट जो मैसेजेस को Uint8Array ऑब्जेक्ट में एन्कोड करता है।
  • निम्न कॉन्फिगरेशन विकल्पों के साथ OpenAI क्लास का एक नया इंस्टेंस बनाता है:
    • streaming: true पर सेट, यह दर्शाता है कि API को स्ट्रीमिंग प्रतिक्रियाएं लौटानी चाहिए।
    • callbacks: दो कॉलबैक फंक्शन वाले एक ऑब्जेक्ट युक्त एक सरणी, जिसका उपयोग LLM द्वारा प्रतिक्रिया निर्माण के प्रत्येक चरण को इंटरसेप्ट करने के लिए किया जाता है।
  • handleLLMNewToken: भाषा मॉडल द्वारा एक नया टोकन जनरेट होने पर आह्वान किया जाने वाला एक कॉलबैक। यह एन्कोडेड टोकन को कंट्रोलर में एन्क्यू करता है।
  • handleLLMEnd: एक एसिंक्रोनस कॉलबैक जो भाषा मॉडल जनरेशन पूरा होने पर आह्वान किया जाता है। यह कंट्रोलर को बंद करता है।

आगे, app/api/stream/completion डायरेक्टरी में निम्न कोड के साथ route.ts नामक एक फाइल बनाएं। आपके द्वारा पहले बनाए गए प्रारंभिक स्ट्रीमिंग रूट हैंडलर से परिवर्तनों को नीचे हाइलाइट किया गया है:

// File: app/api/stream/completion/route.ts
// इस रूट की प्रतिक्रिया को Vercel पर कैश होने से रोकता है
export const dynamic = "force-dynamic";
+ import { completionModel } from "@/app/lib/completionModel";
export async function POST(request: Request) {
+ // अनुरोध के बॉडी से यूजर मैसेज प्राप्त करें
+ const { message } = await request.json();
  const encoder = new TextEncoder();
  // एक स्ट्रीमिंग प्रतिक्रिया बनाएं
  const customReadable = new ReadableStream({
    async start(controller) {
+ // LangChain के साथ OpenAI से एक स्ट्रीमिंग प्रतिक्रिया जनरेट करें
+ await completionModel(controller, encoder).invoke(message);
    },
  });
  // स्ट्रीम प्रतिक्रिया लौटाएं और कनेक्शन को जीवित रखें
  return new Response(customReadable, {
    // सर्वर-सेंट इवेंट्स (SSE) के लिए हेडर सेट करें
    headers: {
      Connection: "keep-alive",
      "Content-Encoding": "none",
      "Cache-Control": "no-cache, no-transform",
      "Content-Type": "text/event-stream; charset=utf-8",
    },
  });
}

Next.js में एक स्ट्रीमिंग एंडपॉइंट बनाने के लिए आपने पहले जो किया था, उसके अलावा, उपरोक्त कोड परिवर्धन निम्न कार्य करते हैं:

  • completionModel फंक्शन आयात करता है।
  • request.json() का उपयोग करके अनुरोध बॉडी से यूजर मैसेज निकालता है।
  • ReadableStream के start मेथड के अंदर, completionModel फंक्शन को अनुरोध से प्राप्त मैसेज के साथ एसिंक्रोनसली आह्वान किया जाता है। यह फंक्शन LangChain के साथ OpenAI से एक स्ट्रीमिंग प्रतिक्रिया जनरेट करता है।

Upstash के साथ यूजर क्वेरी और उनकी प्रतिक्रियाओं को कैश करने के लिए, completionModel फंक्शन में Upstash Redis कैश क्लाइंट आयात करें:

import { OpenAI } from "@langchain/openai";
+ import cache from '@/app/lib/upstashCache';
export const completionModel = (
  controller: ReadableStreamDefaultController,
  encoder: TextEncoder
) => new OpenAI({
+ cache,
  streaming: true,
  temperature: 0.9,
  callbacks: [
    {
      handleLLMNewToken(token) {
        controller.enqueue(encoder.encode(token));
      },
      async handleLLMEnd(output) {
        console.log(output.generations[0][0].text);
        controller.close();
      },
    },
  ],
});

न्यूनतम परिवर्तनों के साथ, आपने Upstash के साथ OpenAI Completion API प्रतिक्रियाओं की कैशिंग सक्षम कर दी है।

अब, आइए जानें कि Next.js एंडपॉइंट्स में OpenAI Chat Completion API प्रतिक्रियाओं को कैसे स्ट्रीम किया जाए।

LangChain कॉलबैक्स के साथ OpenAI Chat Completion API प्रतिक्रियाओं को स्ट्रीम करना

OpenAI Chat Completion API प्रदान किए गए मैसेजेस के आधार पर रियल-टाइम बातचीत प्रतिक्रियाएं जनरेट करने के लिए एक शक्तिशाली उपकरण प्रदान करता है। एप्लिकेशन प्राकृतिक संवाद में संलग्न होने में सक्षम चैटबॉट बनाने से लेकर AI-संचालित इंटरैक्शन क्षमताओं के साथ ग्राहक सहायता सिस्टम को बढ़ाने तक फैले हुए हैं। यह डेवलपर्स को गतिशील और प्रतिक्रियाशील संवादात्मक इंटरफेस बनाने में सक्षम बनाता है।

app/lib डायरेक्टरी में chatCompletionModel.tsx नामक एक फाइल बनाएं, जो एक chatCompletionModel फंक्शन को परिभाषित करती है जो LangChain कॉलबैक्स के साथ OpenAI के Chat Completion API के लिए एक स्ट्रीमिंग इंटरफेस बनाती है, जो प्रदान किए गए मैसेजेस के आधार पर रियल-टाइम बातचीत जनरेशन की सुविधा प्रदान करती है।

// File: app/lib/chatCompletionModel.tsx
import { ChatOpenAI } from "@langchain/openai";
export type ConversationMessage = { role: string; content: string; };
export type ConversationMessages = ConversationMessage[];
export const chatCompletionModel = (
  controller: ReadableStreamDefaultController,
  encoder: TextEncoder
) => new ChatOpenAI({
  streaming: true,
  callbacks: [
    {
      handleLLMNewToken(token) {
        controller.enqueue(encoder.encode(`data: ${token}\n\n`));
      },
      async handleLLMEnd(output) {
        controller.close();
      },
    },
  ],
});

उपरोक्त कोड निम्न कार्य करता है:

  • @langchain/openai पैकेज से ChatOpenAI क्लास आयात करता है।
  • निम्न प्रकार की परिभाषाएं बनाता है:
    • ConversationMessage: एक बातचीत में एकल मैसेज के लिए एक प्रकार परिभाषित करता है। इसमें दो प्रॉपर्टीज हैं: role (भेजने वाले की भूमिका दर्शाता है) और content (मैसेज कंटेंट)।
    • ConversationMessages: बातचीत मैसेजेस की एक सरणी के लिए एक प्रकार परिभाषित करता है।
  • chatCompletionModel नामक एक फंक्शन एक्सपोर्ट करता है जो दो पैरामीटर लेता है:
    • controller: एक ReadableStreamDefaultController ऑब्जेक्ट जो आपको स्ट्रीम में मैसेजेस एन्क्यू करने की अनुमति देता है।
    • encoder: एक TextEncoder ऑब्जेक्ट जो मैसेजेस को Uint8Array ऑब्जेक्ट में एन्कोड करता है।
  • निम्न कॉन्फिगरेशन विकल्पों के साथ ChatOpenAI क्लास का एक नया इंस्टेंस बनाता है:
    • streaming: true पर सेट, यह दर्शाता है कि API को स्ट्रीमिंग प्रतिक्रियाएं लौटानी चाहिए।
    • callbacks: दो कॉलबैक फंक्शन वाले एक ऑब्जेक्ट युक्त एक सरणी, जिसका उपयोग LLM द्वारा प्रतिक्रिया निर्माण के प्रत्येक चरण को इंटरसेप्ट करने के लिए किया जाता है।
  • handleLLMNewToken: भाषा मॉडल द्वारा एक नया टोकन जनरेट होने पर आह्वान किया जाने वाला एक कॉलबैक। यह एन्कोडेड टोकन को कंट्रोलर में एन्क्यू करता है।
  • handleLLMEnd: एक एसिंक्रोनस कॉलबैक जो भाषा मॉडल जनरेशन पूरा होने पर आह्वान किया जाता है। यह कंट्रोलर को बंद करता है।

आगे, app/api/stream/completion/chat डायरेक्टरी में निम्न कोड के साथ route.ts नामक एक फाइल बनाएं। आपके द्वारा पहले बनाए गए प्रारंभिक स्ट्रीमिंग रूट हैंडलर से परिवर्तनों को नीचे हाइलाइट किया गया है:

// File: app/api/stream/completion/chat/route.ts
// इस रूट की प्रतिक्रिया को Vercel पर कैश होने से रोकता है
export const dynamic = "force-dynamic";
+ import {
+ type ConversationMessage,
+ chatCompletionModel,
+ } from "@/app/lib/chatCompletionModel";
export async function POST(request: Request) {
+ // अनुरोध के बॉडी से बातचीत मैसेजेस प्राप्त करें
+ const { messages = [] } = await request.json();
  const encoder = new TextEncoder();
  // एक स्ट्रीमिंग प्रतिक्रिया बनाएं
  const customReadable = new ReadableStream({
    async start(controller) {
+ // LangChain के साथ OpenAI से एक स्ट्रीमिंग प्रतिक्रिया जनरेट करें
+ await chatCompletionModel(controller, encoder).invoke(
+ messages.map((i: ConversationMessage) => [i["role"], i["content"]])
+ );
    },
  });
  // स्ट्रीम प्रतिक्रिया लौटाएं और कनेक्शन को जीवित रखें
  return new Response(customReadable, {
    // सर्वर-सेंट इवेंट्स (SSE) के लिए हेडर सेट करें
    headers: {
      Connection: "keep-alive",
      "Content-Encoding": "none",
      "Cache-Control": "no-cache, no-transform",
      "Content-Type": "text/event-stream; charset=utf-8",
    },
  });
}

Next.js में एक स्ट्रीमिंग एंडपॉइंट बनाने के लिए आपने पहले जो किया था, उसके अलावा, उपरोक्त कोड परिवर्धन निम्न कार्य करते हैं:

  • chatCompletionModel फंक्शन और ConversationMessage प्रकार परिभाषा आयात करता है।
  • request.json() का उपयोग करके अनुरोध बॉडी से बातचीत में मैसेजेस निकालता है।
  • ReadableStream के start मेथड के अंदर, chatCompletionModel फंक्शन को ट्रांसफॉर्म्ड मैसेजेस सरणी के बाद एसिंक्रोनसली आह्वान किया जाता है। प्रत्येक मैसेज को मैसेज की भूमिका और कंटेंट युक्त एक सरणी में ट्रांसफॉर्म किया जाता है। यह फंक्शन LangChain के साथ OpenAI से एक स्ट्रीमिंग प्रतिक्रिया जनरेट करता है।

Upstash के साथ चैट इतिहास को कैश करने के लिए, chatCompletionModel फंक्शन में Upstash Redis कैश क्लाइंट आयात करें:

+ import cache from '@/app/lib/upstashCache';
import { ChatOpenAI } from "@langchain/openai";
export type ConversationMessage = { role: string; content: string; };
export type ConversationMessages = ConversationMessage[];
export const chatCompletionModel = (
  controller: ReadableStreamDefaultController,
  encoder: TextEncoder
) => new ChatOpenAI({
+ cache,
  streaming: true,
  temperature: 0.9,
  callbacks: [
    {
      handleLLMNewToken(token) {
        controller.enqueue(encoder.encode(token));
      },
      async handleLLMEnd(output) {
        console.log(output.generations[0][0].text);
        controller.close();
      },
    },
  ],
});

न्यूनतम परिवर्तनों के साथ, आपने Upstash के साथ संपूर्ण चैट इतिहास की कैशिंग सक्षम कर दी है।

अब, आइए स्ट्रीमिंग एंडपॉइंट्स का उपभोग करने के लिए क्लाइंट-साइड रिएक्ट कंपोनेंट्स बनाने पर आगे बढ़ें।

सर्वर-सेंट इवेंट्स को सुनने के लिए Next.js फ्रंटएंड सेट करना

इस सेक्शन में, आप सीखेंगे कि सर्वर-सेंट इवेंट्स API मैसेजेस के लिए एक न्यूनतम लिस्नर कैसे सेट करें, और यूजर और AI के बीच आदान-प्रदान किए गए मैसेजेस की स्थिति को प्रबंधित करने का एक दृष्टिकोण।

रिएक्ट में सर्वर-सेंट इवेंट्स API को सुनना

रिएक्ट में हमारे क्लाइंट-साइड कंपोनेंट में SSE API को सुनने के लिए, आप निर्दिष्ट API रूट पर एक POST अनुरोध आरंभ करने जा रहे हैं। प्रतिक्रिया प्राप्त होने पर, आप TextDecoderStream विधि का उपयोग करके इनकमिंग डेटा को स्ट्रिंग के रूप में डीकोड करेंगे, और स्ट्रीम से डेटा को लगातार पढ़ेंगे।

"use client";
export default function () {
  const obtainAPIResponse = async (apiRoute: string, apiData: any) => {
    // SSE API से कनेक्ट करने के लिए पहली कॉल आरंभ करें
    const apiResponse = await fetch(apiRoute, {
      method: "POST",
      headers: { "Content-Type": "text/event-stream" },
      body: JSON.stringify(apiData),
    });
    if (!apiResponse.body) return;
    // इनकमिंग डेटा को स्ट्रिंग के रूप में डीकोड करने के लिए
    const reader = apiResponse.body
      .pipeThrough(new TextDecoderStream())
      .getReader();
    while (true) {
      const { value, done } = await reader.read();
      if (done) { break; }
      if (value) { /* कुछ करें */ }
    }
  };
  return <></>
}

रिएक्ट में बातचीत की स्थिति प्रबंधित करना

यूजर और चैटबॉट के बीच बातचीत की स्थिति को प्रबंधित करने के लिए, आप स्टेट वेरिएबल्स का उपयोग कर सकते हैं। आप स्टेट वेरिएबल्स messages और latestMessage को अपडेट करेंगे ताकि क्रमशः बातचीत इतिहास और नवीनतम मैसेज स्टोर किया जा सके। SSE API से इनकमिंग डेटा को प्रोसेस करने वाले लूप के भीतर इन स्टेट वेरिएबल्स को अपडेट करके, आप बातचीत डिस्प्ले के रियल-टाइम अपडेट सुनिश्चित कर सकते हैं। इसे प्राप्त करने के लिए कोड परिवर्धन निम्न हैं:

"use client";
+ import { useEffect, useState } from "react";
+ import { ConversationMessages } from "@/app/lib/chatCompletionModel";
export default function () {
+ const [latestMessage, setLatestMessage] = useState("");
+ const [messages, setMessages] = useState([]);
  const obtainAPIResponse = async (apiRoute: string, apiData: any) => {
    // SSE API से कनेक्ट करने के लिए पहली कॉल आरंभ करें
    const apiResponse = await fetch(apiRoute, {
      method: "POST",
      headers: { "Content-Type": "text/event-stream" },
      body: JSON.stringify(apiData),
    });
    if (!apiResponse.body) return;
    // इनकमिंग डेटा को स्ट्रिंग के रूप में डीकोड करने के लिए
    const reader = apiResponse.body
      .pipeThrough(new TextDecoderStream())
      .getReader();
+ let incomingMessage = "";
    while (true) {
      const { value, done } = await reader.read();
      if (done) {
+ // प्राप्त प्रतिक्रिया को मैसेजेस स्टेट में डालें
+ setMessages((messages) => [
+ ...messages,
+ { role: "assistant", content: incomingMessage },
+ ]);
+ // नवीनतम मैसेज की स्थिति रीसेट करें
+ setLatestMessage("");
        break;
      }
      if (value) {
+ // नवीनतम मैसेज के मान में इनकमिंग डेटा जोड़ें
+ incomingMessage += value;
+ setLatestMessage(incomingMessage);
      }
    }
  };
  return <></>
}

उपरोक्त कोड परिवर्धन निम्न कार्य करते हैं:

  • SSE API से प्राप्त इनकमिंग डेटा स्ट्रीम को स्टोर करने के लिए एक स्टेट वेरिएबल घोषित की जाती है।
  • एक पूर्ण मैसेज प्राप्त होने पर (done true होने से संकेतित), नवीनतम प्राप्त मैसेज को messages स्टेट सरणी में जोड़ा जाता है। इस मैसेज को assistant की भूमिका के साथ फॉर्मेट किया जाता है ताकि इसे यूजर मैसेजेस से अलग किया जा सके। साथ ही, अगले इनकमिंग मैसेज की तैयारी के लिए नवीनतम मैसेज स्टेट को खाली स्ट्रिंग पर रीसेट किया जाता है।
  • जैसे ही डेटा वृद्धिशील रूप से प्राप्त होता है (अभी तक पूर्ण मैसेज नहीं बना रहा), इसे incomingMessage वेरिएबल में जोड़ा जाता है।
  • नवीनतम मैसेज स्टेट को संयोजित इनकमिंग डेटा के साथ अपडेट किया जाता है, जिससे नए डेटा के आने पर रियल-टाइम अपडेट सुनिश्चित होते हैं।

बहुत बढ़िया! प्रतिक्रियाशील latestMessage और messages वेरिएबल्स के साथ, आप अब बातचीत में आदान-प्रदान किए गए मैसेजेस और नवीनतम AI-जनरेटेड प्रतिक्रिया का प्रतिनिधित्व करने वाले डायनामिक यूजर इंटरफेस बना सकते हैं।

यह बहुत सीखने वाला था! अब आप सब पूरा हो गया है ✨

Vercel पर डेप्लॉय करें

रिपॉजिटरी अब Vercel पर डेप्लॉय के लिए तैयार है। डेप्लॉय करने के लिए निम्न चरणों का उपयोग करें:

  • अपने ऐप के कोड युक्त एक GitHub रिपॉजिटरी बनाकर शुरू करें।
  • फिर, Vercel डैशबोर्ड पर जाएं और एक New Project बनाएं।
  • नए प्रोजेक्ट को आपके द्वारा अभी बनाए गए GitHub रिपॉजिटरी से लिंक करें।
  • Settings में, Environment Variables को अपडेट करें ताकि वे आपके स्थानीय .env फाइल में मौजूद हों।
  • डेप्लॉय करें! 🚀

अधिक जानकारी

अधिक विस्तृत अंतर्दृष्टि के लिए, इस पोस्ट में उद्धृत संदर्भों का पता लगाएं।

  • GitHub Repository
  • Server Sent Events
  • Next.js Streaming
  • Caching layer for LLMs
  1. C++ में एक रेखा पर अधिकतम बिंदु C++ में एक रेखा पर अधिकतम बिंदु

    मान लीजिए हमारे पास एक 2D तल है। हमें उन अधिकतम बिंदुओं की संख्या ढूंढनी है जो एक ही सीधी रेखा पर स्थित हैं। तो यदि बिंदु इस तरह हैं -तो 4 बिंदु हैंइसे हल करने के लिए, हम निम्नलिखित चरणों का पालन करेंगे -n := बिंदुओं की संख्या, यदि n < 3, तो n लौटाएंans := 2i को 1 से n - 1 तक की रेंज मेंcount := 0इं

  1. रिटेल सफलता के लिए रियल-टाइम इन्वेंट्री की महत्वपूर्ण भूमिका रिटेल सफलता के लिए रियल-टाइम इन्वेंट्री की महत्वपूर्ण भूमिका

    यह ब्लॉग पोस्ट हमारी नई ई-बुक, रियल-टाइम इन्वेंट्री: Redis Enterprise के साथ प्रतिस्पर्धात्मक लाभ बनाना से अंश है। इसे अभी मुफ्त में डाउनलोड करें! Dave से मिलें। Dave एक उपनगरीय पिता है जो एक नया इंस्टापॉट खरीदना चाहता है ताकि अपने परिवार के भोजन को तेज़ और अधिक सुविधाजनक बना सके। Dave के पास ज

  1. रूबी डीबगिंग में महारत: सामान्य त्रुटियों के लिए त्वरित सुधार रूबी डीबगिंग में महारत: सामान्य त्रुटियों के लिए त्वरित सुधार

    आपका प्रोग्राम पहली बार में कितनी बार वही करता है जो आप चाहते हैं? कई बार हमारे प्रोग्राम्स हमारी अपेक्षा के अनुसार काम नहीं करते, इसलिए हमें यह पता लगाने में मदद के लिए रूबी डीबगिंग की कला का उपयोग करना पड़ता है कि क्यों। आप निम्नलिखित त्रुटि संदेश से परिचित हो सकते हैं: undefined method some_metho