১. সংক্ষিপ্ত বিবরণ
ভার্চুয়ালি বা সশরীরে এমন একটি খেলনার দোকানে প্রবেশের কথা ভাবুন, যেখানে নিখুঁত উপহারটি খুঁজে পাওয়া অত্যন্ত সহজ। আপনি কী খুঁজছেন তা বর্ণনা করতে পারেন, একটি খেলনার ছবি আপলোড করতে পারেন, বা এমনকি নিজের নকশাও তৈরি করতে পারেন, এবং দোকানটি সঙ্গে সঙ্গে আপনার প্রয়োজন বুঝে নেয় ও আপনার জন্য বিশেষভাবে তৈরি একটি অভিজ্ঞতা প্রদান করে। এটি কোনো ভবিষ্যৎ-কল্পনা নয়; এটি কৃত্রিম বুদ্ধিমত্তা (AI), ক্লাউড প্রযুক্তি এবং ব্যক্তিগতকৃত ই-কমার্সের একটি রূপকল্প দ্বারা চালিত এক বাস্তবতা।
চ্যালেঞ্জ: আপনার কল্পনার সাথে মেলে এমন নিখুঁত পণ্যটি খুঁজে বের করাই কঠিন হতে পারে। সাধারণ সার্চ টার্ম, কীওয়ার্ড এবং অস্পষ্ট সার্চ প্রায়শই ব্যর্থ হয়, অগণিত পৃষ্ঠা ঘাঁটাঘাঁটি করা ক্লান্তিকর হতে পারে, এবং আপনার কল্পনা ও উপলব্ধ পণ্যের মধ্যেকার অমিল হতাশার কারণ হতে পারে।
সমাধান: ডেমো অ্যাপ্লিকেশনটি কৃত্রিম বুদ্ধিমত্তার শক্তিকে কাজে লাগিয়ে প্রাসঙ্গিক অনুসন্ধান এবং অনুসন্ধানের প্রেক্ষাপটের সাথে মেলে এমন পণ্যের কাস্টম জেনারেশনের মাধ্যমে একটি সত্যিকারের ব্যক্তিগতকৃত ও নির্বিঘ্ন অভিজ্ঞতা প্রদান করে, যা এই চ্যালেঞ্জটিকে সরাসরি মোকাবেলা করে।
আপনি যা তৈরি করবেন
এই ল্যাবের অংশ হিসেবে, আপনি যা করবেন:
- একটি AlloyDB ইনস্ট্যান্স তৈরি করুন এবং Toys ডেটাসেট লোড করুন।
- AlloyDB-তে pgvector এবং জেনারেটিভ এআই মডেল এক্সটেনশনগুলি সক্রিয় করুন।
- পণ্যের বিবরণ থেকে এমবেডিং তৈরি করুন এবং ব্যবহারকারীর অনুসন্ধানের টেক্সটের জন্য রিয়েল-টাইম কোসাইন সিমিলারিটি সার্চ সম্পাদন করুন।
- প্রাসঙ্গিক খেলনা অনুসন্ধানের জন্য ব্যবহারকারীর আপলোড করা ছবিটি বর্ণনা করতে জেমিনি ২.০ ফ্ল্যাশ চালু করুন।
- ব্যবহারকারীর আগ্রহ অনুযায়ী নিজস্ব খেলনা তৈরি করতে Imagen 3 ব্যবহার করুন।
- বিশেষভাবে তৈরি খেলনাটির মূল্যের বিবরণ জানতে, ডেটাবেসের জন্য জেন এআই টুলবক্স ব্যবহার করে তৈরি একটি মূল্য পূর্বাভাস টুল চালু করুন।
- সার্ভারলেস ক্লাউড রান ফাংশনগুলিতে সমাধানটি স্থাপন করুন
প্রয়োজনীয়তা
- ক্রোম বা ফায়ারফক্সের মতো একটি ব্রাউজার
- বিলিং সক্ষম একটি গুগল ক্লাউড প্রজেক্ট।
২. স্থাপত্য
ডেটা প্রবাহ: চলুন, আমাদের সিস্টেমের মধ্যে দিয়ে ডেটা কীভাবে চলাচল করে তা আরও ভালোভাবে দেখে নেওয়া যাক:
- এআই-চালিত RAG (রিট্রিভাল অগমেন্টেড জেনারেশন) এর মাধ্যমে প্রাসঙ্গিক অনুসন্ধান
বিষয়টা এভাবে ভাবুন: শুধু 'লাল গাড়ি' খোঁজার পরিবর্তে, সিস্টেমটি নিচের বিষয়গুলো বোঝে:
তিন বছর বয়সী ছেলের জন্য উপযুক্ত ছোট গাড়ি।
ভিত্তি হিসেবে AlloyDB: আমরা আমাদের খেলনার ডেটা, যেমন—বর্ণনা, ছবির ইউআরএল এবং অন্যান্য প্রাসঙ্গিক বৈশিষ্ট্য সংরক্ষণের জন্য গুগল ক্লাউডের সম্পূর্ণভাবে পরিচালিত ও PostgreSQL-উপযোগী ডেটাবেস AlloyDB ব্যবহার করি।
সিমান্টিক সার্চের জন্য pgvector: pgvector, PostgreSQL-এর একটি এক্সটেনশন, যা আমাদেরকে খেলনার বিবরণ এবং ব্যবহারকারীর সার্চ কোয়েরি উভয়েরই ভেক্টর এমবেডিং সংরক্ষণ করতে দেয়। এটি সিমান্টিক সার্চ সক্ষম করে, যার অর্থ হলো সিস্টেমটি শুধু সঠিক কীওয়ার্ডই নয়, শব্দগুলোর পেছনের অর্থও বুঝতে পারে।
প্রাসঙ্গিকতার জন্য কোসাইন সাদৃশ্য: আমরা ব্যবহারকারীর সার্চ ভেক্টর এবং খেলনার বিবরণ ভেক্টরগুলোর মধ্যে শব্দার্থগত সাদৃশ্য পরিমাপ করতে কোসাইন সাদৃশ্য ব্যবহার করি, যা সবচেয়ে প্রাসঙ্গিক ফলাফলগুলো প্রদর্শন করে।
গতি এবং নির্ভুলতার জন্য ScaNN ইনডেক্স: দ্রুত এবং নির্ভুল ফলাফল নিশ্চিত করতে, বিশেষ করে আমাদের খেলনার ভান্ডার বাড়ার সাথে সাথে, আমরা ScaNN (স্কেলেবল নিয়ারেস্ট নেইবারস) ইনডেক্সকে অন্তর্ভুক্ত করি। এটি আমাদের ভেক্টর সার্চের কার্যকারিতা এবং রিকল উল্লেখযোগ্যভাবে উন্নত করে।
- জেমিনি ২.০ ফ্ল্যাশ ব্যবহার করে চিত্র-ভিত্তিক অনুসন্ধান ও অনুধাবন।
টেক্সট হিসেবে কনটেক্সট টাইপ করার পরিবর্তে, ধরা যাক ব্যবহারকারী তার পরিচিত কোনো খেলনার ছবি আপলোড করতে চান, যা দিয়ে তিনি সার্চ করতে চান। ব্যবহারকারীরা তাদের পছন্দের খেলনার একটি ছবি আপলোড করে এর মাধ্যমে প্রাসঙ্গিক ফিচারগুলো পেতে পারেন। আমরা ছবিটি বিশ্লেষণ করতে এবং খেলনাটির রঙ, উপাদান, ধরন ও উদ্দিষ্ট বয়সসীমার মতো প্রাসঙ্গিক তথ্য বের করতে LangChain4j দ্বারা চালিত গুগলের Gemini 2.0 ফ্ল্যাশ মডেল ব্যবহার করি।
- জেনারেটিভ এআই দিয়ে আপনার স্বপ্নের খেলনা তৈরি: ইমাজেন ৩
আসল জাদুটা তখনই ঘটে যখন ব্যবহারকারীরা নিজেদের খেলনা তৈরি করার সিদ্ধান্ত নেন। Imagen 3 ব্যবহার করে, আমরা তাদেরকে সহজ টেক্সট প্রম্পটের মাধ্যমে তাদের স্বপ্নের খেলনাটির বর্ণনা দেওয়ার সুযোগ দিই। ভাবুন তো, আপনি বলতে পারছেন: "আমি বেগুনি ডানা আর বন্ধুত্বপূর্ণ মুখের একটি নরম ড্রাগন চাই" এবং সেই ড্রাগনটিকে আপনার স্ক্রিনে জীবন্ত হয়ে উঠতে দেখছেন! এরপর Imagen 3 সেই বিশেষভাবে ডিজাইন করা খেলনাটির একটি ছবি তৈরি করে, যা ব্যবহারকারীকে তার সৃষ্টিটির একটি স্পষ্ট দৃশ্যকল্প দেয়।
- এজেন্ট ও জেন এআই টুলবক্স ফর ডাটাবেস দ্বারা চালিত মূল্য পূর্বাভাস
আমরা একটি মূল্য পূর্বাভাস বৈশিষ্ট্য চালু করেছি যা বিশেষভাবে ডিজাইন করা খেলনাটি তৈরির খরচ অনুমান করে। এটি এমন একটি এজেন্ট দ্বারা চালিত হয়, যার মধ্যে একটি অত্যাধুনিক মূল্য গণনার টুল রয়েছে।
জেন এআই টুলবক্স ফর ডেটাবেস: এই এজেন্টটি গুগলের নতুন ওপেন-সোর্স টুল, জেন এআই টুলবক্স ফর ডেটাবেস ব্যবহার করে আমাদের ডেটাবেসের সাথে নির্বিঘ্নে সংযুক্ত করা হয়েছে। এর ফলে এজেন্টটি কাঁচামালের খরচ, উৎপাদন প্রক্রিয়া এবং অন্যান্য প্রাসঙ্গিক বিষয়ের রিয়েল-টাইম ডেটা অ্যাক্সেস করে একটি সঠিক মূল্য অনুমান প্রদান করতে পারে। এ সম্পর্কে আরও জানতে এখানে পড়ুন।
- সুসংহত ডেভেলপমেন্ট এবং সার্ভারবিহীন ডেপ্লয়মেন্টের জন্য জাভা স্প্রিং বুট, জেমিনি কোড অ্যাসিস্ট এবং ক্লাউড রান
সম্পূর্ণ অ্যাপ্লিকেশনটি জাভা স্প্রিং বুট ব্যবহার করে তৈরি করা হয়েছে, যা একটি শক্তিশালী এবং স্কেলেবল ফ্রেমওয়ার্ক। আমরা পুরো ডেভেলপমেন্ট প্রক্রিয়া জুড়ে, বিশেষ করে ফ্রন্ট-এন্ড ডেভেলপমেন্টের জন্য, জেমিনি কোড অ্যাসিস্ট ব্যবহার করেছি, যা ডেভেলপমেন্ট চক্রকে উল্লেখযোগ্যভাবে ত্বরান্বিত করেছে এবং কোডের মান উন্নত করেছে। আমরা সম্পূর্ণ অ্যাপ্লিকেশনটি ডেপ্লয় করার জন্য ক্লাউড রান এবং ডাটাবেস ও এজেন্টিক কার্যকারিতাগুলোকে স্বাধীন এন্ডপয়েন্ট হিসেবে ডেপ্লয় করার জন্য ক্লাউড রান ফাংশনস ব্যবহার করেছি।
৩. শুরু করার আগে
একটি প্রকল্প তৈরি করুন
- গুগল ক্লাউড কনসোলের প্রজেক্ট সিলেক্টর পেজে, একটি গুগল ক্লাউড প্রজেক্ট নির্বাচন করুন বা তৈরি করুন।
- আপনার ক্লাউড প্রোজেক্টের জন্য বিলিং চালু আছে কিনা তা নিশ্চিত করুন। কোনো প্রোজেক্টে বিলিং চালু আছে কিনা তা কীভাবে পরীক্ষা করবেন, তা জেনে নিন।
- আপনি ক্লাউড শেল ব্যবহার করবেন, যা গুগল ক্লাউডে চলমান একটি কমান্ড-লাইন পরিবেশ এবং এটি bq-এর সাথে আগে থেকেই লোড করা থাকে। গুগল ক্লাউড কনসোলের শীর্ষে থাকা ‘Activate Cloud Shell’-এ ক্লিক করুন।

- ক্লাউড শেলে সংযুক্ত হওয়ার পর, আপনি নিম্নলিখিত কমান্ডটি ব্যবহার করে যাচাই করে নিন যে আপনি ইতিমধ্যেই প্রমাণীকৃত এবং প্রজেক্টটি আপনার প্রজেক্ট আইডিতে সেট করা আছে:
gcloud auth list
- gcloud কমান্ডটি আপনার প্রজেক্ট সম্পর্কে অবগত আছে কিনা, তা নিশ্চিত করতে ক্লাউড শেলে নিম্নলিখিত কমান্ডটি চালান।
gcloud config list project
- আপনার প্রজেক্টটি সেট করা না থাকলে, এটি সেট করতে নিম্নলিখিত কমান্ডটি ব্যবহার করুন:
gcloud config set project <YOUR_PROJECT_ID>
- আপনার ক্লাউড শেল টার্মিনালে নিম্নলিখিত কমান্ডগুলি এক এক করে চালিয়ে প্রয়োজনীয় API গুলি সক্রিয় করুন:
নিচের কমান্ডগুলো চালানোর জন্য একটিমাত্র কমান্ডও রয়েছে, কিন্তু আপনি যদি ট্রায়াল অ্যাকাউন্টের ব্যবহারকারী হন, তবে একসাথে অনেকগুলো চালু করতে গেলে কোটা সংক্রান্ত সমস্যার সম্মুখীন হতে পারেন। এই কারণেই কমান্ডগুলো প্রতি লাইনে একটি করে আলাদাভাবে দেওয়া হয়েছে।
gcloud services enable alloydb.googleapis.com
gcloud services enable compute.googleapis.com
gcloud services enable cloudresourcemanager.googleapis.com
gcloud services enable servicenetworking.googleapis.com
gcloud services enable run.googleapis.com
gcloud services enable cloudbuild.googleapis.com
gcloud services enable cloudfunctions.googleapis.com
gcloud services enable aiplatform.googleapis.com
gcloud কমান্ডের বিকল্প হলো কনসোলের মাধ্যমে প্রতিটি পণ্য অনুসন্ধান করা অথবা এই লিঙ্কটি ব্যবহার করা।
যদি কোনো API বাদ পড়ে যায়, তাহলে আপনি বাস্তবায়ন চলাকালীন সময়েই তা সক্রিয় করে নিতে পারেন।
gcloud কমান্ড এবং এর ব্যবহার সম্পর্কে জানতে ডকুমেন্টেশন দেখুন।
৪. ডাটাবেস সেটআপ
এই ল্যাবে আমরা টয়স্টোরের ডেটা সংরক্ষণের জন্য ডাটাবেস হিসেবে অ্যালয়ডিবি (AlloyDB) ব্যবহার করব। এটি ডাটাবেস এবং লগের মতো সমস্ত রিসোর্স ধারণ করার জন্য ক্লাস্টার ব্যবহার করে। প্রতিটি ক্লাস্টারে একটি প্রাইমারি ইনস্ট্যান্স থাকে যা ডেটাতে অ্যাক্সেস পয়েন্ট হিসেবে কাজ করে। টেবিলগুলোতে মূল ডেটা থাকবে।
চলুন একটি AlloyDB ক্লাস্টার, ইনস্ট্যান্স এবং টেবিল তৈরি করি যেখানে ইকমার্স ডেটাসেটটি লোড করা হবে।
একটি ক্লাস্টার এবং ইনস্ট্যান্স তৈরি করুন
- ক্লাউড কনসোলে AlloyDB পেজটিতে যান। ক্লাউড কনসোলের বেশিরভাগ পেজ খুঁজে পাওয়ার একটি সহজ উপায় হলো কনসোলের সার্চ বার ব্যবহার করে সেগুলোর জন্য অনুসন্ধান করা।
- সেই পৃষ্ঠা থেকে CREATE CLUSTER নির্বাচন করুন:

- আপনি নীচেরটির মতো একটি স্ক্রিন দেখতে পাবেন। নিম্নলিখিত মানগুলি দিয়ে একটি ক্লাস্টার এবং ইনস্ট্যান্স তৈরি করুন (আপনি যদি রিপো থেকে অ্যাপ্লিকেশন কোড ক্লোন করেন তবে নিশ্চিত করুন যে মানগুলি মিলে যায়):
- ক্লাস্টার আইডি : "
vector-cluster" - পাসওয়ার্ড : "
alloydb" - PostgreSQL 15 সামঞ্জস্যপূর্ণ
- অঞ্চল : "
us-central1" - নেটওয়ার্কিং : "
default"

- আপনি যখন ডিফল্ট নেটওয়ার্ক নির্বাচন করবেন, তখন নিচের স্ক্রিনের মতো একটি স্ক্রিন দেখতে পাবেন।
সংযোগ স্থাপন নির্বাচন করুন। 
- সেখান থেকে, " Use an automatically allocated IP range " নির্বাচন করুন এবং Continue নির্বাচন করুন। তথ্য পর্যালোচনা করার পর, CREATE CONNECTION নির্বাচন করুন।

- আপনার নেটওয়ার্ক সেট আপ হয়ে গেলে, আপনি আপনার ক্লাস্টার তৈরি করা চালিয়ে যেতে পারেন। নিচে দেখানো অনুযায়ী ক্লাস্টার সেট আপ সম্পন্ন করতে CREATE CLUSTER-এ ক্লিক করুন:

ইনস্ট্যান্স আইডি পরিবর্তন করতে ভুলবেন না
vector-instance
যদি আপনি এটি পরিবর্তন করতে না পারেন, তাহলে পরবর্তী সমস্ত রেফারেন্সে ইনস্ট্যান্স আইডিটি পরিবর্তন করতে মনে রাখবেন।
মনে রাখবেন, ক্লাস্টার তৈরি হতে প্রায় ১০ মিনিট সময় লাগবে। এটি সফল হলে, আপনি আপনার তৈরি করা ক্লাস্টারের একটি সার্বিক চিত্র দেখতে পাবেন।
৫. ডেটা গ্রহণ
এখন স্টোর সম্পর্কিত ডেটা সহ একটি টেবিল যোগ করার সময় এসেছে। AlloyDB-তে যান, প্রাইমারি ক্লাস্টার নির্বাচন করুন এবং তারপর AlloyDB Studio-তে যান:

আপনার ইনস্ট্যান্সটি তৈরি হওয়া শেষ না হওয়া পর্যন্ত আপনাকে অপেক্ষা করতে হতে পারে। এটি তৈরি হয়ে গেলে, ক্লাস্টার তৈরির সময় আপনি যে ক্রেডেনশিয়ালগুলো তৈরি করেছিলেন, সেগুলো ব্যবহার করে AlloyDB-তে সাইন ইন করুন। PostgreSQL-এ প্রমাণীকরণের জন্য নিম্নলিখিত ডেটা ব্যবহার করুন:
- ব্যবহারকারীর নাম : "
postgres" - ডাটাবেস : "
postgres" - পাসওয়ার্ড : "
alloydb"
AlloyDB Studio-তে সফলভাবে প্রমাণীকরণের পর, এডিটর-এ SQL কমান্ডগুলো প্রবেশ করানো হয়। শেষ উইন্ডোটির ডানদিকে থাকা প্লাস চিহ্নটি ব্যবহার করে আপনি একাধিক এডিটর উইন্ডো যোগ করতে পারেন।

আপনি এডিটর উইন্ডোতে AlloyDB-এর জন্য কমান্ড লিখবেন এবং প্রয়োজন অনুযায়ী Run, Format ও Clear অপশনগুলো ব্যবহার করবেন।
এক্সটেনশনগুলি সক্ষম করুন
এই অ্যাপটি তৈরি করার জন্য, আমরা pgvector এবং google_ml_integration এক্সটেনশনগুলো ব্যবহার করব। pgvector এক্সটেনশনটি আপনাকে ভেক্টর এমবেডিং সংরক্ষণ এবং অনুসন্ধান করার সুযোগ দেয়। google_ml_integration এক্সটেনশনটি এমন সব ফাংশন সরবরাহ করে যা ব্যবহার করে আপনি Vertex AI প্রেডিকশন এন্ডপয়েন্টগুলো অ্যাক্সেস করে SQL-এ প্রেডিকশন পেতে পারেন। নিম্নলিখিত DDL-গুলো রান করে এই এক্সটেনশনগুলো সক্রিয় করুন :
CREATE EXTENSION IF NOT EXISTS google_ml_integration CASCADE;
CREATE EXTENSION IF NOT EXISTS vector;
আপনার ডাটাবেসে কোন এক্সটেনশনগুলো সক্রিয় করা হয়েছে তা পরীক্ষা করতে চাইলে, এই SQL কমান্ডটি চালান:
select extname, extversion from pg_extension;
একটি টেবিল তৈরি করুন
নিচের DDL স্টেটমেন্টটি ব্যবহার করে একটি টেবিল তৈরি করুন:
CREATE TABLE toys ( id VARCHAR(25), name VARCHAR(25), description VARCHAR(20000), quantity INT, price FLOAT, image_url VARCHAR(200), text_embeddings vector(768)) ;
উপরের কমান্ডটি সফলভাবে কার্যকর হলে, আপনি ডাটাবেসে টেবিলটি দেখতে সক্ষম হবেন।
ডেটা গ্রহণ করুন
এই ল্যাবের জন্য, এই SQL ফাইলটিতে প্রায় ৭২টি রেকর্ডের টেস্ট ডেটা রয়েছে। এতে id, name, description, quantity, price, image_url ফিল্ডগুলো আছে। অন্যান্য ফিল্ডগুলো ল্যাবের পরবর্তী পর্যায়ে পূরণ করা হবে।
সেখান থেকে শুধু প্রথম ৫টি লাইন/ইনসার্ট স্টেটমেন্ট কপি করুন এবং তারপর সেই লাইনগুলো একটি খালি এডিটর ট্যাবে পেস্ট করে রান (RUN) নির্বাচন করুন। আপনি যদি ট্রায়াল বিলিং অ্যাকাউন্ট ব্যবহার না করেন, তাহলে সম্ভবত আপনি সমস্ত ইনসার্ট স্টেটমেন্ট কপি করে রান করতে পারবেন।
টেবিলের বিষয়বস্তু দেখতে, এক্সপ্লোরার সেকশনটি প্রসারিত করুন যতক্ষণ না আপনি apparels নামের টেবিলটি দেখতে পান। টেবিলটি কোয়েরি করার অপশনটি দেখতে ট্রাইকোলন (⋮) নির্বাচন করুন। একটি নতুন এডিটর ট্যাবে একটি SELECT স্টেটমেন্ট খুলে যাবে।

অনুমতি প্রদান করুন
postgres ব্যবহারকারীকে embedding ফাংশনের উপর এক্সিকিউট করার অধিকার দিতে নিচের স্টেটমেন্টটি চালান:
GRANT EXECUTE ON FUNCTION embedding TO postgres;
AlloyDB পরিষেবা অ্যাকাউন্টে Vertex AI ব্যবহারকারীর ROLE প্রদান করুন।
ক্লাউড শেল টার্মিনালে গিয়ে নিম্নলিখিত কমান্ডটি দিন:
PROJECT_ID=$(gcloud config get-value project)
gcloud projects add-iam-policy-binding $PROJECT_ID \
--member="serviceAccount:service-$(gcloud projects describe $PROJECT_ID --format="value(projectNumber)")@gcp-sa-alloydb.iam.gserviceaccount.com" \
--role="roles/aiplatform.user"
৬. কনটেক্সটের জন্য এমবেডিং তৈরি করুন
কম্পিউটারের জন্য টেক্সট প্রসেস করার চেয়ে সংখ্যা প্রসেস করা অনেক বেশি সহজ। একটি এমবেডিং সিস্টেম টেক্সটকে ফ্লোটিং পয়েন্ট সংখ্যার একটি সিরিজে রূপান্তরিত করে, যা টেক্সটটির প্রতিনিধিত্ব করে, তা যেভাবেই লেখা হোক বা যে ভাষাই ব্যবহার করা হোক না কেন।
সমুদ্রতীরবর্তী কোনো স্থানের বর্ণনা দেওয়ার কথা ভাবুন। একে বলা হতে পারে "জলের উপর", "সৈকতের সামনে", "ঘর থেকে হেঁটে সমুদ্রে যাওয়া", "সুর লা মের", "না বেরেগু ওশিয়ানা" ইত্যাদি। এই শব্দগুলো শুনতে ভিন্ন হলেও, এদের অর্থগত তাৎপর্য বা মেশিন লার্নিং-এর পরিভাষায়, এদের এমবেডিংগুলো একে অপরের খুব কাছাকাছি হওয়া উচিত।
এখন যেহেতু ডেটা এবং কনটেক্সট প্রস্তুত, আমরা প্রোডাক্ট ডেসক্রিপশনের এমবেডিংগুলো টেবিলের ' embedding ফিল্ডে যোগ করার জন্য SQL রান করব। আপনি বিভিন্ন ধরনের এমবেডিং মডেল ব্যবহার করতে পারেন। আমরা Vertex AI-এর text-embedding-005 ব্যবহার করছি। পুরো প্রোজেক্ট জুড়ে একই এমবেডিং মডেল ব্যবহার করতে ভুলবেন না!
দ্রষ্টব্য: আপনি যদি কিছুকাল আগে তৈরি করা কোনো বিদ্যমান গুগল ক্লাউড প্রজেক্ট ব্যবহার করেন, তাহলে আপনাকে টেক্সট-এম্বেডিং-গেকোর মতো টেক্সট-এম্বেডিং মডেলের পুরোনো সংস্করণগুলো ব্যবহার করা চালিয়ে যেতে হতে পারে।
AlloyDB Studio ট্যাবে ফিরে যান এবং নিম্নলিখিত DML টাইপ করুন:
UPDATE toys set text_embeddings = embedding( 'text-embedding-005', description);
কিছু এমবেডিং দেখতে toys টেবিলটি আবার দেখুন। পরিবর্তনগুলো দেখতে SELECT স্টেটমেন্টটি অবশ্যই পুনরায় চালান।
SELECT id, name, description, price, quantity, image_url, text_embeddings FROM toys;
এটি খেলনার বিবরণের জন্য এমবেডিংস ভেক্টরটি ফেরত দেবে, যা নিচে দেখানো অনুযায়ী ফ্লোট সংখ্যার একটি অ্যারের মতো দেখতে হবে:

দ্রষ্টব্য: ফ্রি টিয়ারের অধীনে নতুন তৈরি করা গুগল ক্লাউড প্রজেক্টগুলো এমবেডিং মডেলগুলিতে প্রতি সেকেন্ডে অনুমোদিত এমবেডিং অনুরোধের সংখ্যার ক্ষেত্রে কোটা সমস্যার সম্মুখীন হতে পারে। আমরা পরামর্শ দিচ্ছি যে, এমবেডিং তৈরি করার সময় আপনি আইডি-র জন্য একটি ফিল্টার কোয়েরি ব্যবহার করুন এবং তারপর বেছে বেছে ১-৫টি রেকর্ড ইত্যাদি নির্বাচন করুন।
৭. ভেক্টর অনুসন্ধান সম্পাদন করুন
এখন যেহেতু টেবিল, ডেটা এবং এমবেডিং সবই প্রস্তুত, চলুন ব্যবহারকারীর সার্চ টেক্সটটির জন্য রিয়েল টাইম ভেক্টর সার্চটি সম্পাদন করা যাক।
ধরুন ব্যবহারকারী জিজ্ঞাসা করেন:
I want a white plush teddy bear toy with a floral pattern ।
নিচের কোয়েরিটি চালিয়ে আপনি এর সাথে মিল খুঁজে পেতে পারেন:
select * from toys
ORDER BY text_embeddings <=> CAST(embedding('text-embedding-005', 'I want a white plush teddy bear toy with a floral pattern') as vector(768))
LIMIT 2;
চলুন এই কোয়েরিটি বিস্তারিতভাবে দেখি:
এই কোয়েরিতে,
- ব্যবহারকারীর অনুসন্ধানের লেখাটি হলো: "
I want a white plush teddy bear toy with a floral pattern." - আমরা
text-embedding-005মডেলটি ব্যবহার করে `embedding()মেথডে এটিকে এমবেডিং-এ রূপান্তর করছি। গত ধাপের পর এই ধাপটি আপনার কাছে পরিচিত মনে হওয়া উচিত, যেখানে আমরা টেবিলের সমস্ত আইটেমে এমবেডিং ফাংশনটি প্রয়োগ করেছিলাম। - "
<=>" চিহ্নটি কোসাইন সিমিলারিটি ডিসট্যান্স পদ্ধতির ব্যবহার নির্দেশ করে। pgvector-এর ডকুমেন্টেশনে উপলব্ধ সমস্ত সিমিলারিটি মেজার সম্পর্কে জানতে পারবেন। - ডাটাবেসে সংরক্ষিত ভেক্টরগুলোর সাথে সামঞ্জস্যপূর্ণ করার জন্য আমরা এমবেডিং মেথডের ফলাফলকে ভেক্টর টাইপে রূপান্তর করছি।
- LIMIT 5 এর অর্থ হলো, আমরা সার্চ টেক্সটটির জন্য ৫টি নিকটতম প্রতিবেশী ডেটা বের করতে চাই।
ফলাফলটি দেখতে এইরকম:

আপনি আপনার ফলাফলে দেখতে পাচ্ছেন যে, মিলগুলো সার্চ টেক্সটের বেশ কাছাকাছি। টেক্সটটি পরিবর্তন করে দেখুন ফলাফলে কী পরিবর্তন আসে।
গুরুত্বপূর্ণ দ্রষ্টব্য:
এখন ধরা যাক, আমরা ScaNN ইনডেক্স ব্যবহার করে এই ভেক্টর সার্চ ফলাফলের পারফরম্যান্স (কোয়েরি টাইম), দক্ষতা এবং রিকল বাড়াতে চাই। ইনডেক্স সহ এবং ইনডেক্স ছাড়া ফলাফলের পার্থক্য তুলনা করতে অনুগ্রহ করে এই ব্লগের ধাপগুলো পড়ুন।
ঐচ্ছিক ধাপ: ScanN ইনডেক্স ব্যবহার করে দক্ষতা এবং রিকল উন্নত করুন
আপনার রেকর্ডের সংখ্যা ১০০-এর কম হলে এই ধাপটি উপেক্ষা করুন।
সুবিধার জন্য এখানে ইনডেক্স তৈরির ধাপগুলো তালিকাভুক্ত করা হলো:
- যেহেতু আমাদের ক্লাস্টার, ইনস্ট্যান্স, কনটেক্সট এবং এমবেডিং ইতিমধ্যেই তৈরি করা আছে, তাই আমাদের শুধু নিম্নলিখিত স্টেটমেন্টটি ব্যবহার করে ScaNN এক্সটেনশনটি ইনস্টল করতে হবে:
CREATE EXTENSION IF NOT EXISTS alloydb_scann;
- এরপরে আমরা ইনডেক্স (ScaNN) তৈরি করব:
CREATE INDEX toysearch_index ON toys
USING scann (text_embeddings cosine)
WITH (num_leaves=9);
উপরের DDL-এ, apparel_index হলো ইনডেক্সটির নাম।
"খেলনা" হলো আমার টেবিল
'স্ক্যান' হলো সূচক পদ্ধতি
'embedding' হলো টেবিলের সেই কলামটি যা আমি ইনডেক্স করতে চাই।
আমি ইনডেক্সের সাথে দূরত্ব পরিমাপের জন্য 'কোসাইন' পদ্ধতিটি ব্যবহার করতে চাই।
"8" হলো এই ইনডেক্সে প্রয়োগ করার জন্য পার্টিশনের সংখ্যা। এর মান 1 থেকে 1048576-এর মধ্যে যেকোনো একটিতে সেট করুন। এই মানটি কীভাবে নির্ধারণ করতে হয় সে সম্পর্কে আরও তথ্যের জন্য, "Tune a ScaNN index" দেখুন।
ScaNN রিপোতে সুপারিশ অনুযায়ী আমি ডেটা পয়েন্ট সংখ্যার বর্গমূল ব্যবহার করেছি (পার্টিশন করার সময়, num_leaves-এর মান ডেটাপয়েন্ট সংখ্যার বর্গমূলের প্রায় সমান হওয়া উচিত)।
- কোয়েরি ব্যবহার করে ইনডেক্সটি তৈরি হয়েছে কিনা তা পরীক্ষা করুন:
SELECT * FROM pg_stat_ann_indexes;
- ইনডেক্স ছাড়া আমরা যে কোয়েরিটি ব্যবহার করেছিলাম, সেটি ব্যবহার করেই ভেক্টর সার্চ সম্পাদন করুন:
select * from toys
ORDER BY text_embeddings <=> CAST(embedding('text-embedding-005', 'I want a white plush teddy bear toy with a floral pattern') as vector(768))
LIMIT 5;
উপরের কোয়েরিটি সেই একই কোয়েরি যা আমরা ল্যাবের ৮ নম্বর ধাপে ব্যবহার করেছিলাম। তবে এখন আমরা ফিল্ডটিকে ইনডেক্স করেছি।
- ইনডেক্স সহ এবং ইনডেক্স ছাড়া (ইনডেক্স ড্রপ করে) একটি সাধারণ সার্চ কোয়েরি দিয়ে পরীক্ষা করুন:
এই ইউজ কেসটিতে মাত্র ৭২টি রেকর্ড থাকায় ইনডেক্সটি তেমন কার্যকর হয় না। অন্য একটি ইউজ কেসে পরিচালিত পরীক্ষার ফলাফল নিম্নরূপ:
ইনডেক্স করা এমবেডিং ডেটার উপর একই ভেক্টর সার্চ কোয়েরি চালালে উন্নত মানের সার্চ ফলাফল এবং কার্যকারিতা পাওয়া যায়। ইনডেক্স ব্যবহারের ফলে কার্যকারিতা ব্যাপকভাবে উন্নত হয় (কার্য সম্পাদনের সময়ের নিরিখে: ScaNN ছাড়া ১০.৩৭ মিলিসেকেন্ড এবং ScaNN সহ ০.৮৭ মিলিসেকেন্ড)। এই বিষয়ে আরও তথ্যের জন্য, অনুগ্রহ করে এই ব্লগটি দেখুন।
৮. এলএলএম-এর সাথে মিল যাচাইকরণ
কোনো অ্যাপ্লিকেশনে সেরা মিলগুলো ফিরিয়ে দেওয়ার জন্য একটি সার্ভিস তৈরি করার আগে, চলুন একটি জেনারেটিভ এআই মডেল ব্যবহার করে যাচাই করে নিই যে এই সম্ভাব্য উত্তরগুলো সত্যিই প্রাসঙ্গিক এবং ব্যবহারকারীর সাথে শেয়ার করার জন্য নিরাপদ কিনা।
জেমিনির জন্য ইনস্ট্যান্সটি সেট আপ করা নিশ্চিত করা
প্রথমে যাচাই করুন আপনার ক্লাস্টার এবং ইনস্ট্যান্সের জন্য গুগল এমএল ইন্টিগ্রেশন আগে থেকেই সক্রিয় করা আছে কিনা। AlloyDB Studio-তে নিম্নলিখিত কমান্ডটি দিন:
show google_ml_integration.enable_model_support;
যদি মানটি "on" হিসাবে দেখানো হয়, তাহলে আপনি পরবর্তী ২টি ধাপ এড়িয়ে সরাসরি AlloyDB এবং Vertex AI মডেল ইন্টিগ্রেশন সেট আপ করার ধাপে যেতে পারেন।
- আপনার AlloyDB ক্লাস্টারের প্রাইমারি ইনস্ট্যান্সে যান এবং EDIT PRIMARY INSTANCE-এ ক্লিক করুন।

- অ্যাডভান্সড কনফিগারেশন অপশন-এর ফ্ল্যাগস সেকশনে যান এবং নিশ্চিত করুন যে
google_ml_integration.enable_model_support flagনিচে দেখানো অনুযায়ী "on" এ সেট করা আছে:

যদি এটি 'on' করা না থাকে, তবে এটিকে 'on' করুন এবং তারপর 'UPDATE INSTANCE' বোতামে ক্লিক করুন। এই ধাপে কয়েক মিনিট সময় লাগবে।
AlloyDB এবং Vertex AI মডেলের একীকরণ
এখন আপনি AlloyDB Studio-তে সংযোগ করে, নির্দেশিত স্থানে আপনার প্রজেক্ট আইডি ব্যবহার করে, AlloyDB থেকে Gemini মডেল অ্যাক্সেস সেট আপ করার জন্য নিম্নলিখিত DML স্টেটমেন্টটি চালাতে পারেন। কমান্ডটি চালানোর আগে আপনাকে সিনট্যাক্স ত্রুটির বিষয়ে সতর্ক করা হতে পারে, কিন্তু এটি ঠিকঠাকভাবে চলার কথা।
প্রথমে, নিচে দেখানো পদ্ধতি অনুযায়ী জেমিনি ১.৫ মডেলের কানেকশনটি তৈরি করুন। মনে রাখবেন, নিচের কমান্ডে $PROJECT_ID জায়গায় আপনার গুগল ক্লাউড প্রজেক্ট আইডি বসাতে হবে।
CALL
google_ml.create_model( model_id => 'gemini-1.5',
model_request_url => 'https://us-central1-aiplatform.googleapis.com/v1/projects/$PROJECT_ID/locations/us-central1/publishers/google/models/gemini-1.5-pro:streamGenerateContent',
model_provider => 'google',
model_auth_type => 'alloydb_service_agent_iam');
AlloyDB Studio-তে নিম্নলিখিত কমান্ডের মাধ্যমে আপনি অ্যাক্সেসের জন্য কনফিগার করা মডেলগুলি পরীক্ষা করতে পারেন:
select model_id,model_type from google_ml.model_info_view;
অবশেষে, গুগল ভার্টেক্স এআই মডেলের মাধ্যমে প্রেডিকশন চালানোর জন্য ডাটাবেস ব্যবহারকারীদের ml_predict_row ফাংশনটি এক্সিকিউট করার অনুমতি দিতে হবে। নিম্নলিখিত কমান্ডটি চালান:
GRANT EXECUTE ON FUNCTION ml_predict_row to postgres;
দ্রষ্টব্য: আপনি যদি একটি বিদ্যমান গুগল ক্লাউড প্রজেক্ট এবং কিছুকাল আগে তৈরি করা অ্যালয়ডিবি-র (AlloyDB) একটি বিদ্যমান ক্লাস্টার/ইনস্ট্যান্স ব্যবহার করেন, এবং পরবর্তীতে gemini-1.5 চালানোর সময় কোনো সমস্যার সম্মুখীন হন, তাহলে আপনাকে gemini-1.5 মডেলের পুরোনো রেফারেন্সগুলো ড্রপ করে উপরের CALL স্টেটমেন্টটি দিয়ে আবার তৈরি করতে হতে পারে এবং ml_predict_row ফাংশনটিতে আবার grant execute চালাতে হতে পারে।
প্রতিক্রিয়া মূল্যায়ন করা
যদিও পরবর্তী অংশে কোয়েরি থেকে প্রাপ্ত প্রতিক্রিয়াগুলো যুক্তিসঙ্গত কিনা তা নিশ্চিত করার জন্য আমরা একটি বড় কোয়েরি ব্যবহার করব, তবে কোয়েরিটি বোঝা কঠিন হতে পারে। আমরা এখন এর অংশগুলো দেখব এবং কয়েক মিনিটের মধ্যেই বুঝব কীভাবে সেগুলো একত্রিত হয়।
- প্রথমে আমরা ব্যবহারকারীর কোয়েরির সবচেয়ে কাছাকাছি ১০টি ফলাফল পাওয়ার জন্য ডাটাবেসে একটি অনুরোধ পাঠাবো।
- প্রতিক্রিয়াগুলো কতটা বৈধ তা নির্ধারণ করতে, আমরা একটি আউটার কোয়েরি ব্যবহার করব যেখানে আমরা প্রতিক্রিয়াগুলো কীভাবে মূল্যায়ন করতে হয় তা ব্যাখ্যা করব। এই কোয়েরির অংশ হিসেবে এটি ইনার টেবিলের সার্চ টেক্সট
recommended_textফিল্ড এবংcontent(যা খেলনার বিবরণ ফিল্ড) ব্যবহার করে। - সেটা ব্যবহার করে, আমরা এরপর প্রাপ্ত উত্তরগুলোর মান পর্যালোচনা করব।
-
predict_rowতার ফলাফল JSON ফরম্যাটে ফেরত দেয়। সেই JSON থেকে আসল টেক্সট বের করার জন্য "-> 'candidates' -> 0 -> 'content' -> 'parts' -> 0 -> 'text'"কোডটি ব্যবহার করা হয়। ফেরত আসা আসল JSON দেখতে চাইলে আপনি এই কোডটি মুছে ফেলতে পারেন। - অবশেষে, LLM প্রতিক্রিয়া পেতে, আমরা
REGEXP_REPLACE(gemini_validation,'[^a-zA-Z,: ]','','g')ব্যবহার করে এটি বের করি।
SELECT id,
name,
content,
quantity,
price,
image_url,
recommended_text,
REGEXP_REPLACE(gemini_validation, '[^a-zA-Z,: ]', '', 'g') AS gemini_validation
FROM (SELECT id,
name,
content,
quantity,
price,
image_url,
recommended_text,
CAST(ARRAY_AGG(LLM_RESPONSE) AS TEXT) AS gemini_validation
FROM (SELECT id,
name,
content,
quantity,
price,
image_url,
recommended_text,
json_array_elements(google_ml.predict_row(model_id => 'gemini-1.5',
request_body => CONCAT('{ "contents": [ { "role": "user", "parts": [ { "text": "User wants to buy a toy and this is the description of the toy they wish to buy: ', recommended_text, '. Check if the following product items from the inventory are close enough to really, contextually match the user description. Here are the items: ', content, '. Return a ONE-LINE response with 3 values: 1) MATCH: if the 2 contexts are reasonably matching in terms of any of the color or color family specified in the list, approximate style match with any of the styles mentioned in the user search text: This should be a simple YES or NO. Choose NO only if it is completely irrelevant to users search criteria. 2) PERCENTAGE: percentage of match, make sure that this percentage is accurate 3) DIFFERENCE: A clear one-line easy description of the difference between the 2 products. Remember if the user search text says that some attribute should not be there, and the record has it, it should be a NO match. " } ] } ] }')::JSON)) -> 'candidates' -> 0 -> 'content' -> 'parts' -> 0 -> 'text' :: TEXT AS LLM_RESPONSE
FROM (SELECT id,
name,
description AS content,
quantity,
price,
image_url,
'Pink panther standing' AS recommended_text
FROM toys
ORDER BY text_embeddings <=> embedding('text-embedding-005',
'Pink panther standing')::VECTOR
LIMIT 1) AS xyz) AS X
GROUP BY id,
name,
content,
quantity,
price,
image_url,
recommended_text) AS final_matches
-- WHERE REGEXP_REPLACE(gemini_validation, '[^a-zA-Z,: ]', '', 'g') LIKE '%MATCH%:%YES%';
যদিও বিষয়টি এখনও বেশ কঠিন মনে হতে পারে, আশা করি আপনি এখন এটি কিছুটা বুঝতে পারবেন। ফলাফলে বলা থাকে যে ম্যাচটি হয়েছে কি না, ম্যাচের শতাংশ কত এবং রেটিংটির একটি ব্যাখ্যাও দেওয়া থাকে।
লক্ষ্য করুন যে জেমিনি মডেলে স্ট্রিমিং ডিফল্টরূপে চালু থাকে, তাই প্রকৃত প্রতিক্রিয়া একাধিক লাইনে বিভক্ত থাকে:

৯. টয় সার্চকে সার্ভার ছাড়াই ক্লাউডে নিয়ে যান
এই অ্যাপটিকে ওয়েবে নিয়ে যাওয়ার জন্য প্রস্তুত? ক্লাউড রান ফাংশন ব্যবহার করে এই নলেজ ইঞ্জিনটিকে সার্ভারলেস করতে নিচের ধাপগুলো অনুসরণ করুন:
- একটি নতুন ক্লাউড রান ফাংশন তৈরি করতে গুগল ক্লাউড কনসোলের ক্লাউড রান ফাংশনস-এ যান অথবা এই লিঙ্কটি ব্যবহার করুন: https://console.cloud.google.com/functions/add ।
- এনভায়রনমেন্ট হিসেবে " ক্লাউড রান ফাংশন " নির্বাচন করুন। ফাংশনের নাম " get-toys-alloydb " দিন এবং অঞ্চল হিসেবে "us-central1" বেছে নিন। অথেনটিকেশন "Allow unauthenticated invocations"-এ সেট করুন এবং NEXT-এ ক্লিক করুন। রানটাইম হিসেবে জাভা ১৭ এবং সোর্স কোডের জন্য ইনলাইন এডিটর বেছে নিন।
- ডিফল্টরূপে এটি এন্ট্রি পয়েন্ট "
gcfv2.HelloHttpFunction"-এ সেট করে দেবে। আপনার ক্লাউড রান ফাংশনেরHelloHttpFunction.javaএবংpom.xmlএ থাকা প্লেসহোল্ডার কোডটি যথাক্রমে HelloHttpFunction.java এবং pom.xml- এর কোড দিয়ে প্রতিস্থাপন করুন। - জাভা ফাইলে <<YOUR_PROJECT>> প্লেসহোল্ডার এবং AlloyDB কানেকশন ক্রেডেনশিয়ালগুলো আপনার নিজের মান দিয়ে পরিবর্তন করতে মনে রাখবেন। এই কোডল্যাবের শুরুতে আমরা যে AlloyDB ক্রেডেনশিয়ালগুলো ব্যবহার করেছিলাম, সেগুলোই এখানেও ব্যবহার করতে হবে। আপনি যদি ভিন্ন কোনো মান ব্যবহার করে থাকেন, তবে অনুগ্রহ করে জাভা ফাইলে তা পরিবর্তন করে নিন।
- ডিপ্লয়-এ ক্লিক করুন।
একবার স্থাপন করা হয়ে গেলে, ক্লাউড ফাংশনকে আমাদের AlloyDB ডাটাবেস ইনস্ট্যান্স অ্যাক্সেস করার অনুমতি দেওয়ার জন্য, আমরা VPC কানেক্টর তৈরি করব।
গুরুত্বপূর্ণ পদক্ষেপ:
একবার ডেপ্লয়মেন্টের জন্য প্রস্তুত হয়ে গেলে, আপনি Google Cloud Run Functions কনসোলে ফাংশনগুলো দেখতে পাবেন। নতুন তৈরি করা ফাংশনটি ( get-toys-alloydb ) খুঁজুন, সেটির উপর ক্লিক করুন, তারপর EDIT-এ ক্লিক করে নিম্নলিখিত পরিবর্তনগুলো করুন:
- রানটাইম, বিল্ড, সংযোগ এবং নিরাপত্তা সেটিংসে যান
- টাইমআউট বাড়িয়ে ১৮০ সেকেন্ড করুন।
- CONNECTIONS ট্যাবে যান:

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

- VPC কানেক্টরের জন্য একটি নাম দিন এবং নিশ্চিত করুন যে এর অঞ্চলটি আপনার ইনস্ট্যান্সের মতোই। নেটওয়ার্ক ভ্যালুটি ডিফল্ট রাখুন এবং সাবনেট হিসেবে কাস্টম আইপি রেঞ্জ সেট করুন, যেখানে আইপি রেঞ্জ হবে 10.8.0.0 অথবা এর মতো সহজলভ্য কোনো আইপি।
- ‘শো স্কেলিং সেটিংস’ প্রসারিত করুন এবং নিশ্চিত করুন যে আপনার কনফিগারেশনটি হুবহু নিম্নলিখিতভাবে সেট করা আছে:

- CREATE-এ ক্লিক করুন এবং এই কানেক্টরটি এখন বহির্গমন সেটিংসে তালিকাভুক্ত হওয়া উচিত।
- নতুন তৈরি করা সংযোগকারী নির্বাচন করুন
- সমস্ত ট্র্যাফিক এই VPC কানেক্টরের মাধ্যমে রাউট করার বিকল্পটি বেছে নিন।
- NEXT- এ ক্লিক করুন এবং তারপর DEPLOY-তে ক্লিক করুন।
১০. ক্লাউড রান ফাংশনটি পরীক্ষা করুন
আপডেট করা ক্লাউড ফাংশনটি ডেপ্লয় করা হয়ে গেলে, আপনি একটি এন্ডপয়েন্ট তৈরি হতে দেখবেন। সেটি কপি করে নিচের কমান্ডে প্রতিস্থাপন করুন:
বিকল্পভাবে, আপনি নিম্নলিখিত উপায়ে ক্লাউড রান ফাংশনটি পরীক্ষা করতে পারেন:
PROJECT_ID=$(gcloud config get-value project)
curl -X POST <<YOUR_ENDPOINT>> \
-H 'Content-Type: application/json' \
-d '{"search":"I want a standing pink panther toy"}' \
| jq .
এবং ফলাফল:

ব্যাস! AlloyDB ডেটার উপর এমবেডিংস মডেল ব্যবহার করে সিমিলারিটি ভেক্টর সার্চ করা এতটাই সহজ।
১১. ওয়েব অ্যাপ্লিকেশন ক্লায়েন্ট তৈরি করা!
এই অংশে, আমরা এমন একটি ওয়েব অ্যাপ্লিকেশন তৈরি করব যার মাধ্যমে ব্যবহারকারী টেক্সট ও ছবির উপর ভিত্তি করে খেলনা খুঁজে বের করতে পারবে এবং এমনকি নিজের প্রয়োজন অনুযায়ী নতুন খেলনাও তৈরি করতে পারবে। যেহেতু অ্যাপ্লিকেশনটি ইতিমধ্যেই তৈরি করা আছে, আপনি নিচের ধাপগুলো অনুসরণ করে সেটিকে আপনার IDE-তে কপি করে অ্যাপটি চালু করতে পারেন।
- যেহেতু ব্যবহারকারী মিলে যাওয়া খেলনা খুঁজে বের করার জন্য যে ছবি আপলোড করতে পারেন, তা বর্ণনা করতে আমরা জেমিনি ২.০ ফ্ল্যাশ ব্যবহার করি, তাই আমাদের এই অ্যাপ্লিকেশনটির জন্য এপিআই কী (API KEY) সংগ্রহ করতে হবে। তা করার জন্য, https://aistudio.google.com/apikey- এ যান এবং আপনার সক্রিয় গুগল ক্লাউড প্রজেক্টের (যেটিতে আপনি এই অ্যাপ্লিকেশনটি তৈরি করছেন) এপিআই কী (API Key) সংগ্রহ করে কী-টি কোথাও সংরক্ষণ করুন:

- ক্লাউড শেল টার্মিনালে যান
- নিম্নলিখিত কমান্ড ব্যবহার করে রিপোটি ক্লোন করুন:
git clone https://github.com/AbiramiSukumaran/toysearch
cd toysearch
- রিপোটি ক্লোন করা হয়ে গেলে, আপনি আপনার ক্লাউড শেল এডিটর থেকে প্রজেক্টটি অ্যাক্সেস করতে পারবেন।
- আপনাকে ক্লোন করা প্রজেক্ট থেকে 'get-toys-alloydb' এবং 'toolbox-toys' ফোল্ডার দুটি মুছে ফেলতে হবে, কারণ এই দুটি হলো ক্লাউড রান ফাংশন কোড, যা প্রয়োজনে রিপো থেকে রেফারেন্স হিসেবে ব্যবহার করা যেতে পারে।
- web ফোল্ডারে থাকা GenerateToy.java ফাইলে নিম্নলিখিত লাইনটি খুঁজে বের করে মুছে ফেলুন , কারণ allow adult-এর জন্য বিশেষ অনুমতির প্রয়োজন হতে পারে যা কিছু ট্রায়াল বিলিং অ্যাকাউন্টের জন্য উপলব্ধ নাও থাকতে পারে:
paramsMap.put("personGeneration", "allow_adult");
- অ্যাপটি বিল্ড এবং ডিপ্লয় করার আগে নিশ্চিত করুন যে সমস্ত প্রয়োজনীয় এনভায়রনমেন্ট ভেরিয়েবল সেট করা আছে। ক্লাউড শেল টার্মিনালে যান এবং নিম্নলিখিত কমান্ডটি চালান:
PROJECT_ID=$(gcloud config get-value project)
export PROJECT_ID=$PROJECT_ID
export GOOGLE_API_KEY=<YOUR API KEY that you saved>
- অ্যাপটি স্থানীয়ভাবে তৈরি ও চালান:
প্রজেক্ট ডিরেক্টরিতে আছেন তা নিশ্চিত করে, নিম্নলিখিত কমান্ডগুলো চালান:
mvn package
mvn spring-boot:run
- ক্লাউড রানে স্থাপন করুন
gcloud run deploy --source .
১২. জেনারেটিভ এআই-এর বিশদ বিবরণ বোঝা
কোনো পদক্ষেপের প্রয়োজন নেই। শুধু আপনার বোঝার জন্য:
এখন যেহেতু আপনি অ্যাপ্লিকেশনটি ডেপ্লয় করার জন্য প্রস্তুত, তাই আমরা কীভাবে সার্চ (টেক্সট এবং ইমেজ) ও জেনারেশন সম্পন্ন করেছি তা বোঝার জন্য একটু সময় নিন ।
- ব্যবহারকারীর টেক্সট ভিত্তিক ভেক্টর অনুসন্ধান:
'টেক দ্য ভেক্টর সার্চ অ্যাপ্লিকেশন ওয়েব' অংশে আমরা যে ক্লাউড রান ফাংশনগুলো স্থাপন করেছি, সেখানে এই বিষয়টি ইতিমধ্যেই সমাধান করা হয়েছে।
- ছবি আপলোড ভিত্তিক ভেক্টর অনুসন্ধান:
টেক্সট হিসেবে বিষয়বস্তু টাইপ করার পরিবর্তে, ধরা যাক ব্যবহারকারী তার পরিচিত কোনো খেলনার ছবি আপলোড করতে চান, যা দিয়ে তিনি অনুসন্ধান করতে চান। ব্যবহারকারীরা তাদের পছন্দের খেলনার একটি ছবি আপলোড করে এর মাধ্যমে প্রাসঙ্গিক বৈশিষ্ট্যগুলো পেতে পারেন।
আমরা ছবিটি বিশ্লেষণ করতে এবং খেলনাটির রঙ, উপাদান, ধরন ও উদ্দিষ্ট বয়সসীমার মতো প্রাসঙ্গিক তথ্য বের করতে LangChain4j দ্বারা চালিত গুগলের জেমিনি ২.০ ফ্ল্যাশ মডেল ব্যবহার করি।
মাত্র ৫টি ধাপে, আমরা একটি ওপেন সোর্স ফ্রেমওয়ার্ক ব্যবহার করে ব্যবহারকারীর মাল্টিমোডাল ডেটা ইনপুটকে একটি বৃহৎ ল্যাঙ্গুয়েজ মডেল ইনভোকেশনের সাথে সামঞ্জস্যপূর্ণ ফলাফলে পরিণত করেছি। জানুন কীভাবে:
package cloudcode.helloworld.web;
import dev.langchain4j.model.chat.ChatLanguageModel;
import dev.langchain4j.model.googleai.GoogleAiGeminiChatModel;
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;
import java.util.Base64;
import java.util.Optional;
public class GeminiCall {
public String imageToBase64String(byte[] imageBytes) {
String base64Img = Base64.getEncoder().encodeToString(imageBytes);
return base64Img;
}
public String callGemini(String base64ImgWithPrefix) throws Exception {
String searchText = "";
// 1. Remove the prefix
String base64Img = base64ImgWithPrefix.replace("data:image/jpeg;base64,", "");
// 2. Decode base64 to bytes
byte[] imageBytes = Base64.getDecoder().decode(base64Img);
String image = imageToBase64String(imageBytes);
// 3. Get API key from environment variable
String apiKey = Optional.ofNullable(System.getenv("GOOGLE_API_KEY"))
.orElseThrow(() -> new IllegalArgumentException("GOOGLE_API_KEY environment variable not set"));
// 4. Invoke Gemini 2.0
ChatLanguageModel gemini = GoogleAiGeminiChatModel.builder()
.apiKey(apiKey)
.modelName("gemini-2.0-flash-001")
.build();
Response<AiMessage> response = gemini.generate(
UserMessage.from(
ImageContent.from(image, "image/jpeg"),
TextContent.from(
"The picture has a toy in it. Describe the toy in the image in one line. Do not add any prefix or title to your description. Just describe that toy that you see in the image in one line, do not describe the surroundings and other objects around the toy in the image. If you do not see any toy in the image, send response stating that no toy is found in the input image.")));
// 5. Get the text from the response and send it back to the controller
searchText = response.content().text().trim();
System.out.println("searchText inside Geminicall: " + searchText);
return searchText;
}
}
- জেনারেটিভ এআই ব্যবহার করে ব্যবহারকারীর অনুরোধের ভিত্তিতে কীভাবে আমরা ইমাজেন ৩ দিয়ে একটি কাস্টমাইজড খেলনা তৈরি করেছি, তা বুঝুন।
এরপর ইমাজেন ৩ বিশেষভাবে ডিজাইন করা খেলনাটির একটি ছবি তৈরি করে, যা ব্যবহারকারীকে তার সৃষ্টিটি স্পষ্টভাবে দেখতে সাহায্য করে। আমরা মাত্র ৫টি ধাপে এটি যেভাবে করেছি:
// Generate an image using a text prompt using an Imagen model
public String generateImage(String projectId, String location, String prompt)
throws ApiException, IOException {
final String endpoint = String.format("%s-aiplatform.googleapis.com:443", location);
PredictionServiceSettings predictionServiceSettings =
PredictionServiceSettings.newBuilder().setEndpoint(endpoint).build();
// 1. Set up the context and prompt
String context = "Generate a photo-realistic image of a toy described in the following input text from the user. Make sure you adhere to all the little details and requirements mentioned in the prompt. Ensure that the user is only describing a toy. If it is anything unrelated to a toy, politely decline the request stating that the request is inappropriate for the current context. ";
prompt = context + prompt;
// 2. Initialize a client that will be used to send requests. This client only needs to be created
// once, and can be reused for multiple requests.
try (PredictionServiceClient predictionServiceClient =
PredictionServiceClient.create(predictionServiceSettings)) {
// 3. Invoke Imagen 3
final EndpointName endpointName =
EndpointName.ofProjectLocationPublisherModelName(
projectId, location, "google", "imagen-3.0-generate-001"); //"imagegeneration@006"; imagen-3.0-generate-001
Map<String, Object> instancesMap = new HashMap<>();
instancesMap.put("prompt", prompt);
Value instances = mapToValue(instancesMap);
Map<String, Object> paramsMap = new HashMap<>();
paramsMap.put("sampleCount", 1);
paramsMap.put("aspectRatio", "1:1");
paramsMap.put("safetyFilterLevel", "block_few");
paramsMap.put("personGeneration", "allow_adult");
paramsMap.put("guidanceScale", 21);
paramsMap.put("imagenControlScale", 0.95); //Setting imagenControlScale
Value parameters = mapToValue(paramsMap);
// 4. Get prediction response image
PredictResponse predictResponse =
predictionServiceClient.predict(
endpointName, Collections.singletonList(instances), parameters);
// 5. Return the Base64 Encoded String to the controller
for (Value prediction : predictResponse.getPredictionsList()) {
Map<String, Value> fieldsMap = prediction.getStructValue().getFieldsMap();
if (fieldsMap.containsKey("bytesBase64Encoded")) {
bytesBase64EncodedOuput = fieldsMap.get("bytesBase64Encoded").getStringValue();
}
}
return bytesBase64EncodedOuput.toString();
}
}
মূল্য পূর্বাভাস
উপরের পূর্ববর্তী বিভাগে, আমরা আলোচনা করেছি যে Imagen কীভাবে ব্যবহারকারীর নিজের ডিজাইন করা একটি খেলনার ছবি তৈরি করে। ব্যবহারকারীর এটি কেনার সুবিধার জন্য, অ্যাপ্লিকেশনটিকে এর একটি মূল্য নির্ধারণ করতে হবে এবং আমরা এই বিশেষভাবে তৈরি খেলনাটির মূল্য নির্ধারণের জন্য একটি সহজবোধ্য লজিক ব্যবহার করেছি। এই লজিকটি হলো, ব্যবহারকারীর ডিজাইন করা খেলনাটির বর্ণনার সাথে সবচেয়ে বেশি মেলে এমন সেরা ৫টি খেলনার গড় মূল্য ব্যবহার করা।
তৈরি করা খেলনাটির মূল্য পূর্বাভাস এই অ্যাপ্লিকেশনটির একটি গুরুত্বপূর্ণ অংশ এবং এটি তৈরি করতে আমরা একটি এজেন্টিক পদ্ধতি ব্যবহার করেছি। উপস্থাপন করা হচ্ছে ডেটাবেসের জন্য জেন এআই টুলবক্স।
১৩. ডেটাবেসের জন্য জেন এআই টুলবক্স
জেন এআই টুলবক্স ফর ডেটাবেস হলো গুগলের একটি ওপেন সোর্স সার্ভার, যা ডেটাবেসের সাথে কাজ করার জন্য জেন এআই টুল তৈরি করা সহজ করে তোলে। এটি কানেকশন পুলিং, অথেন্টিকেশন এবং আরও অনেক জটিল বিষয় সামলানোর মাধ্যমে আপনাকে আরও সহজে, দ্রুত এবং নিরাপদে টুল তৈরি করতে সক্ষম করে। এটি আপনাকে এমন জেন এআই টুল তৈরি করতে সাহায্য করে, যা আপনার এজেন্টদের ডেটাবেসের ডেটা অ্যাক্সেস করতে দেয়।
আপনার টুল প্রস্তুত করতে এবং আমাদের অ্যাপ্লিকেশনটিকে এজেন্টিক করে তোলার জন্য এই ধাপগুলো অনুসরণ করতে হবে: টুলবক্স কোডল্যাবের লিঙ্ক।
আপনার অ্যাপ্লিকেশনটি এখন এই ডেপ্লয় করা ক্লাউড রান ফাংশন এন্ডপয়েন্টটি ব্যবহার করে, কাস্টম অর্ডার অনুযায়ী তৈরি খেলনার ছবির জন্য জেনারেট করা ইমেজেন ফলাফলের সাথে মূল্যটিও পূরণ করতে পারবে।
১৪. আপনার ওয়েব অ্যাপ্লিকেশনটি পরীক্ষা করুন
এখন যেহেতু আপনার অ্যাপ্লিকেশনের সমস্ত উপাদান তৈরি এবং স্থাপন করা হয়ে গেছে, এটি ক্লাউডে পরিবেশনের জন্য প্রস্তুত। সমস্ত পরিস্থিতিতে আপনার অ্যাপ্লিকেশনটি পরীক্ষা করুন। আপনি কী আশা করতে পারেন, তার একটি ভিডিও লিঙ্ক এখানে দেওয়া হলো:
https://www.youtube.com/shorts/ZMqUAWsghYQ
ল্যান্ডিং পেজটি দেখতে এইরকম:

১৫. পরিষ্কার করুন
এই পোস্টে ব্যবহৃত রিসোর্সগুলোর জন্য আপনার গুগল ক্লাউড অ্যাকাউন্টে চার্জ হওয়া এড়াতে, এই ধাপগুলো অনুসরণ করুন:
- গুগল ক্লাউড কনসোলে, রিসোর্স পরিচালনা (Manage resources) পৃষ্ঠায় যান।
- প্রজেক্ট তালিকা থেকে, আপনি যে প্রজেক্টটি মুছতে চান সেটি নির্বাচন করুন এবং তারপর ডিলিট বোতামে ক্লিক করুন।
- ডায়ালগ বক্সে প্রজেক্ট আইডি টাইপ করুন এবং তারপর প্রজেক্টটি মুছে ফেলার জন্য 'শাট ডাউন'-এ ক্লিক করুন।
১৬. অভিনন্দন
অভিনন্দন! আপনি শক্তিশালী ইন্টিগ্রেশন তৈরির জন্য ওপেন সোর্স লাইব্রেরি ব্যবহার করে AlloyDB, pgvector, Imagen এবং Gemini 2.0-এর সাহায্যে সফলভাবে একটি Toystore কনটেক্সচুয়াল সার্চ ও জেনারেশন সম্পন্ন করেছেন। AlloyDB , Vertex AI এবং Vector Search- এর সক্ষমতা একত্রিত করার মাধ্যমে, আমরা কনটেক্সচুয়াল ও ভেক্টর সার্চকে সহজলভ্য, কার্যকর এবং প্রকৃত অর্থেই অর্থবহ করে তোলার ক্ষেত্রে এক বিশাল পদক্ষেপ এগিয়েছি।