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

1. Giriş

Kitapları incelemeyi seviyor ancak çok fazla seçenek olduğundan kararsız mı kalıyorsunuz? Mükemmel okumayı önermekle kalmayıp seçtiğiniz türe göre kısa bir özet de sunarak kitabın özünü anlamanızı sağlayan yapay zeka destekli bir uygulama kullandığınızı düşünün. Bu codelab'de, Gemini destekli BigQuery ve Cloud Functions ile böyle bir uygulama oluşturma sürecinde size yol göstereceğim.

Projeye Genel Bakış

Kullanım alanımız şu 4 temel bileşen etrafında şekilleniyor:

  • Kitap Veritabanı: İnternet Arşivi kitaplarının bulunduğu 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ış, bilgilendirici özetler oluşturur.
  • BigQuery Entegrasyonu: BigQuery'de, talep üzerine kitap özetleri ve temaları sunmak için Cloud Functions işlevimizi çağıran uzak bir işlev.
  • Kullanıcı arayüzü: Kullanıcılara sonuçları görüntüleyebilecekleri bir web uygulaması sunan, Cloud Run'da barındırılan bir web uygulaması.

Uygulamayı 3 codelab'e böleceğiz:

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

Codelab 2: BigQuery ile yalnızca SQL'den oluşan üretken yapay zeka uygulamaları oluşturmak için Gemini'ı kullanın.

Codelab 3: BigQuery ile etkileşim kuran bir Java Spring Boot web uygulaması oluşturmak için Gemini'ı kullanın.

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

Ne oluşturacaksınız?

Aşağıdakileri oluşturacaksınız:

  • Belirli bir istemi JSON dizisi biçiminde giriş olarak alan ve yanıt döndüren (replies etiketli JSON değeri) Gemini 1.0 Pro'yu uygulayan Java Cloud Functions uygulaması.
  • Gemini'ın yardımıyla derleme ve dağıtım adımlarını gerçekleştireceksiniz.

3. Şartlar

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

Ön koşullar aşağıda verilmiştir:

Projenizi 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.

Cloud Shell'i etkinleştirme

  1. bq önceden yüklenmiş olarak gelen, Google Cloud'da çalışan 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ğinizin doğrulandığını onaylamak için Cloud Shell'de şu 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 ayarlanmamışsa 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'ı ve gerekli API'leri etkinleştirme

Gemini'ı etkinleştirme

  1. API'yi etkinleştirmek için 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 edin ve "Sohbeti başlat"ı tıklayın.

Önemli: Gemini'ı kullanmaya başlamak ve Gemini'ı Cloud Shell IDE'de etkinleştirmek için bu codelab'deki 1. ve 2. adımları uygulayın.

Diğer gerekli API'leri etkinleştirme

Bunu nasıl yapabiliriz? Bu soruyu Gemini'a soralım. Ancak bundan önce şunları unutmayın:

LLM'ler deterministik değildir. Bu nedenle, bu istemleri denerken aldığınız yanıtlar, ekran görüntümdeki yanıtlardan farklı görünebilir.

Google Cloud Console'da arama çubuğunun yanındaki sağ üst köşedeki "Gemini'ı aç" simgesini tıklayarak Gemini ile etkileşim konsoluna gidin.

26e1491322855614.png

"Buraya 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 Terminali'nde uygulayın. Cloud Functions'ın oluşturulup dağıtılması için her ikisine de ihtiyacımız olduğundan Cloud Run için de aynı işlemi yapın:

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'ın etkinleştirildiğini varsayıyorum.

Cloud Shell terminalinizin 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 (ve iptal edilmemiş) olduğundan emin olun. Ayrıca, sol alt köşedeki Google Cloud projenizin, üzerinde çalışmak istediğiniz mevcut etkin projeyi gösterdiğinden emin olun. API'ler etkin değilse bunları tıklayın, yetkilendirin, yönlendirmek 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ı açılır listede "New Application"a (Yeni Uygulama) gidin.

ca08602b576ebd57.png

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

ac2b44245949da68.png

Sonuç listesinde, helloworld yerine "duetai-gemini-calling" proje adını yazın ve Tamam'ı tıklayın.

bf9cfe86e35cdced.png

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

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

d56e410fb76f183f.png

Şu anda işlevi dağıtabilirsiniz. Ancak bu nedenle bu işe başlamadık. Şimdi Java SDK'yı kullanarak bu Cloud Function'da Gemini Pro API uygulamasını oluşturalım.

Şimdi de kullanım alanımız için işlevselliği oluşturalım. Bu kullanım alanında, Gemini Pro modelini bu Cloud Function'da çağıracağız. Bunu yapmak için daha fazla istem ekleyebilir ve kodunuzun Gemini ile kademeli olarak geliştirilmesini sağlayabilir veya mantığı kendiniz yazabilirsiniz. İkisini de kullanacağım.

6. Bağımlılık Ekleme

Gemini ile etkileşim konsolunda (soldaki bölmede Cloud Code Editor'da bulunan) aşağıdaki istemi yazın:

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

com.google.cloud.vertexai paketini özellikle istememin nedeni, Gemini çağırma kodunu uyguladığım kaynak kodumda bu paketi kullanmamdı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 kodu kopyalayın ve pom.xml dosyasına, </dependencies> etiketinden hemen önce yapıştırın. Sürümü 0.1.0 ile değiştirin (Spring Cloud GCP BOM'u, spring-cloud-gcp sürüm numaralarını sizin için yönetmek üzere 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ıdakiyle eşleşecek şekilde güncellediğinizden emin olun. Fark ettiyseniz buna 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ündeki "launch.json" dosyasına gidin. İşlev adını "function-hello-world" yerine "function-gemini-calling" olarak düzenleyin.
  2. entryPoint değerini "cloudcode.helloworld.HelloWorld"dan "cloudcode.bookshelf.Bookshelf" olarak güncelleyin.
  3. Şimdi "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ü ve "HelloWorld.java dosyasını package cloudcode.bookshelf konumuna taşı" seçeneğini tıklayın.

38d721978bddc8a8.png

  1. Sınıf adını Bookshelf olarak güncelleyin ve açılan hatada küçük sarı ampulü tıklayıp "Rename file to Bookshelf.java" (Dosyayı Bookshelf.java olarak yeniden adlandır) seçeneğini belirleyin. Bu seçeneği belirleyin.

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

Bu işlevi Bookshelf.java sınıfında 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, girişi aşağıdaki gibi JSON yapısında 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ölmedeki Cloud Shell Düzenleyici'den Gemini ile etkileşim seçeneğini deneyin. Alternatif olarak, kodun tamamını seçip seçimin sol üst köşesindeki sarı ampulü tıklayabilir ve "Bunu açıkla" seçeneğini belirleyebilirsiniz.

66fb67507793e368.png

9. Cloud Functions işlevini dağıtma

Cloud Function hazır olduğuna göre şimdi Gemini'a nasıl dağıtılacağını soralım. Cloud Code düzenleyicisinde Gemini ile etkileşim'e 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 istiyordum. Bu nedenle, Gemini'dan tam gcloud functions deploy komutunu vermesini istedim. Yanıt aşağıdaki gibi olmalıdır:

b77701c00dc3eaf1.png

Aynı yanıtı alıp almayacağınızı söyleyemem ancak aşağıdaki resimde de görebileceğiniz gibi, yanıtın beni şaşırtacak şekilde birkaç ayrıntı daha eklediğini görmek oldukça ilginçti:

İstek metni biçimi:

82bf20304143a374.png

ve

Yanıt biçimi:

ade55b3de5d823a6.png

Şimdi de Gemini'ın verdiği gcloud komutunu çalıştırarak işlevi dağıtalım. Bunun için Cloud Shell Terminali'ni açmamız gerekir. https://console.cloud.google.com adresinde yeni bir sekmede açabilir ve doğru projenin seçildiğinden emin olabilirsiniz. Konsolun sağ üst köşesindeki Cloud Shell'i Etkinleştir simgesini tıklayarak Cloud Shell Terminali'ni 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 komutu çalıştırın:

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

"Yeni işlev [bookshelf] için kimliği doğrulanmamış çağrılara izin verilsin mi?" diye sorulur. "y" yazıp Enter tuşuna basın. Ardından, geçerliyse birkaç soru sorulur ve sunucusuz Cloud Function'ınız, dağıtılan URL ile dağıtılır: https://us-central1-*******.cloudfunctions.net/bookshelf.

Şimdi dağıtılan Cloud Functions işlevini çağıralım ve test edelim.

Not: "Kimliği doğrulanmamış çağırmalara izin ver" sorusunu yanlışlıkla atladıysanız veya "H" seçeneğini belirlediyseniz ek IAM ayarları vermeden Cloud Functions'ın sonucuna erişemez ve "izin hatası" görürsünüz. Bu nedenle, bu noktaya dikkat edin.

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

Gemini'a soralım mı? İstemi girdim

How to call the deployed cloud function?

Aşağıdaki sonucu aldım: (Aynı yanıtı almayabilirsiniz. İstemle oynayarak yanıtlar arasındaki farkı görebilirsiniz.)

1d2242715571fe6f.png

Dağıtılan işlevi çağırmanın alternatif yolları, gcloud komutu kullanılarak yapılan çağrılar vb. ile ilgili belirli sorularla sohbete sorun. 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) terminalden, senaryomuza uyacak şekilde düzenleyerek kullanabilirsiniz (Alternatif olarak, parametreleri istemin kendisinde iletmeyi deneyin ve yanıtta ayrıntılı gcloud functions call komutunu alıp alamadığınıza bakın):

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

Sonucum:

6f396d915251db78.png

11. Temizleme

Daha önce oluşturduğunuz Cloud Functions işlevlerini, Cloud Functions ayrıntılar sayfasındaki SİL düğmesini tıklayarak silebilirsiniz.

12. Tebrikler

Gemini'ı kullanarak Gemini 1.0 Pro'yu çağıran bir Java Cloud Functions işlevini başarıyla oluşturup dağıttınız ve test ettiniz. Bu uygulama, kitap önerisiyle ilgili giriş istemini kitapların özeti ve temasıyla birlikte alır.