Cloud veritabanları, sunucusuz çalışma ortamları ve açık kaynak entegrasyonlarına sahip oyuncak mağazası arama uygulaması

1. Genel Bakış

Mükemmel hediyeyi kolayca bulabileceğiniz bir oyuncak mağazasına sanal olarak veya bizzat girdiğinizi düşünün. Aradığınız şeyi açıklayabilir, bir oyuncağın resmini yükleyebilir veya kendi tasarımınızı oluşturabilirsiniz. Mağaza, ihtiyaçlarınızı anında anlayarak size özel bir deneyim sunar. Bu, fütüristik bir fantezi değil; yapay zeka, bulut teknolojisi ve kişiselleştirilmiş e-ticaret vizyonuyla desteklenen bir gerçekliktir.

Zorluk: Hayalinizdeki mükemmel ürünü bulmak zor olabilir. Genel arama terimleri, anahtar kelimeler ve yaklaşık aramalar genellikle yetersiz kalır. Sonsuz sayıda sayfaya göz atmak sıkıcı olabilir. Hayal ettiğiniz şey ile mevcut olan arasındaki uyumsuzluk ise hayal kırıklığına yol açabilir.

Çözüm: Demo uygulaması, bu zorluğun üstesinden gelmek için yapay zekanın gücünden yararlanarak bağlamsal arama ve arama bağlamına uygun ürünlerin özel olarak oluşturulmasıyla gerçekten kişiselleştirilmiş ve sorunsuz bir deneyim sunar.

Ne oluşturacaksınız?

Bu laboratuvar kapsamında şunları yapacaksınız:

  1. AlloyDB örneği oluşturma ve Oyuncak Veri Kümesi'ni yükleme
  2. AlloyDB'de pgvector ve üretken yapay zeka modeli uzantılarını etkinleştirme
  3. Ürün açıklamasından yerleştirmeler oluşturma ve kullanıcı arama metni için gerçek zamanlı kosinüs benzerliği araması yapma
  4. Kullanıcının bağlamsal oyuncak araması için yüklediği resmi açıklamak üzere Gemini 2.0 Flash'i çağırma
  5. Kullanıcının ilgi alanına göre özel bir oyuncak oluşturmak için Imagen 3'ü çağırma
  6. Özel olarak oluşturulan oyuncağın fiyat ayrıntıları için Veritabanları için Üretken Yapay Zeka Araç Kutusu kullanılarak oluşturulan bir fiyat tahmini aracını çağırma
  7. Çözümü sunucusuz Cloud Run Functions'ta dağıtma

Şartlar

  • Chrome veya Firefox gibi bir tarayıcı
  • Faturalandırmanın etkin olduğu bir Google Cloud projesi.

2. Mimari

Veri akışı: Verilerin sistemimizde nasıl hareket ettiğine daha yakından bakalım:

  1. Yapay Zeka Destekli RAG (Almayla Artırılmış Üretim) ile Bağlama Duyarlı Arama

Şöyle düşünün: Sistem, yalnızca "kırmızı araba" araması yapmak yerine aşağıdakileri anlar:

"3 yaşındaki bir çocuğa uygun küçük bir araç."

Temel olarak AlloyDB: Açıklamalar, resim URL'leri ve diğer alakalı özellikler dahil olmak üzere oyuncak verilerimizi depolamak için Google Cloud'un tümüyle yönetilen, PostgreSQL uyumlu veritabanı AlloyDB'yi kullanıyoruz.

Semantik Arama için pgvector: PostgreSQL uzantısı olan pgvector, hem oyuncak açıklamalarının hem de kullanıcı arama sorgularının vektör yerleştirmelerini depolamamıza olanak tanır. Bu sayede semantik arama etkinleştirilir. Yani sistem, yalnızca tam anahtar kelimeleri değil, kelimelerin anlamını da anlar.

Alaka Düzeyi İçin Kosinüs Benzerliği: En alakalı sonuçları göstermek için kullanıcının arama vektörü ile oyuncak açıklaması vektörleri arasındaki anlamsal benzerliği ölçmek üzere kosinüs benzerliğini kullanırız.

Hız ve Doğruluk İçin ScaNN Dizini: Özellikle oyuncak envanterimiz büyüdükçe hızlı ve doğru sonuçlar elde etmek için ScaNN (Ölçeklenebilir En Yakın Komşular) dizinini entegre ediyoruz. Bu, vektör arama verimliliğimizi ve hatırlama oranımızı önemli ölçüde artırır.

  1. Gemini 2.0 Flash ile görüntüye dayalı arama ve anlama

Kullanıcının bağlamı metin olarak yazmak yerine, arama yapmak istediği tanıdık bir oyuncağın resmini yüklemek istediğini varsayalım. Kullanıcılar beğendikleri bir oyuncağın resmini yükleyebilir ve bu resimle ilgili özellikleri alabilir. Resmi analiz etmek ve oyuncağın rengi, malzemesi, türü ve amaçlanan yaş grubu gibi alakalı bağlamı çıkarmak için LangChain4j kullanılarak çağrılan Google'ın Gemini 2.0 Flash modelinden yararlanırız.

  1. Building Your Dream Toy Customized with Generative AI: Imagen 3

Asıl sihir, kullanıcılar kendi oyuncaklarını oluşturmaya karar verdiğinde ortaya çıkar. Imagen 3'ü kullanarak basit metin istemleriyle hayallerindeki oyuncağı tarif etmelerine olanak tanıyoruz. "Mor kanatlı ve güler yüzlü bir peluş ejderha istiyorum" dediğinizi ve bu ejderhanın ekranınızda canlandığını hayal edin. Ardından Imagen 3, özel tasarımlı oyuncağın resmini oluşturarak kullanıcının kendi tasarımını net bir şekilde görselleştirmesini sağlar.

  1. Ajanlar ve Veritabanları İçin Üretken Yapay Zeka Araç Kutusu Tarafından Desteklenen Fiyat Tahmini

Özel tasarımlı oyuncağın üretim maliyetini tahmin eden bir fiyat tahmini özelliği uyguladık. Bu özellik, gelişmiş bir fiyat hesaplama aracı içeren bir temsilci tarafından desteklenir.

Veritabanları için Üretken Yapay Zeka Araç Kutusu: Bu aracı, Google'ın yeni açık kaynaklı aracı olan Veritabanları için Üretken Yapay Zeka Araç Kutusu'nu kullanarak veritabanımıza sorunsuz bir şekilde entegre ettik. Bu sayede, doğru bir fiyat tahmini sunmak için malzeme maliyetleri, üretim süreçleri ve diğer ilgili faktörler hakkında gerçek zamanlı verilere erişebilir. Bu konu hakkında daha fazla bilgiye buradan ulaşabilirsiniz.

  1. Kolaylaştırılmış geliştirme ve sunucusuz dağıtım için Java Spring Boot, Gemini Code Assist ve Cloud Run

Uygulamanın tamamı, sağlam ve ölçeklenebilir bir çerçeve olan Java Spring Boot kullanılarak oluşturulmuştur. Geliştirme sürecinde, özellikle ön uç geliştirme için Gemini Code Assist'ten yararlandık. Bu sayede geliştirme döngüsünü önemli ölçüde hızlandırdık ve kod kalitesini artırdık. Uygulamanın tamamını dağıtmak için Cloud Run'ı, veritabanını ve agent işlevlerini bağımsız uç noktalar olarak dağıtmak için ise Cloud Run Functions'ı kullandık.

3. Başlamadan önce

Proje oluşturma

  1. Google Cloud Console'daki proje seçici sayfasında bir Google Cloud projesi seçin veya oluşturun.
  2. Cloud projeniz için faturalandırmanın etkinleştirildiğinden emin olun. Bir projede faturalandırmanın etkin olup olmadığını kontrol etmeyi öğrenin .
  3. bq'nun önceden yüklendiği, Google Cloud'da çalışan bir komut satırı ortamı olan Cloud Shell'i kullanacaksınız. Google Cloud Console'un üst kısmından Cloud Shell'i etkinleştir'i tıklayın.

Cloud Shell'i etkinleştir düğmesinin resmi

  1. Cloud Shell'e bağlandıktan sonra aşağıdaki komutu kullanarak kimliğinizin doğrulandığını ve projenin proje kimliğinize ayarlandığını kontrol edin:
gcloud auth list
  1. gcloud komutunun projeniz hakkında bilgi sahibi olduğunu onaylamak için Cloud Shell'de aşağıdaki komutu çalıştırın.
gcloud config list project
  1. Projeniz ayarlanmamışsa ayarlamak için aşağıdaki komutu kullanın:
gcloud config set project <YOUR_PROJECT_ID>
  1. Cloud Shell terminalinizde aşağıdaki komutları tek tek çalıştırarak gerekli API'leri etkinleştirin:

Aşağıdaki komutları çalıştırmak için tek bir komut da vardır ancak deneme hesabı kullanıcısıysanız bunları toplu olarak etkinleştirmeye çalışırken kota sorunlarıyla karşılaşabilirsiniz. Bu nedenle komutlar her satırda bir tane olacak şekilde ayrılır.

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 komutuna alternatif olarak, her ürünü arayarak veya bu bağlantıyı kullanarak konsolu kullanabilirsiniz.

Herhangi bir API atlanırsa uygulama sırasında istediğiniz zaman etkinleştirebilirsiniz.

gcloud komutları ve kullanımı için belgelere bakın.

4. Veritabanı kurulumu

Bu laboratuvarda, oyuncak mağazası verilerini tutmak için veritabanı olarak AlloyDB'yi kullanacağız. Veritabanları ve günlükler gibi tüm kaynakları tutmak için kümeler kullanılır. Her kümede, verilere erişim noktası sağlayan bir birincil örnek bulunur. Tablolar gerçek verileri içerir.

E-ticaret veri kümesinin yükleneceği bir AlloyDB kümesi, örneği ve tablosu oluşturalım.

Küme ve örnek oluşturma

  1. Cloud Console'da AlloyDB sayfasına gidin. Cloud Console'daki çoğu sayfayı bulmanın kolay bir yolu, konsolun arama çubuğunu kullanarak arama yapmaktır.
  2. Bu sayfada KÜME OLUŞTUR'u seçin:

f76ff480c8c889aa.png

  1. Aşağıdaki gibi bir ekran görürsünüz. Aşağıdaki değerlerle bir küme ve örnek oluşturun (Uygulama kodunu depodan klonluyorsanız değerlerin eşleştiğinden emin olun):
  • küme kimliği: "vector-cluster"
  • password: "alloydb"
  • PostgreSQL 15 ile uyumlu
  • Bölge: "us-central1"
  • Networking: "default"

538dba58908162fb.png

  1. Varsayılan ağı seçtiğinizde aşağıdaki gibi bir ekran görürsünüz.

BAĞLANTIYI AYARLA'yı seçin.
7939bbb6802a91bf.png

  1. Buradan "Otomatik olarak atanmış bir IP aralığı kullan"ı seçip Devam'ı tıklayın. Bilgileri inceledikten sonra BAĞLANTI OLUŞTUR'u seçin. 768ff5210e79676f.png
  2. Ağınız kurulduktan sonra kümenizi oluşturmaya devam edebilirsiniz. Aşağıda gösterildiği gibi küme kurulumunu tamamlamak için CREATE CLUSTER'ı (KÜME OLUŞTUR) tıklayın:

e06623e55195e16e.png

Örnek kimliğini değiştirdiğinizden emin olun.

vector-instance

Değiştiremiyorsanız gelecekteki tüm referanslarda örnek kimliğini değiştirmeyi unutmayın.

Küme oluşturma işleminin yaklaşık 10 dakika süreceğini unutmayın. İşlem başarılı olduğunda, yeni oluşturduğunuz kümenizin genel görünümünü gösteren bir ekran görürsünüz.

5. Veri kullanımı

Şimdi de mağazayla ilgili verilerin bulunduğu bir tablo ekleme zamanı. AlloyDB'ye gidin, birincil kümeyi ve ardından AlloyDB Studio'yu seçin:

847e35f1bf8a8bd8.png

Örneğinizin oluşturulmasının tamamlanmasını beklemeniz gerekebilir. Bu işlem tamamlandıktan sonra, kümeyi oluştururken oluşturduğunuz kimlik bilgilerini kullanarak AlloyDB'de oturum açın. PostgreSQL'de kimlik doğrulaması yapmak için aşağıdaki verileri kullanın:

  • Kullanıcı adı : "postgres"
  • Veritabanı : "postgres"
  • Şifre : "alloydb"

AlloyDB Studio'da kimliğinizi başarıyla doğruladıktan sonra SQL komutları Düzenleyici'ye girilir. Son pencerenin sağındaki artı işaretini kullanarak birden fazla Düzenleyici penceresi ekleyebilirsiniz.

91a86d9469d499c4.png

AlloyDB için komutları düzenleyici pencerelerine girerken gerektiğinde Çalıştır, Biçimlendir ve Temizle seçeneklerini kullanacaksınız.

Uzantıları etkinleştirme

Bu uygulamayı oluşturmak için pgvector ve google_ml_integration uzantılarını kullanacağız. pgvector uzantısı, vektör yerleştirmelerini depolamanıza ve aramanıza olanak tanır. google_ml_integration uzantısı, SQL'de tahmin almak için Vertex AI tahmin uç noktalarına erişmek üzere kullandığınız işlevleri sağlar. Aşağıdaki DDL'leri çalıştırarak bu uzantıları etkinleştirin:

CREATE EXTENSION IF NOT EXISTS google_ml_integration CASCADE;
CREATE EXTENSION IF NOT EXISTS vector;

Veritabanınızda etkinleştirilen uzantıları kontrol etmek istiyorsanız şu SQL komutunu çalıştırın:

select extname, extversion from pg_extension;

Tablo oluşturma

Aşağıdaki DDL ifadesini kullanarak bir tablo oluşturun:

CREATE TABLE toys ( id VARCHAR(25), name VARCHAR(25), description VARCHAR(20000), quantity INT, price FLOAT, image_url VARCHAR(200), text_embeddings vector(768)) ;

Yukarıdaki komut başarıyla yürütüldüğünde tablonun veritabanında görüntülenebilmesi gerekir.

Veri alma

Bu laboratuvar için SQL dosyasında yaklaşık 72 kayıttan oluşan test verileri bulunmaktadır. id, name, description, quantity, price, image_url alanlarını içerir. Diğer alanlar laboratuvarın ilerleyen bölümlerinde doldurulacaktır.

Yalnızca ilk 5 satırı/ekleme ifadesini kopyalayıp boş bir düzenleyici sekmesine yapıştırın ve ÇALIŞTIR'ı seçin. Deneme faturalandırma hesabında DEĞİLSENİZ muhtemelen tüm ekleme ifadelerini kopyalayıp çalıştırabilirsiniz.

Tablo içeriklerini görmek için Gezgin bölümünü, giysiler adlı tabloyu görene kadar genişletin. Tabloya sorgu gönderme seçeneğini görmek için üç nokta simgesini (⋮) seçin. SELECT ifadesi yeni bir Düzenleyici sekmesinde açılır.

cfaa52b717f9aaed.png

İzin Ver

embedding işlevinde postgres kullanıcısına yürütme hakları vermek için aşağıdaki ifadeyi çalıştırın:

GRANT EXECUTE ON FUNCTION embedding TO postgres;

AlloyDB hizmet hesabına Vertex AI Kullanıcısı ROLÜ'nü verme

Cloud Shell terminaline gidip aşağıdaki komutu verin:

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"

6. Bağlam için yerleştirmeler oluşturma

Bilgisayarların sayıları işlemesi, metinleri işlemesinden çok daha kolaydır. Yerleştirme sistemi, metni nasıl ifade edildiğine veya hangi dili kullandığına bakılmaksızın metni temsil etmesi gereken bir dizi kayan nokta sayısına dönüştürür.

Deniz kenarında bir yeri tarif etmeyi deneyin. Örneğin, "denize sıfır", "sahilde", "odanızdan okyanusa yürüyerek gidebilirsiniz", "sur la mer", "на берегу океана" gibi ifadeler kullanılabilir. Bu terimlerin hepsi farklı görünse de anlamsal anlamları veya makine öğrenimi terminolojisindeki yerleştirmeleri birbirine çok yakın olmalıdır.

Veriler ve bağlam hazır olduğuna göre, ürün açıklamasının yerleştirmelerini embedding alanındaki tabloya eklemek için SQL'i çalıştıracağız. Kullanabileceğiniz çeşitli yerleştirme modelleri vardır. Vertex AI'dan text-embedding-005 kullanıyoruz. Proje boyunca aynı yerleştirme modelini kullandığınızdan emin olun.

Not: Bir süre önce oluşturulmuş mevcut bir Google Cloud projesini kullanıyorsanız textembedding-gecko gibi metin yerleştirme modelinin eski sürümlerini kullanmaya devam etmeniz gerekebilir.

AlloyDB Studio sekmesine dönün ve aşağıdaki DML'yi yazın:

UPDATE toys set text_embeddings = embedding( 'text-embedding-005', description);

Bazı yerleştirmeleri görmek için toys tablosuna tekrar bakın. Değişiklikleri görmek için SELECT ifadesini yeniden çalıştırdığınızdan emin olun.

SELECT id, name, description, price, quantity, image_url, text_embeddings FROM toys;

Bu işlem, oyuncak açıklaması için aşağıdaki gibi bir kayan nokta dizisi olan yerleştirme vektörünü döndürmelidir:

7d32f7cd7204e1f3.png

Not: Ücretsiz katman kapsamında yeni oluşturulan Google Cloud projeleri, saniye başına yerleştirme modellerine izin verilen yerleştirme isteği sayısı konusunda kota sorunlarıyla karşılaşabilir. Yerleştirme oluştururken kimlik için bir filtre sorgusu kullanmanızı ve ardından 1-5 kayıt seçmenizi öneririz.

7. Vektör araması yapma

Tablo, veriler ve yerleştirmeler hazır olduğuna göre artık kullanıcı arama metni için anlık vektör aramasını gerçekleştirebiliriz.

Kullanıcının şu soruyu sorduğunu varsayalım:

"I want a white plush teddy bear toy with a floral pattern."

Aşağıdaki sorguyu çalıştırarak bununla ilgili eşleşmeleri bulabilirsiniz:

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;

Bu sorguyu ayrıntılı olarak inceleyelim:

Bu sorguda,

  1. Kullanıcının arama metni: "I want a white plush teddy bear toy with a floral pattern."
  2. embedding() yönteminde text-embedding-005 modeli kullanılarak yerleştirmelere dönüştürülüyor. Bu adım, son adımda yerleştirme işlevini tablodaki tüm öğelere uyguladığımız için tanıdık gelecektir.
  3. "<=>", KOSİNÜS BENZERLİĞİ uzaklık yönteminin kullanımını gösterir. Kullanılabilen tüm benzerlik ölçülerini pgvector dokümanlarında bulabilirsiniz.
  4. Yerleştirme yönteminin sonucunu, veritabanında depolanan vektörlerle uyumlu hale getirmek için vektör türüne dönüştürüyoruz.
  5. LIMIT 5, arama metni için en yakın 5 komşuyu çıkarmak istediğimizi gösterir.

Sonuç şu şekilde görünür:

fa7f0fc3a4c68804.png

Sonuçlarınızda da görebileceğiniz gibi, eşleşmeler arama metnine oldukça yakındır. Sonuçların nasıl değiştiğini görmek için metni değiştirmeyi deneyin.

Önemli Not:

Şimdi de ScaNN dizinini kullanarak bu vektör arama sonucunun performansını (sorgu süresi), verimliliğini ve hatırlama oranını artırmak istediğimizi varsayalım. Sonuçlardaki indeksli ve indekssiz farkı karşılaştırmak için lütfen bu blogdaki adımları okuyun.

İsteğe bağlı adım: ScaNN diziniyle verimliliği ve geri çağırmayı iyileştirme

Kayıt sayınız 100'den azsa bu adımı atlayın.

Kolaylık sağlamak için dizin oluşturma adımlarını burada listeliyoruz:

  1. Küme, örnek, bağlam ve yerleştirmeler zaten oluşturulduğu için ScaNN uzantısını aşağıdaki ifadeyi kullanarak yüklememiz yeterli:
CREATE EXTENSION IF NOT EXISTS alloydb_scann;
  1. Ardından dizini (ScaNN) oluşturacağız:
CREATE INDEX toysearch_index ON toys
USING scann (text_embeddings cosine)
WITH (num_leaves=9);

Yukarıdaki DDL'de apparel_index, dizinin adıdır.

"toys" (oyuncaklar) tablom

"scann" dizin yöntemidir

"embedding", tablodaki dizine eklemek istediğim sütun

"cosine", dizinle kullanmak istediğim mesafe yöntemidir.

"8", bu dizine uygulanacak bölüm sayısıdır. 1 ile 1048576 arasında herhangi bir değere ayarlayın. Bu değere nasıl karar vereceğiniz hakkında daha fazla bilgi için ScaNN dizinini ayarlama başlıklı makaleyi inceleyin.

ScaNN deposunda önerildiği gibi veri noktalarının sayısının KAREKÖKÜNÜ kullandım (Bölümlendirme sırasında num_leaves, veri noktalarının sayısının yaklaşık olarak karekökü olmalıdır).

  1. Dizinin aşağıdaki sorgu kullanılarak oluşturulup oluşturulmadığını kontrol edin:
SELECT * FROM pg_stat_ann_indexes;
  1. Dizini kullanmadan kullandığımız sorguyla Vector Search'ü gerçekleştirin:
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;

Yukarıdaki sorgu, laboratuvarda 8. adımda kullandığımız sorguyla aynıdır. Ancak artık alan dizine eklenmiş durumda.

  1. Dizinle ve dizin olmadan (dizini bırakarak) basit bir arama sorgusuyla test edin:

Bu kullanım alanında yalnızca 72 kayıt olduğundan dizin gerçekten etkili olmaz. Başka bir kullanım alanında yapılan testin sonuçları aşağıdaki gibidir:

INDEXED yerleştirme verilerinde aynı Vector Search sorgusu kullanıldığında kaliteli arama sonuçları ve verimlilik elde edilir. Dizinle birlikte verimlilik büyük ölçüde artar (yürütme süresi açısından: ScaNN olmadan 10,37 ms ve ScaNN ile 0,87 ms). Bu konuyla ilgili daha fazla bilgi için lütfen bu blogu inceleyin.

8. LLM ile Eşleşme Doğrulama

Devam etmeden ve bir uygulamaya en iyi eşleşmeleri döndüren bir hizmet oluşturmadan önce, bu olası yanıtların gerçekten alakalı olup olmadığını ve kullanıcıyla paylaşmanın güvenli olup olmadığını doğrulamak için üretken yapay zeka modelini kullanalım.

Örneğin Gemini için ayarlandığından emin olma

Öncelikle Google ML entegrasyonunun kümeniz ve örneğiniz için etkinleştirilmiş olup olmadığını kontrol edin. AlloyDB Studio'da aşağıdaki komutu verin:

show google_ml_integration.enable_model_support;

Değer "on" olarak gösteriliyorsa sonraki 2 adımı atlayabilir ve doğrudan AlloyDB ile Vertex AI Model entegrasyonunu ayarlamaya gidebilirsiniz.

  1. AlloyDB kümenizin birincil örneğine gidin ve BİRİNCİL ÖRNEĞİ DÜZENLE'yi tıklayın.

cb76b934ba3735bd.png

  1. Gelişmiş Yapılandırma Seçenekleri'ndeki Flags (Deneysel Özellikler) bölümüne gidin. ve google_ml_integration.enable_model_support flag seçeneğinin aşağıda gösterildiği gibi "on" olarak ayarlandığından emin olun:

6a59351fcd2a9d35.png

"Açık" olarak ayarlanmamışsa "Açık" olarak ayarlayın ve UPDATE INSTANCE (Örneği güncelle) düğmesini tıklayın. Bu adım birkaç dakika sürer.

AlloyDB ve Vertex AI Model entegrasyonu

Artık AlloyDB Studio'ya bağlanabilir ve belirtilen yerlerde proje kimliğinizi kullanarak AlloyDB'den Gemini model erişimini ayarlamak için aşağıdaki DML ifadesini çalıştırabilirsiniz. Komutu çalıştırmadan önce söz dizimi hatası konusunda uyarılabilirsiniz ancak komut sorunsuz bir şekilde çalışır.

İlk olarak, aşağıdaki şekilde gösterildiği gibi Gemini 1.5 model bağlantısını oluşturuyoruz. Aşağıdaki komutta $PROJECT_ID yerine Google Cloud proje kimliğinizi yazmayı unutmayın.

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'da aşağıdaki komutu kullanarak erişim için yapılandırılmış modelleri kontrol edebilirsiniz:

select model_id,model_type from google_ml.model_info_view;        

Son olarak, Google Vertex AI modelleri aracılığıyla tahmin yürütmek için veritabanı kullanıcılarına ml_predict_row işlevini yürütme izni vermemiz gerekir. Aşağıdaki komutu çalıştırın:

GRANT EXECUTE ON FUNCTION ml_predict_row to postgres;

Not: Mevcut bir Google Cloud projesi ve bir süre önce oluşturulmuş mevcut bir AlloyDB kümesi/örneği kullanıyorsanız gemini-1.5 modeline yapılan eski referansları bırakmanız ve yukarıdaki CALL ifadesiyle yeniden oluşturmanız gerekebilir. Ayrıca, gemini-1.5'in sonraki çağrılarında sorun yaşarsanız ml_predict_row işlevinde tekrar yürütme izni vermeniz gerekebilir.

Yanıtları değerlendirme

Sorgudan gelen yanıtların makul olmasını sağlamak için bir sonraki bölümde tek bir büyük sorgu kullanacağız ancak bu sorguyu anlamak zor olabilir. Şimdi parçalara bakacağız ve birkaç dakika içinde nasıl bir araya geldiklerini göreceğiz.

  1. Öncelikle, kullanıcı sorgusuna en yakın 10 eşleşmeyi almak için veritabanına bir istek göndeririz.
  2. Yanıtların geçerliliğini belirlemek için yanıtların nasıl değerlendirileceğini açıkladığımız bir dış sorgu kullanırız. Sorgunun bir parçası olarak, arama metni olan recommended_text alanını ve iç tablonun content alanını (oyuncak açıklaması alanı) kullanır.
  3. Bunu kullanarak döndürülen yanıtların "kalitesini" inceleyeceğiz.
  4. predict_row, sonucu JSON biçiminde döndürür. Bu JSON'dan gerçek metni çıkarmak için "-> 'candidates' -> 0 -> 'content' -> 'parts' -> 0 -> 'text'" kodu kullanılır. Döndürülen gerçek JSON'u görmek için bu kodu kaldırabilirsiniz.
  5. Son olarak, LLM yanıtını almak için REGEXP_REPLACE(gemini_validation, '[^a-zA-Z,: ]', '', 'g') kullanarak çıkarırız.
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%';

Bu durum hâlâ gözünüzü korkutuyor olabilir ancak umarız artık biraz daha anlamlı geliyordur. Sonuçlar, eşleşme olup olmadığını, eşleşme yüzdesini ve puanla ilgili bazı açıklamaları gösterir.

Gemini modelinde varsayılan olarak akışın etkin olduğunu unutmayın. Bu nedenle, gerçek yanıt birden fazla satıra yayılır:

c2b006aeb3f3a2fc.png

9. Oyuncak Arama uygulamasını sunucusuz olarak buluta taşıma

Bu uygulamayı web'e taşımaya hazır mısınız? Bu Bilgi Motorunu Cloud Run Functions ile Sunucusuz hale getirmek için aşağıdaki adımları uygulayın:

  1. Yeni bir Cloud Run işlevi OLUŞTURMAK için Google Cloud Console'da Cloud Run Functions'a gidin veya şu bağlantıyı kullanın: https://console.cloud.google.com/functions/add.
  2. Ortam olarak "Cloud Run işlevi"ni seçin. İşlev adı olarak "get-toys-alloydb" girin ve bölge olarak "us-central1"i seçin. Kimlik Doğrulama'yı "Kimliği doğrulanmayan çağrılara izin ver" olarak ayarlayın ve SONRAKİ'yi tıklayın. Çalışma zamanı olarak Java 17'yi, kaynak kodu için ise Satır İçi Düzenleyici'yi seçin.
  3. Varsayılan olarak giriş noktası "gcfv2.HelloHttpFunction" olarak ayarlanır. Cloud Run işlevinizin HelloHttpFunction.java ve pom.xml bölümlerindeki yer tutucu kodu sırasıyla HelloHttpFunction.java ve pom.xml dosyalarındaki kodla değiştirin.
  4. Java dosyasındaki <<YOUR_PROJECT>> yer tutucusunu ve AlloyDB bağlantı kimlik bilgilerini kendi değerlerinizle değiştirmeyi unutmayın. AlloyDB kimlik bilgileri, bu codelab'in başında kullandığımız kimlik bilgileridir. Farklı değerler kullandıysanız lütfen Java dosyasında bunları değiştirin.
  5. Dağıt'ı tıklayın.

Dağıtım tamamlandıktan sonra Cloud Functions işlevinin AlloyDB veritabanı örneğimize erişmesine izin vermek için VPC bağlayıcısını oluşturacağız.

ÖNEMLİ ADIM:

Dağıtıma hazır olduğunuzda işlevleri Google Cloud Run Functions Console'da görebilirsiniz. Yeni oluşturulan işlevi (get-toys-alloydb) arayın, işlevi tıklayın, ardından DÜZENLE'yi tıklayıp aşağıdakileri değiştirin:

  1. Çalışma zamanı, derleme, bağlantılar ve güvenlik ayarlarına gitme
  2. Zaman aşımını 180 saniyeye çıkarın.
  3. BAĞLANTILAR sekmesine gidin:

4e83ec8a339cda08.png

  1. Giriş ayarları bölümünde "Tüm trafiğe izin ver" seçeneğinin belirlendiğinden emin olun.
  2. Çıkış ayarları bölümünde, Ağ açılır listesini tıklayın ve "Yeni VPC bağlayıcı ekle" seçeneğini belirleyin. Ardından, açılan iletişim kutusunda gördüğünüz talimatları uygulayın:

8126ec78c343f199.png

  1. VPC bağlayıcısı için bir ad girin ve bölgenin örneğinizle aynı olduğundan emin olun. Ağ değerini varsayılan olarak bırakın ve alt ağı, 10.8.0.0 IP aralığına sahip özel IP aralığı olarak ayarlayın veya benzer bir aralık kullanın.
  2. ÖLÇEKLENDİRME AYARLARINI GÖSTER'i genişletin ve yapılandırmanın tam olarak aşağıdaki gibi ayarlandığından emin olun:

7baf980463a86a5c.png

  1. OLUŞTUR'u tıkladığınızda bu bağlayıcı artık çıkış ayarlarında listelenir.
  2. Yeni oluşturulan bağlayıcıyı seçin
  3. Tüm trafiğin bu VPC bağlayıcısı üzerinden yönlendirilmesini tercih edin.
  4. SONRAKİ'yi ve ardından DAĞIT'ı tıklayın.

10. Cloud Run işlevini test etme

Güncellenen Cloud Functions işlevi dağıtıldıktan sonra oluşturulan uç noktayı görürsünüz. Bu değeri kopyalayıp aşağıdaki komutta değiştirin:

Alternatif olarak, Cloud Run işlevini aşağıdaki şekilde test edebilirsiniz:

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 .

Sonuç:

23861e9091565a64.png

İşte bu kadar. AlloyDB verilerinde yerleştirme modelini kullanarak benzerlik vektörü araması yapmak bu kadar basittir.

11. Web Uygulaması İstemcisini Oluşturma

Bu bölümde, kullanıcının etkileşimde bulunabileceği ve metin, resim gibi girdilere göre eşleşen oyuncakları bulabileceği, hatta ihtiyaçlarına göre yeni oyuncaklar oluşturabileceği bir web uygulaması oluşturacağız. Uygulama zaten oluşturulduğundan, IDE'nize kopyalamak ve uygulamayı çalıştırmak için aşağıdaki adımları uygulayabilirsiniz.

  1. Kullanıcının, eşleşen oyuncakları bulmak için yükleyebileceği resmi açıklamak üzere Gemini 2.0 Flash'i kullandığımızdan bu uygulama için API anahtarını almamız gerekir. Bunu yapmak için https://aistudio.google.com/apikey adresine gidin ve bu uygulamayı uyguladığınız etkin Google Cloud projenizin API anahtarını alıp bir yere kaydedin:

ae2db169e6a94e4a.png

  1. Cloud Shell Terminal'e gitme
  2. Aşağıdaki komutla depoyu klonlayın:
git clone https://github.com/AbiramiSukumaran/toysearch

cd toysearch
  1. Depo klonlandıktan sonra projeye Cloud Shell Düzenleyici'den erişebilirsiniz.
  2. Klonlanan projeden "get-toys-alloydb" ve "toolbox-toys" klasörlerini silmeniz gerekir. Bu iki klasör, ihtiyacınız olduğunda depodan referans verilebilecek Cloud Run İşlevleri kodudur.
  3. Web klasöründe GenerateToy.java'ya gidin ve şu satırı bulun. Yetişkinlere izin verme, bazı deneme faturalandırma hesaplarında kullanılamayabilecek özel izinler gerektirebileceğinden bu satırı kaldırın:

paramsMap.put("personGeneration", "allow_adult");

  1. Uygulamayı oluşturup dağıtmadan önce gerekli tüm ortam değişkenlerinin ayarlandığından emin olun. Cloud Shell Terminal'e gidin ve aşağıdakileri yürütün:
PROJECT_ID=$(gcloud config get-value project)

export PROJECT_ID=$PROJECT_ID

export GOOGLE_API_KEY=<YOUR API KEY that you saved>
  1. Uygulamayı yerel olarak derleyip çalıştırma:

Proje dizininde olduğunuzdan emin olduktan sonra aşağıdaki komutları çalıştırın:

mvn package

mvn spring-boot:run 
  1. Cloud Run'a dağıtma
gcloud run deploy --source .

12. Üretken yapay zeka ayrıntılarını anlama

Herhangi bir işlem yapmanız gerekmez. Bilginize:

Dağıtılacak uygulamayı edindiğinize göre, biraz zaman ayırarak arama (metin ve resim) ve üretme işlemlerini nasıl gerçekleştirdiğimizi anlayın.

  1. Kullanıcı metnine dayalı vektör arama:

Bu konu, "Vektör Arama uygulaması web'ini kullanma" bölümünde dağıttığımız Cloud Run işlevlerinde ele alınmıştır.

  1. Resim yüklemeye dayalı vektör arama:

Kullanıcının bağlamı metin olarak yazmak yerine, arama yapmak istediği tanıdık bir oyuncağın resmini yüklemek istediğini varsayalım. Kullanıcılar beğendikleri bir oyuncağın resmini yükleyebilir ve bu resimle ilgili özellikleri alabilir.

Resmi analiz etmek ve oyuncağın rengi, malzemesi, türü ve amaçlanan yaş grubu gibi alakalı bağlamı çıkarmak için LangChain4j kullanılarak çağrılan Google'ın Gemini 2.0 Flash modelinden yararlanırız.

Sadece 5 adımda, açık kaynak çerçevesi kullanarak büyük dil modeli çağrısıyla eşleşen sonuçlar elde etmek için kullanıcıların çok formatlı veri girişini kullandık. Bunu nasıl yapacağınızı öğrenin:

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;
  }
}
  1. Üretken yapay zeka ile kullanıcı isteğine göre özelleştirilmiş bir oyuncak oluşturmak için Imagen 3'ü nasıl kullandığımızı öğrenin.

Ardından Imagen 3, özel tasarımlı oyuncağın resmini oluşturarak kullanıcının kendi tasarımını net bir şekilde görselleştirmesini sağlar. Bu işlemi 5 adımda tamamladık:

// 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();
    }
  }

Fiyat tahmini

Yukarıdaki önceki bölümde, Imagen'in kullanıcının kendi tasarlamak istediği oyuncağın resmini nasıl oluşturduğunu ele aldık. Kullanıcıların satın alabilmesi için uygulamanın fiyat belirlemesi gerekir. Özel sipariş oyuncağın fiyatını belirlemek için sezgisel bir mantık kullandık. Buradaki mantık, kullanıcının tasarladığı oyuncağın açıklaması açısından en yakın 5 oyuncağın ortalama fiyatını kullanmaktır.

Üretilen oyuncağın fiyat tahmini, bu uygulamanın önemli bir parçasıdır ve bunu oluşturmak için bir aracı yaklaşımı kullandık. Veritabanları için Üretken Yapay Zeka Araç Kutusu'nu kullanıma sunuyoruz.

13. Veritabanları için Üretken Yapay Zeka Araç Kutusu

Veritabanları için Üretken Yapay Zeka Araç Kutusu, Google'ın veritabanlarıyla etkileşim kurmak için üretken yapay zeka araçları oluşturmayı kolaylaştıran açık kaynaklı bir sunucusudur. Bağlantı havuzu oluşturma ve kimlik doğrulama gibi karmaşık işlemleri yöneterek araçları daha kolay, daha hızlı ve daha güvenli bir şekilde geliştirmenizi sağlar. Bu araç, temsilcilerinizin veritabanınızdaki verilere erişmesine olanak tanıyan üretken yapay zeka araçları oluşturmanıza yardımcı olur.

Aracınızı hazırlamak ve uygulamamızı etkili hale getirmek için aşağıdaki adımları uygulamanız gerekir: Toolbox Codelab'e bağlantı

Uygulamanız artık bu dağıtılmış Cloud Run işlevi uç noktasını kullanarak, özel sipariş üzerine üretilen oyuncak resmi için oluşturulan Imagen sonucuyla birlikte fiyatı doldurabilir.

14. Web uygulamanızı test etme

Uygulamanızın tüm bileşenleri oluşturulup dağıtıldığına göre artık bulutta sunulmaya hazırdır. Uygulamanızı tüm senaryolarda test edin. Bu süreçte sizi nelerin beklediğini gösteren video bağlantısını aşağıda bulabilirsiniz:

https://www.youtube.com/shorts/ZMqUAWsghYQ

Açılış sayfası şu şekilde görünür:

241db19e7176e93e.png

15. Temizleme

Bu yayında kullanılan kaynaklar için Google Cloud hesabınızın ücretlendirilmesini istemiyorsanız şu adımları uygulayın:

  1. Google Cloud Console'da Kaynakları yönetin sayfasına gidin.
  2. Proje listesinde silmek istediğiniz projeyi seçin ve Sil'i tıklayın.
  3. İletişim kutusunda proje kimliğini yazın ve projeyi silmek için Kapat'ı tıklayın.

16. Tebrikler

Tebrikler! Açık kaynak kitaplıklarından yararlanarak güçlü entegrasyonlar oluştururken AlloyDB, pgvector, Imagen ve Gemini 2.0 kullanarak bir oyuncak mağazası bağlamsal arama ve oluşturma işlemini başarıyla gerçekleştirdiniz. AlloyDB, Vertex AI ve Vector Search'ün özelliklerini birleştirerek bağlamsal ve vektör aramalarını erişilebilir, verimli ve gerçekten anlam odaklı hale getirme konusunda büyük bir adım attık.