paint-brush
Next.js, OpenAI, LangChain और Supabase के साथ वेब पेज सारांशीकरण ऐप कैसे बनाएंद्वारा@nassermaronie
6,088 रीडिंग
6,088 रीडिंग

Next.js, OpenAI, LangChain और Supabase के साथ वेब पेज सारांशीकरण ऐप कैसे बनाएं

द्वारा Nasser Maronie13m2024/06/27
Read on Terminal Reader

बहुत लंबा; पढ़ने के लिए

इस लेख में, हम आपको दिखाएंगे कि एक आसान वेब ऐप कैसे बनाया जाए जो किसी भी वेब पेज की सामग्री को सारांशित कर सके। एक सहज और तेज़ वेब अनुभव के लिए [Next.js], प्रोसेसिंग लैंग्वेज के लिए [LangChain], सारांश बनाने के लिए [OpenAI](https://openai.com/) और वेक्टर डेटा को प्रबंधित करने और संग्रहीत करने के लिए [Supabase] का उपयोग करके, हम एक शक्तिशाली टूल बनाएंगे।
featured image - Next.js, OpenAI, LangChain और Supabase के साथ वेब पेज सारांशीकरण ऐप कैसे बनाएं
Nasser Maronie HackerNoon profile picture

एक ऐसा ऐप जो किसी भी वेब पेज के संदर्भ को समझ सकता है।

इस लेख में, हम आपको दिखाएंगे कि एक आसान वेब ऐप कैसे बनाया जाए जो किसी भी वेब पेज की सामग्री को सारांशित कर सके। एक सहज और तेज़ वेब अनुभव के लिए Next.js , प्रोसेसिंग लैंग्वेज के लिए LangChain , सारांश बनाने के लिए OpenAI और वेक्टर डेटा को प्रबंधित करने और संग्रहीत करने के लिए Supabase का उपयोग करके, हम एक शक्तिशाली टूल बनाएंगे।



हम इसे क्यों बना रहे हैं

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

यह कैसा होगा

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

संभावना और प्रभाव

यह सारांशीकरण ऐप कई मायनों में उपयोगी हो सकता है। यह शोधकर्ताओं को अकादमिक शोधपत्रों को सरसरी तौर पर पढ़ने, समाचार प्रेमियों को अपडेट रखने और बहुत कुछ करने में मदद कर सकता है। साथ ही, डेवलपर्स इस ऐप पर और भी अधिक उपयोगी सुविधाएँ बना सकते हैं।


टेक स्टैक

नेक्स्ट.js

Next.js वर्सेल द्वारा विकसित एक शक्तिशाली और लचीला रिएक्ट फ्रेमवर्क है जो डेवलपर्स को सर्वर-साइड रेंडरिंग (SSR) और स्टैटिक वेब एप्लिकेशन को आसानी से बनाने में सक्षम बनाता है। यह अनुकूलित और स्केलेबल वेब एप्लिकेशन बनाने के लिए रिएक्ट की सर्वश्रेष्ठ विशेषताओं को अतिरिक्त क्षमताओं के साथ जोड़ता है।

ओपनएआई

Node.js में OpenAI मॉड्यूल OpenAI के API के साथ बातचीत करने का एक तरीका प्रदान करता है, जिससे डेवलपर्स को GPT-3 और GPT-4 जैसे शक्तिशाली भाषा मॉडल का लाभ उठाने की अनुमति मिलती है। यह मॉड्यूल आपको अपने Node.js अनुप्रयोगों में उन्नत AI कार्यक्षमताओं को एकीकृत करने में सक्षम बनाता है।

लैंगचेन.js

लैंगचेन एक शक्तिशाली फ्रेमवर्क है जिसे भाषा मॉडल के साथ एप्लिकेशन विकसित करने के लिए डिज़ाइन किया गया है। मूल रूप से पायथन के लिए विकसित, इसे बाद में Node.js सहित अन्य भाषाओं के लिए अनुकूलित किया गया है। Node.js के संदर्भ में LangChain का अवलोकन यहाँ दिया गया है:

लैंगचेन क्या है?

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

बड़े भाषा मॉडल (एलएलएम) कैसे काम करते हैं?

ओपनएआई के जीपीटी-3.5 जैसे बड़े भाषा मॉडल (एलएलएम) को मानव जैसा टेक्स्ट समझने और बनाने के लिए बड़ी मात्रा में टेक्स्ट डेटा पर प्रशिक्षित किया जाता है। वे प्रतिक्रियाएँ उत्पन्न कर सकते हैं, भाषाओं का अनुवाद कर सकते हैं और कई अन्य प्राकृतिक भाषा प्रसंस्करण कार्य कर सकते हैं।

सुपबेस

सुपाबेस एक ओपन-सोर्स बैकएंड-एज़-ए-सर्विस (BaaS) प्लेटफ़ॉर्म है जिसे डेवलपर्स को स्केलेबल एप्लिकेशन को जल्दी से बनाने और तैनात करने में मदद करने के लिए डिज़ाइन किया गया है। यह टूल और सेवाओं का एक सूट प्रदान करता है जो डेटाबेस प्रबंधन, प्रमाणीकरण, भंडारण और वास्तविक समय की क्षमताओं को सरल बनाता है, जो सभी PostgreSQL के शीर्ष पर निर्मित हैं


आवश्यक शर्तें

शुरू करने से पहले, सुनिश्चित करें कि आपके पास निम्नलिखित हैं:

  • Node.js और npm स्थापित
  • एक सुपाबेस खाता
  • एक OpenAI खाता

चरण 1: सुपाबेस की स्थापना

सबसे पहले, हमें एक सुपाबेस परियोजना स्थापित करनी होगी और अपना डेटा संग्रहीत करने के लिए आवश्यक तालिकाएँ बनानी होंगी।

एक सुपरबेस प्रोजेक्ट बनाएं

  1. सुपाबेस पर जाएं और एक खाते के लिए साइन अप करें।


  2. एक नया प्रोजेक्ट बनाएं, और अपने सुपाबेस यूआरएल और एपीआई कुंजी को नोट कर लें। आपको बाद में इनकी ज़रूरत पड़ेगी।

सुपबेस के लिए SQL स्क्रिप्ट

अपने सुपाबेस डैशबोर्ड में एक नई SQL क्वेरी बनाएं, और आवश्यक तालिकाओं और फ़ंक्शन बनाने के लिए निम्नलिखित स्क्रिप्ट चलाएं:

सबसे पहले, यदि हमारे वेक्टर स्टोर के लिए एक्सटेंशन पहले से मौजूद नहीं है तो उसे बनाएं:

 create extension if not exists vector;


इसके बाद, “दस्तावेज़” नाम से एक तालिका बनाएँ। इस तालिका का उपयोग वेब पेज की सामग्री को वेक्टर प्रारूप में संग्रहीत और एम्बेड करने के लिए किया जाएगा:

 create table if not exists documents ( id bigint primary key generated always as identity, content text, metadata jsonb, embedding vector(1536) );


अब, हमें अपने एम्बेडेड डेटा को क्वेरी करने के लिए एक फ़ंक्शन की आवश्यकता है:

 create or replace function match_documents ( query_embedding vector(1536), match_count int default null, filter jsonb default '{}' ) returns table ( id bigint, content text, metadata jsonb, similarity float ) language plpgsql as $$ begin return query select id, content, metadata, 1 - (documents.embedding <=> query_embedding) as similarity from documents where metadata @> filter order by documents.embedding <=> query_embedding limit match_count; end; $$;


इसके बाद, हमें वेब पेज का विवरण संग्रहीत करने के लिए अपनी तालिका सेट अप करनी होगी:

 create table if not exists files ( id bigint primary key generated always as identity, url text not null, created_at timestamp with time zone default timezone('utc'::text, now()) not null );

चरण 2: OpenAI की स्थापना

OpenAI प्रोजेक्ट बनाएं


  • API पर जाएँ: लॉग इन करने के बाद, API सेक्शन पर जाएँ और एक नई API कुंजी बनाएँ। यह आमतौर पर डैशबोर्ड से एक्सेस किया जा सकता है।

चरण 3: Next.js सेट अप करना

Next.js ऐप बनाएं

 $ npx create-next-app summarize-page $ cd ./summarize-page


आवश्यक निर्भरताएँ स्थापित करें:

 npm install @langchain/community @langchain/core @langchain/openai @supabase/supabase-js langchain openai axios


फिर, हम अपना इंटरफ़ेस बनाने के लिए मटेरियल यूआई स्थापित करेंगे; अन्य लाइब्रेरी का उपयोग करने के लिए स्वतंत्र महसूस करें:

 npm install @mui/material @emotion/react @emotion/styled

चरण 4: ओपनएआई और सुपबेस क्लाइंट

इसके बाद, हमें OpenAI और Supabase क्लाइंट सेट अप करने की आवश्यकता है। अपने प्रोजेक्ट में libs डायरेक्टरी बनाएँ, और निम्न फ़ाइलें जोड़ें।

src/libs/openAI.ts

यह फ़ाइल OpenAI क्लाइंट को कॉन्फ़िगर करेगी.

 import { ChatOpenAI, OpenAIEmbeddings } from "@langchain/openai"; const openAIApiKey = process.env.OPENAI_API_KEY; if (!openAIApiKey) throw new Error('OpenAI API Key not found.') export const llm = new ChatOpenAI({ openAIApiKey, modelName: "gpt-3.5-turbo", temperature: 0.9, }); export const embeddings = new OpenAIEmbeddings( { openAIApiKey, }, { maxRetries: 0 } );
  • llm : भाषा मॉडल उदाहरण, जो हमारा सारांश तैयार करेगा।


  • embeddings : यह हमारे दस्तावेज़ों के लिए एम्बेडिंग बनाएगा, जो समान सामग्री खोजने में मदद करेगा।

src/libs/supabaseClient.ts

यह फ़ाइल Supabase क्लाइंट को कॉन्फ़िगर करेगी।

 import { createClient } from "@supabase/supabase-js"; const supabaseUrl = process.env.SUPABASE_URL || ""; const supabaseAnonKey = process.env.SUPABASE_ANON_KEY || ""; if (!supabaseUrl) throw new Error("Supabase URL not found."); if (!supabaseAnonKey) throw new Error("Supabase Anon key not found."); export const supabaseClient = createClient(supabaseUrl, supabaseAnonKey);
  • supabaseClient : हमारे Supabase डाटाबेस के साथ इंटरैक्ट करने के लिए Supabase क्लाइंट इंस्टैंस.

चरण 5: सामग्री और फ़ाइलों के लिए सेवाएँ बनाना

एक services निर्देशिका बनाएं, और सामग्री प्राप्त करने तथा फ़ाइलों का प्रबंधन करने के लिए निम्नलिखित फ़ाइलें जोड़ें।

src/services/content.ts

यह सेवा वेब पेज की सामग्री लाएगी और HTML टैग, स्क्रिप्ट और शैलियों को हटाकर उसे साफ करेगी।

 import axios from "axios"; export async function getContent(url: string): Promise<string> { let htmlContent: string = ""; const response = await axios.get(url as string); htmlContent = response.data; if (!htmlContent) return ""; // Remove unwanted elements and tags return htmlContent .replace(/style="[^"]*"/gi, "") .replace(/<style[^>]*>[\s\S]*?<\/style>/gi, "") .replace(/\s*on\w+="[^"]*"/gi, "") .replace( /<script(?![^>]*application\/ld\+json)[^>]*>[\s\S]*?<\/script>/gi, "" ) .replace(/<[^>]*>/g, "") .replace(/\s+/g, " "); }

यह फ़ंक्शन किसी दिए गए URL की HTML सामग्री को प्राप्त करता है और शैलियों, स्क्रिप्ट और HTML टैग्स को हटाकर उसे साफ़ करता है।

src/services/file.ts

यह सेवा वेब पेज की सामग्री को सुपाबेस में सहेजेगी और सारांश प्राप्त करेगी।

 import { embeddings, llm } from "@/libs/openAI"; import { supabaseClient } from "@/libs/supabaseClient"; import { SupabaseVectorStore } from "@langchain/community/vectorstores/supabase"; import { StringOutputParser } from "@langchain/core/output_parsers"; import { ChatPromptTemplate, HumanMessagePromptTemplate, SystemMessagePromptTemplate, } from "@langchain/core/prompts"; import { RunnablePassthrough, RunnableSequence, } from "@langchain/core/runnables"; import { RecursiveCharacterTextSplitter } from "langchain/text_splitter"; import { formatDocumentsAsString } from "langchain/util/document"; export interface IFile { id?: number | undefined; url: string; created_at?: Date | undefined; } export async function saveFile(url: string, content: string): Promise<IFile> { const doc = await supabaseClient .from("files") .select() .eq("url", url) .single<IFile>(); if (!doc.error && doc.data?.id) return doc.data; const { data, error } = await supabaseClient .from("files") .insert({ url }) .select() .single<IFile>(); if (error) throw error; const splitter = new RecursiveCharacterTextSplitter({ separators: ["\n\n", "\n", " ", ""], }); const output = await splitter.createDocuments([content]); const docs = output.map((d) => ({ ...d, metadata: { ...d.metadata, file_id: data.id }, })); await SupabaseVectorStore.fromDocuments(docs, embeddings, { client: supabaseClient, tableName: "documents", queryName: "match_documents", }); return data; } export async function getSummarization(fileId: number): Promise<string> { const vectorStore = await SupabaseVectorStore.fromExistingIndex(embeddings, { client: supabaseClient, tableName: "documents", queryName: "match_documents", }); const retriever = vectorStore.asRetriever({ filter: (rpc) => rpc.filter("metadata->>file_id", "eq", fileId), k: 2, }); const SYSTEM_TEMPLATE = `Use the following pieces of context, explain what is it about and summarize it. If you can't explain it, just say that you don't know, don't try to make up some explanation. ---------------- {context}`; const messages = [ SystemMessagePromptTemplate.fromTemplate(SYSTEM_TEMPLATE), HumanMessagePromptTemplate.fromTemplate("{format_answer}"), ]; const prompt = ChatPromptTemplate.fromMessages(messages); const chain = RunnableSequence.from([ { context: retriever.pipe(formatDocumentsAsString), format_answer: new RunnablePassthrough(), }, prompt, llm, new StringOutputParser(), ]); const format_summarization = ` Give it title, subject, description, and the conclusion of the context in this format, replace the brackets with the actual content: [Write the title here] By: [Name of the author or owner or user or publisher or writer or reporter if possible, otherwise leave it "Not Specified"] [Write the subject, it could be a long text, at least minimum of 300 characters] ---------------- [Write the description in here, it could be a long text, at least minimum of 1000 characters] Conclusion: [Write the conclusion in here, it could be a long text, at least minimum of 500 characters] `; const summarization = await chain.invoke(format_summarization); return summarization; }
  • saveFile : फ़ाइल और उसकी सामग्री को Supabase में सहेजता है, सामग्री को प्रबंधनीय खंडों में विभाजित करता है, और उन्हें वेक्टर स्टोर में संग्रहीत करता है।


  • getSummarization : वेक्टर स्टोर से प्रासंगिक दस्तावेज़ों को पुनर्प्राप्त करता है और OpenAI का उपयोग करके सारांश तैयार करता है।

चरण 6: API हैंडलर बनाना

अब, आइए सामग्री को संसाधित करने और सारांश तैयार करने के लिए एक API हैंडलर बनाएं।

pages/api/content.ts

 import { getContent } from "@/services/content"; import { getSummarization, saveFile } from "@/services/file"; import { NextApiRequest, NextApiResponse } from "next"; export default async function handler( req: NextApiRequest, res: NextApiResponse ) { if (req.method !== "POST") return res.status(404).json({ message: "Not found" }); const { body } = req; try { const content = await getContent(body.url); const file = await saveFile(body.url, content); const result = await getSummarization(file.id as number); res.status(200).json({ result }); } catch (err) { res.status( 500).json({ error: err }); } }

यह API हैंडलर एक URL प्राप्त करता है, सामग्री प्राप्त करता है, उसे Supabase में सहेजता है, और सारांश तैयार करता है। यह हमारी सेवाओं से saveFile और getSummarization दोनों फ़ंक्शन को संभालता है।


चरण 7: फ्रंटएंड का निर्माण

अंत में, आइए src/pages/index.tsx में फ्रंटएंड बनाएं ताकि उपयोगकर्ता URL इनपुट कर सकें और सारांश प्रदर्शित कर सकें।

src/pages/index.tsx

 import axios from "axios"; import { useState } from "react"; import { Alert, Box, Button, Container, LinearProgress, Stack, TextField, Typography, } from "@mui/material"; export default function Home() { const [loading, setLoading] = useState(false); const [url, setUrl] = useState(""); const [result, setResult] = useState(""); const [error, setError] = useState<any>(null); const onSubmit = async () => { try { setError(null); setLoading(true); const res = await axios.post("/api/content", { url }); setResult(res.data.result); } catch (err) { console.error("Failed to fetch content", err); setError(err as any); } finally { setLoading(false); } }; return ( <Box sx={{ height: "100vh", overflowY: "auto" }}> <Container sx={{ backgroundColor: (theme) => theme.palette.background.default, position: "sticky", top: 0, zIndex: 2, py: 2, }} > <Typography sx={{ mb: 2, fontSize: "24px" }}> Summarize the content of any page </Typography> <TextField fullWidth label="Input page's URL" value={url} onChange={(e) => { if (result) setResult(""); setUrl(e.target.value); }} sx={{ mb: 2 }} /> <Button disabled={loading} variant="contained" onClick={onSubmit} > Summarize </Button> </Container> <Container maxWidth="lg" sx={{ py: 2 }}> {loading ? ( <LinearProgress /> ) : ( <Stack sx={{ gap: 2 }}> {result && ( <Alert> <Typography sx={{ whiteSpace: "pre-line", wordBreak: "break-word", }} > {result} </Typography> </Alert> )} {error && <Alert severity="error">{error.message || error}</Alert>} </Stack> )} </Container> </Box> ); }

यह रिएक्ट घटक उपयोगकर्ताओं को एक URL इनपुट करने, उसे सबमिट करने और उत्पन्न सारांश प्रदर्शित करने की अनुमति देता है। यह बेहतर उपयोगकर्ता अनुभव प्रदान करने के लिए लोडिंग स्थिति और त्रुटि संदेशों को संभालता है।


चरण 8: एप्लिकेशन चलाना

अपने पर्यावरण चरों को संग्रहीत करने के लिए अपने प्रोजेक्ट के मूल में एक .env फ़ाइल बनाएँ:

 SUPABASE_URL=your-supabase-url SUPABASE_ANON_KEY=your-supabase-anon-key OPENAI_API_KEY=your-openai-api-key


अंत में, अपना Next.js एप्लिकेशन प्रारंभ करें:

 npm run dev


अब, आपके पास एक चालू एप्लीकेशन होगी जहां आप वेब पेज का यूआरएल इनपुट कर सकते हैं, और पेज की संक्षिप्त प्रतिक्रियाएं प्राप्त कर सकते हैं।


निष्कर्ष

बधाई हो! आपने Next.js, OpenAI, LangChain और Supabase का उपयोग करके एक पूरी तरह कार्यात्मक वेब पेज सारांशीकरण एप्लिकेशन बनाया है। उपयोगकर्ता URL इनपुट कर सकते हैं, सामग्री प्राप्त कर सकते हैं, उसे Supabase में संग्रहीत कर सकते हैं और OpenAI की क्षमताओं का उपयोग करके सारांश तैयार कर सकते हैं। यह सेटअप आपकी आवश्यकताओं के आधार पर आगे के संवर्द्धन और अनुकूलन के लिए एक मजबूत आधार प्रदान करता है।


अधिक सुविधाएँ जोड़कर, UI में सुधार करके, या अतिरिक्त API एकीकृत करके इस परियोजना का विस्तार करने के लिए स्वतंत्र महसूस करें।

इस रेपो में स्रोत कोड की जाँच करें:

https://github.com/firstpersoncode/summarize-page


हैप्पी कोडिंग!