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

लैंगचेन और अपस्टैश रेडिस के साथ निरंतर चैट इतिहास

<पी> लैंगचेन मानव और एआई के बीच बातचीत करने के लिए एक सरल इंटरफ़ेस प्रदान करता है। इसे BufferMemory का उपयोग करने के लिए आसानी से कॉन्फ़िगर किया जा सकता है , आपको वार्तालाप इतिहास को स्मृति में संग्रहीत करने में सक्षम बनाता है। यह कुछ उपयोग के मामलों के लिए संतोषजनक हो सकता है, लेकिन आपके ऐप्स को चैट इतिहास की दीर्घकालिक निरंतरता की भी आवश्यकता हो सकती है। सौभाग्य से, इसे अपस्टैश रेडिस उदाहरण के लिए बदलना उतना ही सरल है।

<पी> लैंगचेन रेडिस के लिए कई एकीकरण प्रदान करता है, जिसमें ioredis शामिल है , node-redis और अपस्टैश रेडिस। क्योंकि अपस्टैश रेडिस क्लाइंट REST के माध्यम से काम करता है, आप इसका उपयोग एज-रेडी एप्लिकेशन बनाने के लिए कर सकते हैं जिन्हें वर्सेल, क्लाउडफ्लेयर वर्कर्स या किसी अन्य सर्वर रहित वातावरण में तैनात किया जा सकता है। हम इसका उपयोग मेमोरी के साथ एक सरल चैट ऐप बनाने के लिए करेंगे जो पूरे सत्र में बनी रहेगी।

<पी> आप इस डेमो के लिए पूर्ण स्रोत कोड यहां पा सकते हैं।

आवश्यकताएँ

  • एक अपस्टैश रेडिस डेटाबेस
  • एक OpenAI API कुंजी

आरंभ करना

प्रोजेक्ट बनाना

<पी> अपस्टैश रेडिस के साथ लैंगचेन का उपयोग कैसे करें, यह प्रदर्शित करने के लिए हम वर्सेल एआई एसडीके का उपयोग करके एक बुनियादी Next.js ऐप का निर्माण करेंगे। आरंभ करने के लिए, एक नया Next.js ऐप बनाएं:

npx create-next-app@latest
<पी> यह आपसे कुछ प्रोजेक्ट विकल्प चुनने के लिए कहेगा। अधिकांश ऐप्स के लिए, डिफ़ॉल्ट ठीक काम करेंगे। इस डेमो के प्रयोजन के लिए, टाइपस्क्रिप्ट और app को सक्षम करना सुनिश्चित करें निर्देशिका.

निर्भरताएं स्थापित करना

<पी> एक बार ऐप बन जाने के बाद, आपको कुछ निर्भरताएँ इंस्टॉल करनी होंगी:

npm install ai langchain openai @upstash/redis
<पी> हालांकि कड़ाई से आवश्यक नहीं है, वर्सेल एआई एसडीके ओपनएआई से हमारे नेक्स्ट.जेएस फ्रंटएंड पर प्रतिक्रियाओं को स्ट्रीम करना आसान बना देगा। हमें केवल @upstash/redis का उपयोग करना होगा Redis क्लाइंट बनाने के लिए—LangChain बाकी का ध्यान रखेगा।

पर्यावरण चर सेट करना

<पी> अंत में, हमें पहले की शर्तों से निम्नलिखित पर्यावरण चर की आवश्यकता होगी। सुनिश्चित करें कि उनका नाम बिल्कुल वैसा ही रखें जैसा यहां बताया गया है, क्योंकि अन्यथा वे स्वचालित रूप से नहीं पढ़े जाएंगे! आप इन्हें .env में जोड़ सकते हैं अपने नए प्रोजेक्ट के मूल में फ़ाइल करें:

UPSTASH_REDIS_REST_URL="https://********.upstash.io"
UPSTASH_REDIS_REST_TOKEN="********"
OPENAI_API_KEY="sk-********"

एक बुनियादी चैट क्लाइंट बनाना

<पी> आप देखेंगे कि Next.js ने हमारे लिए कई फ़ाइलें बनाई हैं। हम app में केवल कुछ फ़ाइलों के साथ काम करेंगे निर्देशिका, ताकि आप आगे बढ़ सकें और वर्तमान में public में मौजूद सभी चीज़ों को हटा सकें और app .

<पी> आरंभ करने के लिए, हम एक बुनियादी app/layout.tsx बनाएंगे हमारे ऐप को रखने के लिए:

import type { PropsWithChildren } from "react";
 
export default function RootLayout({ children }: PropsWithChildren) {
 return (
 <html lang="en">
 <body>{children}</body>
 </html>
 );
}
<पी> इसके बाद, हमें उपयोगकर्ता से संदेश स्वीकार करने के लिए इनपुट के साथ एक बुनियादी फॉर्म की आवश्यकता होगी। इसे हमारे app/page.tsx में जोड़ा जा सकता है :

export default function Home() {
 return (
 <main>
 <form>
 <input placeholder="Enter a message..." />
 <button type="submit">Send</button>
 </form>
 </main>
 );
}
<पी> लैंगचेन और अपस्टैश रेडिस के साथ निरंतर चैट इतिहास

<पी> वर्सेल एआई एसडीके useChat नामक एक उपयोगी हुक निर्यात करता है , जो हमारे चैट ऐप के लिए एक पारंपरिक यूजर इंटरफेस बनाना बहुत आसान बनाता है। यह चैट संदेशों की स्ट्रीमिंग और हमारे चैट इनपुट की स्थिति को प्रबंधित करता है। हुक का उपयोग करने के लिए, हमें "use client" जोड़कर रिएक्ट को यह बताना होगा कि यह एक क्लाइंट घटक है। हमारी फ़ाइल के शीर्ष पर निर्देश। फिर, हम useChat से कुछ संपत्तियों को नष्ट कर सकते हैं हुक:

  • messages संदेशों की एक श्रृंखला है जो भेजे और प्राप्त किए गए हैं।
  • input इनपुट फ़ील्ड का वर्तमान मान है।
  • handleInputChange एक फ़ंक्शन है जो इनपुट मान को अपडेट करता है।
  • handleSubmit एक फ़ंक्शन है जो संदेशों को हमारे समापन बिंदु पर भेजता है।
"use client";
 
import { useChat } from "ai/react";
 
export default function Home() {
 const { messages, input, handleInputChange, handleSubmit } = useChat();
 
 return (
 <main>
 <form onSubmit={handleSubmit}>
 <input
 value={input}
 onChange={handleInputChange}
 placeholder="Enter a message..."
 />
 <button type="submit">Send</button>
 </form>
 </main>
 );
}
<पी> आंतरिक रूप से, useChat हुक स्वचालित रूप से input जुड़ जाता है messages पर जब handleSubmit कॉल किया जाता है, जिससे री-रेंडर ट्रिगर हो जाता है ताकि हमें स्वयं यूआई को अपडेट करने के बारे में चिंता न करनी पड़े। यह इनपुट फ़ील्ड को भी साफ़ कर देगा और निर्दिष्ट समापन बिंदु पर एक एपीआई कॉल ट्रिगर करेगा। डिफ़ॉल्ट रूप से, यह /api/chat है .

<पी> अंत में, आइए messages को प्रस्तुत करें हमारे फॉर्म के ऊपर:

<main>
 <section>
 {messages.map((message) => (
 <p key={message.id}>{message.content}</p>
 ))}
 </section>
 
 {/* snip */}
</main>

एपीआई एंडपॉइंट बनाना

<पी> हम एक app/api/chat/route.ts बनाकर शुरुआत कर सकते हैं हमारे समापन बिंदु को रखने के लिए फ़ाइल करें। Next.js एपीआई एंडपॉइंट के साथ-साथ पेजों के लिए फ़ाइल-आधारित रूटिंग का उपयोग करता है - यही कारण है कि इस नई फ़ाइल के लिए फ़ोल्डर संरचना डिफ़ॉल्ट एंडपॉइंट से मेल खाती है, /api/chat , पहले से.

<पी> चूँकि हम अपस्टैश रेडिस का उपयोग कर रहे हैं, हमारा समापन बिंदु किनारे-संगत है। हम इसे const runtime = "edge" निर्यात करके निर्दिष्ट कर सकते हैं हमारे समापन बिंदु से. समापन बिंदु में ही, हम messages पुनः प्राप्त कर सकते हैं वह फ़ील्ड जो useChat है हुक हमारे लिए आबाद है। यह हमें लैंगचेन को नवीनतम संदेश भेजने की अनुमति देता है:

import { type NextRequest } from "next/server";
 
import { LangChainStream, StreamingTextResponse } from "ai";
 
export const runtime = "edge";
 
export async function POST(req: NextRequest) {
 const { messages } = await req.json();
 const { stream, handlers } = LangChainStream();
 
 const latestMessage = messages[messages.length - 1];
 
 return new StreamingTextResponse(stream);
}
<पी> जैसे useChat पहले से, LangChainStream कुछ संपत्तियाँ भी लौटाता है जिन्हें हम नष्ट कर सकते हैं।

  • stream एक ReadableStream है इसमें अंततः लैंगचेन प्रक्रिया के परिणाम शामिल होंगे।
  • handlers एक ऑब्जेक्ट है जिसमें एलएलएम कॉलबैक फ़ंक्शंस शामिल हैं जिन्हें लैंगचेन को पास किया जा सकता है।
<पी> इससे पहले कि हम श्रृंखला को स्वयं लागू कर सकें, हमें कुछ अतिरिक्त कक्षाएं आयात करने की आवश्यकता होगी:

import { Redis } from "@upstash/redis";
import { ConversationChain } from "langchain/chains";
import { ChatOpenAI } from "langchain/chat_models/openai";
import { BufferMemory } from "langchain/memory";
import { UpstashRedisChatMessageHistory } from "langchain/stores/message/upstash_redis";
<पी> अब हम एक रेडिस क्लाइंट बना सकते हैं और अपनी श्रृंखला के लिए मेमोरी सेट कर सकते हैं। यहां, हम एक ConversationChain बनाते हैं जिसे हम मॉडल के बदले में ही कॉल कर सकते हैं। यह एक कस्टम श्रृंखला है जो मानव और एआई के बीच बातचीत की सुविधा प्रदान करती है। हम एक कस्टम BaseMemory पास कर सकते हैं श्रृंखला में कार्यान्वयन, जिसका उपयोग संदेशों को संग्रहीत करने और पुनः प्राप्त करने के लिए किया जाएगा। इस मामले में, हम BufferMemory का उपयोग कर रहे हैं UpstashRedisChatMessageHistory के साथ अपस्टैश रेडिस में संदेशों को संग्रहीत करने के लिए:

// snip
const latestMessage = messages[messages.length - 1];
 
const memory = new BufferMemory({
 chatHistory: new UpstashRedisChatMessageHistory({
 sessionId: new Date().toLocaleDateString(),
 client: Redis.fromEnv(),
 }),
});
 
const model = new ChatOpenAI({
 modelName: "gpt-3.5-turbo",
 streaming: true,
});
 
const chain = new ConversationChain({ llm: model, memory });
// snip
<पी> हम Redis का उपयोग करके एक नया रेडिस क्लाइंट बनाते हैं @upstash/redis से वर्ग का अन्वेषण किया गया . यह आसानी से पर्यावरण चर को स्वचालित रूप से लोड करने की एक विधि प्रदान करता है, जो ChatOpenAI के व्यवहार को प्रतिबिंबित करता है। . जब तक आपने अपने पर्यावरण चर को सही ढंग से नामित किया है, तब तक आपको इनमें से किसी भी वर्ग में कोई अतिरिक्त तर्क पारित करने की आवश्यकता नहीं होगी।

<पी> अपने ऐप में, आप sessionId के लिए उपयोगकर्ता की आईडी या किसी अन्य विशिष्ट पहचानकर्ता का उपयोग करना चाह सकते हैं यह सुनिश्चित करने के लिए कि संदेश उपयोगकर्ताओं के बीच साझा नहीं किए जाते हैं, लेकिन हम इस डेमो के लिए वर्तमान तिथि का उपयोग करेंगे। UpstashRedisChatMessageHistory sessionTTL जैसे अधिक कॉन्फ़िगरेशन विकल्प प्रदान करता है कैश का जीवनकाल निर्धारित करने के लिए।

<पी> streaming को सक्षम करना महत्वपूर्ण है मॉडल पर, क्योंकि यह हमें हमारे डिस्ट्रक्चर्ड handlers का उपयोग करने की अनुमति देगा श्रृंखला के परिणामों को stream पर पाइप करने के लिए पहले से ऑब्जेक्ट करें . अंत में, हम नवीनतम संदेश और handlers भेजकर श्रृंखला को कॉल कर सकते हैं वस्तु:

// snip
const chain = new ConversationChain({ llm: model, memory });
 
chain.call({
 input: latestMessage.content,
 callbacks: [handlers],
});
 
return new StreamingTextResponse(stream);
// snip
<पी> हमारा latestMessage पहले के ऑब्जेक्ट का उपयोग एलएलएम के लिए प्रॉम्प्ट के रूप में किया जाता है। हम handlers भी पास करते हैं श्रृंखला पर ऑब्जेक्ट करें, जिसका उपयोग परिणामों को stream पर पाइप करने के लिए किया जाएगा .

निष्कर्ष

<पी> बस इतना ही! अब आप अपना ऐप npm run dev के साथ चला सकते हैं और अपने AI से चैट करना शुरू करें। प्रतिक्रिया स्वचालित रूप से हमारे द्वारा पहले बनाए गए क्लाइंट पर स्ट्रीम की जाएगी, और वार्तालाप इतिहास अपस्टैश रेडिस में संग्रहीत किया जाएगा।

<पी> लैंगचेन और अपस्टैश रेडिस के साथ निरंतर चैट इतिहास

<पी> लैंगचेन और अपस्टैश रेडिस के साथ निरंतर चैट इतिहास


  1. पाइथन में हिस्टोग्राम प्रदर्शित करने के लिए सीबोर्न लाइब्रेरी का उपयोग कैसे किया जा सकता है? पाइथन में हिस्टोग्राम प्रदर्शित करने के लिए सीबोर्न लाइब्रेरी का उपयोग कैसे किया जा सकता है?

    डेटा को विज़ुअलाइज़ करना एक महत्वपूर्ण कदम है क्योंकि यह यह समझने में मदद करता है कि वास्तव में संख्याओं को देखे बिना और जटिल गणना किए बिना डेटा में क्या चल रहा है। यह दर्शकों को मात्रात्मक अंतर्दृष्टि को प्रभावी ढंग से संप्रेषित करने में मदद करता है। सीबॉर्न एक पुस्तकालय है जो डेटा की कल्पना करने

  1. सीएसएस के साथ पेजिनेशन कैसे बनाएं? सीएसएस के साथ पेजिनेशन कैसे बनाएं?

    CSS के साथ पेजिनेशन बनाने के लिए निम्नलिखित कोड है - उदाहरण <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>Document</title>

  1. बताएं कि पायथन में फ़ैक्टरप्लॉट फ़ंक्शन का उपयोग करके वायलिन प्लॉट की कल्पना कैसे की जा सकती है? बताएं कि पायथन में फ़ैक्टरप्लॉट फ़ंक्शन का उपयोग करके वायलिन प्लॉट की कल्पना कैसे की जा सकती है?

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