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 fiziksel olarak girdiğinizi hayal edin. Aradığınız ürünü tanımlayabilir, bir oyuncağın resmini yükleyebilir veya kendi tasarımınızı oluşturabilirsiniz. Mağaza, ihtiyaçlarınızı anında anlayıp 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: Hayal gücünüzle eşleşen mükemmel ürünü bulmak zor olabilir. Genel arama terimleri, anahtar kelimeler ve bulanık aramalar genellikle yetersiz kalır, sonsuz sayfalara göz atma işlemi sıkıcı olabilir ve hayal ettiğiniz ile mevcut olan arasında bağlantı olmaması can sıkıcı olabilir.

Çözüm: Demo uygulama, bağlamsal arama ve arama bağlamıyla eşleşen ürünün özel olarak oluşturulmasıyla gerçekten kişiselleştirilmiş ve sorunsuz bir deneyim sunmak için yapay zekanın gücünden yararlanarak bu sorunu doğrudan ele alır.

Ne oluşturacaksınız?

Bu laboratuvarda şunları yapacaksınız:

  1. AlloyDB örneği oluşturma ve Oyuncak veri kümesini yükleme
  2. AlloyDB'de pgvector ve üretken yapay zeka model uzantılarını etkinleştirme
  3. Ürün açıklamasından yerleştirmeler oluşturun ve kullanıcı arama metni için gerçek zamanlı kosinüs benzerlik araması yapın
  4. Bağlama dayalı oyuncak araması için kullanıcı tarafından yüklenen resmi açıklamak üzere Gemini 2.0 Flash'ı ç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 Aracı Kutusu kullanılarak oluşturulan bir fiyat tahmini aracını çağırma
  7. Çözümü sunucusuz Cloud Run işlevlerinde dağıtma

Şartlar

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

2. Mimari

Veri Akışları: Verilerin sistemimizde nasıl hareket ettiğini daha yakından inceleyelim:

  1. Yapay zeka destekli RAG (Almayla Artırılmış Üretim) ile bağlama dayalı arama

Bunu şu şekilde düşünebilirsiniz: Sistem, yalnızca "kırmızı araba" araması yapmak yerine aşağıdakileri anlar:

"3 yaşındaki bir erkek çocuk için uygun küçük araç."

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

Anlamsal 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, anlamsal aramayı etkinleştirir. Yani sistem, yalnızca tam anahtar kelimeleri değil, kelimelerin arkasındaki anlamı da anlar.

Alaka düzeyi için kosinüs benzerliği: Kullanıcının arama vektörü ile oyuncak açıklaması vektörleri arasındaki anlamsal benzerliği ölçmek için kosinüs benzerliğini kullanırız. Böylece en alakalı sonuçları gösteririz.

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 Yakın Komşular) dizini entegre edilir. Bu, vektör aramamızın verimliliğini ve hatırlama oranını önemli ölçüde artırır.

  1. Gemini 2.0 Flash ile Görüntü Tabanlı 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 sevdikleri bir oyuncağın resmini yükleyebilir ve bu oyuncağa ait alakalı özellikleri görebilir. Resmi analiz etmek ve oyuncağın rengi, malzemesi, türü ve hedef yaş grubu gibi alakalı bağlamı ayıklamak için LangChain4j kullanılarak çağrılan Google'ın Gemini 2.0 Flash modelinden yararlanırız.

  1. Üretken yapay zeka ile özelleştirilmiş hayalinizdeki oyuncağınızı oluşturma: Imagen 3

Asıl eğlence, kullanıcıların kendi oyuncaklarını oluşturmaya karar vermesiyle başlar. Imagen 3'ü kullanarak, basit metin istemleri kullanarak hayallerindeki oyuncağı açıklamalarına olanak tanıyoruz. "Mor kanatlı ve sevimli bir peluş ejderha istiyorum" dediğinizde ekranınızda bu ejderhanın canlandığını hayal edin. Ardından Imagen 3, özel tasarlanmış oyuncağın resmini oluşturur ve kullanıcıya tasarımının net bir görselini sunar.

  1. Temsilciler Tarafından Güçlendirilen Fiyat Tahmini ve Veritabanları İçin Üretken Yapay Zeka Aracı Kutusu

Özel olarak tasarlanmış oyuncağın üretim maliyetini tahmin eden bir fiyat tahmini özelliğini kullanıma sunduk. Bu özellik, gelişmiş bir fiyat hesaplama aracı içeren bir temsilci tarafından desteklenir.

Veritabanları için Üretken Yapay Zeka Aracı Kutusu: Bu aracı, Google'ın yeni açık kaynak aracı olan Veritabanları için Üretken Yapay Zeka Aracı Kutusu kullanılarak veritabanımıza sorunsuz bir şekilde entegre edilir. Bu sayede temsilci, doğru bir fiyat tahmini sunmak için malzeme maliyetleri, üretim süreçleri ve diğer ilgili faktörlerle ilgili anlık verilere erişebilir. Bu konu hakkında daha fazla bilgiye buradan ulaşabilirsiniz.

  1. Java Spring Boot, Gemini Code Assist ve Cloud Run ile kolaylaştırılmış geliştirme ve sunucusuz dağıtım

Uygulamanın tamamı, güçlü ve ölçeklenebilir bir çerçeve olan Java Spring Boot kullanılarak oluşturulmuştur. Geliştirme süreci boyunca, özellikle de ön uç geliştirme için Gemini Code Assist'ten yararlanarak 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'u, veritabanı ve aracı işlevlerini bağımsız uç noktalar olarak dağıtmak için 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 projenizde faturalandırmanın etkinleştirildiğinden emin olun. Projede faturalandırmanın etkin olup olmadığını nasıl kontrol edebileceğinizi öğrenin .
  3. Google Cloud'da çalışan ve bq ile önceden yüklenmiş 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üğmesi resmi

  1. Cloud Shell'e bağlandıktan sonra aşağıdaki komutu kullanarak kimliğinizin doğrulanıp doğrulanmadığını ve projenin proje kimliğinize ayarlanıp ayarlanmadığı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 ayarlanmadıysa 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ğıdakileri ç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 tek tek belirtilir.

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 komutunun alternatifi, her ürünü arayarak veya bu bağlantıyı kullanarak konsoldan geçmektir.

Atlanan bir API varsa 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 depolamak için veritabanı olarak AlloyDB'yi kullanacağız. Veritabanları ve günlükler gibi tüm kaynakları tutmak için kümeler kullanır. Her kümenin, verilere erişim noktası sağlayan bir birincil örneği vardır. 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ğıdakine benzer bir ekran görürsünüz. Aşağıdaki değerlerle bir küme ve örnek oluşturun (Repo'dan uygulama kodunu 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"
  • : "default"

538dba58908162fb.png

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

BAĞLANTI KUR'u 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. Kümenin ayarlanmasını tamamlamak için aşağıda gösterildiği gibi KÜME OLUŞTUR'u tıklayın:

e06623e55195e16e.png

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

vector-instance"

.

Küme oluşturma işleminin yaklaşık 10 dakika süreceğini unutmayın. İşlem başarıyla tamamlandığında, yeni oluşturduğunuz kümenize genel bakış sunan bir ekran görürsünüz.

5. Veri kullanımı

Şimdi, mağazayla ilgili verileri içeren 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ğrulama için aşağıdaki verileri kullanın:

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

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

91a86d9469d499c4.png

Gerektiği gibi Çalıştır, Biçimlendir ve Temizle seçeneklerini kullanarak AlloyDB komutlarını düzenleyici pencerelerine girersiniz.

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ında 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 çalıştırıldığında tabloyu veritabanında görüntüleyebilirsiniz.

Verileri besleme

Bu laboratuvarda, SQL dosyasında yaklaşık 72 kayıtlık test verileri var. id, name, description, quantity, price, image_url alanlarını içerir. Diğer alanlar laboratuvarda doldurulur.

Satırları/insert ifadelerini oradan kopyalayın, ardından bu satırları boş bir düzenleyici sekmesine yapıştırın ve ÇALIŞTIR'ı seçin.

Tablo içeriğini görmek için Gezgin bölümünü, giysiler adlı tabloyu görene kadar genişletin. Tabloyu sorgulama seçeneğini görmek için üç noktayı (⋮) seçin. Yeni bir Düzenleyici sekmesinde bir SELECT ifadesi açılır.

cfaa52b717f9aaed.png

İzin Ver

embedding işleviyle ilgili yürütme haklarını postgres kullanıcısına 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ı ROLÜ 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 gömmeler oluşturma

Bilgisayarların sayıları işlemesi metinleri işlemekten çok daha kolaydır. Yerleştirme sistemi, metni nasıl ifade edildiğine, hangi dilin kullanıldığına vb. bakılmaksızın metni temsil etmesi gereken bir dizi kayan noktalı sayıya dönüştürür.

Deniz kıyısındaki bir yeri açıklamayı deneyin. Bu terimler "deniz kıyısında", "deniz kenarında", "odanızdan okyanusa yürüyüş mesafesinde", "sur la mer", "на берегу океана" vb. gibi farklı şekillerde adlandırılabilir. Bu terimlerin tümü farklı görünse de anlamsal anlamları veya makine öğrenimi terminolojisinde yer paylaşımları birbirine çok yakın olmalıdır.

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

Not: Bir süre önce oluşturulmuş mevcut bir Google Cloud projesi 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ırın.

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

Bu işlem, oyuncak açıklaması için aşağıda gösterildiği gibi bir kayan nokta dizisi gibi görünen embedding vektörünü döndürür:

7d32f7cd7204e1f3.png

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

7. Vektör araması yapma

Tablo, veriler ve yerleştirmeler hazır olduğuna göre kullanıcı arama metni için gerçek zamanlı vektör araması yapalım.

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 bu terimle eşleşen öğeleri 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 5;

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. Bu modeli text-embedding-005 kullanarak embedding() yönteminde yerleştirmelere dönüştürüyoruz. Bu adım, tablodaki tüm öğelere yerleştirme işlevini uyguladığımız son adımdan sonra tanıdık gelecektir.
  3. "<=>", KOSİNÜS BENZERLİĞİ uzaklık yönteminin kullanıldığını gösterir. Kullanılabilen tüm benzerlik ölçümlerini 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 metnine en yakın 5 komşuyu ayıklamak istediğimizi gösterir.

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

fa7f0fc3a4c68804.png

Sonuçlarınızda 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, ScaNN dizini kullanarak bu Vektör Arama sonucunun performansını (sorgu süresi), verimliliğini ve hatırlama oranını artırmak istediğimizi varsayalım. Dizinle ve dizin olmadan elde edilen sonuçlar arasındaki farkı karşılaştırmak için lütfen bu blog'daki adımları okuyun.

İsteğe bağlı adım: ScaNN dizini ile verimliliği ve hatırlamayı artırma

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

  1. Küme, örnek, bağlam ve yerleştirmeler zaten oluşturulduğundan, aşağıdaki ifadeyi kullanarak ScaNN uzantısını yüklememiz yeterlidir:
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.

"oyuncaklar" tablomdur

"scann" dizin yöntemidir

"embedding", dizine eklemek istediğim tablodaki sütundur.

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

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

ScaNN repo'sunda önerildiği gibi veri noktalarının KÖK KARESİ'ni kullandım (Bölümlendirme sırasında num_leaves, yaklaşık olarak veri noktalarının kare kökü olmalıdır).

  1. Dizinin sorgu kullanılarak oluşturulup oluşturulmadığını kontrol edin:
SELECT * FROM pg_stat_ann_indexes;
  1. Dizin olmadan kullandığımız aynı sorguyu kullanarak vektör araması yapın:
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 eklendi.

  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 bir testin sonuçları aşağıdaki gibidir:

Dizinlenen gömme verileri üzerinde aynı Vektör Arama sorgusu, kaliteli arama sonuçları ve verimlilik sağlar. Dizinle 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 konu hakkında daha fazla bilgi için lütfen bu blogu inceleyin.

8. LLM ile Eşleşme Doğrulaması

Devam edip bir uygulamaya en iyi eşleşmeleri döndürecek bir hizmet oluşturmadan önce, bu potansiyel 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 modeli kullanalım.

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

Öncelikle, Google ML entegrasyonunun kümeniz ve örneğiniz için etkinleştirilip etkinleştirilmediğini kontrol edin. AlloyDB Studio'da aşağıdaki komutu verin:

show google_ml_integration.enable_model_support;

Değer "açık" olarak gösteriliyorsa sonraki 2 adımı atlayabilir ve doğrudan AlloyDB ile Vertex AI Model entegrasyonunu ayarlamaya geçebilirsiniz.

  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 İşaretler bölümüne gidin. ve google_ml_integration.enable_model_support flag değerinin 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 ardından ÖRNEK YENİLE düğmesini tıklayın. Bu adım birkaç dakika sürer.

AlloyDB ve Vertex AI modeli entegrasyonu

Artık AlloyDB Studio'ya bağlanabilir ve belirtilen yerde 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ı alabilirsiniz ancak komut sorunsuz şekilde çalışır.

Öncelikle, aşağıdaki gibi Gemini 1.5 model bağlantısını oluştururuz. Aşağıdaki komuttaki $PROJECT_ID ifadesini Google Cloud proje kimliğinizle değiştirmeyi 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, veritabanı kullanıcılarının Google Vertex AI modelleri aracılığıyla tahmin yürütmek için ml_predict_row işlevini yürütmesine izin 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 modelinin eski referanslarını bırakmanız ve yukarıdaki CALL ifadesiyle tekrar oluşturmanız, ardından gemini-1.5'in sonraki çağrılarında sorun yaşama ihtimaline karşı grant execute on function ml_predict_row komutunu tekrar çalıştırmanız gerekebilir.

Yanıtları değerlendirme

Sorgudan alınan yanıtların makul olmasını sağlamak için sonraki bölümde tek bir büyük sorgu kullanacağız. Ancak bu sorgunun anlaşılması zor olabilir. Şimdi parçalara bakacağız ve birkaç dakika içinde bunların nasıl bir araya geldiğini 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 ne kadar geçerli olduğunu 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. Bu bilgileri kullanarak, döndürülen yanıtların "iyiliğini" inceleriz.
  4. predict_row, sonucunu JSON biçiminde döndürür. "-> 'candidates' -> 0 -> 'content' -> 'parts' -> 0 -> 'text'" kodu, söz konusu JSON'dan asıl metni ayıklamak için 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')
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 10) 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 süreç yine de göz korkutucu görünse de umarım bu konuda daha fazla bilgi edinebilirsiniz. Sonuçlar, eşleşme olup olmadığını, eşleşmenin yüzdesini ve derecelendirmeyle ilgili bazı açıklamaları gösterir.

Gemini modelinde akış özelliğinin varsayılan olarak etkin olduğunu ve bu nedenle gerçek yanıtın birden fazla satıra yayıldığını unutmayın:

c2b006aeb3f3a2fc.png

9. Oyuncak aramayı sunucusuz olarak buluta taşıma

Bu uygulamayı web'e taşımaya hazır mısınız? Bu Bilgi Motoru'nu 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'daki Cloud Run işlevlerine gidin veya https://console.cloud.google.com/functions/add bağlantısını kullanın.
  2. Ortamı "Cloud Run işlevi" olarak seçin. "get-toys-alloydb" işlev adını girin ve Bölge olarak "us-central1"i seçin. Kimlik doğrulamayı "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 kod için de 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ümündeki yer tutucu kodunu sırasıyla HelloHttpFunction.java ve pom.xml'deki 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 da aynı değişiklikleri yapın.
  5. Dağıt'ı tıklayın.

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

ÖNEMLİ ADIM:

Dağıtım için hazırlık yaptıktan sonra işlevleri Google Cloud Run Functions konsolunda görebilirsiniz. Yeni oluşturulan işlevi (get-toys-alloydb) arayın, tıklayın, ardından DÜZENLE'yi tıklayın ve aşağıdakileri değiştirin:

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

4e83ec8a339cda08.png

  1. Giriş ayarlarının altında "Tüm trafiğe izin ver" seçeneğinin seçili olduğundan emin olun.
  2. Çıkış ayarları bölümünde Ağ açılır menüsünü tıklayın ve "Yeni VPC Bağlantısı Ekle" seçeneğini belirleyin. 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ığı veya kullanılabilir benzer bir değerle Özel IP Aralığı olarak ayarlayın.
  2. YÜKSEK ÇÖZÜNÜRLÜKLÜ AYARLARI GÖSTER'i genişletin ve yapılandırmayı tam olarak aşağıdaki şekilde ayarladığınızdan emin olun:

7baf980463a86a5c.png

  1. OLUŞTUR'u tıklayın. 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 seçin.
  4. SONRAKİ'yi ve ardından DAĞIT'ı tıklayın.

10. Cloud Run işlevini test etme

Güncellenen Cloud Functions dağıtıldıktan sonra uç noktayı aşağıdaki biçimde görürsünüz:

https://us-central1-YOUR_PROJECT_ID.cloudfunctions.net/get-toys-alloydb

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

PROJECT_ID=$(gcloud config get-value project)

curl -X POST https://us-central1-$PROJECT_ID.cloudfunctions.net/get-toys-alloydb \
  -H 'Content-Type: application/json' \
  -d '{"search":"I want a standing pink panther toy"}' \
  | jq .

Sonuç:

23861e9091565a64.png

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

11. Web Uygulaması İstemcisini Oluşturma

Bu bölümde, kullanıcının metne ve resme göre eşleşen oyuncakları bulduğu ve hatta ihtiyaçlarına göre yeni oyuncaklar oluşturduğu bir web uygulaması oluşturacağız. Uygulama zaten derlenmiş olduğundan, aşağıdaki adımları uygulayarak uygulamayı IDE'nize kopyalayıp çalıştırabilirsiniz.

  1. Kullanıcının eşleşen oyuncakları bulmak için yükleyebileceği resmi tanımlamak amacıyla Gemini 2.0 Flash'ı kullandığımızdan bu uygulamanın API ANAHTARI'nı almamız gerekir. Bunu yapmak için https://aistudio.google.com/apikey adresine gidin ve bu uygulamayı uyguladığınız etkin Google Cloud projeniz için API anahtarınızı alın ve anahtarı bir yere kaydedin:

ae2db169e6a94e4a.png

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

cd toysearch
  1. Depo klonlandıktan sonra projeye Cloud Shell Düzenleyici'nizden erişebilirsiniz.
  2. "get-toys-alloydb" ve "toolbox-toys" klasörlerini klonlanmış projeden silmeniz gerekir. Bu iki klasör, ihtiyaç duyduğunuzda kod deposundan referans verilebilen Cloud Run işlevleri kodudur.
  3. Uygulamayı derleyip 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ırın:

Proje dizininde olduğunuzdan emin olarak 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. Bilginiz olması amacıyla:

Uygulamayı dağıtmaya hazırsınız. Şimdi aramayı (metin ve görsel) ve oluşturmayı nasıl yaptığımızı anlamak için biraz zaman ayırın.

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

Bu konu, "Vector Search uygulamasını web'e taşıma" bölümünde dağıttığımız Cloud Run işlevlerinde zaten ele alınmıştır.

  1. Resim yükleme tabanlı 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 sevdikleri bir oyuncağın resmini yükleyebilir ve bu oyuncağa ait alakalı özellikleri görebilir.

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

Açık kaynak bir çerçeve kullanarak kullanıcının çoklu modal veri girişini, sonuçları büyük dil modeli çağrısıyla eşleştirmeye sadece 5 adımda aldı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 tasarlanmış oyuncağın resmini oluşturur ve kullanıcıya tasarımının net bir görselini sunar. Bunu sadece 5 adımda nasıl yaptığımızı öğrenin:

// 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 başına tasarlamak istediği oyuncağın resmini nasıl oluşturduğunu ele aldık. Kullanıcıların bu ürünü satın alabilmesi için uygulamanın ürün için bir fiyat belirlemesi gerekir. Özel sipariş üzerine üretilen oyuncağın fiyatını belirlemek için sezgisel bir mantık kullandık. Mantık, kullanıcının tasarladığı oyuncağa en yakın 5 oyuncağın (açıklama açısından) ortalama fiyatını kullanmaktır.

Oluşturulan oyuncağın fiyat tahmini, bu uygulamanın önemli bir parçasıdır ve bunu oluşturmak için aracıcı 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 Aracı Kutusu, Google'ın veritabanlarıyla etkileşim kurmak için üretken yapay zeka araçları oluşturmayı kolaylaştıran açık kaynak bir sunucusudur. Bağlantı havuzu oluşturma, kimlik doğrulama ve daha birçok karmaşıklığı ele alarak araçları daha kolay, daha hızlı ve daha güvenli bir şekilde geliştirmenize olanak tanır. Temsilcilerinizin veritabanınızdaki verilere erişmesine olanak tanıyan üretken yapay zeka araçları oluşturmanıza yardımcı olur.

Aşağıda, aracınızı hazırlamak ve uygulamanızın aracılık yapmasını sağlamak için bu ayarı yapabilmek üzere uygulamanız gereken adımlar verilmiştir: Araç Kutusu Codelab'e bağlantı

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

14. Web uygulamanızı test etme

Uygulamanızın tüm bileşenleri oluşturulup dağıtıldığına göre uygulamanız bulutta yayınlanmaya hazırdır. Uygulamanızı tüm senaryolar için test edin. Bu süreçte sizi nelerin beklediğine dair video bağlantısını burada 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 ardından Sil'i tıklayın.
  3. İletişim kutusuna proje kimliğini yazın ve projeyi silmek için Kapat'ı tıklayın.

16. Tebrikler

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