Genkit Go ve Nano Banana Pro kullanarak fotoğraf restorasyon uygulaması oluşturma

1. Giriş

Bu codelab'de, fotoğraf restorasyon aracı olan GlowUp'ı oluşturacağız. GlowUp, eski, hasarlı veya siyah beyaz fotoğrafları yapay zeka kullanarak restore eder ve yüksek kaliteli 4K renkli görüntüler oluşturur. Bu aracı kullanarak aile fotoğraflarınıza yeni bir görünüm kazandırabilir, hatta hasarlı resimleri, çizimleri, tabloları veya diğer görüntüleri onarmak için de kullanabilirsiniz.

Uygulama mantığını uygulamak için Genkit Go'yu, fotoğrafları işlemek için ise Gemini 3 Pro Image (Nano Banana Pro olarak da bilinir) modelini kullanacaksınız.

Ön koşullar

  • Go programlama diliyle ilgili temel düzeyde bilgi
  • Google Cloud Console hakkında temel bilgiler

Neler öğreneceksiniz?

  • Go'da Genkit uygulamaları geliştirme
  • Akışlar, eklentiler ve istemler gibi temel Genkit kavramları
  • Handlebar şablonlarıyla istem yazma
  • Model yanıtlarından görüntü verilerini alma

İhtiyacınız olanlar

Bu atölye çalışması, gerekli tüm bağımlılıklar (gcloud CLI, kod düzenleyici, Go, Gemini CLI) önceden yüklenmiş olarak gelen Google Cloud Shell'de tamamen yapılabilir.

Alternatif olarak, kendi makinenizde çalışmayı tercih ederseniz aşağıdakilere ihtiyacınız olacaktır:

  • Go araç zinciri (1.24 veya sonraki sürümler)
  • Node.js v20 veya sonraki sürümler (genkit CLI için)
  • gcloud CLI'nın yüklü olduğu bir terminal
  • Kodunuzu düzenlemek için VS Code veya benzeri bir IDE
  • Önerilen: Gemini CLI veya Antigravity gibi bir kodlama aracısı

Önemli Teknolojiler

Kullanacağımız teknolojiler hakkında daha fazla bilgiyi burada bulabilirsiniz:

  • Gemini Nano Banana Pro (Gemini 3 Pro Image): Restorasyon sürecimizi destekleyen model
  • Genkit Go: Model çağrılarını düzenlemeye yönelik araç setimiz

2. Ortam Kurulumu

Aşağıdaki seçeneklerden birini belirleyin: Bu codelab'i kendi makinenizde çalıştırmak istiyorsanız Kendi hızınızda ortam kurulumu'nu, bu codelab'i tamamen bulutta çalıştırmak istiyorsanız Cloud Shell'i başlat'ı seçin.

Yönlendirmesiz ortam kurulumu

  1. Google Cloud Console'da oturum açın ve yeni bir proje oluşturun veya mevcut bir projeyi yeniden kullanın. Gmail veya Google Workspace hesabınız yoksa hesap oluşturmanız gerekir.

295004821bab6a87.png

37d264871000675d.png

96d86d3d5655cdbe.png

  • Proje adı, bu projenin katılımcıları için görünen addır. Google API'leri tarafından kullanılmayan bir karakter dizesidir. Bu bilgiyi istediğiniz zaman güncelleyebilirsiniz.
  • Proje kimliği, tüm Google Cloud projelerinde benzersizdir ve sabittir (ayarlandıktan sonra değiştirilemez). Cloud Console, benzersiz bir dizeyi otomatik olarak oluşturur. Genellikle bu dizenin ne olduğuyla ilgilenmezsiniz. Çoğu codelab'de proje kimliğinize (genellikle PROJECT_ID olarak tanımlanır) başvurmanız gerekir. Oluşturulan kimliği beğenmezseniz başka bir rastgele kimlik oluşturabilirsiniz. Dilerseniz kendi adınızı deneyerek kullanılabilir olup olmadığını kontrol edebilirsiniz. Bu adım tamamlandıktan sonra değiştirilemez ve proje süresince geçerli kalır.
  • Bazı API'lerin kullandığı üçüncü bir değer olan Proje Numarası da vardır. Bu üç değer hakkında daha fazla bilgiyi belgelerde bulabilirsiniz.
  1. Ardından, Cloud kaynaklarını/API'lerini kullanmak için Cloud Console'da faturalandırmayı etkinleştirmeniz gerekir. Bu codelab'i tamamlamak neredeyse hiç maliyetli değildir. Bu eğitimin ötesinde faturalandırılmayı önlemek için kaynakları kapatmak üzere oluşturduğunuz kaynakları veya projeyi silebilirsiniz. Yeni Google Cloud kullanıcıları 300 ABD doları değerinde ücretsiz deneme programından yararlanabilir.

Cloud Shell'i başlatma

Google Cloud, dizüstü bilgisayarınızdan uzaktan çalıştırılabilir. Ancak bu codelab'de, Cloud'da çalışan bir komut satırı ortamı olan Google Cloud Shell'i kullanacaksınız.

Google Cloud Console'da sağ üstteki araç çubuğunda Cloud Shell simgesini tıklayın:

Cloud Shell'i etkinleştirme

Ortamın temel hazırlığı ve bağlanması yalnızca birkaç dakikanızı alır. İşlem tamamlandığında aşağıdakine benzer bir sonuç görürsünüz:

Ortamın bağlandığını gösteren Google Cloud Shell terminalinin ekran görüntüsü

Bu sanal makine, ihtiyaç duyacağınız tüm geliştirme araçlarını içerir. 5 GB boyutunda kalıcı bir ana dizin sunar ve Google Cloud üzerinde çalışır. Bu sayede ağ performansı ve kimlik doğrulama önemli ölçüde güçlenir. Bu codelab'deki tüm çalışmalarınızı tarayıcıda yapabilirsiniz. Herhangi bir şey yüklemeniz gerekmez.

3. Proje Ayarları

Projeyi oluşturma

Öncelikle projeniz için yeni bir dizin oluşturup Go modülünü başlatmanız gerekir. Terminalinizde aşağıdaki komutları çalıştırın:

mkdir -p glowup && cd glowup
go mod init glowup

Genkit CLI'yı yükleme

Şimdi Genkit CLI'yı yüklememiz gerekiyor. Bu sayede, geliştirici kullanıcı arayüzü de dahil olmak üzere yerel geliştirici araçlarına erişebilirsiniz. Terminal pencerenize şunu yazın:

curl -sL cli.genkit.dev | bash

Ortam değişkenlerini yapılandırma

Doğru Google Cloud kimlik bilgilerinizin ayarlandığından emin olun. your-project-id öğesini kendi proje kimliğinizle değiştirin. Gemini 3 Pro Önizleme modelleri (Nano Banana Pro da bunlardan biridir) kullanılırken konum global olmalıdır.

export GOOGLE_CLOUD_PROJECT=$(gcloud config get project)
export GOOGLE_CLOUD_LOCATION=global

Vertex AI API'yi etkinleştirmek için kabuk modunda aşağıdaki komutu çalıştırın:

gcloud services enable aiplatform.googleapis.com

Yerel makinenizden (Cloud Shell'de değil) çalıştırıyorsanız gcloud komutuyla kimliğinizi doğrulamanız gerekir:

gcloud auth application-default login

4. İlk Genkit uygulamanızı oluşturma

Genkit, geliştiricilerin üretime hazır yapay zeka destekli uygulamalar oluşturmasına, dağıtmasına ve izlemesine yardımcı olmak için tasarlanmış açık kaynaklı bir çerçevedir. Bu bölümde, fotoğraf restorasyon mantığına geçmeden önce çerçeveye alışmanıza yardımcı olmak için basit bir "Hello World" uygulaması oluşturacağız.

Genkit terminolojisi

Genkit ile çalışmaya başlamadan önce birkaç temel terimi anlamanız önemlidir:

  • Eklentiler: Genkit'in özelliklerini genişletmek için kullanılır. Uygulamanıza güç katacak yapay zeka modellerini kaydettiğiniz yerler arasında eklentiler de bulunur.
  • Akışlar: Genkit'in ana mimari bileşeni. Tipik bir akış, girişi alır, işler ve çıkış döndürür. Model kullanılması zorunlu olmasa da akışlarınızda genellikle modelleri kullanırsınız.
  • İstemler: dotprompt biçiminde depolanan etkileşim şablonları (*.prompt dosyaları olarak kaydedilir). Bunlar yalnızca model talimatlarını değil, aynı zamanda model adı, model parametreleri, girişler ve çıkışlar gibi yapılandırmaları da içerir.

Yapay zeka modelleriyle bağlantı kurma

Genkit, kodunuzu model sağlayıcılara bağlamak için eklentileri kullanır. Google, Anthropic ve OpenAI dahil olmak üzere tüm büyük model sağlayıcılar için eklentiler vardır. Ayrıca, yerel modellere bağlanmak (ör. Ollama'yı kullanarak) veya Genkit'in özelliklerini genişletmek (ör. MCP sunucularına bağlanmak) için de eklentileri kullanabilirsiniz.

Google modellerine erişmek için googlegenai eklentisini kullanmanız gerekir. İki arka ucu destekler:

  • Google AI: Prototip oluşturmak için en iyisidir. API anahtarı kullanır.
  • Vertex AI (Google Cloud): Üretim için önerilir. Proje kimliğini ve konumu kullanır.

Bu codelab'de, laboratuvarın başında oluşturduğunuz projeye referans veren Vertex AI kimlik doğrulamasını kullanacağız.

Karşılama akışı oluşturma

Glow Up fotoğraf restorasyonu akışını daha ayrıntılı incelemeden önce, kavramlara aşina olmak ve kurulumumuzun düzgün çalıştığından emin olmak için temel bir akış oluşturalım.

Akış, yapay zeka mantığınızı sarmalayarak aşağıdakileri sağlayan özel bir Genkit işlevidir:

  • Tür güvenli girişler ve çıkışlar: Şemaları statik ve çalışma zamanı doğrulaması için Go yapılarını kullanarak tanımlayın.
  • Akış desteği: Kısmi yanıtları veya özel verileri yayınlayın
  • Geliştirici kullanıcı arayüzü entegrasyonu: Görsel izlerle akışları test etme ve hatalarını ayıklama
  • Kolay dağıtım: Herhangi bir platforma HTTP uç noktaları olarak dağıtın.

IDE'nizi açın ve proje dizininizde bir main.go dosyası oluşturun. Cloudshell kullanıyorsanız aşağıdaki komutu kullanabilirsiniz:

cloudshell edit main.go

Ardından aşağıdaki kodu ekleyin:

main.go

package main

import (
        "context"
        "log"
        "os"
        "os/signal"
        "syscall"

        "github.com/firebase/genkit/go/genkit"
        "github.com/firebase/genkit/go/ai"
        "github.com/firebase/genkit/go/plugins/googlegenai"
)

func main() {
        ctx, cancel := signal.NotifyContext(context.Background(), os.Interrupt, syscall.SIGTERM)
        defer cancel()

        // Initialize Genkit with the Vertex AI plugin
        g := genkit.Init(ctx,
                genkit.WithPlugins(&googlegenai.VertexAI{}),
        )

        // Define the greeter flow
        genkit.DefineFlow(g, "greeter", func(ctx context.Context, name string) (string, error) {
                text, err := genkit.GenerateText(ctx, g,
                        ai.WithModelName("vertexai/gemini-2.5-pro"),
                        ai.WithPrompt("Say a warm and creative hello to %s", name),
                )
                if err != nil {
                        return "", err
                }

                return text, nil
        })

        // Register the flow here in the next steps
        log.Println("GlowUp initialized. Ready for flows.")
        <-ctx.Done()
}

Dosyayı kaydedin ve bağımlılıklarınızı güncellemek için go mod tidy komutunu çalıştırın:

go mod tidy

Yukarıdaki kod, Genkit'i VertexAI eklentisiyle başlatır, "greeter" adlı bir akış tanımlar ve ardından <-ctx.Done() üzerinde süresiz olarak bekler. Akışı gerçekten yürütmesi için herhangi bir talimat vermediğimizden, bu programın hemen sonlandırılmaması için yürütmeyi durduruyoruz.

Bu nedenle, bu programı şu anki haliyle çalıştırırsanız kendi başına pek bir şey yapmaz. Akışı bir şekilde çağırmamız gerekir. Gerçek bir üretim uygulamasında bu akışı bir web sunucusuna veya CLI uygulamasına sarmalayacak olsak da geliştirme sırasında akışı geliştirmemize ve optimize etmemize yardımcı olması için genkit CLI'yı kullanabiliriz.

genkit CLI, modelleri, istemleri, akışları ve Genkit yığınının diğer bileşenlerini test etmemize yardımcı olmak için geliştirildi. Ayrıca, uygulamanın arka planda nasıl çalıştığını anlamak istediğinizde çok kullanışlı olan izlemeler için tam destek sunar. genkit CLI'yı kullanarak karşılama akışımızı başlatmak için aşağıdaki komutu çalıştırın:

genkit start -- go run main.go

Bu işlem, Telemetri API'si ve Geliştirici kullanıcı arayüzü uç noktalarını başlatır. Aşağıdakine benzer bir tablo görürsünüz:

$ genkit start -- go run main.go
Telemetry API running on http://localhost:4033
Project root: /home/daniela/glowup
Genkit Developer UI: http://localhost:4000

Geliştirici kullanıcı arayüzünü başlatmak için tarayıcınızda localhost:4000 simgesini açarsanız. Aşağıdaki gibi bir ekran görürsünüz:

93d9bd9e1bd6627d.png

Geliştirici kullanıcı arayüzünü keşfetmek için zaman ayırın. İşleyiş şeklini görmek için "karşılama" akışını bir kez tetikleyebilirsiniz.

İstem şablonlarını kullanma

Önceki örnekte yaptığımız gibi istemlerinizi model çağrılarına sabit kodlayabilirsiniz ancak daha iyi bir yaklaşım, uygulamamızın tüm istemlerini merkezi bir şekilde depolamak için istem şablonları oluşturmaktır. Bu sayede, kodda bakım yaparken istemleri bulmak kolaylaşır ve istemlerle akışlardan bağımsız olarak denemeler yapabilirsiniz.

Genkit, istem şablonlarını tanımlamak için *.prompt dosyaları olarak kaydedilen açık kaynaklı dotprompt biçimini kullanır. .prompt dosyası iki bölümden oluşur:

  1. Ön kısım: Modeli, model parametrelerini, giriş ve çıkış şemalarını tanımlayan bir YAML bloğu
  2. Gövde: İstem gövdesi, "handlebars" söz dizimi kullanılarak şablon haline getirilebilir. Örneğin, variable-name adlı bir giriş tanımlarsanız bunu gövdede {{variable-name}} olarak referans verebilirsiniz.

Projenin dizin yapısı şöyle görünür:

glowup/
 ├── main.go        
 └── prompts/
      └── greeter.prompt

Bunu uygulamalı olarak görelim. Öncelikle istemlerinizi depolayacağınız klasörü oluşturun:

mkdir -p prompts

Ardından bir greeter.prompt dosyası oluşturun:

cloudshell edit prompts/greeter.prompt

Aşağıdaki içeriği ekleyin:

greeter.prompt

ec9fc82a98604123.png

Bu istem, şablon dilinin bazı özelliklerini gösterir. Öncelikle, ön yazıda vertexai/gemini-2.5-flash modelini belirtiriz. Bir modeli belirtmek için ilgili eklenti belgelerinde tanımlanan adlandırmayı kullanmanız gerekir.

Yapılandırma bölümü, model parametrelerini yapılandırmamıza olanak tanır. Modelin daha yaratıcı olmasına olanak tanımak için 1,9 sıcaklık değerini kullanıyoruz. Sıcaklık 0 (daha tutarlı çıkışlar) ile 2 (daha yaratıcı çıkışlar) arasında değişir. Bu ve diğer model parametreleri genellikle modelin model sayfasında yayınlanır. Örneğin, gemini-2.5-flash modelinin model sayfası aşağıda verilmiştir.

Giriş bölümü, istem için argümanlar belirtmemize olanak tanır. Bu örnekte, adı dize olarak tanımlıyoruz. Ön kısımdan sonra istem gövdesi gelir. Buradaki ilk blok, sistem istemini, ikinci blok ise kullanıcı istemini tanımlar. Tüm bu öğeler bir araya geldiğinde çok güçlü istem teknikleri kullanmanıza olanak tanır. dotprompt ile ilgili tüm belgelere buradan ulaşabilirsiniz.

Şimdi, greeter akışını, az önce oluşturduğumuz istemi kullanacak şekilde uyarlayalım:

main.go

package main

import (
        "context"
        "os"
        "os/signal"
        "syscall"

        "github.com/firebase/genkit/go/ai"
        "github.com/firebase/genkit/go/genkit"
        "github.com/firebase/genkit/go/plugins/googlegenai"
)

func main() {
        ctx, cancel := signal.NotifyContext(context.Background(), os.Interrupt, syscall.SIGTERM)
        defer cancel()

        // Initialize Genkit with the Vertex AI plugin
        g := genkit.Init(ctx,
                genkit.WithPlugins(&googlegenai.VertexAI{}),
                genkit.WithDefaultModel("vertexai/gemini-2.5-flash"),
        )

        // Define the greeter flow
        genkit.DefineFlow(g, "greeter", func(ctx context.Context, name *string) (string, error) {
                prompt := genkit.LookupPrompt(g, "greeter")

                input := map[string]any{
                        "name": name,
                }

                resp, err := prompt.Execute(ctx, ai.WithInput(input))
                if err != nil {
                        return "", err
                }
                return resp.Text(), nil
        })

        <-ctx.Done()
}

Farkı görmek için akışı komut satırından adla ve adsız olarak çalıştırmayı deneyin. Adsız çalıştırma:

genkit flow:run greeter

Örnek çıkış:

$ genkit flow:run greeter
Telemetry API running on http://localhost:4035
Running '/flow/greeter' (stream=false)...
Result:
"Hello there, absolutely delightful human!\n\nThe very moment your message arrived, the day instantly sparkled a little brighter. It's not just nice, it's genuinely **wonderful** to meet you!\n\nMay your entire day be filled with unexpected pockets of joy, effortless triumphs, and all the happiness you truly deserve! We're thrilled to have you here!"

Adla birlikte:

genkit flow:run greeter '{"name":"Daniela"}'

Örnek çıkış:

$ genkit flow:run greeter '{"name":"Daniela"}'
Telemetry API running on http://localhost:4035
Running '/flow/greeter' (stream=false)...
Result:
"Well hello there, Daniela! What a truly beautiful name, and what an absolute pleasure it is to meet you!\n\nRight from this moment, I just know your day is going to be brimming with positive energy and wonderful surprises. May it be filled with brilliant ideas, joyful moments, and the delightful realization that you're an amazing person doing incredible things. So glad you're here!"

Şablonun beklendiği gibi çalıştığını görebilirsiniz. Bu projeyi bir sonraki seviyeye taşımaya hazırız.

5. Nano Banana Pro ile görüntüleri geri yükleme

Restorasyon istemi

Genkit'in temel bileşenlerini öğrendiğinize göre artık fotoğraf restorasyonu istemimizi oluşturabiliriz.

İstemler dizininde glowup.prompt adlı bir dosya oluşturun ve aşağıdaki içeriği bu dosyaya yapıştırın:

glowup.prompt

fd0f1551466c8138.png

Geri yükleme istemi, "karşılama" istemimizle aynı kalıbı izler. Aralarında yalnızca birkaç önemli fark vardır:

  • Resim boyutu: imageSize özelliği, Nano Banana Pro'nun modele özgü bir parametresidir.imageConfig Bu sayede çıkış boyutunu 1K, 2K veya 4K olarak belirleyebiliriz.
  • Medya girişi: Kullanıcı istemine fotoğraf eklemek için {{ media }} şablonunu kullanıyoruz. Bu teknik, modele çok formatlı istemler (metin + resim) göndermemize olanak tanır.

Bu istemi geliştirici kullanıcı arayüzünde test edebilirsiniz. Çıkışı nasıl etkilediğini görmek için bu ayarı değiştirebilirsiniz.

Resim restorasyon akışı

Geri yükleme istemi hazır olduğuna göre şimdi CLI uygulamamızı oluşturalım. main.go dosyasının içeriğini aşağıdaki kodla değiştirin:

main.go

package main

import (
        "context"
        "encoding/base64"
        "errors"
        "flag"
        "fmt"
        "log"
        "mime"
        "os"
        "os/signal"
        "strings"
        "syscall"

        "github.com/firebase/genkit/go/ai"
        "github.com/firebase/genkit/go/genkit"
        "github.com/firebase/genkit/go/plugins/googlegenai"
)

func main() {
        url := flag.String("url", "", "url of the image to restore")
        contentType := flag.String("contentType", "image/jpeg", "content type of the image (default: image/jpeg)")
        flag.Parse()

        ctx, cancel := signal.NotifyContext(context.Background(), os.Interrupt, syscall.SIGTERM)
        defer cancel()

        // Initialize Genkit with the Vertex AI plugin
        g := genkit.Init(ctx,
                genkit.WithPlugins(&googlegenai.VertexAI{}),
        )

        // Input schema for the glowUp flow
        type Input struct {
                URL         string `json:"url,omitempty"`
                ContentType string `json:"contentType,omitempty"`
        }

        glowup := genkit.DefineFlow(g, "glowUp", func(ctx context.Context, input Input) (string, error) {
                // 1. Retrieve prompt
                prompt := genkit.LookupPrompt(g, "glowup")
                if prompt == nil {
                        return "", errors.New("prompt 'glowup' not found")
                }

                resp, err := prompt.Execute(ctx, ai.WithInput(input))
                if err != nil {
                        return "", fmt.Errorf("generation failed: %w", err)
                }

                return resp.Media(), nil
        })

        // triggers the flow and returns the encoded response from the model
        out, err := glowup.Run(ctx, Input{URL: *url, ContentType: *contentType})
        if err != nil {
                log.Fatalln(err)
        }

        // decodes image data and returns the appropriate file extension
        data, ext, err := decode(out)
        if err != nil {
                log.Fatalln(err)
        }

        // writes restored file to disk
        filename := "restored" + ext
        if err := os.WriteFile(filename, data, 0644); err != nil {
                log.Fatalln(err)
        }
}

// decode returns the decoded data and the file extension appropriate for the mime type
func decode(text string) ([]byte, string, error) {
        if !strings.HasPrefix(text, "data:") {
                return nil, "", errors.New("unsupported enconding format")
        }
        text = strings.TrimPrefix(text, "data:")
        parts := strings.Split(text, ";base64,")

        mimeType := parts[0]
        decoded, err := base64.StdEncoding.DecodeString(parts[1])
        if err != nil {
                return nil, "", err
        }

        ext, err := mime.ExtensionsByType(mimeType)
        if err != nil {
                return nil, "", err
        }

        return decoded, ext[0], nil
}

Kodun yapısı greeter akışına çok benzer ancak bu kez bağımsız bir CLI uygulaması olarak çalışacak şekilde uyarlanmıştır. Sonsuza kadar engellemek yerine glowUp akışını çalıştırır, çıkışın kodunu çözer ve sonuçtaki ikili verileri diske kaydeder.

Model, görüntü verilerini aşağıdaki biçimde döndürdüğü için çıkışı kod çözmemiz gerekir:

data:<mime type>;base64,<base64 encoded image>

decode işlevinde, MIME türünü ve kodlanmış resim bölümlerini ayırmak için dize işleme kullandığımızı görebilirsiniz. Ardından, dosyayı kaydetmek için ihtiyacımız olan bilgileri ayıklamak üzere mime.ExtensionByType ve base64.DecodeString işlevlerini kullanırız.

Geri yükleme akışını test etme

Artık bu akışı gerçek bir resimle çalıştırmanın zamanı geldi. Elinizde restore edilmesi gereken eski fotoğraflar yoksa Kongre Kütüphanesi web sitesinden alınan bu kamu malı resimle deneyebilirsiniz:

f0fc83a81e88052a.png

Akışa aktarmak için fotoğrafın doğrudan bağlantısı: https://tile.loc.gov/storage-services/service/pnp/fsa/8c01000/8c01700/8c01765v.jpg

export IMAGE_URL="https://tile.loc.gov/storage-services/service/pnp/fsa/8c01000/8c01700/8c01765v.jpg"
go run main.go --url $IMAGE_URL

Geri yüklenen ve renklendirilen çıktı:

5ed7bfcf6d26313c.png

Başarılı aktarım

6. GlowUp'ı web hizmeti olarak dağıtma

Akışlarınızı komut satırı uygulaması yerine bir web hizmetinde kullanıma sunmak istiyorsanız Genkit, genkit.Handler bağdaştırıcısını kullanarak akışları uç noktalara dönüştürmek için uygun bir yol sunar. Aşağıdaki kod, glowUp kullanarak glowUp akışını glowUp uç noktası olarak kaydeder.genkit.Handler

Bunları, standart kitaplıktaki http paketini kullanarak normalde yaptığınız gibi düzenli bir HTTP sunucusuyla kullanıma sunabilirsiniz. Ancak Genkit, kapatma sinyallerini düzgün şekilde işleme gibi bazı yaygın sunucu standartlarıyla ilgili yardımcı olan bir server eklentisi de sağlar.

Web sunucunuzu oluşturmak için main.go içeriğini aşağıdaki kodla değiştirin.

package main

import (
        "context"
        "errors"
        "fmt"
        "log"
        "net/http"
        "os"

        "github.com/firebase/genkit/go/ai"
        "github.com/firebase/genkit/go/genkit"
        "github.com/firebase/genkit/go/plugins/googlegenai"
        "github.com/firebase/genkit/go/plugins/server"
)

func main() {
        ctx := context.Background()

        PORT := os.Getenv("PORT")
        if PORT == "" {
                PORT = "8080"
        }

        listenAddr := ":" + PORT

        // Initialize Genkit with the Vertex AI plugin
        g := genkit.Init(ctx,
                genkit.WithPlugins(&googlegenai.VertexAI{}),
        )

        // Input schema for the glowUp flow
        type Input struct {
                URL         string `json:"url,omitempty"`
                ContentType string `json:"contentType,omitempty"`
        }

        genkit.DefineFlow(g, "glowUp", func(ctx context.Context, input Input) (string, error) {
                prompt := genkit.LookupPrompt(g, "glowup")
                if prompt == nil {
                        return "", errors.New("prompt 'glowup' not found")
                }

                resp, err := prompt.Execute(ctx, ai.WithInput(input))
                if err != nil {
                        return "", fmt.Errorf("generation failed: %w", err)
                }

                return resp.Media(), nil
        })

        log.Printf("GlowUp Flow Server started. Listening on %s", listenAddr)
        mux := http.NewServeMux()
        for _, flow := range genkit.ListFlows(g) {
                mux.HandleFunc("POST /"+flow.Name(), genkit.Handler(flow))
        }

        if err := server.Start(ctx, listenAddr, mux); err != nil {
                // Check if the error is due to context cancellation
                if ctx.Err() != nil {
                        log.Println("GlowUp server shutting down gracefully...")
                        return
                }
                log.Fatal(err)
        }
}

Bu hizmeti yerel olarak veya bulutta çalıştırabilirsiniz. Artık program tamamlandığı için dosyayı doğrudan çalıştırarak yerel olarak çalıştırabilirsiniz. Bu nedenle, dosyayı genkit CLI üzerinden başlatmanız gerekmez. Örneğin:

go run main.go

Bu işlem engelleyici bir işlem olduğundan, testi gerçekleştirmek için ikinci bir terminal başlatmanız gerekir. En hızlı yöntem curl komutunu kullanmaktır:

curl -sS -X POST http://localhost:8080/glowUp \
     -H "Content-Type: application/json" \
     -d '{"data":{"url": $IMAGE_URL, "contentType":"image/jpeg"}}' \
     > result.json

Bu bir sunucu yanıtı olduğundan base64 kodlu görüntünün kodunu çözmemiz gerekir:

cat result.json | jq -r '.result' | awk -F ',' '{print $2}' | base64 -d > restored.png

Web hizmetini Cloud Run'a dağıtma

Bu sunucunun "bilgisayarımda çalışması" sorun değil ancak ideal durumda bunu tüm kullanıcılarımızın erişebileceği başka bir yere dağıtırız. Bu tür hizmetleri dağıtmanın en kolay yollarından biri Cloud Run'ın kaynaktan dağıtma özelliğini kullanmaktır. Bu özellik sayesinde kapsayıcıyı kendiniz oluşturmanıza bile gerek kalmaz. Her şey otomatik olarak yapılır.

Bu hizmeti kaynaktan dağıtım kullanarak Cloud Run'a dağıtmak için aşağıdaki komutu çalıştırın (proje kimliğini kendi kimliğinizle değiştirin):

gcloud run deploy glowup --source . --region us-central1 --no-allow-unauthenticated --set-env-vars GOOGLE_GENAI_USE_VERTEXAI=True,GOOGLE_CLOUD_LOCATION=$GOOGLE_CLOUD_LOCATION,GOOGLE_CLOUD_PROJECT=$GOOGLE_CLOUD_PROJECT

Dağıtım işleminin tamamlanması birkaç dakika sürebilir. İşlemi tamamladıktan sonra curl üzerinden başka bir istek göndererek uç noktayı test edebilirsiniz:

GLOWUP_URL=$(gcloud run services describe glowup --region us-central1 --format='value(status.url)')

curl -X POST "$GLOWUP_URL/glowUp" \
     -H "Authorization: Bearer $(gcloud auth print-identity-token)" \
     -H "Content-Type: application/json" \
     -d "{\"data\":{\"url\":\"$IMAGE_URL\", \"contentType\":\"image/jpeg\"} }" \
     > result.json

Base64 kodlu görüntüyü tekrar çözmemiz gerekir:

cat result.json | jq -r '.result' | awk -F ',' '{print $2}' | base64 -d > restored_cloudrun.png

Artık tamamen çalışan bir fotoğraf restorasyonu web sunucumuz var.

İsteğe bağlı: İstemci uygulamasına "sezgisel kodlama" ekleme

Manuel kod yazmak eğlenceli olsa da daha önce belirli bir proje türü üzerinde çalışmadıysanız zorlayıcı olabilir. Neyse ki günümüzde bu süreci hızlandırmamıza yardımcı olabilecek kodlama aracıları var.

Bu adımda kodu kendimiz yazmak yerine Gemini CLI'dan (veya en sevdiğiniz kodlama aracından) kodu yazmasını isteyeceğiz. Aşağıdaki istemi kullanın:

GlowUp is a photo restoration service that takes a restoration request as input and returns a restored picture as output. Your task is to create a client application that uses this server to process image urls and save a restored file locally.

TODO:
- Write a CLI application that receives three arguments: an url (required), content type (optional, defaults to image/jpeg) and addr (server address, optional, defaults to localhost:8080)
- The CLI should send a POST request to the /glowUp endpoint in the server with the body '{"data":{"url": <url>, "contentType": <contentType>} }'
- The server response should be parsed by stripping the "data:" prefix. The remainder will have the format <mimeType>;base64,<encoded imageData>
- Extract the mime type and convert to a file extension using the mime package
- Extract the image data and decode it using the base64 package
Save a file named "restored" + the detected file extension

Acceptance Criteria:
- The client builds successfully
- Use the client to restore the image https://tile.loc.gov/storage-services/service/pnp/fsa/8c01000/8c01700/8c01765v.jpg
- Check that restored.png exists after processing the image above

Aynı modülde iki "main" işlevi olamayacağından, dosyaların biraz yeniden düzenlenmesi gerekebilir. Agent'ın çalışmasını izleyin ve gerekirse sunucu kodunu veya snippet'lerini vererek doğru uygulamaya yönlendirin.

Laboratuvar çalışmasından sonra temizleme

7. Sonuç

Tebrikler! Genkit ve Nano Banana Pro'yu kullanarak yüksek kaliteli bir fotoğraf restorasyon uygulaması oluşturduysanız,

Bu codelab'de şunları öğrendiniz:

  • Genkit Go uygulamaları geliştirmek için ortamınızı yapılandırma
  • dotprompt ile çok formatlı istemler oluşturma
  • İstem şablonlarını kullanarak Genkit akışları oluşturma
  • Görüntüleri işlemek için Nano Banana Pro'yu kullanma
  • Genkit akışlarını komut satırı uygulamaları ve web hizmetleri olarak paketleme
  • Genkit uygulamalarını Cloud Run'a dağıtma

Testi tamamladıktan sonra ortamı temizlemeyi unutmayın.

Sonraki adımlar

Bu platformdaki diğer codelab'leri inceleyerek veya kendi başınıza glowUp'ta iyileştirmeler yaparak öğrenme yolculuğunuza devam edebilirsiniz.

İyileştirme fikirlerine ihtiyacınız varsa şunları deneyebilirsiniz:

  • Yerel dosyaları geri yüklemek için glowUp CLI'yi etkinleştirme
  • GlowUp web hizmeti için bir ön uç oluşturma
  • Verilerden MIME türünü otomatik olarak algılama
  • Diğer görüntü işleme türlerini gerçekleştirme (fotoğraftan çizime, çizimden fotoğrafa, taslaktan nihai resme vb.)
  • İstemci oluşturma veya iyileştirme (ör. akıllı telefon uygulaması oluşturma)

Seçenekleriniz sınırsızdır. Kendi başınıza ilerlemek biraz korkutucu geliyorsa Gemini CLI veya Antigravity gibi bir kodlama aracından yardım alabilirsiniz. Genkit ile daha fazlasını yapmak istiyorsanız Genkit MCP Sunucusu ile eşleştirilmiş kodlama aracıları hayatınızı çok daha kolay hale getirebilir.

Son olarak, bu depodaki kodun tamamına erişmek isterseniz buradan ulaşabilirsiniz.

Keyifli kodlamalar!