Kitap Rafı oluşturucu: Gemini'ı kullanarak Gemini uygulaması için Java Cloud Functions işlevi geliştirme

1. Giriş

Kitap okumayı seviyor ancak seçeneklerin çokluğu nedeniyle kararsız kalıyor musunuz? Hem mükemmel bir okuma önerisi sunan hem de seçtiğiniz türe göre kısa bir özet sunarak kitabın özünü anlamanıza yardımcı olan yapay zeka destekli bir uygulamayı hayal edin. Bu kod laboratuvarında, Gemini tarafından desteklenen BigQuery ve Cloud Functions ile böyle bir uygulama oluşturma konusunda size yol göstereceğim.

Projeye Genel Bakış

Kullanım alanımız şu 4 temel bileşene odaklanıyor:

  • Kitap Veritabanı: İnternet arşiv kitaplarının yer aldığı geniş BigQuery herkese açık veri kümesi, kapsamlı kitap kataloğumuz olarak kullanılacak.
  • Yapay Zeka Özetleme Motoru: Gemini-Pro dil modeliyle donatılmış Google Cloud Functions, kullanıcı isteklerine göre uyarlanmış, bilgi dolu özetler oluşturur.
  • BigQuery Entegrasyonu: İsteğe bağlı kitap özetlerini ve temalarını sunmak için Cloud işlevimizi çağıran BigQuery'deki uzak bir işlevdir.
  • Kullanıcı Arayüzü: Cloud Run'da barındırılan ve kullanıcıların sonuçları görüntüleyebileceği bir web uygulaması sunan bir web uygulaması.

Uygulamayı 3 kod laboratuvarına ayıracağız:

1. Codelab: Gemini uygulaması için Java Cloud Functions işlevi oluşturmak üzere Gemini'i kullanma

2. kod deneme çalışması: BigQuery ile yalnızca SQL kullanan üretken yapay zeka uygulamaları oluşturmak için Gemini'yi kullanma.

Codelab 3: Gemini ile BigQuery ile etkileşime geçen bir Java Spring Boot web uygulaması oluşturun.

2. Java Cloud Functions'da sunucusuz bir üretken yapay zeka uygulaması oluşturmak için Gemini'yi kullanma

Ne oluşturacaksınız?

Verinin tamamını

  • JSON Dizisi biçiminde giriş olarak belirli bir istem almak üzere Gemini 1.0 Pro'yu uygulayan ve bir yanıt ("yanıtlar" etiketli Json değeri) döndüren bir Java Cloud Functions uygulaması.
  • Derleme ve dağıtma adımlarını Gemini'nin yardımıyla gerçekleştireceksiniz

3. Şartlar

  • Chrome veya Firefox gibi bir tarayıcı
  • Faturalandırma özelliği etkinleştirilmiş bir Google Cloud projesi

Gerekli ön koşullar aşağıda verilmiştir:

Projenizi oluşturun

  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 edeceğinizi öğrenin.

Cloud Shell'i etkinleştirme

  1. Google Cloud'da çalışan ve bq ile önceden yüklenmiş olarak gelen bir komut satırı ortamı olan Cloud Shell'i kullanacaksınız:

Cloud Console'da, sağ üst köşedeki Cloud Shell'i Etkinleştir'i tıklayın: 6757b2fb50ddcc2d.png

  1. Cloud Shell'e bağlandıktan sonra kimliğinizin doğrulandığını ve projenin proje kimliğinize ayarlandığını görürsünüz. Kimliğinizi doğrulamak için Cloud Shell'de aşağıdaki komutu çalıştırın:
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>

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

4. Google Cloud için Gemini'yi ve gerekli API'leri etkinleştirme

Gemini'yi etkinleştirme

  1. API'yi etkinleştirmek üzere Marketplace'te Google Cloud için Gemini'a gidin. Aşağıdaki komutu da kullanabilirsiniz:
gcloud services enable cloudaicompanion.googleapis.com --project PROJECT_ID
  1. Gemini sayfasını ziyaret edip "Sohbet etmeye başla"yı tıklayın.

Önemli: Gemini'ı kullanmaya başlamak için sırasıyla bu codelab'deki 1. ve 2. adımları uygulayarak Gemini'ı Cloud Shell IDE'de etkinleştirin.

Gerekli diğer API'leri etkinleştirme

Bunu nasıl yapacağız? Gemini'ye soralım. Ancak bundan önce şunları unutmayın:

Büyük dil modelleri (LLM) belirlenemez. Bu istemleri denerken alacağınız yanıt, ekran görüntümdeki yanıtlardan farklı görünebilir.

Google Cloud Console'daki arama çubuğunun sağ üst köşesindeki "Gemini'yi aç" simgesini tıklayarak Gemini sohbet konsoluna gidin.

26e1491322855614.png

"Buraya bir istem girin" bölümüne şu soruyu yazın:

How do I enable the cloud functions api using a gcloud command? 

Şuna benzer bir yanıt alırsınız:

gcloud services enable cloudfunctions.googleapis.com

Bu komutu kopyalayın (komut snippet'inin üst kısmındaki kopyalama simgesini kullanabilirsiniz) ve Cloud Functions'ı etkinleştirmek için Cloud Shell Terminal'de çalıştırın. Aynısını Cloud Run'da da yapın. Cloud Functions'ın derlenip dağıtılması için ikisine de ihtiyacımız var:

gcloud services enable \
  cloudfunctions.googleapis.com \
  aiplatform.googleapis.com \
  run.googleapis.com \
  cloudbuild.googleapis.com

5. Gemini ile Cloud Functions şablonu hazırlama

Bu noktada, Cloud Shell IDE'nizde Gemini'yi zaten etkinleştirdiğinizi varsayıyorum.

Cloud Shell Terminal'inizin sağ üst köşesindeki Düzenleyiciyi Aç simgesini tıklayarak Cloud Shell Düzenleyici'yi açın (Genellikle terminali ve düzenleyiciyi paralel olarak ayrı sekmelerde açmayı tercih ederim. Böylece birinde kod yazabilir, diğerinde derleme yapabiliriz).

edd258384bc74f1f.png

Düzenleyiciyi açtıktan sonra, düzenleyici konsolunun sağ alt köşesindeki Gemini logosunun etkin olduğundan (ve iptal edilmediğinden) emin olun. Ayrıca, sol alt köşedeki Google Cloud projenizin, çalışmak istediğiniz mevcut etkin projenizi gösterdiğinden emin olun. Etkin değilse tıklayın, yetkilendirin, işaret etmesini istediğiniz Google Cloud projesini seçin ve etkinleştirin.

Her ikisi de etkinleştirildikten sonra sol alt köşedeki proje adını tıklayın ve "Cloud Code" başlıklı pop-up listede "Yeni Uygulama"ya gidin.

ca08602b576ebd57.png

Bu listeden Cloud Functions uygulamasını seçin. Açılan listeden Java'yı seçin:

ac2b44245949da68.png

Açılan listede, helloworld yerine "duetai-gemini-calling" proje adını yazıp Tamam'ı tıklayın.

bf9cfe86e35cdced.png

Yaşasın! Basit Java Cloud Functions uygulamanızı Gemini ile başlattınız. Yapılandırmaları etkinleştirme ve etkinleştirme dışında pek bir şey yapmadınız, değil mi?

Görmeniz gereken proje yapısı şöyledir:

d56e410fb76f183f.png

Şu anda işlevi dağıtmaya hazırsınız. Ancak bu projeyi bu yüzden başlatmadık. Şimdi Java SDK'sını kullanarak bu Cloud Function'da Gemini Pro API uygulamasını oluşturalım.

Şimdi, bu Cloud Functions işlevinde Gemini Pro modelini çağıran kullanım alanımıza yönelik işlevi oluşturalım. Bunu yapmak için daha fazla istem ekleyebilir ve kodunuzu Gemini ile kademeli olarak geliştirebilir veya mantığı kendiniz yazabilirsiniz. İkisini de karışık olarak yapacağım.

6. Bağımlılık ekleme

Gemini sohbet konsoluna (sol bölmedeki Cloud Code Düzenleyici'deki konsol) aşağıdaki isteği yazın:

what is the maven dependency for com.google.cloud.vertexai library

Özellikle com.google.cloud.vertexai paketini istememin nedeni, Gemini çağrı kodunu uyguladığım kaynak kodunda bunu kullanıyor olmamdır.

Şu sonucu aldım:

62c4295b9b4654e9.png

 <dependency>
      <groupId>com.google.cloud</groupId>
      <artifactId>google-cloud-vertexai</artifactId>
      <version>0.1.0</version>
    </dependency>

Bu metni kopyalayıp pom.xml dosyasına, </dependencies> etiketinin hemen önüne yapıştırın. Sürümü 0.1.0 ile değiştirin (spring-cloud-gcp sürüm numaralarını sizin için yönetmek üzere Spring Cloud GCP BOM'u kullanıyorsanız <version> etiketini kaldırabilirsiniz).

Bağımlılık bölümü aşağıdaki gibi görünmelidir:

1800f10af9331210.png

Gerekirse sürüm numaralarını yukarıdakilerle eşleşecek şekilde güncellediğinizden emin olun. Gördüğünüz gibi, bununla birlikte başka bir bağımlılık da ekledim:

    <dependency>
      <groupId>com.google.code.gson</groupId>
      <artifactId>gson</artifactId>
      <version>2.10</version>
    </dependency>

7. İşlev giriş noktasını ve sınıf adını değiştirme

  1. ".vscode" klasörünün altındaki "launch.json" dosyasına gidin. "function-hello-world" olan işlev adını, "function-gemini-calling" olarak düzenleyin.
  2. "cloudcode.helloworld.HelloWorld"deki giriş noktası değerini cloudcode.bookshelf.Bookshelf olarak güncelleyin.
  3. Ardından "HelloWorld.java" adlı Java sınıf dosyasına gidin. Paket adını package cloudcode.bookshelf olarak değiştirin; Açılan hatada sarı ampulün ardından "HelloWorld.java dosyasını package cloudcode.bookshelf'e taşı" seçeneğini tıklayın.

38d721978bddc8a8.png

  1. Sınıf adını Bookshelf olarak güncelleyin. Açılan hata mesajında, küçük sarı ampulü tıklayın ve "Refile to Bookshelf.java olarak yeniden adlandır"ı seçin. Bu seçeneği belirleyin.

8. Gemini Pro'yu çağıran yöntemi oluşturun

Bu işlevi Bookshelf.java sınıfına uygulayalım. Bookshelf.java dosyanızı aşağıdaki kodla değiştirin:

package cloudcode.bookshelf;
import java.io.BufferedWriter;
import com.google.cloud.functions.HttpFunction;
import com.google.cloud.functions.HttpRequest;
import com.google.cloud.functions.HttpResponse;
import com.google.cloud.vertexai.VertexAI;
import com.google.cloud.vertexai.api.GenerateContentResponse;
import com.google.cloud.vertexai.api.GenerationConfig;
import com.google.cloud.vertexai.generativeai.preview.GenerativeModel;
import com.google.cloud.vertexai.generativeai.preview.ResponseHandler;
import java.io.IOException;
import java.util.List;
import java.util.Arrays;
import java.util.Map;
import java.util.LinkedHashMap;
import com.google.gson.Gson;
import com.google.gson.JsonObject;
import com.google.gson.JsonArray;

public class Bookshelf implements HttpFunction {
  private static final Gson gson = new Gson();

 @Override
  public void service(HttpRequest request, HttpResponse response) throws Exception {
    BufferedWriter writer = response.getWriter();

 // Get the request body as a JSON object.
 JsonObject requestJson = new Gson().fromJson(request.getReader(), JsonObject.class);
 JsonArray calls_array = requestJson.getAsJsonArray("calls");
 JsonArray calls = (JsonArray) calls_array.get(0);
 String context = calls.get(0).toString().replace("\"", "");

 //Invoke Gemini model
  String raw_result = callGemini(context);
  raw_result = raw_result.replace("\n","");
  String trimmed = raw_result.trim();
  List<String> result_list = Arrays.asList(trimmed);
  Map<String, List<String>> stringMap = new LinkedHashMap<>();
  stringMap.put("replies", result_list);
 
  // Serialization
  String return_value = gson.toJson(stringMap);
  writer.write(return_value);
    }
  public String callGemini(String context) throws IOException{
      String res = "";
        try (VertexAI vertexAi = new VertexAI("REPLACE_WITH_YOUR_PROJECT_ID", "us-central1"); ) {
          GenerationConfig generationConfig =
              GenerationConfig.newBuilder()
                  .setMaxOutputTokens(2048)
                  .setTemperature(0.4F)
                  .setTopK(32)
                  .setTopP(1)
                  .build();  
        GenerativeModel model = new GenerativeModel("gemini-pro", generationConfig, vertexAi);
        GenerateContentResponse response = model.generateContent(context);
        res = ResponseHandler.getText(response);
      }catch(Exception e){
        System.out.println(e);
        }
        return res;
    }
}

Bu sınıf, JSON yapısında aşağıdaki gibi giriş yapılmasını bekler:

{ "calls": [["YOUR_PROMPT_HERE"]] }

Aşağıdaki gibi bir yanıt döndürür:

(Json) Map<String, List<String>> {"replies": ["response"]}

Kodu açıklamak için sol bölmede bulunan Cloud Shell Düzenleyici'deki Gemini sohbet seçeneğini deneyin. Alternatif olarak, kodun tamamını seçip seçimin sol üst köşesindeki sarı ampul simgesini tıklayıp "Bunu açıkla" seçeneğini belirleyebilirsiniz.

66fb67507793e368.png

9. Cloud Functions işlevini dağıtma

Cloud Functions hazır olduğuna göre Gemini'den nasıl dağıtılacağını öğrenelim. Cloud Code düzenleyicisindeki Gemini sohbet oturumuna gidin ve aşağıdakileri girin:

   How to deploy this Cloud Function with a gcloud command?

Aşağıdaki yanıtı aldım:

9f9db98933841864.png

Şimdi bu konuyu daha ayrıntılı incelemek istiyorum. Gemini'den gcloud functions deploy komutunun tamamını vermelerini istedim. Yanıt aşağıdaki gibidir:

b77701c00dc3eaf1.png

Aynı yanıtı alıp almayacağınızı bilmiyorum ancak aşağıda görüldüğü gibi, yanıtın birkaç ayrıntı daha içerdiğini görmek beni şaşırttı:

İstek içeriği biçimi:

82bf20304143a374.png

ve

Yanıt biçimi:

ade55b3de5d823a6.png

Şimdi Gemini'ın bize verdiği gcloud komutunu çalıştırarak işlevi dağıtalım. Bunun için Cloud Shell Terminal'i açmamız gerekiyor. Projeyi yeni bir sekmede https://console.cloud.google.com için açıp doğru projenin seçildiğinden emin olabilirsiniz. Konsolun sağ üst köşesindeki Cloud Shell'i Etkinleştir simgesini tıklayarak Cloud Shell Terminal'i açın ve aşağıdaki komutu kullanarak doğru proje klasöründe olduğunuzdan emin olun:

cd duetai-gemini-calling

Ardından aşağıdaki komut kullanılır:

gcloud functions deploy bookshelf --runtime java17 --trigger-http --entry-point cloudcode.bookshelf.Bookshelf --allow-unauthenticated

"Yeni işlevin [bookshelf] kimliği doğrulanmamış çağrılarına izin verilecek mi?" sorusunu görürsünüz. "Evet" deyin ve Enter tuşuna basın. Ardından, geçerliyse birkaç soru sorulur ve sunucusuz Cloud işleviniz, dağıtılan URL ile dağıtılır: https://us-central1-*******.cloudfunctions.net/bookshelf.

Şimdi dağıtılan Cloud Functions işlevini çağırıp test edelim.

Not: "Kimliği doğrulanmamış çağrılara izin ver" sorusunu yanlışlıkla atladıysanız veya "Hayır"ı seçtiyseniz Cloud Functions sonucuna erişemezsiniz ve ek IAM ayarları vermeden "izin hatası" görürsünüz. O yüzden buna dikkat edin.

10. Dağıtılan Cloud Functions işlevini çağırma

Gemini'ye soralım. İstemi girdim

How to call the deployed cloud function?

Aşağıdaki sonucu aldım: (Aynı yanıtı görebilir veya görmeyebilirsiniz; istemde denemeler yapıp yanıtlardaki farkı görebilirsiniz).

1d2242715571fe6f.png

Dağıtılan işlevi çağırmanın alternatif yolları, gcloud komutunu kullanarak çağırma vb. ile ilgili belirli sorularla sohbeti araştırın. Aşağıdaki istemi gönderdim:

how to call the deployed cloud function using gcloud

Aşağıdaki yanıtı aldım: e7b29b2cfb57782c.png

Bu yanıtı ("gcloud functions call" komutu) senaryomuz için çalışacak şekilde ayarlayarak terminalden kullanabilirsiniz (Alternatif olarak, parametreleri istemde iletmeyi deneyin ve yanıt olarak ayrıntılı gcloud functions call alıp alamadığınızı görün):

gcloud functions call bookshelf --region=us-central1 --gen2 --data '{"calls":[["Hello! This is my test prompt."]]}'

Elde ettiğim sonuç şöyle:

6f396d915251db78.png

11. Temizleme

Cloud Functions'ın ayrıntılar sayfasındaki SİL düğmesini tıklayarak daha önce oluşturduğunuz Cloud Functions'ı silebilirsiniz.

12. Tebrikler

Gemini'ı kullanarak Gemini 1.0 Pro'yu çağırmak için bir Java Cloud Functions işlevi derleyip dağıttınız ve test ettiniz. Bu uygulama, kitap özeti ve temasıyla birlikte kitap önerisiyle ilgili giriş istemini alır.