এই টিউটোরিয়ালে, আমরা কীভাবে Dewy এবং LangChain.js ব্যবহার করে একটি প্রশ্ন-উত্তরকারী CLI টুল তৈরি করতে হয় তার উপর ফোকাস করছি। Dewy হল একটি মুক্ত-উৎস জ্ঞানের ভিত্তি যা বিকাশকারীদের দক্ষতার সাথে তথ্য সংগঠিত করতে এবং পুনরুদ্ধার করতে সহায়তা করে। LangChain.js হল একটি ফ্রেমওয়ার্ক যা অ্যাপ্লিকেশানগুলিতে বৃহৎ ভাষা মডেলের (LLM) একীকরণকে সহজ করে। LangChain.js এর LLM ইন্টিগ্রেশনের সাথে জ্ঞান পরিচালনার জন্য Dewy-এর ক্ষমতার সমন্বয় করে, আপনি এমন সরঞ্জাম তৈরি করতে পারেন যা সুনির্দিষ্ট এবং প্রাসঙ্গিক তথ্য সহ জটিল প্রশ্নের উত্তর দেয়।
এই নির্দেশিকা আপনাকে আপনার পরিবেশ সেট আপ করার, Dewy-এ নথি লোড করার এবং সঞ্চিত ডেটার উপর ভিত্তি করে প্রশ্নের উত্তর দেওয়ার জন্য LangChain.js এর মাধ্যমে একটি LLM ব্যবহার করার মাধ্যমে নিয়ে যায়। এটি ইঞ্জিনিয়ারদের জন্য ডিজাইন করা হয়েছে যারা তাদের প্রজেক্টগুলিকে উন্নত প্রশ্ন-উত্তর কার্যকারিতা সহ উন্নত করতে চাইছেন৷
Dewy হল একটি OSS নলেজ বেস যা ডেভেলপারদের তথ্য সঞ্চয়, সংগঠিত এবং পুনরুদ্ধার করার পদ্ধতিকে প্রবাহিত করার জন্য ডিজাইন করা হয়েছে। এর নমনীয়তা এবং ব্যবহারের সহজতা এটিকে জ্ঞান-চালিত অ্যাপ্লিকেশন তৈরি করার লক্ষ্যে বিকাশকারীদের জন্য একটি চমৎকার পছন্দ করে তোলে।
অন্যদিকে, LangChain.js হল একটি শক্তিশালী ফ্রেমওয়ার্ক যা ডেভেলপারদের তাদের অ্যাপ্লিকেশানগুলিতে নির্বিঘ্নে LLM একীভূত করতে সক্ষম করে৷ Dewy-এর কাঠামোগত জ্ঞান ব্যবস্থাপনাকে LangChain.js-এর LLM ক্ষমতার সাথে একত্রিত করে, বিকাশকারীরা পরিশীলিত প্রশ্ন-উত্তর সিস্টেম তৈরি করতে পারে যা জটিল প্রশ্নগুলি বুঝতে এবং প্রক্রিয়া করতে পারে, সুনির্দিষ্ট এবং প্রাসঙ্গিকভাবে প্রাসঙ্গিক উত্তর প্রদান করে।
আমাদের লক্ষ্য হল একটি সহজ অথচ শক্তিশালী প্রশ্ন-উত্তর CLI স্ক্রিপ্ট তৈরি করা। এই স্ক্রিপ্ট ব্যবহারকারীদের Dewy নলেজ বেসে ডকুমেন্ট লোড করতে এবং তারপর Dewy-এ সঞ্চিত তথ্যের উপর ভিত্তি করে প্রশ্নের উত্তর দিতে LangChain.js-এর মাধ্যমে একটি LLM ব্যবহার করার অনুমতি দেবে। এই টিউটোরিয়ালটি আপনার পরিবেশ সেট আপ করা থেকে শুরু করে CLI স্ক্রিপ্ট বাস্তবায়ন পর্যন্ত প্রক্রিয়ার মাধ্যমে আপনাকে গাইড করবে।
আপনি শিখবেন কীভাবে ল্যাংচেইন ব্যবহার করে একটি সহজ প্রশ্ন-উত্তর অ্যাপ্লিকেশন তৈরি করতে হয়, এবং কীভাবে Dewy কে জ্ঞানের উৎস হিসাবে একীভূত করতে হয়, আপনার আবেদনকারীকে আপনার দেওয়া নির্দিষ্ট নথির উপর ভিত্তি করে প্রশ্নের উত্তর দেওয়ার অনুমতি দেয়।
টিউটোরিয়ালে ডুব দেওয়ার আগে, নিশ্চিত করুন যে আপনি নিম্নলিখিত পূর্বশর্তগুলি কভার করেছেন:
আপনি যদি এগিয়ে যেতে চান তবে এই উদাহরণের জন্য চূড়ান্ত কোডটি ডিউই রেপোতে উপলব্ধ।
প্রথমে, TypeScript CLI প্রকল্পের জন্য একটি ডিরেক্টরি তৈরি করুন এবং ডিরেক্টরিতে পরিবর্তন করুন
mkdir dewy_qa cd dewy_qa
ডিরেক্টরি সেট আপ করে, আপনি টাইপস্ক্রিপ্ট ইনস্টল করতে পারেন এবং প্রকল্পটি শুরু করতে পারেন:
npm init -y npm i typescript --save-dev npx tsc --init
আপনার পরিবেশের উপর নির্ভর করে, আপনাকে আপনার TypeScript কনফিগারেশনে কিছু পরিবর্তন করতে হতে পারে। নিশ্চিত করুন যে আপনার tsconfig.json
নিম্নলিখিত মত কিছু দেখায়:
{ "compilerOptions": { "target": "ES6", "module": "CommonJS", "moduleResolution": "node", "declaration": true, "outDir": "./dist", "esModuleInterop": true, "strict": true, }
এখন আপনি CLI অ্যাপ্লিকেশন তৈরি করতে প্রস্তুত। কোডটিকে খুব অগোছালো না করতে, নিম্নলিখিত লেআউট সহ এটিকে কয়েকটি ডিরেক্টরিতে সংগঠিত করুন
dewy_qa/ ├── commands/ │ └── ... ├── utils/ │ └── ... ├── index.ts ├── package.json └── tsconfig.ts
প্রতিটি কমান্ড commands
ডিরেক্টরিতে প্রয়োগ করা হবে, এবং ভাগ করা কোড utils
ডিরেক্টরিতে যাবে। CLI অ্যাপ্লিকেশনের এন্ট্রিপয়েন্ট হল index.ts
ফাইল।
index.ts
এর একটি সাধারণ "হ্যালো ওয়ার্ল্ড" সংস্করণ দিয়ে শুরু করুন - আপনি পরবর্তী বিভাগে এটি পূরণ করতে শুরু করবেন
#!/usr/bin/env ts-node-script console.log("hello world");
পরিবেশটি সঠিকভাবে সেটআপ করা হয়েছে তা যাচাই করতে, নিম্নলিখিত কমান্ডটি চালানোর চেষ্টা করুন - আপনি কনসোলে "হ্যালো ওয়ার্ল্ড" মুদ্রিত দেখতে পাবেন:
npx ts-node index.ts
প্রতিবার এই খুব দীর্ঘ কমান্ডটি টাইপ করার পরিবর্তে, কমান্ডের জন্য package.json
এ একটি এন্ট্রি তৈরি করা যাক। এটি আমাদের মনে রাখতে সাহায্য করবে কিভাবে CLI চালু করতে হয় এবং কমান্ড হিসাবে ইনস্টল করা সহজ করে তোলে:
{ ... "bin": { "dewy_qa": "./index.ts" } ... }
এখন আপনি npm exec dewy_qa
বা npm link
দিয়ে আপনার স্ক্রিপ্ট চালাতে পারেন এবং এটিকে শুধু dewy_qa
হিসাবে চালাতে পারেন
Dewy ক্লায়েন্ট সেট আপ করে নথি লোড করুন। প্রথম ধাপ হল প্রকল্পে কিছু নির্ভরতা যোগ করা। প্রথমটি হল dewy-ts
, Dewy-এর জন্য ক্লায়েন্ট লাইব্রেরি। দ্বিতীয়টি হল commander
, যা আর্গুমেন্ট পার্সিং, সাবকমান্ড এবং আরও অনেক কিছু সহ একটি CLI অ্যাপ্লিকেশন তৈরি করতে সাহায্য করবে। অবশেষে, প্রম্পটগুলিকে আরও রঙিন করতে chalk
।
npm install dewy-ts commander chalk
এর পরে, লোড কমান্ডের যুক্তি প্রয়োগ করুন। আপনি commands/load.ts
নামে একটি পৃথক ফাইলে এটি করবেন। এই ফাইলটি load
নামের একটি ফাংশন প্রয়োগ করে, যা একটি URL এবং কিছু অতিরিক্ত বিকল্পের প্রত্যাশা করে - এটি পরবর্তী বিভাগে CLI এর সাথে সংযুক্ত করা হবে।
Dewy দস্তাবেজ লোড করা খুব সহজ করে তোলে - শুধু ক্লায়েন্ট সেটআপ করুন এবং আপনি যে ফাইলটি লোড করতে চান তার URL দিয়ে 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);
Dewy-এ নথি লোড করার ক্ষমতার সাথে, এখন LangChain.js-কে সংহত করার সময় প্রশ্নের উত্তর দেওয়ার জন্য LLM ব্যবহার করার জন্য। এই ধাপে Dewy নলেজ বেস জিজ্ঞাসা করার জন্য LangChain.js সেট আপ করা এবং উত্তর তৈরি করতে LLM ব্যবহার করে ফলাফলগুলি প্রক্রিয়া করা জড়িত।
শুরু করতে, LLM হিসাবে OpenAI API ব্যবহার করার জন্য কিছু অতিরিক্ত প্যাকেজ - langchain
এবং openai
ইনস্টল করুন:
npm install dewy-langchain langchain @langchain/openai openai
এই কমান্ডটি বেশ দীর্ঘ, তাই শেষ পর্যন্ত একত্রিত করার আগে আমরা এর কয়েকটি টুকরো দিয়ে হাঁটব
সেটআপ করার প্রথম জিনিসটি হল ডিউই (আগের মতো) এবং একটি এলএলএম। আগের থেকে একটি পার্থক্য হল যে 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 });
এটি একটি স্ট্রিং টেমপ্লেট যা এলএলএমকে নির্দেশ দেয় যে এটি কীভাবে আচরণ করা উচিত, অতিরিক্ত প্রসঙ্গের জন্য স্থানধারক সহ যা "চেইন" তৈরি করার সময় প্রদান করা হবে। এই ক্ষেত্রে, LLM কে প্রশ্নের উত্তর দেওয়ার জন্য নির্দেশ দেওয়া হয়, কিন্তু শুধুমাত্র এটি দেওয়া তথ্য ব্যবহার করে। এটি মডেলের "হ্যালুসিনেট" করার প্রবণতাকে হ্রাস করে, বা এমন একটি উত্তর তৈরি করে যা যুক্তিসঙ্গত কিন্তু ভুল। context
এবং question
মান পরবর্তী ধাপে প্রদান করা হয়েছে:
const prompt = PromptTemplate.fromTemplate(`Answer the question based only on the following context: {context} Question: {question}`);
ল্যাংচেইন আচরণের "চেইন" তৈরি করে কাজ করে যা LLM এবং অন্যান্য ডেটা উত্সগুলি কীভাবে অনুসন্ধান করতে হয় তা নিয়ন্ত্রণ করে। এই উদাহরণটি LCEL ব্যবহার করে, যা LangChain-এর মূল ইন্টারফেসের তুলনায় আরও নমনীয় প্রোগ্রামিং অভিজ্ঞতা প্রদান করে।
একটি LCEL চেইন তৈরি করতে একটি RunnableSequence
ব্যবহার করুন। এই চেইনটি বর্ণনা করে যে কীভাবে context
এবং question
মান তৈরি করতে হয়: পূর্বে তৈরি করা পুনরুদ্ধার ব্যবহার করে প্রসঙ্গ তৈরি করা হয় এবং ধাপের ইনপুটটি অতিক্রম করে প্রশ্ন তৈরি করা হয়। Dewy retrieves ফলাফল formatDocumentsAsString
ফাংশনে পাইপ করে একটি স্ট্রিং হিসাবে ফর্ম্যাট করা হয়।
এই চেইন নিম্নলিখিত কাজ করে:
DewyRetriever
ব্যবহার করে নথিগুলি পুনরুদ্ধার করে এবং সেগুলিকে context
বরাদ্দ করে এবং question
চেইনের ইনপুট মান নির্ধারণ করে।context
এবং question
ভেরিয়েবল ব্যবহার করে ফর্ম্যাট করে। const chain = RunnableSequence.from([ { context: retriever.pipe(formatDocumentsAsString), question: new RunnablePassthrough(), }, prompt, model, new StringOutputParser(), ]);
এখন যেহেতু চেইনটি তৈরি করা হয়েছে, এটি চালান এবং ফলাফলগুলি কনসোলে আউটপুট করুন। আপনি দেখতে পাবেন, question
হল ফাংশনের কলার দ্বারা প্রদত্ত একটি ইনপুট আর্গুমেন্ট।
chain.streamLog()
ব্যবহার করে চেইন চালানোর ফলে আপনি প্রতিটি প্রতিক্রিয়া খণ্ড দেখতে পারবেন কারণ এটি LLM থেকে ফিরে এসেছে। স্ট্রীম হ্যান্ডলার লুপটি বেশ কুৎসিত, কিন্তু এটি কেবলমাত্র উপযুক্ত স্ট্রিম ফলাফলগুলি ফিল্টার করে এবং 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}`)); } }
Dewy এবং LangChain.js সমন্বিত করে, পরবর্তী ধাপ হল CLI ইন্টারফেস তৈরি করা। একটি ব্যবহারকারী-বান্ধব কমান্ড-লাইন ইন্টারফেস তৈরি করতে commander
মতো একটি লাইব্রেরি ব্যবহার করুন যা Dewy-এ নথি লোড করার জন্য কমান্ড সমর্থন করে এবং LangChain.js ব্যবহার করে জ্ঞানের ভিত্তি অনুসন্ধান করে।
প্রথমে, সাবকমান্ড 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 }
একটি বড় PDF এর বিষয়বস্তু বের করতে এক বা দুই মিনিট সময় লাগতে পারে, তাই আপনি যখন প্রথমবার একটি নতুন নথি লোড করবেন তখন আপনি প্রায়ই "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...
এই নির্দেশিকা অনুসরণ করে, আপনি শিখেছেন কীভাবে একটি CLI তৈরি করতে হয় যা জ্ঞান পরিচালনার জন্য Dewy এবং LangChain.js প্রশ্ন প্রক্রিয়াকরণ এবং উত্তর তৈরি করতে ব্যবহার করে। এই টুলটি LLM-এর বিশ্লেষণাত্মক শক্তির সাথে একটি কাঠামোগত জ্ঞানের ভিত্তিকে একত্রিত করার ব্যবহারিক প্রয়োগ প্রদর্শন করে, যা ডেভেলপারদের আরও বুদ্ধিমান এবং প্রতিক্রিয়াশীল অ্যাপ্লিকেশন তৈরি করতে সক্ষম করে।