paint-brush
डेवी और लैंगचेन.जेएस के साथ एक प्रश्न-उत्तर सीएलआई बनानाद्वारा@kerinin
494 रीडिंग
494 रीडिंग

डेवी और लैंगचेन.जेएस के साथ एक प्रश्न-उत्तर सीएलआई बनाना

द्वारा Ryan11m2024/02/17
Read on Terminal Reader

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

इस ट्यूटोरियल में, हम इस बात पर ध्यान केंद्रित कर रहे हैं कि डेवी और लैंगचेन.जेएस का उपयोग करके प्रश्न-उत्तर देने वाला सीएलआई टूल कैसे बनाया जाए।
featured image - डेवी और लैंगचेन.जेएस के साथ एक प्रश्न-उत्तर सीएलआई बनाना
Ryan HackerNoon profile picture
0-item
1-item
2-item

इस ट्यूटोरियल में, हम इस बात पर ध्यान केंद्रित कर रहे हैं कि डेवी और लैंगचेन.जेएस का उपयोग करके प्रश्न-उत्तर देने वाला सीएलआई टूल कैसे बनाया जाए। डेवी एक ओपन-सोर्स नॉलेज बेस है जो डेवलपर्स को जानकारी को कुशलतापूर्वक व्यवस्थित करने और पुनः प्राप्त करने में मदद करता है। langChain.js एक ढांचा है जो अनुप्रयोगों में बड़े भाषा मॉडल (एलएलएम) के एकीकरण को सरल बनाता है। ज्ञान के प्रबंधन के लिए डेवी की क्षमताओं को लैंगचेन.जेएस के एलएलएम एकीकरण के साथ जोड़कर, आप ऐसे उपकरण बना सकते हैं जो सटीक और प्रासंगिक जानकारी के साथ जटिल प्रश्नों का उत्तर देते हैं।


यह मार्गदर्शिका आपको अपना परिवेश स्थापित करने, डेवी में दस्तावेज़ लोड करने और संग्रहीत डेटा के आधार पर प्रश्नों के उत्तर देने के लिए लैंगचेन.जेएस के माध्यम से एलएलएम का उपयोग करने के बारे में बताती है। इसे उन इंजीनियरों के लिए डिज़ाइन किया गया है जो उन्नत प्रश्न-उत्तर कार्यक्षमताओं के साथ अपनी परियोजनाओं को बढ़ाना चाहते हैं।

डेवी और लैंगचेन.जेएस क्यों?

डेवी एक ओएसएस ज्ञानकोष है जिसे डेवलपर्स द्वारा जानकारी संग्रहीत करने, व्यवस्थित करने और पुनः प्राप्त करने के तरीके को सुव्यवस्थित करने के लिए डिज़ाइन किया गया है। इसका लचीलापन और उपयोग में आसानी इसे ज्ञान-संचालित एप्लिकेशन बनाने का लक्ष्य रखने वाले डेवलपर्स के लिए एक उत्कृष्ट विकल्प बनाती है।


दूसरी ओर, langChain.js एक शक्तिशाली ढांचा है जो डेवलपर्स को एलएलएम को अपने अनुप्रयोगों में सहजता से एकीकृत करने में सक्षम बनाता है। डेवी के संरचित ज्ञान प्रबंधन को LangChain.js की एलएलएम क्षमताओं के साथ जोड़कर, डेवलपर्स परिष्कृत प्रश्न-उत्तर प्रणाली बना सकते हैं जो जटिल प्रश्नों को समझ और संसाधित कर सकते हैं, सटीक और प्रासंगिक रूप से प्रासंगिक उत्तर प्रदान कर सकते हैं।

लक्ष्य

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


आप सीखेंगे कि एक सरल प्रश्न-उत्तर देने वाला एप्लीकेटन बनाने के लिए लैंगचेन का उपयोग कैसे करें, और डेवी को ज्ञान के स्रोत के रूप में कैसे एकीकृत किया जाए, जिससे आपके एप्लीकेटन को आपके द्वारा प्रदान किए गए विशिष्ट दस्तावेजों के आधार पर प्रश्नों का उत्तर देने की अनुमति मिल सके।

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

ट्यूटोरियल में जाने से पहले, सुनिश्चित करें कि आपने निम्नलिखित आवश्यक शर्तें पूरी कर ली हैं:

  • टाइपस्क्रिप्ट प्रोग्रामिंग का बुनियादी ज्ञान
  • सीएलआई उपकरण विकास से परिचित
  • आपकी स्थानीय मशीन पर चल रही डेवी की एक प्रति (यदि आपको सहायता की आवश्यकता हो तो यहां डेवी के इंस्टॉलेशन निर्देश देखें)।

चरण 1: अपना प्रोजेक्ट सेट करें

यदि आप आगे बढ़ना चाहते हैं तो इस उदाहरण के लिए अंतिम कोड डेवी रेपो में उपलब्ध है।

सबसे पहले, टाइपस्क्रिप्ट सीएलआई प्रोजेक्ट के लिए एक निर्देशिका बनाएं और निर्देशिका में बदलें

 mkdir dewy_qa cd dewy_qa

निर्देशिका सेट अप के साथ, आप टाइपस्क्रिप्ट स्थापित कर सकते हैं और प्रोजेक्ट प्रारंभ कर सकते हैं:

 npm init -y npm i typescript --save-dev npx tsc --init

आपके परिवेश के आधार पर, आपको अपने टाइपस्क्रिप्ट कॉन्फ़िगरेशन में कुछ बदलाव करने की आवश्यकता हो सकती है। सुनिश्चित करें कि आपका tsconfig.json कुछ इस तरह दिखता है:

 { "compilerOptions": { "target": "ES6", "module": "CommonJS", "moduleResolution": "node", "declaration": true, "outDir": "./dist", "esModuleInterop": true, "strict": true, }

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

 dewy_qa/ ├── commands/ │ └── ... ├── utils/ │ └── ... ├── index.ts ├── package.json └── tsconfig.ts

प्रत्येक कमांड को commands डायरेक्टरी में लागू किया जाएगा, और साझा कोड utils डायरेक्टरी में जाएगा। सीएलआई एप्लिकेशन का प्रवेश बिंदु फ़ाइल index.ts है।

index.ts के एक सरल "हैलो वर्ल्ड" संस्करण से शुरुआत करें - आप इसे अगले भाग में भरना शुरू करेंगे

 #!/usr/bin/env ts-node-script console.log("hello world");

यह सत्यापित करने के लिए कि वातावरण सही ढंग से सेटअप है, निम्न कमांड चलाने का प्रयास करें - आपको कंसोल में "हैलो वर्ल्ड" मुद्रित देखना चाहिए:

 npx ts-node index.ts

इस बहुत लंबे कमांड को हर बार टाइप करने के बजाय, आइए कमांड के लिए package.json में एक प्रविष्टि बनाएं। इससे हमें यह याद रखने में मदद मिलेगी कि सीएलआई को कैसे लागू किया जाए, और इसे कमांड के रूप में इंस्टॉल करना आसान हो जाएगा:

 { ... "bin": { "dewy_qa": "./index.ts" } ... }

अब आप अपनी स्क्रिप्ट को npm exec dewy_qa के साथ चला सकते हैं या npm link और इसे केवल dewy_qa के रूप में चला सकते हैं

चरण 2: दस्तावेज़ लोडिंग लागू करें

डेवी क्लाइंट सेट करके दस्तावेज़ लोड करें। पहला कदम प्रोजेक्ट में कुछ निर्भरताएँ जोड़ना है। पहला है dewy-ts , जो Dewy के लिए क्लाइंट लाइब्रेरी है। दूसरा commander है, जो हमें तर्क पार्सिंग, उपकमांड और बहुत कुछ के साथ सीएलआई एप्लिकेशन बनाने में मदद करेगा। अंत में, chalk संकेतों को और अधिक रंगीन बनाता है।

 npm install dewy-ts commander chalk

इसके बाद, लोड कमांड के तर्क को लागू करें। आप इसे commands/load.ts नाम की एक अलग फ़ाइल में करेंगे। यह फ़ाइल load नामक एक फ़ंक्शन लागू करती है, जो एक यूआरएल और कुछ अतिरिक्त विकल्पों की अपेक्षा करती है - इसे बाद के अनुभाग में सीएलआई के साथ जोड़ा जाएगा।


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

 import { Dewy } from 'dewy-ts'; import { success, error } from '../utils/colors'; export async function load(url: string, options: { collection: string, dewy_endpoint: string }): Promise<void> { console.log(success(`Loading ${url} into collection: ${options.collection}`)); try { const dewy = new Dewy({ BASE: options.dewy_endpoint }) const result = await dewy.kb.addDocument({ collection: options.collection, url }); console.log(success(`File loaded successfully`)); console.log(JSON.stringify(result, null, 2)); } catch (err: any) { console.error(error(`Failed to load file: ${err.message}`)); } }

आपने देखा होगा कि कुछ फ़ंक्शन ../utils/colors से आयात किए गए थे। यह फ़ाइल कंसोल आउटपुट को रंगने के लिए कुछ सहायक सेट करती है - इसे utils में डालें ताकि इसे अन्यत्र उपयोग किया जा सके:

 import chalk from 'chalk'; export const success = (message: string) => chalk.green(message); export const info = (message: string) => chalk.blue(message); export const error = (message: string) => chalk.red(message);

चरण 3: प्रश्न-उत्तर क्रियान्वित करें

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


आरंभ करने के लिए, ओपनएआई एपीआई को एलएलएम के रूप में उपयोग करने के लिए कुछ अतिरिक्त पैककेज - langchain और openai स्थापित करें:

 npm install dewy-langchain langchain @langchain/openai openai

यह कमांड काफी लंबा है, इसलिए अंत में उन्हें संयोजित करने से पहले हम इसके कई टुकड़ों पर गौर करेंगे

OpenAI और Dewy के लिए क्लाइंट बनाएं

सेटअप करने वाली पहली चीज़ डेवी (पहले की तरह) और एलएलएम है। पहले से एक अंतर यह है कि dewy उपयोग DewyRetriever बनाने के लिए किया जाता है: यह एक विशेष प्रकार है जिसका उपयोग लैंगचेन द्वारा श्रृंखला के हिस्से के रूप में जानकारी प्राप्त करने के लिए किया जाता है। आप देखेंगे कि केवल एक मिनट में रिट्रीवर का उपयोग कैसे किया जाता है।

 const model = new ChatOpenAI({ openAIApiKey: options.openai_api_key, }); const dewy = new Dewy({ BASE: options.dewy_endpoint }) const retriever = new DewyRetriever({ dewy, collection });

एक लैंगचेन प्रॉम्प्ट बनाएं

यह एक स्ट्रिंग टेम्प्लेट है जो एलएलएम को निर्देश देता है कि उसे कैसे व्यवहार करना चाहिए, अतिरिक्त संदर्भ के लिए प्लेसहोल्डर्स के साथ जो "चेन" बनने पर प्रदान किया जाएगा। इस मामले में, एलएलएम को प्रश्न का उत्तर देने का निर्देश दिया जाता है, लेकिन केवल उसके द्वारा प्रदान की गई जानकारी का उपयोग करके। इससे मॉडल की "मतिभ्रम" करने या ऐसा उत्तर देने की प्रवृत्ति कम हो जाती है जो प्रशंसनीय लेकिन गलत हो। context और question के मान अगले चरण में प्रदान किए गए हैं:

 const prompt = PromptTemplate.fromTemplate(`Answer the question based only on the following context: {context} Question: {question}`);

श्रृंखला का निर्माण करें

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


LCEL श्रृंखला बनाने के लिए RunnableSequence का उपयोग करें। यह श्रृंखला बताती है कि context और question मान कैसे उत्पन्न करें: संदर्भ पहले बनाए गए रिट्रीवर का उपयोग करके उत्पन्न होता है, और प्रश्न चरण के इनपुट से गुजरकर उत्पन्न होता है। Dewy द्वारा प्राप्त परिणामों को formatDocumentsAsString फ़ंक्शन में पाइप करके एक स्ट्रिंग के रूप में स्वरूपित किया जाता है।


यह श्रृंखला निम्नलिखित कार्य करती है:

  1. यह DewyRetriever का उपयोग करके दस्तावेज़ पुनर्प्राप्त करता है और उन्हें context में निर्दिष्ट करता है और श्रृंखला के इनपुट मान को question पर निर्दिष्ट करता है।
  2. यह context और question चर का उपयोग करके प्रॉम्प्ट स्ट्रिंग को प्रारूपित करता है।
  3. यह प्रतिक्रिया उत्पन्न करने के लिए एलएलएम को स्वरूपित संकेत भेजता है।
  4. यह एलएलएम की प्रतिक्रिया को एक स्ट्रिंग के रूप में प्रारूपित करता है।
 const chain = RunnableSequence.from([ { context: retriever.pipe(formatDocumentsAsString), question: new RunnablePassthrough(), }, prompt, model, new StringOutputParser(), ]);

शृंखला निष्पादित करें

अब जब श्रृंखला का निर्माण हो गया है, तो इसे निष्पादित करें और परिणामों को कंसोल पर आउटपुट करें। जैसा कि आप देखेंगे, question फ़ंक्शन के कॉलर द्वारा प्रदान किया गया एक इनपुट तर्क है।


chain.streamLog() का उपयोग करके श्रृंखला को निष्पादित करने से आप प्रत्येक प्रतिक्रिया खंड को देख सकते हैं क्योंकि यह एलएलएम से लौटाया गया है। स्ट्रीम हैंडलर लूप कुछ हद तक बदसूरत है, लेकिन यह केवल उपयुक्त स्ट्रीम परिणामों को फ़िल्टर कर रहा है और उन्हें STDOUT पर लिख रहा है ( console.log उपयोग करके यह प्रत्येक खंड के बाद नई लाइनें जोड़ देगा)।

 const stream = await chain.streamLog(question); // Write chunks of the response to STDOUT as they're received console.log("Answer:"); for await (const chunk of stream) { if (chunk.ops?.length > 0 && chunk.ops[0].op === "add") { const addOp = chunk.ops[0]; if ( addOp.path.startsWith("/logs/ChatOpenAI") && typeof addOp.value === "string" && addOp.value.length ) { process.stdout.write(addOp.value); } } }

एक आदेश के रूप में यह सब एक साथ खींचें

अब जब आपने सभी टुकड़े देख लिए हैं, तो आप query कमांड बनाने के लिए तैयार हैं। यह कुछ अतिरिक्त आयातों के साथ पहले के load कमांड के समान दिखना चाहिए।

 import { StringOutputParser } from "@langchain/core/output_parsers"; import { PromptTemplate } from "@langchain/core/prompts"; import { formatDocumentsAsString } from "langchain/util/document"; import { RunnablePassthrough, RunnableSequence } from "@langchain/core/runnables"; import { ChatOpenAI } from "@langchain/openai"; import { Dewy } from 'dewy-ts'; import { DewyRetriever } from 'dewy-langchain'; import { success, error } from '../utils/colors'; export async function query(question: string, options: { collection: string, dewy_endpoint: string, openai_api_key: string }): Promise<void> { console.log(success(`Querying ${options.collection} collection for: "${question}"`)); try { const model = new ChatOpenAI({ openAIApiKey: options.openai_api_key, }); const dewy = new Dewy({ BASE: options.dewy_endpoint }) const retriever = new DewyRetriever({ dewy, collection: options.collection }); const prompt = PromptTemplate.fromTemplate(`Answer the question based only on the following context: {context} Question: {question}`); const chain = RunnableSequence.from([ { context: retriever.pipe(formatDocumentsAsString), question: new RunnablePassthrough(), }, prompt, model, new StringOutputParser(), ]); const stream = await chain.streamLog(question); // Write chunks of the response to STDOUT as they're received console.log("Answer:"); for await (const chunk of stream) { if (chunk.ops?.length > 0 && chunk.ops[0].op === "add") { const addOp = chunk.ops[0]; if ( addOp.path.startsWith("/logs/ChatOpenAI") && typeof addOp.value === "string" && addOp.value.length ) { process.stdout.write(addOp.value); } } } } catch (err: any) { console.error(error(`Failed to query: ${err.message}`)); } }

चरण 4: सीएलआई का निर्माण

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


सबसे पहले, उपकमांड load और query बनाने के लिए index.ts फिर से लिखें। --collection तर्क यह निर्धारित करता है कि दस्तावेज़ को किस Dewy संग्रह में लोड किया जाना चाहिए (Dewy आपको दस्तावेज़ों को फ़ाइल फ़ोल्डरों के समान विभिन्न संग्रहों में व्यवस्थित करने देता है)। --dewy-endpoint तर्क आपको यह निर्दिष्ट करने देता है कि Dewy से कैसे कनेक्ट किया जाए - डिफ़ॉल्ट रूप से पोर्ट 8000 पर स्थानीय रूप से चलने वाला एक उदाहरण माना जाता है। अंत में, --openai_api_key तर्क (जो एक पर्यावरण चर के लिए डिफ़ॉल्ट है) OpenAI API को कॉन्फ़िगर करता है:

 #!/usr/bin/env ts-node-script import { Command } from 'commander'; import { load } from './commands/load'; import { query } from './commands/query'; const program = new Command(); program.name('dewy-qa').description('CLI tool for interacting with a knowledge base API').version('1.0.0'); const defaultOpenAIKey = process.env.OPENAI_API_KEY; program .command('load') .description("Load documents into Dewy from a URL") .option('--collection <collection>', 'Specify the collection name', 'main') .option('--dewy-endpoint <endpoint>', 'Specify the collection name', 'http://localhost:8000') .argument('<url>', 'URL to load into the knowledge base') .action(load); program .command('query') .description('Ask questions using an LLM and the loaded documents for answers') .option('--collection <collection>', 'Specify the collection name', 'main') .option('--dewy-endpoint <endpoint>', 'Specify the collection name', 'http://localhost:8000') .option('--openai-api-key <key>', 'Specify the collection name', defaultOpenAIKey) .argument('<question>', 'Question to ask the knowledge base') .action(query); program.parse(process.argv);

ठीक है, सब हो गया - क्या यह आसान नहीं था? आप कमांड चलाकर इसे आज़मा सकते हैं:

 dewy_qa load https://arxiv.org/pdf/2009.08553.pdf

आपको कुछ इस तरह देखना चाहिए

 Loading https://arxiv.org/pdf/2009.08553.pdf into collection: main File loaded successfully { "id": 18, "collection": "main", "extracted_text": null, "url": "https://arxiv.org/pdf/2009.08553.pdf", "ingest_state": "pending", "ingest_error": null }

एक बड़े पीडीएफ की सामग्री को निकालने में एक या दो मिनट लग सकते हैं, इसलिए जब आप पहली बार कोई नया दस्तावेज़ लोड करते हैं तो आपको अक्सर "ingest_state": "pending" दिखाई देगा।

इसके बाद, कुछ प्रश्न पूछने का प्रयास करें:

 dewy_qa query "tell me about RAG

आपको कुछ इस तरह देखना चाहिए

 Querying main collection for: "tell me about RAG" Answer: Based on the given context, RAG refers to the RAG proteins, which are involved in DNA binding and V(D)J recombination. The RAG1 and RAG2 proteins work together to bind specific DNA sequences known as RSS (recombination signal sequences) and facilitate the cutting and rearrangement of DNA segments during the process of V(D)J recombination...

निष्कर्ष

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

आगे पढ़ना और संसाधन