1. Wprowadzenie
W tym ćwiczeniu utworzymy GlowUp, czyli narzędzie do przywracania zdjęć. GlowUp wykorzystuje AI do przywracania starych, uszkodzonych lub czarno-białych zdjęć, tworząc wysokiej jakości kolorowe obrazy w rozdzielczości 4K. Możesz użyć tego narzędzia, aby odnowić stare rodzinne fotografie, a nawet przywrócić uszkodzone ilustracje, rysunki, obrazy lub inne formy obrazów.
Do wdrożenia logiki aplikacji użyjesz Genkit Go, a do przetwarzania zdjęć – modelu Gemini 3 Pro Image (znanego też jako Nano Banana Pro).
Wymagania wstępne
- Podstawowa wiedza o języku programowania Go
- Podstawowa znajomość konsoli Google Cloud
Czego się nauczysz
- Jak tworzyć aplikacje Genkit w Go
- podstawowe pojęcia związane z Genkit, takie jak automatyzacje, wtyczki i prompty;
- Jak pisać prompty z użyciem szablonów Handlebars
- Jak uzyskać dane obrazu z odpowiedzi modelu
Czego potrzebujesz
Te warsztaty można w całości przeprowadzić w Google Cloud Shell, które ma wstępnie zainstalowane wszystkie niezbędne zależności (gcloud CLI, edytor kodu, Go, interfejs wiersza poleceń Gemini).
Możesz też pracować na własnym urządzeniu. W tym celu potrzebujesz:
- łańcuch narzędzi Go (wersja 1.24 lub nowsza),
- Node.js w wersji 20 lub nowszej (w przypadku interfejsu
genkitCLI) - terminal z zainstalowanym interfejsem wiersza poleceń
gcloud, - IDE do edytowania kodu, np. VS Code lub podobne
- Zalecane: agent do kodowania, np. interfejs wiersza poleceń Gemini lub Antigravity.
Kluczowe technologie
Więcej informacji o technologiach, z których będziemy korzystać, znajdziesz tutaj:
- Gemini Nano Banana Pro (Gemini 3 Pro Image): model, który obsługuje nasz proces przywracania
- Genkit Go: nasz zestaw narzędzi do koordynowania wywołań modeli
2. Konfiguracja środowiska
Wybierz jedną z tych opcji: Self-paced environment setup (Konfiguracja środowiska we własnym tempie), jeśli chcesz uruchomić ten przewodnik na własnym komputerze, lub Start Cloud Shell (Uruchom Cloud Shell), jeśli chcesz uruchomić go w całości w chmurze.
Samodzielne konfigurowanie środowiska
- Zaloguj się w konsoli Google Cloud i utwórz nowy projekt lub użyj istniejącego. Jeśli nie masz jeszcze konta Gmail ani Google Workspace, musisz je utworzyć.



- Nazwa projektu to wyświetlana nazwa uczestników tego projektu. Jest to ciąg znaków, który nie jest używany przez interfejsy API Google. Zawsze możesz ją zaktualizować.
- Identyfikator projektu jest unikalny we wszystkich projektach Google Cloud i nie można go zmienić po ustawieniu. Konsola Cloud automatycznie generuje unikalny ciąg znaków. Zwykle nie musisz się tym przejmować. W większości ćwiczeń z programowania musisz odwoływać się do identyfikatora projektu (zwykle oznaczanego jako
PROJECT_ID). Jeśli wygenerowany identyfikator Ci się nie podoba, możesz wygenerować inny losowy identyfikator. Możesz też spróbować własnej nazwy i sprawdzić, czy jest dostępna. Po tym kroku nie można go zmienić i pozostaje on taki przez cały czas trwania projektu. - Warto wiedzieć, że istnieje też trzecia wartość, numer projektu, której używają niektóre interfejsy API. Więcej informacji o tych 3 wartościach znajdziesz w dokumentacji.
- Następnie musisz włączyć płatności w konsoli Cloud, aby korzystać z zasobów i interfejsów API Google Cloud. Wykonanie tego laboratorium nie będzie kosztować dużo, a może nawet nic. Aby wyłączyć zasoby i uniknąć naliczania opłat po zakończeniu tego samouczka, możesz usunąć utworzone zasoby lub projekt. Nowi użytkownicy Google Cloud mogą skorzystać z bezpłatnego okresu próbnego, w którym mają do dyspozycji środki w wysokości 300 USD.
Uruchamianie Cloud Shell
Z Google Cloud można korzystać zdalnie na laptopie, ale w tym module praktycznym będziesz używać Google Cloud Shell, czyli środowiska wiersza poleceń działającego w chmurze.
W konsoli Google Cloud kliknij ikonę Cloud Shell na pasku narzędzi w prawym górnym rogu:

Uzyskanie dostępu do środowiska i połączenie się z nim powinno zająć tylko kilka chwil. Po zakończeniu powinno wyświetlić się coś takiego:

Ta maszyna wirtualna zawiera wszystkie potrzebne narzędzia dla programistów. Zawiera również stały katalog domowy o pojemności 5 GB i działa w Google Cloud, co znacznie zwiększa wydajność sieci i usprawnia proces uwierzytelniania. Wszystkie zadania w tym laboratorium możesz wykonać w przeglądarce. Nie musisz niczego instalować.
3. Konfiguracja projektu
Tworzenie projektu
Najpierw musimy utworzyć nowy katalog projektu i zainicjować moduł Go. W terminalu uruchom te polecenia:
mkdir -p glowup && cd glowup
go mod init glowup
Instalowanie interfejsu wiersza poleceń Genkit
Teraz musimy zainstalować interfejs wiersza poleceń Genkit. Dzięki temu uzyskasz dostęp do lokalnych narzędzi dla programistów, w tym interfejsu programisty. W oknie terminala wpisz:
curl -sL cli.genkit.dev | bash
Konfigurowanie zmiennych środowiskowych
Sprawdź, czy masz prawidłowo skonfigurowane dane logowania do Google Cloud. Zastąp your-project-id rzeczywistym identyfikatorem projektu. Lokalizacja musi być global, gdy używasz modeli Gemini 3 Pro w wersji testowej (jednym z nich jest Nano Banana Pro).
export GOOGLE_CLOUD_PROJECT=$(gcloud config get project)
export GOOGLE_CLOUD_LOCATION=global
Aby włączyć interfejs Vertex AI API, uruchom to polecenie w trybie powłoki:
gcloud services enable aiplatform.googleapis.com
Jeśli uruchamiasz polecenie na komputerze lokalnym (nie w Cloud Shell), musisz uwierzytelnić się za pomocą polecenia gcloud:
gcloud auth application-default login
4. Tworzenie pierwszej aplikacji Genkit
Genkit to platforma open source, która pomaga programistom tworzyć, wdrażać i monitorować gotowe do użycia w środowisku produkcyjnym aplikacje oparte na AI. W tej sekcji utworzymy prostą aplikację „Hello World”, aby pomóc Ci zapoznać się z platformą, zanim przejdziemy do logiki przywracania zdjęć.
Terminologia Genkit
Zanim zaczniesz korzystać z Genkit, warto poznać kilka kluczowych terminów:
- Wtyczki: służą do rozszerzania możliwości Genkit. Za pomocą wtyczek możesz m.in. rejestrować modele AI, które będą obsługiwać Twoją aplikację.
- Przepływy:główny element architektury Genkit. Typowy przepływ pracy polega na przyjęciu danych wejściowych, ich przetworzeniu i zwróceniu danych wyjściowych. Nie wymaga to koniecznie użycia modelu, ale w większości przypadków będziesz używać modeli w swoich przepływach.
- Prompty: szablony interakcji zapisane w formacie dotprompt (zapisane jako pliki
*.prompt). Zawierają one nie tylko instrukcje dotyczące modelu, ale także konfiguracje, takie jak nazwa modelu, parametry modelu, dane wejściowe i wyjściowe.
Nawiązywanie połączenia z modelami AI
Genkit używa wtyczek do łączenia kodu z dostawcami modeli. Dostępne są wtyczki do wszystkich głównych dostawców modeli, w tym Google, Anthropic i OpenAI. Możesz też używać wtyczek do łączenia się z modelami lokalnymi (np. za pomocą Ollamy) lub do rozszerzania możliwości Genkitu (np. łączenia się z serwerami MCP).
Aby uzyskać dostęp do modeli Google, użyj wtyczki googlegenai. Obsługuje 2 backendy:
- Google AI: najlepsze do prototypowania. Używa klucza interfejsu API.
- Vertex AI (Google Cloud): zalecana w środowiskach produkcyjnych. Korzysta z identyfikatora projektu i lokalizacji.
W tym ćwiczeniu w Codelabs użyjemy uwierzytelniania Vertex AI, odwołując się do projektu utworzonego na początku tego modułu.
Tworzenie przepływu powitania
Zanim zagłębimy się w proces przywracania zdjęć za pomocą funkcji Glow Up, zbudujmy podstawowy proces, aby zapoznać się z koncepcjami i upewnić się, że nasza konfiguracja działa prawidłowo.
Przepływ to specjalna funkcja Genkit, która otacza logikę AI, aby zapewnić:
- Bezpieczne pod względem typów dane wejściowe i wyjściowe: definiuj schematy za pomocą struktur Go na potrzeby weryfikacji statycznej i w czasie działania.
- Obsługa strumieniowania: strumieniowanie częściowych odpowiedzi lub danych niestandardowych
- Integracja z interfejsem programisty: testowanie i debugowanie przepływów za pomocą śladów wizualnych.
- Łatwe wdrażanie: wdrażaj jako punkty końcowe HTTP na dowolnej platformie.
Otwórz IDE i utwórz plik main.go w katalogu projektu. Jeśli używasz Cloud Shell, możesz użyć tego polecenia:
cloudshell edit main.go
Następnie dodaj ten kod:
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()
}
Zapisz plik, a potem uruchom polecenie go mod tidy, aby zaktualizować zależności:
go mod tidy
Powyższy kod inicjuje Genkit za pomocą wtyczki VertexAI, definiuje przepływ o nazwie „greeter”, a następnie czeka w nieskończoność na <-ctx.Done(). Wstrzymujemy wykonanie, aby program nie zakończył się od razu, ponieważ nie podajemy mu żadnych instrukcji dotyczących wykonania przepływu.
Oznacza to, że jeśli uruchomisz ten program w obecnej postaci, nie będzie on działać samodzielnie – musimy jakoś wywołać przepływ. W prawdziwej aplikacji produkcyjnej ten przepływ umieścilibyśmy w serwerze WWW lub aplikacji CLI, ale podczas programowania możemy użyć interfejsu wiersza poleceń genkit, aby ułatwić sobie tworzenie i optymalizację przepływu.
genkit CLI zostało opracowane, aby pomóc nam testować modele, prompty, przepływy i inne komponenty stosu Genkit. Ma też pełną obsługę śladów, co jest bardzo wygodne, gdy chcesz zrozumieć, jak aplikacja działa w tle. Aby uruchomić przepływ powitalny za pomocą interfejsu wiersza poleceń genkit, uruchom to polecenie:
genkit start -- go run main.go
Spowoduje to uruchomienie interfejsu Telemetry API i punktów końcowych interfejsu deweloperskiego. Powinien pojawić się ekran podobny do tego:
$ genkit start -- go run main.go Telemetry API running on http://localhost:4033 Project root: /home/daniela/glowup Genkit Developer UI: http://localhost:4000
Jeśli otworzysz localhost:4000 w przeglądarce, aby uruchomić interfejs Dev-UI. Powinien pojawić się ekran podobny do tego:

Poświęć trochę czasu na zapoznanie się z interfejsem programisty. Możesz uruchomić automatyzację „powitania” tylko raz, aby sprawdzić, jak działa.
Korzystanie z szablonów promptów
Możesz wprawdzie zakodować na stałe prompty w wywołaniach modelu, tak jak w poprzednim przykładzie, ale lepszym rozwiązaniem byłoby utworzenie szablonów promptów, aby przechowywać wszystkie prompty aplikacji w jednym miejscu. Ułatwia to nie tylko znajdowanie ich podczas konserwacji kodu, ale też pozwala eksperymentować z promptami niezależnie od przepływów.
Do definiowania szablonów promptów Genkit używa formatu open source dotprompt, który jest zapisywany jako pliki *.prompt. Plik .prompt składa się z 2 części:
- Wstęp: blok YAML, który definiuje model, parametry modelu oraz schematy wejściowe i wyjściowe.
- Treść: treść promptu, którą można szablonować za pomocą składni „handlebars”. Jeśli na przykład zdefiniujesz dane wejściowe o nazwie
variable-name, możesz się do nich odwołać w treści jako{{variable-name}}.
Struktura katalogów projektu będzie wyglądać tak:
glowup/
├── main.go
└── prompts/
└── greeter.prompt
Zobaczmy, jak to wygląda w praktyce. Najpierw utwórz folder, w którym będziesz przechowywać prompty:
mkdir -p prompts
Następnie utwórz plik greeter.prompt:
cloudshell edit prompts/greeter.prompt
Wstaw tę treść:
greeter.prompt

Ten prompt prezentuje kilka funkcji języka szablonu. Najpierw w nagłówku określamy model vertexai/gemini-2.5-flash. Aby określić model, musisz użyć nazewnictwa zdefiniowanego w dokumentacji odpowiedniej wtyczki.
Sekcja konfiguracji umożliwia skonfigurowanie parametrów modelu. Używamy temperatury 1,9, aby model mógł być bardziej kreatywny. Temperatura mieści się w zakresie od 0 (bardziej spójne wyniki) do 2 (bardziej kreatywne wyniki). Te i inne parametry modelu są zwykle publikowane w karcie modelu. Oto na przykład karta modelu gemini-2.5-flash.
W sekcji danych wejściowych możemy określić argumenty promptu. W tym przypadku definiujemy nazwę jako ciąg znaków. Po wstępie znajduje się treść promptu. Pierwszy blok zawiera prompt systemowy, a drugi – prompt użytkownika. Wszystkie te elementy razem umożliwiają stosowanie bardzo skutecznych technik promptowania. Pełną dokumentację znajdziesz dotprompt tutaj.
Teraz dostosujmy greeter, aby używać utworzonego prompta:
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()
}
Spróbuj uruchomić przepływ z poziomu wiersza poleceń z nazwą i bez niej, aby zobaczyć różnicę. Uruchamianie bez nazwy:
genkit flow:run greeter
Przykładowe dane wyjściowe:
$ 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!"
Z nazwą:
genkit flow:run greeter '{"name":"Daniela"}'
Przykładowe dane wyjściowe:
$ 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!"
Widzisz, że szablon działa zgodnie z oczekiwaniami. Jesteśmy gotowi, aby przenieść ten projekt na wyższy poziom.
5. Przywracanie obrazów za pomocą Nano Banana Pro
The Restoration Prompt
Znasz już podstawowe elementy Genkit. Czas utworzyć prompt do przywracania zdjęć.
W katalogu prompts utwórz plik o nazwie glowup.prompt i wklej do niego tę zawartość:
glowup.prompt

Prompt przywracania ma taki sam wzór jak prompt „powitalny”, ale z kilkoma istotnymi różnicami:
- Rozmiar obrazu: właściwość
imageSizeparametruimageConfigjest parametrem Nano Banana Pro, który jest specyficzny dla tego modelu. Umożliwia określenie rozmiaru wyjściowego jako 1K, 2K lub 4K. - Dane wejściowe multimediów: używamy szablonu
{{ media }}, aby wstawić zdjęcie do prompta użytkownika. Ta technika umożliwia wysyłanie do modelu promptów multimodalnych (tekst + obraz).
Możesz przetestować ten prompt w interfejsie programisty. Możesz go dostosować, aby sprawdzić, jak wpłynie to na wynik.
Proces przywracania obrazu
Gdy prompt przywracania będzie gotowy, możemy utworzyć aplikację CLI. Zastąp zawartość pliku main.go poniższym kodem:
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
}
Struktura kodu jest bardzo podobna do struktury przepływu greeter, ale tym razem jest on dostosowany do działania jako samodzielna aplikacja CLI. Zamiast blokować na zawsze, uruchomi przepływ glowUp, zdekoduje dane wyjściowe i zapisze wynikowe dane binarne na dysku.
Musimy zdekodować dane wyjściowe, ponieważ model zwraca dane obrazu w tym formacie:
data:<mime type>;base64,<base64 encoded image>
W funkcji decode widać, że używamy operacji na ciągach znaków, aby podzielić typ MIME i zakodowane części obrazu. Następnie używamy funkcji mime.ExtensionByType i base64.DecodeString, aby wyodrębnić informacje potrzebne do zapisania pliku.
Testowanie procesu przywracania
Teraz możesz wreszcie uruchomić ten proces z prawdziwym zdjęciem. Jeśli nie masz pod ręką starych zdjęć, które wymagają odnowienia, możesz spróbować z tym zdjęciem z domeny publicznej pobranym ze strony Biblioteki Kongresu:

Oto bezpośredni link do zdjęcia, który możesz przekazać do przepływu: 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
A oto odrestaurowane i pokolorowane dane wyjściowe:

Gotowe!
6. Wdrażanie glowUp jako usługi sieciowej
Jeśli zamiast aplikacji wiersza poleceń chcesz udostępniać przepływy w usłudze internetowej, Genkit zapewnia wygodny sposób przekształcania przepływów w punkty końcowe za pomocą genkit.Handler adaptera. Poniższy kod rejestruje przepływ glowUp jako punkt końcowy glowUp za pomocą genkit.Handler.
Możesz je udostępniać za pomocą zwykłego serwera HTTP, tak jak zwykle, używając pakietu http z biblioteki standardowej, ale Genkit udostępnia też wtyczkę server, która pomaga w niektórych typowych zadaniach związanych z serwerem, takich jak prawidłowe obsługiwanie sygnałów wyłączania.
Aby utworzyć serwer WWW, zastąp zawartość pliku main.go poniższym kodem.
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)
}
}
Możesz uruchomić tę usługę lokalnie lub w chmurze. Aby uruchomić go lokalnie, możesz po prostu uruchomić plik bezpośrednio, ponieważ program jest już gotowy, więc nie musisz go uruchamiać za pomocą interfejsu Genkit CLI. Na przykład:
go run main.go
Jest to operacja blokująca, więc aby ją przetestować, musisz uruchomić drugi terminal. Najszybszym sposobem jest użycie polecenia curl:
curl -sS -X POST http://localhost:8080/glowUp \
-H "Content-Type: application/json" \
-d '{"data":{"url": $IMAGE_URL, "contentType":"image/jpeg"}}' \
> result.json
Ponieważ jest to odpowiedź serwera, musimy zdekodować obraz w formacie base64:
cat result.json | jq -r '.result' | awk -F ',' '{print $2}' | base64 -d > restored.png
Wdrażanie usługi internetowej w Cloud Run
To, że serwer „działa na moim komputerze”, jest w porządku, ale w idealnym świecie wdrożylibyśmy go gdzieś indziej, aby był dostępny dla wszystkich naszych użytkowników. Jednym z najwygodniejszych sposobów wdrażania takich usług jest korzystanie z funkcji wdrażania z kodu źródłowego w Cloud Run. Dzięki tej funkcji nie musisz nawet samodzielnie tworzyć kontenera, ponieważ wszystko jest zautomatyzowane.
Aby wdrożyć tę usługę w Cloud Run za pomocą wdrożenia ze źródła, wykonaj to polecenie (zastąp identyfikator projektu własnym):
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
Wdrożenie może potrwać kilka minut. Gdy skończysz, możesz przetestować punkt końcowy, wysyłając kolejne żądanie za pomocą curl:
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
Ponownie musimy zdekodować obraz w formacie Base64:
cat result.json | jq -r '.result' | awk -F ',' '{print $2}' | base64 -d > restored_cloudrun.png
Mamy już w pełni działający serwer WWW do przywracania zdjęć.
Opcjonalnie: „vibe coding” aplikacji klienta
Pisanie kodu ręcznie jest ciekawe, ale może być też trudne, jeśli nigdy wcześniej nie wykonywałeś(-aś) określonego typu projektu. Na szczęście mamy teraz agentów kodowania, którzy mogą przyspieszyć ten proces.
W tym kroku zamiast pisać kod samodzielnie poprosimy o to interfejs wiersza poleceń Gemini (lub innego ulubionego agenta do kodowania). Użyj tego prompta:
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
Agent może potrzebować nieco zmienić organizację plików, ponieważ w tym samym module nie mogą znajdować się 2 funkcje „main”. Obserwuj jego działanie i kieruj go w stronę właściwego wdrożenia, podając w razie potrzeby kod serwera lub fragmenty kodu.
Sprzątanie po zakończeniu modułu
7. Podsumowanie
Gratulacje! Udało Ci się utworzyć aplikację do przywracania zdjęć w wysokiej jakości za pomocą Genkit i Nano Banana Pro.
Z tego modułu dowiedzieliśmy się, jak:
- Konfigurowanie środowiska do tworzenia aplikacji Genkit Go
- Tworzenie promptów multimodalnych za pomocą
dotprompt - Tworzenie przepływów Genkit za pomocą szablonów promptów
- Przetwarzanie obrazów za pomocą Nano Banana Pro
- Pakowanie przepływów Genkit jako aplikacji wiersza poleceń i usług internetowych
- Wdrażanie aplikacji Genkit w Cloud Run
Po zakończeniu testowania pamiętaj o zwolnieniu miejsca w środowisku.
Dalsze kroki
Możesz kontynuować naukę, przeglądając inne codelaby na tej platformie lub samodzielnie ulepszając aplikację glowUp.
Jeśli potrzebujesz pomysłów na ulepszenia, możesz spróbować:
- Włącz interfejs wiersza poleceń glowUp, aby przywrócić pliki lokalne
- Tworzenie frontendu usługi internetowej GlowUp
- Automatyczne wykrywanie typu MIME na podstawie danych
- wykonywać inne rodzaje przetwarzania obrazów (np. przekształcanie zdjęcia w rysunek, rysunku w zdjęcie, szkicu w gotową grafikę itp.);
- utworzyć lub ulepszyć klienta (może stworzyć aplikację na smartfona?),
Możliwości są nieograniczone. Jeśli pomysł samodzielnego tworzenia kodu Cię przeraża, zawsze możesz skorzystać z pomocy agenta do kodowania, takiego jak interfejs wiersza poleceń Gemini lub Antigravity. Jeśli chcesz robić więcej za pomocą Genkit, kodowanie agentów w połączeniu z serwerem Genkit MCP może znacznie ułatwić Ci pracę.
Pełny kod tego repozytorium znajdziesz tutaj.
Pozdrawiamy