Vertex AI এবং LangChain4j সহ জাভাতে জেমিনি

1. ভূমিকা

এই কোডল্যাবটি জেমিনি লার্জ ল্যাঙ্গুয়েজ মডেল (LLM) এর উপর ফোকাস করে, যা Google ক্লাউডে Vertex AI- তে হোস্ট করা হয়েছে। Vertex AI হল এমন একটি প্ল্যাটফর্ম যা Google ক্লাউডে সমস্ত মেশিন লার্নিং পণ্য, পরিষেবা এবং মডেলগুলিকে অন্তর্ভুক্ত করে৷

আপনি LangChain4j ফ্রেমওয়ার্ক ব্যবহার করে Gemini API এর সাথে ইন্টারঅ্যাক্ট করতে Java ব্যবহার করবেন। প্রশ্নের উত্তর, আইডিয়া জেনারেশন, এন্টিটি এবং স্ট্রাকচার্ড কন্টেন্ট এক্সট্রাকশন, রিট্রিভাল অগমেন্টেড জেনারেশন এবং ফাংশন কলিং এর জন্য LLM এর সুবিধা নিতে আপনি কংক্রিট উদাহরণ দিয়ে যাবেন।

জেনারেটিভ এআই কি?

জেনারেটিভ এআই নতুন বিষয়বস্তু যেমন টেক্সট, ছবি, সঙ্গীত, অডিও এবং ভিডিও তৈরি করতে কৃত্রিম বুদ্ধিমত্তার ব্যবহারকে বোঝায়।

জেনারেটিভ এআই বড় ভাষা মডেল (এলএলএম) দ্বারা চালিত হয় যা বহু-কাজ করতে পারে এবং সারসংক্ষেপ, প্রশ্নোত্তর, শ্রেণিবিন্যাস এবং আরও অনেক কিছুর মতো কাজগুলি সম্পাদন করতে পারে। ন্যূনতম প্রশিক্ষণের সাথে, ভিত্তিমূলক মডেলগুলিকে খুব কম উদাহরণ ডেটা সহ লক্ষ্যযুক্ত ব্যবহারের ক্ষেত্রে অভিযোজিত করা যেতে পারে।

জেনারেটিভ এআই কিভাবে কাজ করে?

জেনারেটিভ এআই একটি মেশিন লার্নিং (এমএল) মডেল ব্যবহার করে মানুষের তৈরি সামগ্রীর একটি ডেটাসেটের নিদর্শন এবং সম্পর্কগুলি শিখতে কাজ করে। এটি তারপর নতুন বিষয়বস্তু তৈরি করতে শেখা নিদর্শন ব্যবহার করে।

একটি জেনারেটিভ এআই মডেল প্রশিক্ষণের সবচেয়ে সাধারণ উপায় হল তত্ত্বাবধানে শিক্ষার ব্যবহার। মডেলটিকে মানব-সৃষ্ট সামগ্রী এবং সংশ্লিষ্ট লেবেলের একটি সেট দেওয়া হয়েছে। এটি তখন এমন সামগ্রী তৈরি করতে শেখে যা মানুষের তৈরি সামগ্রীর মতো।

সাধারণ জেনারেটিভ এআই অ্যাপ্লিকেশন কি কি?

জেনারেটিভ এআই ব্যবহার করা যেতে পারে:

  • উন্নত চ্যাট এবং অনুসন্ধান অভিজ্ঞতার মাধ্যমে গ্রাহকের মিথস্ক্রিয়া উন্নত করুন।
  • কথোপকথন ইন্টারফেস এবং সারসংক্ষেপের মাধ্যমে বিশাল পরিমাণে অসংগঠিত ডেটা অন্বেষণ করুন।
  • প্রস্তাবের জন্য অনুরোধের উত্তর দেওয়া, বিভিন্ন ভাষায় বিপণনের বিষয়বস্তু স্থানীয়করণ এবং সম্মতির জন্য গ্রাহক চুক্তি পরীক্ষা করা এবং আরও অনেক কিছুর মতো পুনরাবৃত্তিমূলক কাজগুলিতে সহায়তা করুন।

গুগল ক্লাউডে কী জেনারেটিভ এআই অফার রয়েছে?

Vertex AI-এর সাথে, আপনি আপনার অ্যাপ্লিকেশনগুলিতে ফাউন্ডেশন মডেলগুলির সাথে যোগাযোগ করতে, কাস্টমাইজ করতে এবং এম্বেড করতে পারেন সামান্য থেকে কোন ML দক্ষতা ছাড়াই৷ আপনি মডেল গার্ডেনে ফাউন্ডেশন মডেলগুলি অ্যাক্সেস করতে পারেন, Vertex AI স্টুডিওতে একটি সাধারণ UI এর মাধ্যমে মডেলগুলি টিউন করতে পারেন, বা ডেটা সায়েন্স নোটবুকে মডেলগুলি ব্যবহার করতে পারেন৷

Vertex AI সার্চ এবং কথোপকথন ডেভেলপারদের জেনারেটিভ AI চালিত সার্চ ইঞ্জিন এবং চ্যাটবট তৈরি করার দ্রুততম উপায় অফার করে।

Gemini দ্বারা চালিত, Google ক্লাউডের জন্য Gemini হল একটি AI-চালিত সহযোগী Google ক্লাউড এবং IDE জুড়ে উপলব্ধ একটি AI-চালিত সহযোগী যা আপনাকে আরও দ্রুত, আরও কাজ করতে সাহায্য করে৷ জেমিনি কোড অ্যাসিস্ট কোড সম্পূর্ণতা, কোড জেনারেশন, কোড ব্যাখ্যা প্রদান করে এবং আপনাকে প্রযুক্তিগত প্রশ্ন জিজ্ঞাসা করতে এটির সাথে চ্যাট করতে দেয়।

মিথুন কি?

Gemini হল Google DeepMind দ্বারা ডেভেলপ করা জেনারেটিভ এআই মডেলের একটি পরিবার যা মাল্টিমোডাল ব্যবহারের ক্ষেত্রে ডিজাইন করা হয়েছে। মাল্টিমোডাল মানে এটি বিভিন্ন ধরণের সামগ্রী যেমন পাঠ্য, কোড, চিত্র এবং অডিও প্রক্রিয়া করতে এবং তৈরি করতে পারে।

b9913d011999e7c7.png

মিথুন বিভিন্ন বৈচিত্র্য এবং আকারে আসে:

  • জেমিনি আল্ট্রা : জটিল কাজের জন্য সবচেয়ে বড়, সবচেয়ে সক্ষম সংস্করণ।
  • জেমিনি ফ্ল্যাশ : দ্রুততম এবং সবচেয়ে সাশ্রয়ী, উচ্চ-ভলিউম কাজের জন্য অপ্টিমাইজ করা।
  • জেমিনি প্রো : মাঝারি আকারের, বিভিন্ন কাজ জুড়ে স্কেলিং করার জন্য অপ্টিমাইজ করা।
  • জেমিনি ন্যানো : সবচেয়ে দক্ষ, ডিভাইসে কাজ করার জন্য ডিজাইন করা হয়েছে।

মূল বৈশিষ্ট্য:

  • মাল্টিমোডালিটি : মিথুনের একাধিক তথ্য বিন্যাস বোঝা এবং পরিচালনা করার ক্ষমতা ঐতিহ্যগত পাঠ্য-শুধু ভাষার মডেলের বাইরে একটি উল্লেখযোগ্য পদক্ষেপ।
  • পারফরম্যান্স : জেমিনি আল্ট্রা বর্তমান অত্যাধুনিক অনেক বেঞ্চমার্ককে ছাড়িয়ে গেছে এবং চ্যালেঞ্জিং MMLU (ম্যাসিভ মাল্টিটাস্ক ল্যাঙ্গুয়েজ আন্ডারস্ট্যান্ডিং) বেঞ্চমার্কে মানব বিশেষজ্ঞদের ছাড়িয়ে যাওয়া প্রথম মডেল।
  • নমনীয়তা : বিভিন্ন মিথুন মাপ এটিকে বিভিন্ন ব্যবহারের ক্ষেত্রে অভিযোজনযোগ্য করে তোলে, বড় আকারের গবেষণা থেকে শুরু করে মোবাইল ডিভাইসে স্থাপনা পর্যন্ত।

আপনি কিভাবে জাভা থেকে Vertex AI-তে মিথুনের সাথে যোগাযোগ করতে পারেন?

আপনার দুটি বিকল্প আছে:

  1. জেমিনি লাইব্রেরির জন্য অফিসিয়াল Vertex AI Java API
  2. LangChain4j ফ্রেমওয়ার্ক।

এই কোডল্যাবে, আপনি LangChain4j ফ্রেমওয়ার্ক ব্যবহার করবেন।

LangChain4j ফ্রেমওয়ার্ক কি?

LangChain4j ফ্রেমওয়ার্ক হল একটি ওপেন সোর্স লাইব্রেরি যা আপনার জাভা অ্যাপ্লিকেশানগুলিতে এলএলএমগুলিকে একীভূত করার জন্য, বিভিন্ন উপাদান যেমন এলএলএম নিজেই অর্কেস্ট্রেট করে, তবে অন্যান্য সরঞ্জাম যেমন ভেক্টর ডেটাবেস (অর্থবোধক অনুসন্ধানের জন্য), নথি লোডার এবং স্প্লিটার (ডকুমেন্ট বিশ্লেষণ এবং শিখতে) তাদের থেকে), আউটপুট পার্সার এবং আরও অনেক কিছু।

প্রকল্পটি ল্যাংচেইন পাইথন প্রকল্প দ্বারা অনুপ্রাণিত হয়েছিল কিন্তু জাভা বিকাশকারীদের পরিবেশন করার লক্ষ্যে।

bb908ea1e6c96ac2.png

আপনি কি শিখবেন

  • Gemini এবং LangChain4j ব্যবহার করার জন্য কীভাবে একটি জাভা প্রকল্প সেটআপ করবেন
  • কিভাবে আপনার প্রথম প্রম্পট মিথুন প্রোগ্রামে পাঠাবেন
  • কিভাবে মিথুন থেকে প্রতিক্রিয়া স্ট্রিম করা যায়
  • কীভাবে একজন ব্যবহারকারী এবং মিথুনের মধ্যে কথোপকথন তৈরি করবেন
  • টেক্সট এবং ইমেজ উভয় পাঠিয়ে একটি মাল্টিমোডাল প্রেক্ষাপটে মিথুন কিভাবে ব্যবহার করবেন
  • অসংগঠিত বিষয়বস্তু থেকে কীভাবে দরকারী কাঠামোগত তথ্য বের করা যায়
  • প্রম্পট টেমপ্লেটগুলি কীভাবে পরিচালনা করবেন
  • কিভাবে পাঠ্য শ্রেণীবিভাগ করা যায় যেমন অনুভূতি বিশ্লেষণ
  • কীভাবে আপনার নিজের নথির সাথে চ্যাট করবেন (পুনরুদ্ধার অগমেন্টেড জেনারেশন)
  • কীভাবে আপনার চ্যাটবটগুলিকে ফাংশন কলিংয়ের মাধ্যমে প্রসারিত করবেন
  • ওল্লামা এবং টেস্টকন্টেনারগুলির সাথে স্থানীয়ভাবে জেমা কীভাবে ব্যবহার করবেন

আপনি কি প্রয়োজন হবে

  • জাভা প্রোগ্রামিং ভাষার জ্ঞান
  • একটি Google ক্লাউড প্রকল্প
  • একটি ব্রাউজার, যেমন ক্রোম বা ফায়ারফক্স

2. সেটআপ এবং প্রয়োজনীয়তা

স্ব-গতিসম্পন্ন পরিবেশ সেটআপ

  1. Google ক্লাউড কনসোলে সাইন-ইন করুন এবং একটি নতুন প্রকল্প তৈরি করুন বা বিদ্যমান একটি পুনরায় ব্যবহার করুন৷ আপনার যদি ইতিমধ্যেই একটি Gmail বা Google Workspace অ্যাকাউন্ট না থাকে, তাহলে আপনাকে অবশ্যই একটি তৈরি করতে হবে।

fbef9caa1602edd0.png

a99b7ace416376c4.png

5e3ff691252acf41.png

  • প্রকল্পের নাম এই প্রকল্পের অংশগ্রহণকারীদের জন্য প্রদর্শনের নাম। এটি একটি অক্ষর স্ট্রিং যা Google API দ্বারা ব্যবহৃত হয় না। আপনি সবসময় এটি আপডেট করতে পারেন.
  • প্রোজেক্ট আইডি সমস্ত Google ক্লাউড প্রোজেক্ট জুড়ে অনন্য এবং অপরিবর্তনীয় (সেট করার পরে পরিবর্তন করা যাবে না)। ক্লাউড কনসোল স্বয়ংক্রিয়ভাবে একটি অনন্য স্ট্রিং তৈরি করে; সাধারণত আপনি এটা কি যত্ন না. বেশিরভাগ কোডল্যাবে, আপনাকে আপনার প্রকল্প আইডি উল্লেখ করতে হবে (সাধারণত PROJECT_ID হিসাবে চিহ্নিত)। আপনি যদি জেনারেট করা আইডি পছন্দ না করেন, তাহলে আপনি অন্য একটি এলোমেলো আইডি তৈরি করতে পারেন। বিকল্পভাবে, আপনি নিজের চেষ্টা করতে পারেন, এবং এটি উপলব্ধ কিনা দেখতে পারেন। এই ধাপের পরে এটি পরিবর্তন করা যাবে না এবং প্রকল্পের সময়কালের জন্য থাকে।
  • আপনার তথ্যের জন্য, একটি তৃতীয় মান আছে, একটি প্রকল্প নম্বর , যা কিছু API ব্যবহার করে। ডকুমেন্টেশনে এই তিনটি মান সম্পর্কে আরও জানুন।
  1. এরপরে, ক্লাউড রিসোর্স/এপিআই ব্যবহার করতে আপনাকে ক্লাউড কনসোলে বিলিং সক্ষম করতে হবে। এই কোডল্যাবের মাধ্যমে চালানোর জন্য খুব বেশি খরচ হবে না, যদি কিছু হয়। এই টিউটোরিয়ালের বাইরে বিলিং এড়াতে সংস্থানগুলি বন্ধ করতে, আপনি আপনার তৈরি করা সংস্থানগুলি মুছতে বা প্রকল্প মুছতে পারেন। নতুন Google ক্লাউড ব্যবহারকারীরা $300 USD বিনামূল্যের ট্রায়াল প্রোগ্রামের জন্য যোগ্য৷

ক্লাউড শেল শুরু করুন

যদিও Google ক্লাউড আপনার ল্যাপটপ থেকে দূরবর্তীভাবে পরিচালিত হতে পারে, এই কোডল্যাবে আপনি ক্লাউড শেল ব্যবহার করবেন, ক্লাউডে চলমান একটি কমান্ড লাইন পরিবেশ।

ক্লাউড শেল সক্রিয় করুন

  1. ক্লাউড কনসোল থেকে, ক্লাউড শেল সক্রিয় করুন ক্লিক করুন 853e55310c205094.png .

3c1dabeca90e44e5.png

যদি এটি আপনার প্রথমবার ক্লাউড শেল শুরু হয়, তাহলে এটি কী তা বর্ণনা করে আপনাকে একটি মধ্যবর্তী স্ক্রীন উপস্থাপন করা হবে। যদি আপনি একটি মধ্যবর্তী স্ক্রীনের সাথে উপস্থাপিত হন, তবে চালিয়ে যান ক্লিক করুন।

9c92662c6a846a5c.png

ক্লাউড শেলের সাথে সংযোগ করতে এবং সংযোগ করতে এটির মাত্র কয়েক মুহূর্ত লাগবে৷

9f0e51b578fecce5.png

এই ভার্চুয়াল মেশিনটি প্রয়োজনীয় সমস্ত বিকাশের সরঞ্জাম দিয়ে লোড করা হয়েছে। এটি একটি ক্রমাগত 5 GB হোম ডিরেক্টরি অফার করে এবং Google ক্লাউডে চলে, যা নেটওয়ার্ক কর্মক্ষমতা এবং প্রমাণীকরণকে ব্যাপকভাবে উন্নত করে। এই কোডল্যাবে আপনার অনেক কাজ, যদি সব না হয়, ব্রাউজার দিয়ে করা যেতে পারে।

একবার ক্লাউড শেলের সাথে সংযুক্ত হয়ে গেলে, আপনি দেখতে পাবেন যে আপনি প্রমাণীকৃত হয়েছেন এবং প্রকল্পটি আপনার প্রকল্প আইডিতে সেট করা আছে।

  1. আপনি প্রমাণীকৃত কিনা তা নিশ্চিত করতে ক্লাউড শেলে নিম্নলিখিত কমান্ডটি চালান:
gcloud auth list

কমান্ড আউটপুট

 Credentialed Accounts
ACTIVE  ACCOUNT
*       <my_account>@<my_domain.com>

To set the active account, run:
    $ gcloud config set account `ACCOUNT`
  1. gcloud কমান্ড আপনার প্রকল্প সম্পর্কে জানে তা নিশ্চিত করতে ক্লাউড শেলে নিম্নলিখিত কমান্ডটি চালান:
gcloud config list project

কমান্ড আউটপুট

[core]
project = <PROJECT_ID>

যদি এটি না হয়, আপনি এই কমান্ড দিয়ে এটি সেট করতে পারেন:

gcloud config set project <PROJECT_ID>

কমান্ড আউটপুট

Updated property [core/project].

3. আপনার উন্নয়ন পরিবেশ প্রস্তুত করা

এই কোডল্যাবে, আপনি আপনার জাভা প্রোগ্রামগুলি বিকাশ করতে ক্লাউড শেল টার্মিনাল এবং ক্লাউড শেল সম্পাদক ব্যবহার করতে যাচ্ছেন।

Vertex AI APIs সক্ষম করুন

Google ক্লাউড কনসোলে, নিশ্চিত করুন যে আপনার প্রোজেক্টের নামটি আপনার Google ক্লাউড কনসোলের শীর্ষে প্রদর্শিত হচ্ছে। যদি তা না হয়, তাহলে প্রজেক্ট সিলেক্টর খুলতে একটি প্রজেক্ট নির্বাচন করুন ক্লিক করুন এবং আপনার উদ্দেশ্যপ্রণোদিত প্রকল্প নির্বাচন করুন।

আপনি Google ক্লাউড কনসোলের Vertex AI বিভাগ থেকে বা ক্লাউড শেল টার্মিনাল থেকে Vertex AI APIs সক্ষম করতে পারেন।

Google ক্লাউড কনসোল থেকে সক্ষম করতে, প্রথমে, Google ক্লাউড কনসোল মেনুর Vertex AI বিভাগে যান:

451976f1c8652341.png

Vertex AI ড্যাশবোর্ডে সমস্ত প্রস্তাবিত API সক্রিয় করুন ক্লিক করুন৷

এটি বেশ কয়েকটি API সক্রিয় করবে, কিন্তু কোডল্যাবের জন্য সবচেয়ে গুরুত্বপূর্ণ হল aiplatform.googleapis.com

বিকল্পভাবে, আপনি নিম্নলিখিত কমান্ডের সাহায্যে ক্লাউড শেল টার্মিনাল থেকে এই API সক্রিয় করতে পারেন:

gcloud services enable aiplatform.googleapis.com

Github সংগ্রহস্থল ক্লোন করুন

ক্লাউড শেল টার্মিনালে, এই কোডল্যাবের জন্য সংগ্রহস্থল ক্লোন করুন:

git clone https://github.com/glaforge/gemini-workshop-for-java-developers.git

প্রকল্পটি চালানোর জন্য প্রস্তুত কিনা তা পরীক্ষা করতে, আপনি "হ্যালো ওয়ার্ল্ড" প্রোগ্রাম চালানোর চেষ্টা করতে পারেন।

আপনি শীর্ষ স্তরের ফোল্ডারে আছেন তা নিশ্চিত করুন:

cd gemini-workshop-for-java-developers/ 

গ্রেডল র‍্যাপার তৈরি করুন:

gradle wrapper

gradlew দিয়ে চালান:

./gradlew run

আপনি নিম্নলিখিত আউটপুট দেখতে হবে:

..
> Task :app:run
Hello World!

ক্লাউড এডিটর খুলুন এবং সেটআপ করুন

ক্লাউড শেল থেকে ক্লাউড কোড এডিটর দিয়ে কোডটি খুলুন:

42908e11b28f4383.png

ক্লাউড কোড এডিটরে, File -> Open Folder নির্বাচন করে কোডল্যাব উত্স ফোল্ডারটি খুলুন এবং কোডল্যাব উত্স ফোল্ডারে নির্দেশ করুন (যেমন /home/username/gemini-workshop-for-java-developers/ )।

পরিবেশ ভেরিয়েবল সেটআপ করুন

Terminal -> New Terminal নির্বাচন করে ক্লাউড কোড এডিটরে একটি নতুন টার্মিনাল খুলুন। কোড উদাহরণ চালানোর জন্য প্রয়োজনীয় দুটি পরিবেশ ভেরিয়েবল সেট আপ করুন:

  • PROJECT_ID — আপনার Google ক্লাউড প্রকল্প আইডি
  • অবস্থান — যে অঞ্চলে মিথুন মডেল স্থাপন করা হয়েছে

নিম্নরূপ ভেরিয়েবল রপ্তানি করুন:

export PROJECT_ID=$(gcloud config get-value project)
export LOCATION=us-central1

4. প্রথমে মিথুন মডেলকে কল করুন

এখন যেহেতু প্রকল্পটি সঠিকভাবে সেট আপ করা হয়েছে, এটি জেমিনি API কল করার সময়।

app/src/main/java/gemini/workshop ডিরেক্টরিতে QA.java দেখুন:

package gemini.workshop;

import dev.langchain4j.model.vertexai.VertexAiGeminiChatModel;
import dev.langchain4j.model.chat.ChatLanguageModel;

public class QA {
    public static void main(String[] args) {
        ChatLanguageModel model = VertexAiGeminiChatModel.builder()
            .project(System.getenv("PROJECT_ID"))
            .location(System.getenv("LOCATION"))
            .modelName("gemini-1.5-flash-002")
            .build();

        System.out.println(model.generate("Why is the sky blue?"));
    }
}

এই প্রথম উদাহরণে, আপনাকে VertexAiGeminiChatModel ক্লাস আমদানি করতে হবে, যা ChatModel ইন্টারফেস প্রয়োগ করে।

main পদ্ধতিতে, আপনি VertexAiGeminiChatModel এর জন্য নির্মাতা ব্যবহার করে চ্যাট ভাষার মডেল কনফিগার করুন এবং উল্লেখ করুন:

  • প্রকল্প
  • অবস্থান
  • মডেলের নাম ( gemini-1.5-flash-002 )।

এখন যেহেতু ভাষা মডেল প্রস্তুত, আপনি generate() পদ্ধতিতে কল করতে পারেন এবং আপনার প্রম্পট, আপনার প্রশ্ন বা নির্দেশাবলী এলএলএম-এ পাঠাতে পারেন। এখানে, আপনি আকাশকে কী নীল করে তোলে সে সম্পর্কে একটি সহজ প্রশ্ন জিজ্ঞাসা করুন।

বিভিন্ন প্রশ্ন বা কাজ চেষ্টা করার জন্য এই প্রম্পটটি পরিবর্তন করতে দ্বিধা বোধ করুন।

সোর্স কোড রুট ফোল্ডারে নমুনা চালান:

./gradlew run -q -DjavaMainClass=gemini.workshop.QA

আপনি এই এক অনুরূপ একটি আউটপুট দেখতে হবে:

The sky appears blue because of a phenomenon called Rayleigh scattering.
When sunlight enters the atmosphere, it is made up of a mixture of
different wavelengths of light, each with a different color. The
different wavelengths of light interact with the molecules and particles
in the atmosphere in different ways.

The shorter wavelengths of light, such as those corresponding to blue
and violet light, are more likely to be scattered in all directions by
these particles than the longer wavelengths of light, such as those
corresponding to red and orange light. This is because the shorter
wavelengths of light have a smaller wavelength and are able to bend
around the particles more easily.

As a result of Rayleigh scattering, the blue light from the sun is
scattered in all directions, and it is this scattered blue light that we
see when we look up at the sky. The blue light from the sun is not
actually scattered in a single direction, so the color of the sky can
vary depending on the position of the sun in the sky and the amount of
dust and water droplets in the atmosphere.

অভিনন্দন, আপনি মিথুনকে আপনার প্রথম কল করেছেন!

স্ট্রিমিং প্রতিক্রিয়া

আপনি কি লক্ষ্য করেছেন যে প্রতিক্রিয়াটি কয়েক সেকেন্ড পরে একযোগে দেওয়া হয়েছিল? স্ট্রিমিং রেসপন্স ভেরিয়েন্টের জন্য ধন্যবাদ ক্রমান্বয়ে সাড়া পাওয়াও সম্ভব। স্ট্রিমিং প্রতিক্রিয়া, মডেলটি উপলব্ধ হওয়ার সাথে সাথে টুকরো টুকরো প্রতিক্রিয়া প্রদান করে।

এই কোডল্যাবে, আমরা নন-স্ট্রিমিং রেসপন্সের সাথে লেগে থাকব কিন্তু এটা কিভাবে করা যায় তা দেখতে স্ট্রিমিং রেসপন্স দেখে নেওয়া যাক।

app/src/main/java/gemini/workshop ডিরেক্টরিতে StreamQA.java এ আপনি স্ট্রিমিং প্রতিক্রিয়া দেখতে পাবেন:

package gemini.workshop;

import dev.langchain4j.model.chat.StreamingChatLanguageModel;
import dev.langchain4j.model.vertexai.VertexAiGeminiStreamingChatModel;

import static dev.langchain4j.model.LambdaStreamingResponseHandler.onNext;

public class StreamQA {
    public static void main(String[] args) {
        StreamingChatLanguageModel model = VertexAiGeminiStreamingChatModel.builder()
            .project(System.getenv("PROJECT_ID"))
            .location(System.getenv("LOCATION"))
            .modelName("gemini-1.5-flash-002")
            .maxOutputTokens(4000)
            .build();

        model.generate("Why is the sky blue?", onNext(System.out::println));
    }
}

এইবার, আমরা স্ট্রিমিং ক্লাস ভেরিয়েন্টগুলি আমদানি করি VertexAiGeminiStreamingChatModel যা StreamingChatLanguageModel ইন্টারফেস প্রয়োগ করে৷ আপনাকে LambdaStreamingResponseHandler.onNext স্ট্যাটিক আমদানি করতে হবে যা একটি সুবিধাজনক পদ্ধতি যা জাভা ল্যাম্বডা এক্সপ্রেশন সহ একটি স্ট্রিমিং হ্যান্ডলার তৈরি করতে StreamingResponseHandler s প্রদান করে।

এবার, generate() পদ্ধতির স্বাক্ষর একটু ভিন্ন। একটি স্ট্রিং রিটার্ন করার পরিবর্তে, রিটার্ন টাইপটি অকার্যকর। প্রম্পট ছাড়াও, আপনাকে একটি স্ট্রিমিং প্রতিক্রিয়া হ্যান্ডলার পাস করতে হবে। এখানে, আমরা উপরে উল্লিখিত স্ট্যাটিক ইম্পোর্টের জন্য ধন্যবাদ, আমরা একটি ল্যাম্বডা এক্সপ্রেশন নির্ধারণ করতে পারি যা আপনি onNext() পদ্ধতিতে পাস করেন। প্রতিবার প্রতিক্রিয়ার একটি নতুন অংশ পাওয়া গেলে ল্যাম্বডা এক্সপ্রেশনটিকে বলা হয়, যখন কোনও ত্রুটি ঘটে তবেই পরবর্তীটি বলা হয়।

চালান:

./gradlew run -q -DjavaMainClass=gemini.workshop.StreamQA

আপনি পূর্ববর্তী ক্লাসের অনুরূপ উত্তর পাবেন, কিন্তু এবার, আপনি লক্ষ্য করবেন যে উত্তরটি সম্পূর্ণ উত্তর প্রদর্শনের জন্য অপেক্ষা না করে আপনার শেলে ক্রমান্বয়ে উপস্থিত হচ্ছে।

অতিরিক্ত কনফিগারেশন

কনফিগারেশনের জন্য, আমরা শুধুমাত্র প্রকল্প, অবস্থান এবং মডেলের নাম সংজ্ঞায়িত করেছি, তবে মডেলের জন্য আপনি নির্দিষ্ট করতে পারেন এমন অন্যান্য পরামিতি রয়েছে:

  • temperature(Float temp) - আপনি প্রতিক্রিয়াটি কতটা সৃজনশীল করতে চান তা নির্ধারণ করতে (0 কম সৃজনশীল এবং প্রায়শই বেশি বাস্তব, যখন 2 আরও সৃজনশীল আউটপুটগুলির জন্য)
  • topP(Float topP) - সম্ভাব্য শব্দ নির্বাচন করতে যার মোট সম্ভাব্যতা সেই ফ্লোটিং পয়েন্ট সংখ্যা পর্যন্ত যোগ করে (0 এবং 1 এর মধ্যে)
  • topK(Integer topK) — পাঠ্য সমাপ্তির জন্য সর্বাধিক সম্ভাব্য শব্দের মধ্যে এলোমেলোভাবে একটি শব্দ নির্বাচন করতে (1 থেকে 40 পর্যন্ত)
  • maxOutputTokens(Integer max) — মডেল দ্বারা প্রদত্ত উত্তরের সর্বাধিক দৈর্ঘ্য নির্দিষ্ট করতে (সাধারণত, 4টি টোকেন প্রায় 3টি শব্দ উপস্থাপন করে)
  • maxRetries(Integer retries) — যদি আপনি প্রতি কোটা প্রতি অনুরোধ অতিক্রম করেন, বা প্ল্যাটফর্মটি কিছু প্রযুক্তিগত সমস্যার সম্মুখীন হয়, আপনি মডেলটি 3 বার কলটি পুনরায় চেষ্টা করতে পারেন

এখন পর্যন্ত, আপনি মিথুনকে একটি একক প্রশ্ন করেছেন, কিন্তু আপনি একটি বহুমুখী কথোপকথনও করতে পারেন। এটিই আপনি পরবর্তী বিভাগে অন্বেষণ করবেন।

5. মিথুনের সাথে চ্যাট করুন

আগের ধাপে, আপনি একটি একক প্রশ্ন জিজ্ঞাসা করেছেন। এখন সময় এসেছে একজন ব্যবহারকারী এবং এলএলএম-এর মধ্যে সত্যিকারের কথোপকথনের। প্রতিটি প্রশ্ন ও উত্তর একটি বাস্তব আলোচনা গঠনের জন্য পূর্ববর্তী প্রশ্নগুলির উপর ভিত্তি করে তৈরি করতে পারে।

app/src/main/java/gemini/workshop ফোল্ডারে Conversation.java দেখুন:

package gemini.workshop;

import dev.langchain4j.model.chat.ChatLanguageModel;
import dev.langchain4j.model.vertexai.VertexAiGeminiChatModel;
import dev.langchain4j.memory.chat.MessageWindowChatMemory;
import dev.langchain4j.service.AiServices;

import java.util.List;

public class Conversation {
    public static void main(String[] args) {
        ChatLanguageModel model = VertexAiGeminiChatModel.builder()
            .project(System.getenv("PROJECT_ID"))
            .location(System.getenv("LOCATION"))
            .modelName("gemini-1.5-flash-002")
            .build();

        MessageWindowChatMemory chatMemory = MessageWindowChatMemory.builder()
            .maxMessages(20)
            .build();

        interface ConversationService {
            String chat(String message);
        }

        ConversationService conversation =
            AiServices.builder(ConversationService.class)
                .chatLanguageModel(model)
                .chatMemory(chatMemory)
                .build();

        List.of(
            "Hello!",
            "What is the country where the Eiffel tower is situated?",
            "How many inhabitants are there in that country?"
        ).forEach( message -> {
            System.out.println("\nUser: " + message);
            System.out.println("Gemini: " + conversation.chat(message));
        });
    }
}

এই শ্রেণীতে কিছু নতুন আকর্ষণীয় আমদানি:

  • MessageWindowChatMemory — একটি ক্লাস যা কথোপকথনের বহুমুখী দিক পরিচালনা করতে সাহায্য করবে এবং পূর্ববর্তী প্রশ্ন ও উত্তরগুলি স্থানীয় স্মৃতিতে রাখবে
  • AiServices - একটি উচ্চ-স্তরের বিমূর্ত শ্রেণী যা চ্যাট মডেল এবং চ্যাট মেমরিকে একত্রিত করবে

মূল পদ্ধতিতে, আপনি মডেল, চ্যাট মেমরি এবং এআই পরিষেবা সেট আপ করতে যাচ্ছেন। মডেলটি যথারীতি প্রকল্প, অবস্থান এবং মডেলের নাম তথ্যের সাথে কনফিগার করা হয়েছে।

চ্যাট মেমরির জন্য, আমরা একটি মেমরি তৈরি করতে MessageWindowChatMemory এর নির্মাতা ব্যবহার করি যা শেষ 20টি বার্তা আদান প্রদান করে। এটি কথোপকথনের উপর একটি স্লাইডিং উইন্ডো যার প্রসঙ্গ স্থানীয়ভাবে আমাদের জাভা ক্লাস ক্লায়েন্টে রাখা হয়।

তারপরে আপনি AI service তৈরি করুন যা চ্যাট মেমরির সাথে চ্যাট মডেলকে আবদ্ধ করে।

লক্ষ্য করুন কিভাবে AI পরিষেবা আমাদের সংজ্ঞায়িত একটি কাস্টম ConversationService ইন্টারফেস ব্যবহার করে, যেটি LangChain4j প্রয়োগ করে, এবং এটি একটি String ক্যোয়ারী নেয় এবং একটি String প্রতিক্রিয়া প্রদান করে।

এখন, মিথুনের সাথে কথোপকথনের সময় এসেছে। প্রথমে একটি সাধারণ অভিবাদন পাঠানো হয়, তারপর আইফেল টাওয়ার সম্পর্কে প্রথম প্রশ্ন করা হয় যে এটি কোন দেশে পাওয়া যাবে। লক্ষ্য করুন যে শেষ বাক্যটি প্রথম প্রশ্নের উত্তরের সাথে সম্পর্কিত, কারণ আপনি ভাবছেন যে আইফেল টাওয়ারটি যে দেশে অবস্থিত সেখানে কতজন বাসিন্দা রয়েছে, পূর্ববর্তী উত্তরে যে দেশটি দেওয়া হয়েছিল তা স্পষ্টভাবে উল্লেখ না করে। এটি দেখায় যে অতীতের প্রশ্ন এবং উত্তর প্রতিটি প্রম্পটের সাথে পাঠানো হয়।

নমুনা চালান:

./gradlew run -q -DjavaMainClass=gemini.workshop.Conversation

আপনি এইগুলির অনুরূপ তিনটি উত্তর দেখতে হবে:

User: Hello!
Gemini: Hi there! How can I assist you today?

User: What is the country where the Eiffel tower is situated?
Gemini: France

User: How many inhabitants are there in that country?
Gemini: As of 2023, the population of France is estimated to be around 67.8 million.

আপনি এক-পালা প্রশ্ন জিজ্ঞাসা করতে পারেন বা মিথুনের সাথে বহু-পালা কথোপকথন করতে পারেন তবে এখনও পর্যন্ত, ইনপুটটি কেবল পাঠ্য ছিল। ইমেজ সম্পর্কে কি? আসুন পরবর্তী ধাপে ছবিগুলি অন্বেষণ করি৷

6. মিথুনের সাথে মাল্টিমোডালিটি

মিথুন একটি মাল্টিমডাল মডেল। এটি কেবল পাঠ্যকে ইনপুট হিসাবে গ্রহণ করে না, তবে এটি ছবি বা এমনকি ভিডিওগুলিকেও ইনপুট হিসাবে গ্রহণ করে। এই বিভাগে, আপনি টেক্সট এবং ছবি মিশ্রিত করার জন্য একটি ব্যবহার কেস দেখতে পাবেন।

আপনার কি মনে হয় মিথুন এই বিড়ালটিকে চিনবে?

af00516493ec9ade.png

বরফের মধ্যে একটি বিড়ালের ছবি উইকিপিডিয়া https://upload.wikimedia.org/wikipedia/commons/b/b6/Felis_catus-cat_on_snow.jpg থেকে নেওয়া

app/src/main/java/gemini/workshop ডিরেক্টরিতে Multimodal.java দেখুন:

package gemini.workshop;

import dev.langchain4j.model.chat.ChatLanguageModel;
import dev.langchain4j.model.vertexai.VertexAiGeminiChatModel;
import dev.langchain4j.data.message.UserMessage;
import dev.langchain4j.data.message.AiMessage;
import dev.langchain4j.model.output.Response;
import dev.langchain4j.data.message.ImageContent;
import dev.langchain4j.data.message.TextContent;

public class Multimodal {

    static final String CAT_IMAGE_URL =
        "https://upload.wikimedia.org/wikipedia/" +
        "commons/b/b6/Felis_catus-cat_on_snow.jpg";


    public static void main(String[] args) {
        ChatLanguageModel model = VertexAiGeminiChatModel.builder()
            .project(System.getenv("PROJECT_ID"))
            .location(System.getenv("LOCATION"))
            .modelName("gemini-1.5-flash-002")
            .build();

        UserMessage userMessage = UserMessage.from(
            ImageContent.from(CAT_IMAGE_URL),
            TextContent.from("Describe the picture")
        );

        Response<AiMessage> response = model.generate(userMessage);

        System.out.println(response.content().text());
    }
}

আমদানিতে, লক্ষ্য করুন আমরা বিভিন্ন ধরণের বার্তা এবং বিষয়বস্তুর মধ্যে পার্থক্য করি। একটি UserMessage একটি TextContent এবং একটি ImageContent বিষয়বস্তু উভয়ই থাকতে পারে। এটি খেলার মাল্টিমোডালিটি: টেক্সট এবং ইমেজ মিশ্রিত করা। আমরা কেবল একটি সাধারণ স্ট্রিং প্রম্পট পাঠাই না, আমরা একটি আরও কাঠামোগত অবজেক্ট পাঠাই যা একটি ব্যবহারকারীর বার্তাকে প্রতিনিধিত্ব করে, একটি চিত্র বিষয়বস্তুর অংশ এবং একটি পাঠ্য বিষয়বস্তুর অংশ নিয়ে গঠিত। মডেলটি একটি Response ফেরত পাঠায় যাতে একটি AiMessage রয়েছে।

তারপর আপনি content() মাধ্যমে প্রতিক্রিয়া থেকে AiMessage পুনরুদ্ধার করবেন এবং তারপর বার্তাটির পাঠ্য text() এর জন্য ধন্যবাদ।

নমুনা চালান:

./gradlew run -q -DjavaMainClass=gemini.workshop.Multimodal

ছবির নামটি অবশ্যই আপনাকে ছবিটিতে কী রয়েছে তার একটি ইঙ্গিত দিয়েছে তবে মিথুন আউটপুট নিম্নলিখিতগুলির মতো:

A cat with brown fur is walking in the snow. The cat has a white patch of fur on its chest and white paws. The cat is looking at the camera.

ইমেজ এবং টেক্সট প্রম্পট মিশ্রিত করা আকর্ষণীয় ব্যবহারের ক্ষেত্রে খোলে। আপনি এমন অ্যাপ্লিকেশন তৈরি করতে পারেন যা করতে পারে:

  • ছবিতে পাঠ্য চিনুন।
  • একটি ছবি প্রদর্শন করা নিরাপদ কিনা তা পরীক্ষা করুন।
  • ছবির ক্যাপশন তৈরি করুন।
  • প্লেইন টেক্সট বর্ণনা সহ চিত্রগুলির একটি ডাটাবেসের মাধ্যমে অনুসন্ধান করুন।

ইমেজ থেকে তথ্য আহরণ ছাড়াও, আপনি অসংগঠিত পাঠ্য থেকে তথ্য আহরণ করতে পারেন। যে আপনি পরবর্তী বিভাগে শিখতে যাচ্ছেন কি.

7. কাঠামোবিহীন পাঠ্য থেকে কাঠামোগত তথ্য বের করুন

এমন অনেক পরিস্থিতি রয়েছে যেখানে গুরুত্বপূর্ণ তথ্য প্রতিবেদন নথিতে, ইমেলগুলিতে বা অন্যান্য দীর্ঘ আকারের পাঠ্যগুলি একটি অসংগঠিত উপায়ে দেওয়া হয়। আদর্শভাবে, আপনি কাঠামোবদ্ধ অবজেক্টের আকারে অসংগঠিত পাঠ্যের মধ্যে থাকা মূল বিবরণগুলি বের করতে সক্ষম হতে চান। দেখা যাক কিভাবে আপনি এটা করতে পারেন।

ধরা যাক আপনি একজন ব্যক্তির নাম এবং বয়স বের করতে চান, একটি জীবনী, সিভি বা সেই ব্যক্তির বিবরণ দেওয়া। আপনি LLM-কে একটি চতুরভাবে টুইক করা প্রম্পটের সাহায্যে আনস্ট্রাকচার্ড টেক্সট থেকে JSON বের করার নির্দেশ দিতে পারেন (এটিকে সাধারণত "প্রম্পট ইঞ্জিনিয়ারিং" বলা হয়)।

কিন্তু নীচের উদাহরণে, JSON আউটপুট বর্ণনা করার জন্য একটি প্রম্পট তৈরি করার পরিবর্তে, আমরা একটি নির্দিষ্ট JSON স্কিমা অনুসরণ করে, মডেলটিকে শুধুমাত্র বৈধ JSON সামগ্রী আউটপুট করতে বাধ্য করে স্ট্রাকচার্ড আউটপুট বা কখনও কখনও সীমাবদ্ধ ডিকোডিং নামে জেমিনির একটি শক্তিশালী বৈশিষ্ট্য ব্যবহার করব।

app/src/main/java/gemini/workshopExtractData.java দেখুন:

package gemini.workshop;

import dev.langchain4j.model.chat.ChatLanguageModel;
import dev.langchain4j.model.vertexai.VertexAiGeminiChatModel;
import dev.langchain4j.service.AiServices;
import dev.langchain4j.service.SystemMessage;

import static dev.langchain4j.model.vertexai.SchemaHelper.fromClass;

public class ExtractData {

    record Person(String name, int age) { }

    interface PersonExtractor {
        @SystemMessage("""
            Your role is to extract the name and age 
            of the person described in the biography.
            """)
        Person extractPerson(String biography);
    }

    public static void main(String[] args) {
        ChatLanguageModel model = VertexAiGeminiChatModel.builder()
            .project(System.getenv("PROJECT_ID"))
            .location(System.getenv("LOCATION"))
            .modelName("gemini-1.5-flash-002")
            .responseMimeType("application/json")
            .responseSchema(fromClass(Person.class))
            .build();

        PersonExtractor extractor = AiServices.create(PersonExtractor.class, model);

        String bio = """
            Anna is a 23 year old artist based in Brooklyn, New York. She was born and 
            raised in the suburbs of Chicago, where she developed a love for art at a 
            young age. She attended the School of the Art Institute of Chicago, where 
            she studied painting and drawing. After graduating, she moved to New York 
            City to pursue her art career. Anna's work is inspired by her personal 
            experiences and observations of the world around her. She often uses bright 
            colors and bold lines to create vibrant and energetic paintings. Her work 
            has been exhibited in galleries and museums in New York City and Chicago.    
            """;
        Person person = extractor.extractPerson(bio);

        System.out.println(person.name());  // Anna
        System.out.println(person.age());   // 23
    }
}

চলুন এই ফাইলের বিভিন্ন ধাপ দেখে নেওয়া যাক:

  • একটি Person রেকর্ড একটি ব্যক্তির (নাম এবং বয়স) বর্ণনা বিবরণ প্রতিনিধিত্ব করার জন্য সংজ্ঞায়িত করা হয়.
  • PersonExtractor ইন্টারফেস একটি পদ্ধতির সাথে সংজ্ঞায়িত করা হয় যা একটি অসংগঠিত পাঠ্য স্ট্রিং দেওয়া হলে, একটি Person উদাহরণ প্রদান করে।
  • extractPerson() একটি @SystemMessage টীকা দিয়ে টীকা করা হয় যা এটির সাথে একটি নির্দেশ প্রম্পট যুক্ত করে। এটি সেই প্রম্পট যা মডেলটি তার তথ্য নিষ্কাশনের জন্য নির্দেশিত করতে ব্যবহার করবে, এবং একটি JSON নথির আকারে বিশদগুলি ফেরত দেবে, যা আপনার জন্য পার্স করা হবে এবং একটি Person উদাহরণে আনমার্শাল করা হবে৷

এখন main() পদ্ধতির বিষয়বস্তু দেখি:

  • চ্যাট মডেল কনফিগার করা হয়েছে এবং তাৎক্ষণিকভাবে করা হয়েছে। আমরা মডেল বিল্ডার ক্লাসের 2টি নতুন পদ্ধতি ব্যবহার করছি: responseMimeType() এবং responseSchema() । প্রথমটি জেমিনিকে আউটপুটে বৈধ JSON তৈরি করতে বলে। দ্বিতীয় পদ্ধতিটি JSON অবজেক্টের স্কিমাকে সংজ্ঞায়িত করে যা ফেরত দেওয়া উচিত। তদ্ব্যতীত, পরবর্তীটি একটি সুবিধার পদ্ধতিতে প্রতিনিধি করে যা একটি জাভা ক্লাস বা রেকর্ডকে একটি সঠিক JSON স্কিমাতে রূপান্তর করতে সক্ষম।
  • LangChain4j এর AiServices ক্লাসের জন্য একটি PersonExtractor অবজেক্ট তৈরি করা হয়েছে।
  • তারপরে, আপনি কেবল Person person = extractor.extractPerson(...) অসংগঠিত পাঠ্য থেকে ব্যক্তির বিবরণ বের করতে এবং নাম এবং বয়স সহ একটি Person উদাহরণ ফিরে পেতে পারেন।

নমুনা চালান:

./gradlew run -q -DjavaMainClass=gemini.workshop.ExtractData

আপনি নিম্নলিখিত আউটপুট দেখতে হবে:

Anna
23

হ্যাঁ, এই আন্না এবং তারা 23!

এই AiServices পদ্ধতির সাহায্যে আপনি দৃঢ়ভাবে টাইপ করা বস্তুর সাথে কাজ করেন। আপনি LLM-এর সাথে সরাসরি যোগাযোগ করছেন না। পরিবর্তে, আপনি কংক্রিট ক্লাসের সাথে কাজ করছেন, যেমন এক্সট্রাক্ট করা ব্যক্তিগত তথ্যের প্রতিনিধিত্ব করার জন্য Person রেকর্ড, এবং আপনার কাছে একটি extractPerson() পদ্ধতি সহ একটি PersonExtractor অবজেক্ট রয়েছে যা একটি Person উদাহরণ প্রদান করে। LLM-এর ধারণাটি বিমূর্ত হয়ে গেছে, এবং একজন জাভা বিকাশকারী হিসাবে, আপনি যখন এই PersonExtractor ইন্টারফেসটি ব্যবহার করছেন তখন আপনি কেবল সাধারণ ক্লাস এবং অবজেক্টগুলিকে ম্যানিপুলেট করছেন।

8. প্রম্পট টেমপ্লেট সহ কাঠামো প্রম্পট

আপনি যখন নির্দেশাবলী বা প্রশ্নগুলির একটি সাধারণ সেট ব্যবহার করে একটি LLM এর সাথে ইন্টারঅ্যাক্ট করেন, তখন সেই প্রম্পটের একটি অংশ থাকে যা কখনই পরিবর্তিত হয় না, অন্য অংশগুলিতে ডেটা থাকে। উদাহরণস্বরূপ, আপনি যদি রেসিপি তৈরি করতে চান, আপনি একটি প্রম্পট ব্যবহার করতে পারেন যেমন "আপনি একজন প্রতিভাবান শেফ, অনুগ্রহ করে নিম্নলিখিত উপাদানগুলির সাথে একটি রেসিপি তৈরি করুন: ...", এবং তারপরে আপনি উপাদানগুলিকে এর শেষে যুক্ত করবেন যে পাঠ্য প্রম্পট টেমপ্লেটগুলি এর জন্যই - প্রোগ্রামিং ভাষায় ইন্টারপোলেটেড স্ট্রিংগুলির মতো। একটি প্রম্পট টেমপ্লেটে স্থানধারক রয়েছে যা আপনি এলএলএম-এ একটি নির্দিষ্ট কলের জন্য সঠিক ডেটা দিয়ে প্রতিস্থাপন করতে পারেন।

আরও সুনির্দিষ্টভাবে, আসুন app/src/main/java/gemini/workshop ডিরেক্টরিতে TemplatePrompt.java অধ্যয়ন করি:

package gemini.workshop;

import dev.langchain4j.model.chat.ChatLanguageModel;
import dev.langchain4j.model.vertexai.VertexAiGeminiChatModel;
import dev.langchain4j.data.message.AiMessage;
import dev.langchain4j.model.input.Prompt;
import dev.langchain4j.model.input.PromptTemplate;
import dev.langchain4j.model.output.Response;

import java.util.HashMap;
import java.util.Map;

public class TemplatePrompt {
    public static void main(String[] args) {
        ChatLanguageModel model = VertexAiGeminiChatModel.builder()
            .project(System.getenv("PROJECT_ID"))
            .location(System.getenv("LOCATION"))
            .modelName("gemini-1.5-flash-002")
            .maxOutputTokens(500)
            .temperature(1.0f)
            .topK(40)
            .topP(0.95f)
            .maxRetries(3)
            .build();

        PromptTemplate promptTemplate = PromptTemplate.from("""
            You're a friendly chef with a lot of cooking experience.
            Create a recipe for a {{dish}} with the following ingredients: \
            {{ingredients}}, and give it a name.
            """
        );

        Map<String, Object> variables = new HashMap<>();
        variables.put("dish", "dessert");
        variables.put("ingredients", "strawberries, chocolate, and whipped cream");

        Prompt prompt = promptTemplate.apply(variables);

        Response<AiMessage> response = model.generate(prompt.toUserMessage());

        System.out.println(response.content().text());
    }
}

যথারীতি, আপনি VertexAiGeminiChatModel মডেলটি কনফিগার করেন, উচ্চ তাপমাত্রা সহ উচ্চ স্তরের সৃজনশীলতা এবং উচ্চ টপপি এবং টপকে মান। তারপর আপনি আমাদের প্রম্পটের স্ট্রিং পাস করে এর from() স্ট্যাটিক পদ্ধতির সাথে একটি PromptTemplate তৈরি করুন এবং ডবল কার্লি-ব্রেসেস প্লেসহোল্ডার ভেরিয়েবল ব্যবহার করুন: এবং

আপনি apply() কল করে চূড়ান্ত প্রম্পট তৈরি করেন যা কী/মান জোড়ার একটি মানচিত্র নেয় যা স্থানধারকের নাম এবং এটির সাথে প্রতিস্থাপন করার জন্য স্ট্রিং মান উপস্থাপন করে।

সবশেষে, আপনি সেই প্রম্পট থেকে একটি ব্যবহারকারী বার্তা তৈরি করে জেমিনি মডেলের generate() পদ্ধতিকে কল করুন, prompt.toUserMessage() নির্দেশনা সহ।

নমুনা চালান:

./gradlew run -q -DjavaMainClass=gemini.workshop.TemplatePrompt

আপনার একটি উত্পন্ন আউটপুট দেখতে হবে যা এইটির মতো দেখাচ্ছে:

**Strawberry Shortcake**

Ingredients:

* 1 pint strawberries, hulled and sliced
* 1/2 cup sugar
* 1/4 cup cornstarch
* 1/4 cup water
* 1 tablespoon lemon juice
* 1/2 cup heavy cream, whipped
* 1/4 cup confectioners' sugar
* 1/4 teaspoon vanilla extract
* 6 graham cracker squares, crushed

Instructions:

1. In a medium saucepan, combine the strawberries, sugar, cornstarch, 
water, and lemon juice. Bring to a boil over medium heat, stirring 
constantly. Reduce heat and simmer for 5 minutes, or until the sauce has 
thickened.
2. Remove from heat and let cool slightly.
3. In a large bowl, combine the whipped cream, confectioners' sugar, and 
vanilla extract. Beat until soft peaks form.
4. To assemble the shortcakes, place a graham cracker square on each of 
6 dessert plates. Top with a scoop of whipped cream, then a spoonful of 
strawberry sauce. Repeat layers, ending with a graham cracker square.
5. Serve immediately.

**Tips:**

* For a more elegant presentation, you can use fresh strawberries 
instead of sliced strawberries.
* If you don't have time to make your own whipped cream, you can use 
store-bought whipped cream.

মানচিত্রে dish এবং ingredients মান পরিবর্তন করতে নির্দ্বিধায় এবং তাপমাত্রা, topK এবং tokP পরিবর্তন করুন এবং কোডটি পুনরায় চালান। এটি আপনাকে LLM-তে এই পরামিতিগুলি পরিবর্তন করার প্রভাব পর্যবেক্ষণ করতে দেবে।

প্রম্পট টেমপ্লেটগুলি এলএলএম কলগুলির জন্য পুনরায় ব্যবহারযোগ্য এবং প্যারামিটারাইজযোগ্য নির্দেশাবলী পাওয়ার একটি ভাল উপায়। আপনি ডেটা পাস করতে পারেন এবং আপনার ব্যবহারকারীদের দ্বারা প্রদত্ত বিভিন্ন মানের জন্য প্রম্পট কাস্টমাইজ করতে পারেন।

9. কয়েক শট প্রম্পটিং সহ পাঠ্য শ্রেণিবিন্যাস

এলএলএমগুলি পাঠ্যকে বিভিন্ন বিভাগে শ্রেণিবদ্ধ করতে বেশ ভাল। আপনি পাঠ্যের কিছু উদাহরণ এবং তাদের সম্পর্কিত বিভাগ প্রদান করে সেই কাজে একজন এলএলএমকে সাহায্য করতে পারেন। এই পদ্ধতিকে প্রায়ই কয়েক শট প্রম্পটিং বলা হয়।

একটি নির্দিষ্ট ধরনের টেক্সট শ্রেণীবিভাগ করার জন্য app/src/main/java/gemini/workshop ডিরেক্টরিতে TextClassification.java খুলি: অনুভূতি বিশ্লেষণ।

package gemini.workshop;

import com.google.cloud.vertexai.api.Schema;
import com.google.cloud.vertexai.api.Type;
import dev.langchain4j.data.message.UserMessage;
import dev.langchain4j.memory.chat.MessageWindowChatMemory;
import dev.langchain4j.model.chat.ChatLanguageModel;
import dev.langchain4j.model.vertexai.VertexAiGeminiChatModel;
import dev.langchain4j.data.message.AiMessage;
import dev.langchain4j.service.AiServices;
import dev.langchain4j.service.SystemMessage;

import java.util.List;

public class TextClassification {

    enum Sentiment { POSITIVE, NEUTRAL, NEGATIVE }

    public static void main(String[] args) {
        ChatLanguageModel model = VertexAiGeminiChatModel.builder()
            .project(System.getenv("PROJECT_ID"))
            .location(System.getenv("LOCATION"))
            .modelName("gemini-1.5-flash-002")
            .maxOutputTokens(10)
            .maxRetries(3)
            .responseSchema(Schema.newBuilder()
                .setType(Type.STRING)
                .addAllEnum(List.of("POSITIVE", "NEUTRAL", "NEGATIVE"))
                .build())
            .build();


        interface SentimentAnalysis {
            @SystemMessage("""
                Analyze the sentiment of the text below.
                Respond only with one word to describe the sentiment.
                """)
            Sentiment analyze(String text);
        }

        MessageWindowChatMemory memory = MessageWindowChatMemory.withMaxMessages(10);
        memory.add(UserMessage.from("This is fantastic news!"));
        memory.add(AiMessage.from(Sentiment.POSITIVE.name()));

        memory.add(UserMessage.from("Pi is roughly equal to 3.14"));
        memory.add(AiMessage.from(Sentiment.NEUTRAL.name()));

        memory.add(UserMessage.from("I really disliked the pizza. Who would use pineapples as a pizza topping?"));
        memory.add(AiMessage.from(Sentiment.NEGATIVE.name()));

        SentimentAnalysis sentimentAnalysis =
            AiServices.builder(SentimentAnalysis.class)
                .chatLanguageModel(model)
                .chatMemory(memory)
                .build();

        System.out.println(sentimentAnalysis.analyze("I love strawberries!"));
    }
}

একটি Sentiment enum একটি অনুভূতির জন্য বিভিন্ন মান তালিকাভুক্ত করে: নেতিবাচক, নিরপেক্ষ বা ইতিবাচক।

main() পদ্ধতিতে, আপনি যথারীতি জেমিনি চ্যাট মডেল তৈরি করেন, কিন্তু একটি ছোট সর্বোচ্চ আউটপুট টোকেন নম্বর সহ, কারণ আপনি শুধুমাত্র একটি সংক্ষিপ্ত প্রতিক্রিয়া চান: পাঠ্যটি POSITIVE , NEGATIVE বা NEUTRAL । এবং মডেলটিকে শুধুমাত্র সেই মানগুলি ফেরত দেওয়ার জন্য সীমাবদ্ধ করার জন্য, একচেটিয়াভাবে, আপনি ডেটা নিষ্কাশন বিভাগে আবিষ্কৃত কাঠামোগত আউটপুট সমর্থনের সুবিধা নিতে পারেন। এজন্য responseSchema() পদ্ধতি ব্যবহার করা হয়। এই সময়, আপনি স্কিমা সংজ্ঞা অনুমান করার জন্য SchemaHelper থেকে সুবিধাজনক পদ্ধতি ব্যবহার করছেন না, তবে আপনি স্কিমা সংজ্ঞাটি কেমন তা বোঝার জন্য পরিবর্তে Schema নির্মাতা ব্যবহার করবেন।

মডেলটি কনফিগার হয়ে গেলে, আপনি একটি SentimentAnalysis ইন্টারফেস তৈরি করবেন যা LangChain4j এর AiServices আপনার জন্য LLM ব্যবহার করে বাস্তবায়ন করবে। এই ইন্টারফেসে একটি পদ্ধতি রয়েছে: analyze() । এটি ইনপুট বিশ্লেষণ করতে পাঠ্য লাগে, এবং একটি Sentiment enum মান প্রদান করে। সুতরাং আপনি শুধুমাত্র একটি দৃঢ়ভাবে টাইপ করা বস্তুকে ম্যানিপুলেট করছেন যা স্বীকৃত অনুভূতির শ্রেণিকে প্রতিনিধিত্ব করে।

তারপর, মডেলটিকে তার শ্রেণিবিন্যাসের কাজ করার জন্য "কয়েকটি শট উদাহরণ" দেওয়ার জন্য, আপনি ব্যবহারকারীর বার্তা এবং AI প্রতিক্রিয়াগুলির জোড়া পাস করার জন্য একটি চ্যাট মেমরি তৈরি করেন যা পাঠ্য এবং এর সাথে যুক্ত অনুভূতির প্রতিনিধিত্ব করে।

আসুন আমাদের SentimentAnalysis ইন্টারফেস, ব্যবহার করার মডেল এবং কয়েকটি শট উদাহরণ সহ চ্যাট মেমরি পাস করে AiServices.builder() পদ্ধতির সাথে সবকিছু একসাথে আবদ্ধ করি। সবশেষে, বিশ্লেষণ করার জন্য টেক্সট সহ analyze() পদ্ধতিতে কল করুন।

নমুনা চালান:

./gradlew run -q -DjavaMainClass=gemini.workshop.TextClassification

আপনি একটি একক শব্দ দেখতে হবে:

POSITIVE

স্ট্রবেরি প্রেমের মত দেখাচ্ছে একটি ইতিবাচক অনুভূতি!

10. পুনরুদ্ধার অগমেন্টেড জেনারেশন

এলএলএমগুলিকে প্রচুর পরিমাণে পাঠ্যের উপর প্রশিক্ষণ দেওয়া হয়। যাইহোক, তাদের জ্ঞান শুধুমাত্র তথ্য কভার করে যা এটি তার প্রশিক্ষণের সময় দেখেছে। মডেল প্রশিক্ষণের কাট-অফ-তারিখের পরে প্রকাশিত নতুন তথ্য থাকলে, সেই বিবরণগুলি মডেলের কাছে উপলব্ধ হবে না। সুতরাং, মডেলটি এমন তথ্যের প্রশ্নের উত্তর দিতে সক্ষম হবে না যা এটি দেখেনি।

এই কারণেই রিট্রিভাল অগমেন্টেড জেনারেশন (RAG) এর মতো পদ্ধতিগুলি যা এই বিভাগে কভার করা হবে সেগুলি অতিরিক্ত তথ্য প্রদান করতে সাহায্য করে যা একজন LLM এর ব্যবহারকারীদের অনুরোধ পূরণ করতে, আরও বর্তমান বা ব্যক্তিগত তথ্যের তথ্যের সাথে উত্তর দিতে জানতে হবে। যা প্রশিক্ষণের সময় অ্যাক্সেসযোগ্য নয়।

কথোপকথনে ফিরে আসা যাক। এই সময়, আপনি আপনার নথি সম্পর্কে প্রশ্ন জিজ্ঞাসা করতে সক্ষম হবে. আপনি একটি চ্যাটবট তৈরি করবেন যা আপনার নথিগুলিকে ছোট ছোট টুকরো ("খণ্ড") ধারণ করে একটি ডাটাবেস থেকে প্রাসঙ্গিক তথ্য পুনরুদ্ধার করতে সক্ষম হবে এবং সেই তথ্যটি মডেল দ্বারা তার উত্তরগুলিকে ভিত্তি করার জন্য ব্যবহার করা হবে, শুধুমাত্র এতে থাকা জ্ঞানের উপর নির্ভর না করে এর প্রশিক্ষণ।

রাগে, দুটি পর্যায় রয়েছে:

  1. ইনজেশন ফেজ - ডকুমেন্টগুলি মেমরিতে লোড করা হয়, ছোট খণ্ডগুলিতে বিভক্ত হয় এবং ভেক্টর এম্বেডিংস (খণ্ডগুলির একটি উচ্চ বহুমাত্রিক ভেক্টর উপস্থাপনা) গণনা করা হয় এবং একটি ভেক্টর ডাটাবেসে সংরক্ষণ করা হয় যা শব্দার্থক অনুসন্ধানগুলি করতে সক্ষম। এই ইনজেশন পর্বটি সাধারণত একবার করা হয়, যখন ডকুমেন্ট কর্পাসে নতুন নথি যুক্ত করা দরকার।

CD07D33D20FFA1C8.png

  1. ক্যোয়ারী ফেজ - ব্যবহারকারীরা এখন নথিগুলি সম্পর্কে প্রশ্ন জিজ্ঞাসা করতে পারেন। প্রশ্নটি পাশাপাশি একটি ভেক্টরে রূপান্তরিত হবে এবং ডাটাবেসের অন্যান্য সমস্ত ভেক্টরগুলির সাথে তুলনা করা হবে। সর্বাধিক অনুরূপ ভেক্টরগুলি সাধারণত শব্দার্থগতভাবে সম্পর্কিত এবং ভেক্টর ডাটাবেস দ্বারা ফিরে আসে। তারপরে, এলএলএমকে কথোপকথনের প্রসঙ্গ দেওয়া হয়, পাঠ্যের খণ্ডগুলি যা ডাটাবেস দ্বারা ফিরে আসা ভেক্টরগুলির সাথে মিলে যায় এবং সেই খণ্ডগুলি দেখে তার উত্তরটি গ্রাউন্ড করতে বলা হয়।

A1D2E2DEB83C6D27.png

আপনার নথি প্রস্তুত করুন

এই নতুন উদাহরণের জন্য, আপনি একটি কল্পিত গাড়ি প্রস্তুতকারকের কাছ থেকে একটি কল্পিত গাড়ী মডেল সম্পর্কে প্রশ্ন জিজ্ঞাসা করবেন: সিম্বল স্টারলাইট গাড়ি! ধারণাটি হ'ল একটি কল্পিত গাড়ি সম্পর্কে একটি নথি মডেলের জ্ঞানের অংশ হওয়া উচিত নয়। সুতরাং যদি জেমিনি এই গাড়িটি সম্পর্কে সঠিকভাবে প্রশ্নের উত্তর দিতে সক্ষম হয় তবে এর অর্থ হ'ল আরএজি পদ্ধতির কাজ করে: এটি আপনার দস্তাবেজের মাধ্যমে অনুসন্ধান করতে সক্ষম।

চ্যাটবট বাস্তবায়ন করুন

আসুন কীভাবে 2-ফেজ পদ্ধতির তৈরি করবেন তা অন্বেষণ করুন: প্রথমে ডকুমেন্ট ইনজেশন সহ এবং তারপরে ক্যোয়ারী সময় ("পুনরুদ্ধার পর্বও" নামেও পরিচিত) ব্যবহারকারীরা ডকুমেন্ট সম্পর্কে প্রশ্ন জিজ্ঞাসা করেন।

এই উদাহরণে, উভয় পর্যায় একই শ্রেণিতে প্রয়োগ করা হয়। সাধারণত, আপনার কাছে একটি অ্যাপ্লিকেশন রয়েছে যা ইনজেশনটির যত্ন নেয় এবং অন্য অ্যাপ্লিকেশন যা আপনার ব্যবহারকারীদের কাছে চ্যাটবোট ইন্টারফেস সরবরাহ করে।

এছাড়াও, এই উদাহরণে আমরা একটি ইন-মেমরি ভেক্টর ডাটাবেস ব্যবহার করব। একটি বাস্তব উত্পাদন দৃশ্যে, ইনজেশন এবং ক্যোয়ারী পর্যায়গুলি দুটি স্বতন্ত্র অ্যাপ্লিকেশনগুলিতে পৃথক করা হবে এবং ভেক্টরগুলি স্ট্যান্ডেলোন ডাটাবেসে অব্যাহত রয়েছে।

ডকুমেন্ট ইনজেশন

ডকুমেন্ট ইনজেশন পর্বের প্রথম পদক্ষেপটি হ'ল আমাদের কল্পিত গাড়ি সম্পর্কে পিডিএফ ফাইলটি সনাক্ত করা এবং এটি পড়ার জন্য একটি PdfParser প্রস্তুত করা:

URL url = new URI("https://raw.githubusercontent.com/meteatamel/genai-beyond-basics/main/samples/grounding/vertexai-search/cymbal-starlight-2024.pdf").toURL();
ApachePdfBoxDocumentParser pdfParser = new ApachePdfBoxDocumentParser();
Document document = pdfParser.parse(url.openStream());

প্রথমে সাধারণ চ্যাট ভাষার মডেল তৈরি করার পরিবর্তে, আপনি এম্বেডিং মডেলের একটি উদাহরণ তৈরি করেন। এটি একটি বিশেষ মডেল যার ভূমিকা হ'ল পাঠ্য টুকরা (শব্দ, বাক্য বা এমনকি অনুচ্ছেদ) এর ভেক্টর উপস্থাপনা তৈরি করা। এটি পাঠ্য প্রতিক্রিয়াগুলি ফেরতের পরিবর্তে ভাসমান পয়েন্ট সংখ্যার ভেক্টরগুলি ফেরত দেয়।

VertexAiEmbeddingModel embeddingModel = VertexAiEmbeddingModel.builder()
    .endpoint(System.getenv("LOCATION") + "-aiplatform.googleapis.com:443")
    .project(System.getenv("PROJECT_ID"))
    .location(System.getenv("LOCATION"))
    .publisher("google")
    .modelName("text-embedding-005")
    .maxRetries(3)
    .build();

এরপরে, এতে একসাথে সহযোগিতা করার জন্য আপনার কয়েকটি ক্লাসের প্রয়োজন হবে:

  • খণ্ডগুলিতে পিডিএফ ডকুমেন্টটি লোড করুন এবং বিভক্ত করুন।
  • এই সমস্ত অংশের জন্য ভেক্টর এম্বেডিংস তৈরি করুন।
InMemoryEmbeddingStore<TextSegment> embeddingStore = 
    new InMemoryEmbeddingStore<>();

EmbeddingStoreIngestor storeIngestor = EmbeddingStoreIngestor.builder()
    .documentSplitter(DocumentSplitters.recursive(500, 100))
    .embeddingModel(embeddingModel)
    .embeddingStore(embeddingStore)
    .build();
storeIngestor.ingest(document);

ভেক্টর এম্বেডিংগুলি সঞ্চয় করার জন্য InMemoryEmbeddingStore , একটি ইন-মেমরি ভেক্টর ডাটাবেসের একটি উদাহরণ তৈরি করা হয়েছে।

দস্তাবেজটি নথিগুলিতে বিভক্ত রয়েছে DocumentSplitters ক্লাসকে ধন্যবাদ। এটি পিডিএফ ফাইলের পাঠ্যটিকে 500 টি অক্ষরের স্নিপেটে বিভক্ত করতে চলেছে, 100 টি অক্ষরের ওভারল্যাপ সহ (নিম্নলিখিত অংশ সহ, শব্দ বা বাক্যগুলি কাটা এড়াতে, বিট এবং টুকরাগুলিতে)।

স্টোর ইনজেস্টর ডকুমেন্ট স্প্লিটার, ভেক্টরগুলি গণনা করার জন্য এম্বেডিং মডেল এবং ইন-মেমরি ভেক্টর ডাটাবেসকে লিঙ্ক করে। তারপরে, ingest() পদ্ধতিটি ইনজেশন করার যত্ন নেবে।

এখন, প্রথম পর্বটি শেষ হয়েছে, দস্তাবেজটি তাদের সম্পর্কিত ভেক্টর এম্বেডিংগুলির সাথে পাঠ্য খণ্ডগুলিতে রূপান্তরিত হয়েছে এবং ভেক্টর ডাটাবেসে সংরক্ষণ করা হয়েছে।

প্রশ্ন করা

প্রশ্ন জিজ্ঞাসা করার জন্য প্রস্তুত হওয়ার সময়! কথোপকথনটি শুরু করতে একটি চ্যাট মডেল তৈরি করুন:

ChatLanguageModel model = VertexAiGeminiChatModel.builder()
        .project(System.getenv("PROJECT_ID"))
        .location(System.getenv("LOCATION"))
        .modelName("gemini-1.5-flash-002")
        .maxOutputTokens(1000)
        .build();

এম্বেডিং মডেলের সাথে ভেক্টর ডাটাবেস ( embeddingStore ভেরিয়েবলে) লিঙ্ক করতে আপনার একটি পুনরুদ্ধার শ্রেণির প্রয়োজন। এর কাজটি হ'ল ডাটাবেসে অনুরূপ ভেক্টরগুলি খুঁজে পেতে ব্যবহারকারীর ক্যোয়ারির জন্য ভেক্টর এম্বেডিং গণনা করে ভেক্টর ডাটাবেসকে জিজ্ঞাসা করা:

EmbeddingStoreContentRetriever retriever =
    new EmbeddingStoreContentRetriever(embeddingStore, embeddingModel);

একটি ইন্টারফেস তৈরি করুন যা কোনও গাড়ি বিশেষজ্ঞ সহকারীকে উপস্থাপন করে, এটি এমন একটি ইন্টারফেস যা AiServices ক্লাসটি আপনার মডেলটির সাথে ইন্টারঅ্যাক্ট করার জন্য প্রয়োগ করবে:

interface CarExpert {
    Result<String> ask(String question);
}

CarExpert ইন্টারফেসটি ল্যাংচেইন 4 জে এর Result ক্লাসে মোড়ানো একটি স্ট্রিং প্রতিক্রিয়া প্রদান করে। কেন এই মোড়ক ব্যবহার করবেন? কারণ এটি কেবল আপনাকে উত্তর দেবে না, তবে এটি আপনাকে ডাটাবেস থেকে খণ্ডগুলি পরীক্ষা করতে দেয় যা সামগ্রী পুনরুদ্ধারকারী দ্বারা ফিরে এসেছে। এইভাবে, আপনি ডকুমেন্ট (গুলি) এর উত্সগুলি প্রদর্শন করতে পারেন যা ব্যবহারকারীর চূড়ান্ত উত্তরটি গ্রাউন্ড করতে ব্যবহৃত হয়।

এই মুহুর্তে, আপনি একটি নতুন এআই পরিষেবা কনফিগার করতে পারেন:

CarExpert expert = AiServices.builder(CarExpert.class)
    .chatLanguageModel(model)
    .chatMemory(MessageWindowChatMemory.withMaxMessages(10))
    .contentRetriever(retriever)
    .build();

এই পরিষেবাটি একসাথে আবদ্ধ:

  • আপনি আগে কনফিগার করেছেন এমন চ্যাট ভাষার মডেল।
  • কথোপকথনের উপর নজর রাখতে একটি চ্যাট মেমরি
  • পুনরুদ্ধারকারী একটি ভেক্টর এম্বেডিং ক্যোয়ারিকে ডাটাবেসের ভেক্টরগুলির সাথে তুলনা করে।
.retrievalAugmentor(DefaultRetrievalAugmentor.builder()
    .contentInjector(DefaultContentInjector.builder()
        .promptTemplate(PromptTemplate.from("""
            You are an expert in car automotive, and you answer concisely.

            Here is the question: {{userMessage}}

            Answer using the following information:
            {{contents}}
the following information:
            {{contents}}
            """))
        .build())
    .contentRetriever(retriever)
    .build())

আপনি অবশেষে আপনার প্রশ্ন জিজ্ঞাসা করতে প্রস্তুত!

List.of(
    "What is the cargo capacity of Cymbal Starlight?",
    "What's the emergency roadside assistance phone number?",
    "Are there some special kits available on that car?"
).forEach(query -> {
    Result<String> response = expert.ask(query);
    System.out.printf("%n=== %s === %n%n %s %n%n", query, response.content());
    System.out.println("SOURCE: " + response.sources().getFirst().textSegment().text());
});

সম্পূর্ণ উত্স কোডটি app/src/main/java/gemini/workshop ডিরেক্টরিতে RAG.java রয়েছে।

নমুনা চালান:

./gradlew -q run -DjavaMainClass=gemini.workshop.RAG

আউটপুটে, আপনার আপনার প্রশ্নের উত্তর দেখতে হবে:

=== What is the cargo capacity of Cymbal Starlight? === 

 The Cymbal Starlight 2024 has a cargo capacity of 13.5 cubic feet.
 

SOURCE: Cargo
The Cymbal Starlight 2024 has a cargo capacity of 13.5 cubic feet. The cargo area is located in the trunk of
the vehicle.
To access the cargo area, open the trunk lid using the trunk release lever located in the driver's footwell.
When loading cargo into the trunk, be sure to distribute the weight evenly. Do not overload the trunk, as this
could affect the vehicle's handling and stability.
Luggage

=== What's the emergency roadside assistance phone number? === 

The emergency roadside assistance phone number is 1-800-555-1212.
 

SOURCE: Chapter 18: Emergencies
Roadside Assistance
If you experience a roadside emergency, such as a flat tire or a dead battery, you can call roadside
assistance for help. Roadside assistance is available 24 hours a day, 7 days a week.
To call roadside assistance, dial the following number:
1-800-555-1212
When you call roadside assistance, be prepared to provide the following information:
Your name and contact information
Your vehicle's make, model, and year
Your vehicle's location

=== Are there some special kits available on that car? === 

 Yes, the Cymbal Starlight comes with a tire repair kit.
 

SOURCE: Lane keeping assist:  This feature helps to keep you in your lane by gently steering the vehicle back
into the lane if you start to drift.
Adaptive cruise control:  This feature automatically adjusts your speed to maintain a safe following
distance from the vehicle in front of you.
Forward collision warning:  This feature warns you if you are approaching another vehicle too
quickly.
Automatic emergency braking:  This feature can automatically apply the brakes to avoid a collision.

11। ফাংশন কলিং

এমন কিছু পরিস্থিতি রয়েছে যেখানে আপনি কোনও এলএলএমকে বাহ্যিক সিস্টেমে অ্যাক্সেস পেতে চান, যেমন একটি দূরবর্তী ওয়েব এপিআই যা তথ্য পুনরুদ্ধার করে বা কোনও ক্রিয়া রয়েছে, বা কোনও ধরণের গণনা সম্পাদন করে এমন পরিষেবাগুলি রয়েছে। যেমন:

দূরবর্তী ওয়েব এপিআই:

  • গ্রাহক আদেশ ট্র্যাক এবং আপডেট করুন।
  • কোনও ইস্যু ট্র্যাকারে টিকিট সন্ধান করুন বা তৈরি করুন।
  • স্টক কোটস বা আইওটি সেন্সর পরিমাপের মতো রিয়েল টাইম ডেটা আনুন।
  • একটি ইমেইল পাঠান.

গণনা সরঞ্জাম:

  • আরও উন্নত গণিত সমস্যার জন্য একটি ক্যালকুলেটর।
  • চলমান কোডের জন্য কোড ব্যাখ্যা যখন এলএলএমএস যুক্তিযুক্ত যুক্তি প্রয়োজন।
  • প্রাকৃতিক ভাষার অনুরোধগুলিকে এসকিউএল কোয়েরিতে রূপান্তর করুন যাতে কোনও এলএলএম কোনও ডাটাবেস জিজ্ঞাসা করতে পারে।

ফাংশন কলিং (কখনও কখনও বলা হয় সরঞ্জাম, বা সরঞ্জাম ব্যবহার) মডেলটির পক্ষে তার পক্ষে এক বা একাধিক ফাংশন কল করার জন্য অনুরোধ করার ক্ষমতা, তাই এটি কোনও ব্যবহারকারীর প্রম্পটকে সতেজ ডেটা দিয়ে যথাযথভাবে উত্তর দিতে পারে।

কোনও ব্যবহারকারীর কাছ থেকে একটি নির্দিষ্ট প্রম্পট দেওয়া এবং বিদ্যমান ফাংশনগুলির জ্ঞান যা সেই প্রসঙ্গে প্রাসঙ্গিক হতে পারে, একটি এলএলএম একটি ফাংশন কল অনুরোধের সাথে উত্তর দিতে পারে। এলএলএমকে সংহত করার অ্যাপ্লিকেশনটি তার পক্ষ থেকে ফাংশনটিকে কল করতে পারে এবং তারপরে একটি প্রতিক্রিয়া সহ এলএলএম -তে জবাব দেয় এবং এলএলএম তারপরে একটি পাঠ্য উত্তর দিয়ে জবাব দিয়ে ফিরে ব্যাখ্যা করে।

ফাংশন কলিংয়ের চারটি পদক্ষেপ

আসুন ফাংশন কলিংয়ের একটি উদাহরণ দেখুন: আবহাওয়ার পূর্বাভাস সম্পর্কে তথ্য পাওয়া।

আপনি যদি প্যারিসের আবহাওয়া সম্পর্কে জেমিনি বা অন্য কোনও এলএলএম জিজ্ঞাসা করেন তবে তারা এই বলে জবাব দিতেন যে এটির বর্তমান আবহাওয়ার পূর্বাভাস সম্পর্কে কোনও তথ্য নেই। আপনি যদি চান যে এলএলএম আবহাওয়ার ডেটাতে রিয়েল টাইম অ্যাক্সেস করতে পারে তবে আপনাকে এমন কিছু ফাংশন সংজ্ঞায়িত করতে হবে যা এটি ব্যবহারের জন্য অনুরোধ করতে পারে।

নিম্নলিখিত চিত্রটি একবার দেখুন:

31e0c2aba5e6f21c.png

1⃣ প্রথম, একজন ব্যবহারকারী প্যারিসের আবহাওয়া সম্পর্কে জিজ্ঞাসা করেন। চ্যাটবট অ্যাপ্লিকেশন (ল্যাংচেইন 4 জে ব্যবহার করে) জানে যে এলএলএমকে ক্যোয়ারীটি পূরণ করতে সহায়তা করার জন্য এমন এক বা একাধিক ফাংশন রয়েছে যা এর নিষ্পত্তি রয়েছে। চ্যাটবট উভয়ই প্রাথমিক প্রম্পট পাঠায়, পাশাপাশি কল করা যেতে পারে এমন ফাংশনগুলির তালিকাও প্রেরণ করে। এখানে, getWeather() নামে একটি ফাংশন যা অবস্থানের জন্য একটি স্ট্রিং প্যারামিটার নেয়।

8863be53a73c4a70.png

যেহেতু এলএলএম আবহাওয়ার পূর্বাভাস সম্পর্কে জানে না, পাঠ্যের মাধ্যমে জবাব দেওয়ার পরিবর্তে এটি একটি ফাংশন এক্সিকিউশন অনুরোধটি ফেরত পাঠায়। চ্যাটবটকে অবশ্যই "Paris" দিয়ে অবস্থান প্যারামিটার হিসাবে getWeather() ফাংশনটিতে কল করতে হবে।

D1367CC69C07B14D.PNG

2⃣ চ্যাটবটটি এলএলএমের পক্ষে এই কাজ করে, ফাংশন প্রতিক্রিয়াটি পুনরুদ্ধার করে। এখানে, আমরা কল্পনা করি যে প্রতিক্রিয়াটি {"forecast": "sunny"}

73A5F2ED19F47D8.PNG

3⃣ চ্যাটবট অ্যাপ্লিকেশনটি JSON প্রতিক্রিয়াটিকে এলএলএম -তে ফেরত পাঠায়।

20832CB1EE6FBFEB.PNG

4⃣ এলএলএম জেএসওএন এর প্রতিক্রিয়াটি দেখে, সেই তথ্যের ব্যাখ্যা করে এবং শেষ পর্যন্ত প্যারিসে আবহাওয়া রৌদ্রোজ্জ্বল পাঠ্যটি দিয়ে জবাব দেয়।

কোড হিসাবে প্রতিটি পদক্ষেপ

প্রথমত, আপনি যথারীতি মিথুন মডেলটি কনফিগার করবেন:

ChatLanguageModel model = VertexAiGeminiChatModel.builder()
    .project(System.getenv("PROJECT_ID"))
    .location(System.getenv("LOCATION"))
    .modelName("gemini-1.5-flash-002")
    .maxOutputTokens(100)
    .build();

আপনি একটি সরঞ্জাম স্পেসিফিকেশন সংজ্ঞায়িত করেছেন যা ফাংশনটিকে বর্ণনা করে যা বলা যেতে পারে:

ToolSpecification weatherToolSpec = ToolSpecification.builder()
    .name("getWeather")
    .description("Get the weather forecast for a given location or city")
    .parameters(JsonObjectSchema.builder()
        .addStringProperty(
            "location", 
            "the location or city to get the weather forecast for")
        .build())
    .build();

ফাংশনের নামটি সংজ্ঞায়িত করা হয়েছে, পাশাপাশি প্যারামিটারের নাম এবং প্রকার, তবে লক্ষ্য করুন যে ফাংশন এবং পরামিতি উভয়ই বিবরণ দেওয়া হয়েছে। বিবরণগুলি অত্যন্ত গুরুত্বপূর্ণ এবং এলএলএমকে সত্যিই কোনও ফাংশন কী করতে পারে তা বুঝতে সহায়তা করে এবং এইভাবে কথোপকথনের প্রসঙ্গে এই ফাংশনটি কল করা দরকার কিনা তা বিচার করুন।

আসুন প্যারিসের আবহাওয়া সম্পর্কে প্রাথমিক প্রশ্নটি প্রেরণ করে পদক্ষেপ #1 শুরু করুন:

List<ChatMessage> allMessages = new ArrayList<>();

// 1) Ask the question about the weather
UserMessage weatherQuestion = UserMessage.from("What is the weather in Paris?");
allMessages.add(weatherQuestion);

পদক্ষেপ #2 এ, আমরা মডেলটি ব্যবহার করতে চাই সেই সরঞ্জামটি পাস করি এবং মডেলটি খুব কার্যকর করার অনুরোধের সাথে জবাব দেয়:

// 2) The model replies with a function call request
Response<AiMessage> messageResponse = model.generate(allMessages, weatherToolSpec);
ToolExecutionRequest toolExecutionRequest = messageResponse.content().toolExecutionRequests().getFirst();
System.out.println("Tool execution request: " + toolExecutionRequest);
allMessages.add(messageResponse.content());

ধাপ #3। এই মুহুর্তে, আমরা জানি যে এলএলএম আমাদের কল করতে চাইবে। কোডটিতে, আমরা কোনও বাহ্যিক এপিআই -তে সত্যিকারের কল করছি না, আমরা কেবল একটি অনুমানমূলক আবহাওয়ার পূর্বাভাস সরাসরি ফিরিয়ে দিয়েছি:

// 3) We send back the result of the function call
ToolExecutionResultMessage toolExecResMsg = ToolExecutionResultMessage.from(toolExecutionRequest,
    "{\"location\":\"Paris\",\"forecast\":\"sunny\", \"temperature\": 20}");
allMessages.add(toolExecResMsg);

এবং পদক্ষেপ #4 এ, এলএলএম ফাংশন এক্সিকিউশন ফলাফল সম্পর্কে শিখেছে এবং তারপরে একটি পাঠ্য প্রতিক্রিয়া সংশ্লেষ করতে পারে:

// 4) The model answers with a sentence describing the weather
Response<AiMessage> weatherResponse = model.generate(allMessages);
System.out.println("Answer: " + weatherResponse.content().text());

আউটপুট হল:

Tool execution request: ToolExecutionRequest { id = null, name = "getWeatherForecast", arguments = "{"location":"Paris"}" }
Answer:  The weather in Paris is sunny with a temperature of 20 degrees Celsius.

আপনি সরঞ্জাম এক্সিকিউশন অনুরোধের উপরের আউটপুট, পাশাপাশি উত্তর দেখতে পারেন।

সম্পূর্ণ উত্স কোডটি app/src/main/java/gemini/workshop ডিরেক্টরিতে FunctionCalling.java রয়েছে:

নমুনা চালান:

./gradlew run -q -DjavaMainClass=gemini.workshop.FunctionCalling

আপনি নিম্নলিখিত অনুরূপ একটি আউটপুট দেখতে হবে:

Tool execution request: ToolExecutionRequest { id = null, name = "getWeatherForecast", arguments = "{"location":"Paris"}" }
Answer:  The weather in Paris is sunny with a temperature of 20 degrees Celsius.

12। ল্যাংচেইন 4 জে ফাংশন কলিং পরিচালনা করে

পূর্ববর্তী পদক্ষেপে, আপনি দেখেছেন যে কীভাবে সাধারণ পাঠ্য প্রশ্ন/উত্তর এবং ফাংশন অনুরোধ/প্রতিক্রিয়া ইন্টারঅ্যাকশনগুলি ইন্টারলিভড হয় এবং এর মধ্যে আপনি কোনও সত্যিকারের ফাংশন না বলে সরাসরি অনুরোধ করা ফাংশন প্রতিক্রিয়া সরবরাহ করেছিলেন।

যাইহোক, ল্যাংচেইন 4 জে একটি উচ্চ-স্তরের বিমূর্ততাও সরবরাহ করে যা ফাংশন কলগুলি আপনার জন্য স্বচ্ছভাবে পরিচালনা করতে পারে, যখন কথোপকথনটি যথারীতি পরিচালনা করে।

একক ফাংশন কল

আসুন FunctionCallingAssistant.java , টুকরো টুকরো টুকরো টুকরো টুকরো টুকরো টুকরো টুকরো টুকরো টুকরো টুকরো টুকরো টুকরো টুকরো টুকরো টুকরো টুকরো টুকরো টুকরো টুকরো টুকরো টুকরো টুকরো টুকরো টুকরো টুকরো টুকরো টুকরো টুকরো টুকরো টুকরো টুকরো টুকরো টুকরো টুকরো টুকরো টুকরো টুকরো টুকরো টুকরো টুকরো টুকরো টুকরো টুকরো টুকরো টুকরো টুকরো টুকরো টুকরো টুকরো টুকরো টুকরো টুকরো টুকরো টুকরো টুকরো টুকরো টুকরো টুকরো টুকরো টুকরো টুকরো টুকরো টুকরো টুকরো টুকরো টুকরো টুকরো টুকরো টুকরো টুকরো টুকরো টুকরো টুকরো টুকরো টুকরো

প্রথমত, আপনি এমন একটি রেকর্ড তৈরি করেছেন যা ফাংশনের প্রতিক্রিয়া ডেটা কাঠামোর প্রতিনিধিত্ব করবে:

record WeatherForecast(String location, String forecast, int temperature) {}

প্রতিক্রিয়াটিতে অবস্থান, পূর্বাভাস এবং তাপমাত্রা সম্পর্কে তথ্য রয়েছে।

তারপরে আপনি এমন একটি ক্লাস তৈরি করেন যা আপনি মডেলটিতে উপলব্ধ করতে চান এমন প্রকৃত ফাংশন রয়েছে:

static class WeatherForecastService {
    @Tool("Get the weather forecast for a location")
    WeatherForecast getForecast(@P("Location to get the forecast for") String location) {
        if (location.equals("Paris")) {
            return new WeatherForecast("Paris", "Sunny", 20);
        } else if (location.equals("London")) {
            return new WeatherForecast("London", "Rainy", 15);
        } else {
            return new WeatherForecast("Unknown", "Unknown", 0);
        }
    }
}

নোট করুন যে এই শ্রেণিতে একটি একক ফাংশন রয়েছে, তবে এটি @Tool টীকা দিয়ে টীকাযুক্ত যা মডেল কল করার জন্য অনুরোধ করতে পারে তার ফাংশনের বর্ণনার সাথে মিলে যায়।

ফাংশনের পরামিতিগুলি (এখানে একটি একক) এছাড়াও টিকা দেওয়া হয়, তবে এই সংক্ষিপ্ত @P টীকা দিয়ে, যা প্যারামিটারের বিবরণও দেয়। আপনি যতটা ফাংশন চান ততগুলি যুক্ত করতে পারেন, আরও জটিল পরিস্থিতিতে তাদের মডেলটিতে উপলব্ধ করতে।

এই শ্রেণিতে, আপনি কিছু ক্যানড প্রতিক্রিয়া ফিরিয়ে দেন, তবে আপনি যদি সত্যিকারের বাহ্যিক আবহাওয়ার পূর্বাভাস পরিষেবাটিতে কল করতে চান তবে এটি সেই পদ্ধতির শরীরে রয়েছে যে আপনি সেই পরিষেবাটিতে কল করবেন।

যেমনটি আমরা দেখেছি যখন আপনি পূর্ববর্তী পদ্ধতির মধ্যে কোনও ToolSpecification তৈরি করেছেন, কোনও ফাংশন কী করে তা নথিভুক্ত করা গুরুত্বপূর্ণ এবং পরামিতিগুলি কী সম্পর্কিত তা বর্ণনা করে। এটি মডেলটিকে কীভাবে এবং কখন এই ফাংশনটি ব্যবহার করা যেতে পারে তা বুঝতে সহায়তা করে।

এরপরে, ল্যাংচেইন 4 জে আপনাকে এমন একটি ইন্টারফেস সরবরাহ করতে দেয় যা আপনি চুক্তির সাথে সম্পর্কিত যে আপনি মডেলের সাথে ইন্টারঅ্যাক্ট করতে ব্যবহার করতে চান তার সাথে সম্পর্কিত। এখানে, এটি একটি সাধারণ ইন্টারফেস যা ব্যবহারকারী বার্তার প্রতিনিধিত্ব করে এমন একটি স্ট্রিং নেয় এবং মডেলের প্রতিক্রিয়ার সাথে সম্পর্কিত একটি স্ট্রিং দেয়:

interface WeatherAssistant {
    String chat(String userMessage);
}

ল্যাংচেইন 4 জে এর UserMessage (ব্যবহারকারী বার্তার জন্য) বা AiMessage (একটি মডেলের প্রতিক্রিয়ার জন্য), বা এমনকি একটি TokenStream জড়িত আরও জটিল স্বাক্ষরগুলি ব্যবহার করাও সম্ভব, যদি আপনি আরও উন্নত পরিস্থিতিগুলি পরিচালনা করতে চান, কারণ এই আরও জটিল অবজেক্টগুলিতে অতিরিক্ত অতিরিক্ত রয়েছে টোকেনের সংখ্যা ইত্যাদির মতো তথ্য ইত্যাদি। তবে সরলতার জন্য, আমরা কেবল ইনপুটটিতে স্ট্রিং নেব এবং আউটপুট স্ট্রিং।

আসুন main() পদ্ধতিটি শেষ করি যা সমস্ত টুকরো একসাথে আবদ্ধ করে:

public static void main(String[] args) {
    ChatLanguageModel model = VertexAiGeminiChatModel.builder()
        .project(System.getenv("PROJECT_ID"))
        .location(System.getenv("LOCATION"))
        .modelName("gemini-1.5-pro-002")
        .build();

    WeatherForecastService weatherForecastService = new WeatherForecastService();

    WeatherAssistant assistant = AiServices.builder(WeatherAssistant.class)
        .chatLanguageModel(model)
        .chatMemory(MessageWindowChatMemory.withMaxMessages(10))
        .tools(weatherForecastService)
        .build();

    System.out.println(assistant.chat("What is the weather in Paris?"));
}

যথারীতি, আপনি মিথুন চ্যাট মডেলটি কনফিগার করেন। তারপরে আপনি আপনার আবহাওয়ার পূর্বাভাস পরিষেবাটি ইনস্ট্যান্ট করুন যাতে "ফাংশন" থাকে যা মডেলটি আমাদের কল করার জন্য অনুরোধ করবে।

এখন, আপনি চ্যাট মডেল, চ্যাট মেমরি এবং সরঞ্জাম (যেমন। এর ফাংশন সহ আবহাওয়ার পূর্বাভাস পরিষেবা) বাঁধতে আবার AiServices ক্লাসটি ব্যবহার করেন। AiServices এমন একটি বস্তু ফেরত দেয় যা আপনার সংজ্ঞায়িত আপনার WeatherAssistant ইন্টারফেসকে প্রয়োগ করে। একমাত্র জিনিসটি হ'ল সেই সহকারীটির chat() পদ্ধতি কল করা। এটি অনুরোধ করার সময়, আপনি কেবল পাঠ্য প্রতিক্রিয়াগুলি দেখতে পাবেন, তবে ফাংশন কল অনুরোধগুলি এবং ফাংশন কল প্রতিক্রিয়াগুলি বিকাশকারীদের কাছ থেকে দৃশ্যমান হবে না এবং সেই অনুরোধগুলি স্বয়ংক্রিয়ভাবে এবং স্বচ্ছভাবে পরিচালনা করা হবে। যদি জেমিনি মনে করেন যে কোনও ফাংশন কল করা উচিত, তবে এটি ফাংশন কল অনুরোধের সাথে জবাব দেবে এবং ল্যাংচেইন 4 জে আপনার পক্ষে স্থানীয় ফাংশনটিকে কল করার যত্ন নেবে।

নমুনা চালান:

./gradlew run -q -DjavaMainClass=gemini.workshop.FunctionCallingAssistant

আপনি নিম্নলিখিত অনুরূপ একটি আউটপুট দেখতে হবে:

OK. The weather in Paris is sunny with a temperature of 20 degrees.

এটি একটি একক ফাংশনের উদাহরণ ছিল।

একাধিক ফাংশন কল

আপনার একাধিক ফাংশনও থাকতে পারে এবং ল্যাংচেইন 4 জে আপনার পক্ষে একাধিক ফাংশন কলগুলি পরিচালনা করতে দিন। একাধিক ফাংশন উদাহরণের জন্য MultiFunctionCallingAssistant.java একবার দেখুন।

মুদ্রা রূপান্তর করার জন্য এটির একটি ফাংশন রয়েছে:

@Tool("Convert amounts between two currencies")
double convertCurrency(
    @P("Currency to convert from") String fromCurrency,
    @P("Currency to convert to") String toCurrency,
    @P("Amount to convert") double amount) {

    double result = amount;

    if (fromCurrency.equals("USD") && toCurrency.equals("EUR")) {
        result = amount * 0.93;
    } else if (fromCurrency.equals("USD") && toCurrency.equals("GBP")) {
        result = amount * 0.79;
    }

    System.out.println(
        "convertCurrency(fromCurrency = " + fromCurrency +
            ", toCurrency = " + toCurrency +
            ", amount = " + amount + ") == " + result);

    return result;
}

স্টকের মান পেতে অন্য একটি ফাংশন:

@Tool("Get the current value of a stock in US dollars")
double getStockPrice(@P("Stock symbol") String symbol) {
    double result = 170.0 + 10 * new Random().nextDouble();

    System.out.println("getStockPrice(symbol = " + symbol + ") == " + result);

    return result;
}

প্রদত্ত পরিমাণে শতাংশ প্রয়োগ করতে অন্য একটি ফাংশন:

@Tool("Apply a percentage to a given amount")
double applyPercentage(@P("Initial amount") double amount, @P("Percentage between 0-100 to apply") double percentage) {
    double result = amount * (percentage / 100);

    System.out.println("applyPercentage(amount = " + amount + ", percentage = " + percentage + ") == " + result);

    return result;
}

তারপরে আপনি এই সমস্ত ফাংশন এবং একটি মাল্টিটুলস ক্লাস একত্রিত করতে পারেন এবং "এএপিএল স্টক মূল্যের 10% কী মার্কিন ডলারে থেকে ইউরোতে রূপান্তরিত?" এর মতো প্রশ্ন জিজ্ঞাসা করতে পারেন? "

public static void main(String[] args) {
    ChatLanguageModel model = VertexAiGeminiChatModel.builder()
        .project(System.getenv("PROJECT_ID"))
        .location(System.getenv("LOCATION"))
        .modelName("gemini-1.5-flash-002")
        .maxOutputTokens(100)
        .build();

    MultiTools multiTools = new MultiTools();

    MultiToolsAssistant assistant = AiServices.builder(MultiToolsAssistant.class)
        .chatLanguageModel(model)
        .chatMemory(withMaxMessages(10))
        .tools(multiTools)
        .build();

    System.out.println(assistant.chat(
        "What is 10% of the AAPL stock price converted from USD to EUR?"));
}

এটি নিম্নরূপ চালান:

./gradlew run -q -DjavaMainClass=gemini.workshop.MultiFunctionCallingAssistant

এবং আপনার একাধিক ফাংশন বলা উচিত:

getStockPrice(symbol = AAPL) == 172.8022224055534
convertCurrency(fromCurrency = USD, toCurrency = EUR, amount = 172.8022224055534) == 160.70606683716468
applyPercentage(amount = 160.70606683716468, percentage = 10.0) == 16.07060668371647
10% of the AAPL stock price converted from USD to EUR is 16.07060668371647 EUR.

এজেন্টদের দিকে

জেমিনির মতো বৃহত ভাষার মডেলগুলির জন্য ফাংশন কলিং একটি দুর্দান্ত এক্সটেনশন প্রক্রিয়া। এটি আমাদের প্রায়শই "এজেন্ট" বা "এআই সহায়ক" নামে পরিচিত আরও জটিল সিস্টেমগুলি তৈরি করতে সক্ষম করে। এই এজেন্টগুলি বাহ্যিক এপিআইগুলির মাধ্যমে এবং বাহ্যিক পরিবেশের পার্শ্ব প্রতিক্রিয়া হতে পারে এমন পরিষেবাগুলির সাথে বাহ্যিক বিশ্বের সাথে যোগাযোগ করতে পারে (যেমন ইমেল প্রেরণ, টিকিট তৈরি করা ইত্যাদি)

এই জাতীয় শক্তিশালী এজেন্ট তৈরি করার সময়, আপনার দায়িত্বের সাথে এটি করা উচিত। স্বয়ংক্রিয় ক্রিয়া করার আগে আপনার একটি মানব-ইন-লুপ বিবেচনা করা উচিত। বাহ্যিক বিশ্বের সাথে যোগাযোগ করে এমন এলএলএম-চালিত এজেন্টদের ডিজাইন করার সময় সুরক্ষাটি মনে রাখা গুরুত্বপূর্ণ।

13। ওলামা এবং টেস্টকন্টাইনারদের সাথে জেমমা চালানো

এখনও অবধি, আমরা জেমিনি ব্যবহার করছি তবে এর ছোট্ট বোনের মডেল জেমমাও রয়েছে।

জেমমা হ'ল লাইটওয়েটের একটি পরিবার, জেমিনি মডেলগুলি তৈরি করতে ব্যবহৃত একই গবেষণা এবং প্রযুক্তি থেকে নির্মিত অত্যাধুনিক ওপেন মডেলগুলির একটি পরিবার। জেমমা বিভিন্ন আকারের সাথে দুটি বৈচিত্র্য জেমমা 1 এবং জেমমা 2 এ উপলব্ধ। জেমমা 1 দুটি আকারে উপলব্ধ: 2 বি এবং 7 বি। জেমমা 2 দুটি আকারে উপলব্ধ: 9 বি এবং 27 বি। তাদের ওজন অবাধে উপলভ্য এবং তাদের ছোট আকারের অর্থ আপনি এটি নিজের থেকে চালাতে পারেন এমনকি এমনকি আপনার ল্যাপটপেও বা ক্লাউড শেলেও।

আপনি কিভাবে জেমমা চালাবেন?

জেমমা চালানোর অনেকগুলি উপায় রয়েছে: মেঘে, একটি বোতামের ক্লিকের সাথে ভার্টেক্স এআইয়ের মাধ্যমে বা কিছু জিপিইউ সহ GKE, তবে আপনি স্থানীয়ভাবে এটি চালাতে পারেন।

স্থানীয়ভাবে জেমমা চালানোর জন্য একটি ভাল বিকল্প হ'ল ওলামার সাথে, এমন একটি সরঞ্জাম যা আপনাকে লামা 2, মিস্ট্রাল এবং আপনার স্থানীয় মেশিনে আরও অনেকের মতো ছোট মডেল চালাতে দেয়। এটি ডকারের মতো তবে এলএলএমগুলির জন্য।

আপনার অপারেটিং সিস্টেমের জন্য নির্দেশ অনুসরণ করে ওলামা ইনস্টল করুন।

আপনি যদি লিনাক্স পরিবেশ ব্যবহার করছেন তবে আপনাকে এটি ইনস্টল করার পরে প্রথমে ওলামাকে সক্ষম করতে হবে।

ollama serve > /dev/null 2>&1 & 

স্থানীয়ভাবে ইনস্টল হয়ে গেলে, আপনি একটি মডেল টানতে কমান্ডগুলি চালাতে পারেন:

ollama pull gemma:2b

মডেলটি টানার জন্য অপেক্ষা করুন। এতে কিছু সময় লাগতে পারে।

মডেল চালান:

ollama run gemma:2b

এখন, আপনি মডেলের সাথে ইন্টারঅ্যাক্ট করতে পারেন:

>>> Hello!
Hello! It's nice to hear from you. What can I do for you today?

প্রম্পট থেকে প্রস্থান করতে Ctrl+d টিপুন

টেস্টকন্টেনারগুলিতে ওল্লায় জেমমা চালাচ্ছেন

স্থানীয়ভাবে ওল্লামা ইনস্টল ও চালানোর পরিবর্তে, আপনি টেস্টকন্টেনারদের দ্বারা পরিচালিত একটি ধারক মধ্যে ওলামা ব্যবহার করতে পারেন।

টেস্টকন্টাইনাররা কেবল পরীক্ষার জন্যই কার্যকর নয়, তবে আপনি এটি পাত্রে কার্যকর করার জন্যও ব্যবহার করতে পারেন। এমনকি একটি নির্দিষ্ট OllamaContainer রয়েছে যা আপনি সুবিধা নিতে পারেন!

এখানে পুরো ছবি:

2382c05a48708dfd.png

বাস্তবায়ন

আসুন GemmaWithOllamaContainer.java , টুকরো টুকরো টুকরো টুকরো টুকরো টুকরো টুকরো টুকরো টুকরো টুকরো টুকরো টুকরো টুকরো টুকরো টুকরো টুকরো টুকরো টুকরো টুকরো টুকরো টুকরো টুকরো টুকরো টুকরো টুকরো টুকরো টুকরো টুকরো টুকরো টুকরো টুকরো টুকরো টুকরো টুকরো টুকরো টুকরো টুকরো টুকরো টুকরো টুকরো টুকরো টুকরো টুকরো টুকরো টুকরো টুকরো টুকরো টুকরো টুকরো টুকরো টুকরো টুকরো টুকরো টুকরো টুকরো টুকরো টুকরো টুকরো টুকরো টুকরো টুকরো টুকরো টুকরো টুকরো টুকরো টুকরো টুকরো টুকরো টুকরো টুকরো টুকরো টুকরো টুকরো টুকরো টুকরো টুকরো টুকরো টুকরো টুকরো টুকরো টুকরো টুকরো টুকরো

প্রথমত, আপনাকে জেমমা মডেলটিতে টানতে একটি উত্পন্ন ওলামা ধারক তৈরি করতে হবে। এই চিত্রটি ইতিমধ্যে আগের রান থেকে বিদ্যমান বা এটি তৈরি করা হবে। যদি চিত্রটি ইতিমধ্যে বিদ্যমান থাকে তবে আপনি কেবল টেস্টকন্টাইনারদের বলতে যাচ্ছেন যে আপনি আপনার রত্ন-চালিত বৈকল্পিকের সাথে ডিফল্ট ওলামা চিত্রটির বিকল্প করতে চান:

private static final String TC_OLLAMA_GEMMA_2_B = "tc-ollama-gemma-2b";

// Creating an Ollama container with Gemma 2B if it doesn't exist.
private static OllamaContainer createGemmaOllamaContainer() throws IOException, InterruptedException {

    // Check if the custom Gemma Ollama image exists already
    List<Image> listImagesCmd = DockerClientFactory.lazyClient()
        .listImagesCmd()
        .withImageNameFilter(TC_OLLAMA_GEMMA_2_B)
        .exec();

    if (listImagesCmd.isEmpty()) {
        System.out.println("Creating a new Ollama container with Gemma 2B image...");
        OllamaContainer ollama = new OllamaContainer("ollama/ollama:0.1.26");
        ollama.start();
        ollama.execInContainer("ollama", "pull", "gemma:2b");
        ollama.commitToImage(TC_OLLAMA_GEMMA_2_B);
        return ollama;
    } else {
        System.out.println("Using existing Ollama container with Gemma 2B image...");
        // Substitute the default Ollama image with our Gemma variant
        return new OllamaContainer(
            DockerImageName.parse(TC_OLLAMA_GEMMA_2_B)
                .asCompatibleSubstituteFor("ollama/ollama"));
    }
}

এরপরে, আপনি একটি ওলামা পরীক্ষার ধারক তৈরি এবং শুরু করুন এবং তারপরে আপনি যে মডেলটি ব্যবহার করতে চান তার সাথে ধারকটির ঠিকানা এবং পোর্টের দিকে নির্দেশ করে একটি ওলামা চ্যাট মডেল তৈরি করুন। শেষ অবধি, আপনি কেবল model.generate(yourPrompt) :

public static void main(String[] args) throws IOException, InterruptedException {
    OllamaContainer ollama = createGemmaOllamaContainer();
    ollama.start();

    ChatLanguageModel model = OllamaChatModel.builder()
        .baseUrl(String.format("http://%s:%d", ollama.getHost(), ollama.getFirstMappedPort()))
        .modelName("gemma:2b")
        .build();

    String response = model.generate("Why is the sky blue?");

    System.out.println(response);
}

এটি নিম্নরূপ চালান:

./gradlew run -q -DjavaMainClass=gemini.workshop.GemmaWithOllamaContainer

প্রথম রানটি ধারকটি তৈরি করতে এবং চালাতে কিছুটা সময় নেবে তবে একবার হয়ে গেলে আপনার জেমমা প্রতিক্রিয়া দেখা উচিত:

INFO: Container ollama/ollama:0.1.26 started in PT2.827064047S
The sky appears blue due to Rayleigh scattering. Rayleigh scattering is a phenomenon that occurs when sunlight interacts with molecules in the Earth's atmosphere.

* **Scattering particles:** The main scattering particles in the atmosphere are molecules of nitrogen (N2) and oxygen (O2).
* **Wavelength of light:** Blue light has a shorter wavelength than other colors of light, such as red and yellow.
* **Scattering process:** When blue light interacts with these molecules, it is scattered in all directions.
* **Human eyes:** Our eyes are more sensitive to blue light than other colors, so we perceive the sky as blue.

This scattering process results in a blue appearance for the sky, even though the sun is actually emitting light of all colors.

In addition to Rayleigh scattering, other atmospheric factors can also influence the color of the sky, such as dust particles, aerosols, and clouds.

আপনার মেঘের শেলটিতে জেমমা চলছে!

14। অভিনন্দন

অভিনন্দন, আপনি ল্যাংচেইন 4 জে এবং জেমিনি এপিআই ব্যবহার করে জাভাতে আপনার প্রথম জেনারেটর এআই চ্যাট অ্যাপ্লিকেশনটি সফলভাবে তৈরি করেছেন! আপনি যেভাবে মাল্টিমোডাল বৃহত ভাষার মডেলগুলি প্রশ্ন/উত্তর দেওয়ার মতো বিভিন্ন কাজ পরিচালনা করতে সক্ষম, এমনকি আপনার নিজস্ব ডকুমেন্টেশন, ডেটা নিষ্কাশন, বাহ্যিক এপিআইয়ের সাথে ইন্টারঅ্যাক্ট করা এবং আরও অনেক কিছুতে সক্ষম।

এরপর কি?

শক্তিশালী এলএলএম ইন্টিগ্রেশন সহ আপনার অ্যাপ্লিকেশনগুলিকে বাড়ানোর আপনার পালা!

আরও পড়া

রেফারেন্স ডক্স