1. מבוא
ב-Codelab הזה נבנה את GlowUp, כלי לשחזור תמונות. GlowUp משתמש ב-AI כדי לשחזר תמונות ישנות, פגומות או בשחור-לבן, וליצור תמונות צבעוניות באיכות גבוהה ברזולוציית 4K. אתם יכולים להשתמש בכלי הזה כדי להחיות תמונות משפחתיות, או אפילו להתאים אותו לשחזור של איורים, ציורים או תמונות אחרות שניזוקו.
תשתמשו ב- Genkit Go כדי להטמיע את הלוגיקה של האפליקציה, וב- Gemini 3 Pro Image (שנקרא גם Nano Banana Pro) בתור המודל לעיבוד התמונות.
דרישות מוקדמות
- ידע בסיסי בשפת התכנות Go
- ידע בסיסי במסוף Google Cloud
מה תלמדו
- איך מפתחים אפליקציות Genkit ב-Go
- מושגים בסיסיים ב-Genkit כמו תהליכי עבודה, תוספים והנחיות
- איך כותבים הנחיות באמצעות תבניות Handlebar
- איך מקבלים נתוני תמונות מתשובות של מודלים
הדרישות
אפשר להשתתף בסדנה הזו באופן מלא ב-Google Cloud Shell, שבו כל התלויות הנדרשות (ה-CLI של gcloud, עורך קוד, Go, Gemini CLI) מותקנות מראש.
לחלופין, אם אתם מעדיפים לעבוד על המחשב שלכם, תצטרכו את הדברים הבאים:
- ערכת הכלים של Go (גרסה 1.24 ואילך)
- Node.js גרסה 20 ואילך (ל-
genkitCLI) - טרמינל עם
gcloudCLI מותקן - סביבת פיתוח משולבת (IDE) לעריכת הקוד, כמו VS Code או סביבה דומה
- מומלץ: סוכן לכתיבת קוד כמו Gemini CLI או Antigravity
טכנולוגיות מרכזיות
כאן אפשר למצוא מידע נוסף על הטכנולוגיות שבהן נשתמש:
- Gemini Nano Banana Pro (Gemini 3 Pro Image): המודל שמפעיל את תהליך השחזור שלנו
- Genkit Go: ערכת הכלים שלנו לניהול קריאות למודלים
2. הגדרת הסביבה
בוחרים באחת מהאפשרויות הבאות: הגדרה של סביבה בקצב אישי אם רוצים להריץ את ה-codelab הזה במחשב שלכם, או הפעלה של Cloud Shell אם רוצים להריץ את ה-codelab הזה כולו בענן.
הגדרת סביבה בקצב אישי
- נכנסים ל-מסוף Google Cloud ויוצרים פרויקט חדש או משתמשים בפרויקט קיים. אם עדיין אין לכם חשבון Gmail או Google Workspace, אתם צריכים ליצור חשבון.



- שם הפרויקט הוא השם המוצג של הפרויקט הזה למשתתפים. זו מחרוזת תווים שלא נמצאת בשימוש ב-Google APIs. תמיד אפשר לעדכן את המיקום.
- מזהה הפרויקט הוא ייחודי לכל הפרויקטים ב-Google Cloud ואי אפשר לשנות אותו אחרי שהוא מוגדר. מסוף Cloud יוצר באופן אוטומטי מחרוזת ייחודית, ובדרך כלל לא צריך לדעת מה היא. ברוב ה-Codelabs, תצטרכו להפנות למזהה הפרויקט (בדרך כלל מסומן כ-
PROJECT_ID). אם אתם לא אוהבים את המזהה שנוצר, אתם יכולים ליצור מזהה אקראי אחר. אפשר גם לנסות שם משתמש משלכם ולבדוק אם הוא זמין. אי אפשר לשנות את ההגדרה הזו אחרי השלב הזה, והיא תישאר לאורך הפרויקט. - לידיעתכם, יש ערך שלישי, מספר פרויקט, שחלק מממשקי ה-API משתמשים בו. במאמרי העזרה מפורט מידע נוסף על שלושת הערכים האלה.
- בשלב הבא, תצטרכו להפעיל את החיוב במסוף Cloud כדי להשתמש במשאבי Cloud או בממשקי API של Cloud. השלמת ה-codelab הזה לא תעלה לכם הרבה, אם בכלל. כדי להשבית את המשאבים ולמנוע חיובים נוספים אחרי שתסיימו את המדריך הזה, תוכלו למחוק את המשאבים שיצרתם או למחוק את הפרויקט. משתמשים חדשים ב-Google Cloud זכאים לתוכנית תקופת ניסיון בחינם בשווי 300$.
מפעילים את Cloud Shell
אפשר להפעיל את Google Cloud מרחוק מהמחשב הנייד, אבל ב-codelab הזה תשתמשו ב-Google Cloud Shell, סביבת שורת פקודה שפועלת בענן.
ב-מסוף Google Cloud, לוחצים על סמל Cloud Shell בסרגל הכלים שבפינה הימנית העליונה:

יחלפו כמה רגעים עד שההקצאה והחיבור לסביבת העבודה יושלמו. בסיום התהליך, אמור להופיע משהו כזה:

המכונה הווירטואלית הזו כוללת את כל הכלים שדרושים למפתחים. יש בה ספריית בית בנפח מתמיד של 5GB והיא פועלת ב-Google Cloud, מה שמשפר מאוד את הביצועים והאימות ברשת. אפשר לבצע את כל העבודה ב-codelab הזה בדפדפן. לא צריך להתקין שום דבר.
3. הגדרת הפרויקט
יצירת הפרויקט
קודם כל, צריך ליצור ספרייה חדשה לפרויקט ולאתחל את מודול Go. בטרמינל, מריצים את הפקודות הבאות:
mkdir -p glowup && cd glowup
go mod init glowup
התקנת Genkit CLI
עכשיו צריך להתקין את Genkit CLI. כך מקבלים גישה לכלים מקומיים למפתחים, כולל ממשק המשתמש למפתחים. בחלון הטרמינל, מקלידים:
curl -sL cli.genkit.dev | bash
הגדרת משתני סביבה
מוודאים שהגדרתם את פרטי הכניסה הנכונים ל-Google Cloud. מחליפים את your-project-id במזהה הפרויקט בפועל. כשמשתמשים במודלים בגרסת טרום-השקה של Gemini 3 Pro (כולל Nano Banana Pro), המיקום חייב להיות global.
export GOOGLE_CLOUD_PROJECT=$(gcloud config get project)
export GOOGLE_CLOUD_LOCATION=global
מריצים את הפקודה הבאה במצב מעטפת כדי להפעיל את Vertex AI API:
gcloud services enable aiplatform.googleapis.com
אם אתם מריצים את הפקודה מהמחשב המקומי (לא ב-Cloud Shell), תצטרכו לבצע אימות באמצעות הפקודה gcloud:
gcloud auth application-default login
4. יצירת אפליקציית Genkit הראשונה
Genkit הוא מסגרת קוד פתוח שנועדה לעזור למפתחים ליצור, לפרוס ולנטר אפליקציות מבוססות-AI שמוכנות לייצור. בקטע הזה ניצור אפליקציית Hello World פשוטה כדי שתכירו את המסגרת לפני שנעמיק בלוגיקה של שחזור התמונות.
הסברים על המונחים ב-Genkit
לפני שמתחילים לעבוד עם Genkit, חשוב להבין כמה מונחים מרכזיים:
- פלאגינים: משמשים להרחבת היכולות של Genkit. בין היתר, באמצעות פלאגינים אתם רושמים מודלים של AI כדי להפעיל את האפליקציה שלכם.
- תהליכי עבודה: הרכיב הארכיטקטוני העיקרי של Genkit. תהליך טיפוסי יקבל קלט, יעבד אותו ויחזיר פלט. לא תמיד צריך להשתמש במודל, אבל ברוב המקרים תשתמשו במודלים בתוך התהליכים.
- הנחיות: תבניות של אינטראקציות שמאוחסנות בפורמט dotprompt (נשמרות כקבצים מסוג
*.prompt). הם מכילים לא רק את ההוראות למודל, אלא גם הגדרות כמו שם המודל, פרמטרים של המודל, קלט ופלט.
יצירת קשר עם מודלים של AI
Genkit משתמש בתוספים כדי לקשר את הקוד שלכם לספקי מודלים. יש תוספים לכל ספקי המודלים הגדולים, כולל Google, Anthropic ו-OpenAI. אפשר גם להשתמש בתוספים כדי להתחבר למודלים מקומיים (למשל באמצעות Ollama) או כדי להרחיב את היכולות של Genkit (למשל להתחבר לשרתי MCP).
כדי לגשת למודלים של Google, צריך להשתמש בתוסף googlegenai. הוא תומך בשני סוגים של קצה עורפי:
- Google AI: הכי טוב ליצירת אב טיפוס. השימוש במפתח API.
- Vertex AI (Google Cloud): מומלץ לשימוש בסביבת הייצור. שימוש במזהה הפרויקט ובמיקום.
ב-Codelab הזה נשתמש באימות של Vertex AI בהתייחסות לפרויקט שיצרתם בתחילת ה-Codelab.
יצירת תהליך של הודעת פתיחה
לפני שנצלול לעומק של תהליך שחזור התמונות באמצעות התכונה 'שיפור התמונה', נבנה תהליך בסיסי כדי להכיר את המושגים ולוודא שההגדרה שלנו פועלת בצורה תקינה.
Flow היא פונקציה מיוחדת של Genkit שעוטפת את הלוגיקה של ה-AI כדי לספק:
- קלטים ופלטים בטוחים מבחינת סוג: הגדרת סכימות באמצעות מבני Go לאימות סטטי ובזמן ריצה
- תמיכה בסטרימינג: סטרימינג של תשובות חלקיות או נתונים מותאמים אישית
- שילוב של ממשק משתמש למפתחים: בדיקה וניפוי באגים של תהליכים באמצעות עקבות ויזואליות
- פריסה קלה: אפשר לפרוס כנקודות קצה של HTTP בכל פלטפורמה
פותחים את סביבת הפיתוח המשולבת ויוצרים קובץ main.go בספריית הפרויקט. אם משתמשים ב-Cloud Shell, אפשר להשתמש בפקודה הבאה:
cloudshell edit main.go
לאחר מכן מוסיפים את הקוד הבא:
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()
}
שומרים את הקובץ ואז מריצים את הפקודה go mod tidy כדי לעדכן את התלויות:
go mod tidy
הקוד שלמעלה מאתחל את Genkit באמצעות הפלאגין VertexAI, מגדיר תהליך בשם greeter ואז ממתין לנצח ב-<-ctx.Done(). אנחנו מעכבים את ההפעלה כדי שהתוכנית לא תסתיים באופן מיידי, כי אנחנו לא נותנים לה הוראות להפעלה של התהליך.
המשמעות היא שאם תריצו את התוכנית הזו כמו שהיא עכשיו, היא לא תעשה הרבה בעצמה – צריך להפעיל את רצף הפעולות בצורה כלשהי. בזמן פיתוח, אפשר להשתמש בכלי genkit CLI כדי לפתח את התהליך ולבצע בו אופטימיזציה. ביישום ייצור אמיתי, נשתמש בשרת אינטרנט או באפליקציית CLI כדי לעטוף את התהליך הזה.
פיתחנו את genkit CLI כדי לעזור לנו לבדוק מודלים, הנחיות, תהליכים ורכיבים אחרים של חבילת Genkit. בנוסף, יש לו תמיכה מלאה בנתוני מעקב, וזה מאוד נוח כשרוצים להבין איך האפליקציה פועלת מתחת לפני השטח. כדי להפעיל את תהליך ההצטרפות באמצעות genkit CLI, מריצים את הפקודה הבאה:
genkit start -- go run main.go
הפעולה הזו תתחיל הרצה של נקודות הקצה של Telemetry API ושל ממשק המשתמש למפתחים. אתם אמורים לראות משהו כזה:
$ genkit start -- go run main.go Telemetry API running on http://localhost:4033 Project root: /home/daniela/glowup Genkit Developer UI: http://localhost:4000
אם פותחים את localhost:4000 בדפדפן כדי להפעיל את ממשק המשתמש למפתחים. יוצג מסך כמו זה:

כדאי להקדיש זמן כדי להכיר את ממשק המשתמש למפתחים. אפשר להפעיל את תהליך ה-greeter פעם אחת רק כדי לראות איך הוא עובד.
שימוש בתבניות של הנחיות
אפשר להגדיר את ההנחיות בהקשה ישירות בקריאות למודל כמו בדוגמה הקודמת, אבל גישה טובה יותר היא ליצור תבניות הנחיות כדי לאחסן את כל ההנחיות של האפליקציה בצורה מרכזית. כך קל יותר למצוא אותם כשמבצעים תחזוקה של הקוד, וגם אפשר להתנסות בהנחיות בנפרד מהזרימות.
כדי להגדיר תבניות של הנחיות, Genkit משתמש בפורמט dotprompt בקוד פתוח, שנשמר כקובצי *.prompt. קובץ .prompt מורכב משני חלקים:
- Frontmatter: בלוק YAML שמגדיר את המודל, את הפרמטרים של המודל ואת סכימות הקלט והפלט
- גוף: גוף הפרומפט עצמו, שאפשר ליצור ממנו תבנית באמצעות תחביר Handlebars. לדוגמה, אם מגדירים קלט בשם
variable-name, אפשר להפנות אליו בגוף הבקשה בתור{{variable-name}}.
מבנה הספריות של הפרויקט ייראה כך:
glowup/
├── main.go
└── prompts/
└── greeter.prompt
בואו נראה דוגמה. קודם יוצרים את התיקייה לשמירת ההנחיות:
mkdir -p prompts
לאחר מכן יוצרים קובץ greeter.prompt:
cloudshell edit prompts/greeter.prompt
ומכניסים את התוכן הבא:
greeter.prompt

ההנחיה הזו מדגימה כמה מהתכונות של שפת התבניות. קודם כול מציינים את המודל vertexai/gemini-2.5-flash בחלק העליון של הקובץ. כדי לציין מודל, צריך להשתמש במינוח שמוגדר במסמכי התיעוד של הפלאגין הרלוונטי.
בקטע config אפשר להגדיר את הפרמטרים של המודל. אנחנו משתמשים ברמת אקראיות 1.9 כדי לאפשר למודל להיות יצירתי יותר. רמת האקראיות נעה בין 0 (תוצאות עקביות יותר) ל-2 (תוצאות יצירתיות יותר). הפרמטר הזה ופרמטרים אחרים של המודל מתפרסמים בדרך כלל בגיליון המודל. לדוגמה, הנה גיליון המודל של gemini-2.5-flash.
בקטע הקלט אפשר לציין ארגומנטים להנחיה. במקרה הזה, אנחנו מגדירים את השם כמחרוזת. אחרי ה-frontmatter מופיע גוף ההנחיה. הבלוק הראשון מגדיר את הנחיית המערכת, והבלוק השני הוא הנחיית המשתמש. השילוב של כל האלמנטים האלה מאפשר ליצור טכניקות הנחיה יעילות מאוד. כאן אפשר לעיין במסמכי התיעוד המלאים של dotprompt.
עכשיו נתאים את התהליך greeter כדי להשתמש בהנחיה שיצרנו:
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()
}
כדאי להריץ את התהליך משורת הפקודה, עם שם ובלי שם, כדי לראות את ההבדל. הפעלה ללא שם:
genkit flow:run greeter
פלט לדוגמה:
$ 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!"
עם שם:
genkit flow:run greeter '{"name":"Daniela"}'
פלט לדוגמה:
$ 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!"
אפשר לראות שהתבנית פעלה כמצופה. אנחנו מוכנים לקחת את הפרויקט הזה לשלב הבא.
5. שחזור תמונות באמצעות Nano Banana Pro
ההנחיה לשחזור
אחרי שהכרתם את אבני הבניין של Genkit, הגיע הזמן ליצור את ההנחיה לשחזור התמונה.
יוצרים קובץ בשם glowup.prompt בתיקיית ההנחיות ומדביקים בו את התוכן הבא:
glowup.prompt

ההנחיה לשחזור פועלת לפי אותו דפוס כמו ההנחיה שלנו לשיחה ראשונית, עם כמה הבדלים בולטים:
- גודל התמונה: המאפיין
imageSizeשלimageConfigהוא פרמטר ספציפי למודל Nano Banana Pro. היא מאפשרת לנו לציין את גודל הפלט כ-1K, 2K או 4K. - קלט מדיה: אנחנו משתמשים בתבנית
{{ media }}כדי להוסיף את התמונה להנחיה של המשתמש. הטכניקה הזו מאפשרת לנו לשלוח למודל הנחיות מולטי-מודאליות (טקסט + תמונה).
אפשר לבדוק את ההנחיה הזו בממשק המשתמש למפתחים. אתם יכולים לשנות את ההנחיה כדי לראות איך זה משפיע על הפלט.
תהליך שחזור התמונות
אחרי שההנחיה לשחזור מוכנה, אפשר להתחיל לבנות את אפליקציית ה-CLI. מחליפים את התוכן של main.go בקוד שלמטה:
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
}
מבנה הקוד דומה מאוד לזרימת העבודה של greeter, אבל הפעם הוא מותאם לפעולה כאפליקציית CLI עצמאית. במקום לחסום את הפעולה לתמיד, התהליך glowUp יפעל, הפלט יפוענח והנתונים הבינאריים שיתקבלו יישמרו בדיסק.
אנחנו צריכים לפענח את הפלט כי המודל מחזיר את נתוני התמונה בפורמט הבא:
data:<mime type>;base64,<base64 encoded image>
אפשר לראות בפונקציה decode שאנחנו משתמשים במניפולציה של מחרוזות כדי לפצל את סוג ה-MIME ואת חלקי התמונה המקודדים. לאחר מכן אנחנו משתמשים בפונקציות mime.ExtensionByType ו-base64.DecodeString כדי לחלץ את המידע שדרוש לנו לשמירת הקובץ.
בדיקת תהליך השחזור
עכשיו הגיע הזמן להריץ את התהליך הזה עם תמונה אמיתית. אם אין לכם תמונות ישנות שצריך לשחזר, אתם יכולים לנסות עם התמונה הזו שזמינה בדומיין ציבורי ואוחזרה מהאתר של ספריית הקונגרס:

הנה קישור ישיר לתמונה כדי להעביר אותה לתהליך: 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
והנה הפלט המשוחזר והצבוע:

הצלחת!
6. פריסת glowUp כשירות אינטרנט
אם במקום אפליקציית שורת פקודה אתם רוצים לחשוף את התהליכים שלכם בשירות אינטרנט, Genkit מספק דרך נוחה להמיר תהליכים לנקודות קצה באמצעות מתאם genkit.Handler. הקוד שלמטה רושם את זרימת glowUp כנקודת קצה של glowUp באמצעות genkit.Handler.
אפשר לחשוף אותם באמצעות שרת HTTP רגיל כמו שאתם עושים בדרך כלל באמצעות חבילת http מהספרייה הרגילה, אבל Genkit מספק גם פלאגין server שעוזר עם חלק מהקוד הנפוץ של השרת, כמו טיפול באותות כיבוי בצורה תקינה.
מחליפים את התוכן של main.go בקוד שלמטה כדי ליצור את שרת האינטרנט.
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)
}
}
אפשר להריץ את השירות הזה באופן מקומי או בענן. כדי להריץ את הקובץ באופן מקומי, אפשר להריץ אותו ישירות כי התוכנית הושלמה, ולכן לא צריך להפעיל אותה באמצעות ממשק שורת הפקודה (CLI) של Genkit. לדוגמה:
go run main.go
מכיוון שזו פעולת חסימה, צריך להפעיל טרמינל שני כדי לבדוק אותה. הדרך הכי מהירה היא להשתמש בפקודה curl:
curl -sS -X POST http://localhost:8080/glowUp \
-H "Content-Type: application/json" \
-d '{"data":{"url": $IMAGE_URL, "contentType":"image/jpeg"}}' \
> result.json
מכיוון שמדובר בתגובת שרת, צריך לפענח את התמונה בקידוד base64:
cat result.json | jq -r '.result' | awk -F ',' '{print $2}' | base64 -d > restored.png
פריסת שירות האינטרנט ב-Cloud Run
זה בסדר שהשרת הזה "פועל במחשב שלי", אבל בעולם אידיאלי היינו פורסים אותו במקום אחר שנגיש לכל המשתמשים שלנו. אחת הדרכים הנוחות ביותר לפרוס שירותים כאלה היא באמצעות התכונה 'פריסה ממקור' ב-Cloud Run. עם התכונה הזו, אתם לא צריכים אפילו לבנות את מאגר התגים בעצמכם – הכול אוטומטי.
כדי לפרוס את השירות הזה ב-Cloud Run באמצעות פריסה ממקור, מריצים את הפקודה הבאה (מחליפים את מזהה הפרויקט במזהה שלכם):
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
הפריסה עשויה להימשך כמה דקות. אחרי שמסיימים, אפשר לבדוק את נקודת הקצה על ידי שליחת בקשה נוספת דרך 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
שוב, צריך לפענח את התמונה בקידוד base64:
cat result.json | jq -r '.result' | awk -F ',' '{print $2}' | base64 -d > restored_cloudrun.png
עכשיו יש לנו שרת אינטרנט לשחזור תמונות שפועל באופן מלא.
אופציונלי: 'תכנות בשיטת Vibe coding' של אפליקציית לקוח
לכתוב קוד באופן ידני זה כיף, אבל זה יכול להיות גם מאתגר אם אף פעם לא עבדתם על סוג מסוים של פרויקט. למזלנו, היום יש לנו סוכני תכנות שיכולים לעזור לנו לזרז את התהליך.
בשלב הזה, במקום לכתוב את הקוד בעצמנו, נבקש מ-Gemini CLI (או מסוכן התכנות המועדף עליכם) לעשות את העבודה בשבילנו. משתמשים בהנחיה הבאה:
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
יכול להיות שהסוכן יצטרך לארגן מחדש את הקבצים, כי אי אפשר להגדיר שתי פונקציות בשם main באותו מודול. צופים בה בזמן שהיא פועלת ומכוונים אותה ליישום הנכון, ומספקים לה את קוד השרת או קטעי קוד אם צריך.
ניקוי אחרי שיעור Lab
7. סיכום
מעולה! יצרתם בהצלחה אפליקציה לשחזור תמונות באיכות גבוהה באמצעות Genkit ו-Nano Banana Pro,
ב-codelab הזה למדתם איך:
- הגדרת הסביבה לפיתוח אפליקציות Genkit Go
- יצירת הנחיות מרובות מצבים באמצעות
dotprompt - יצירת תהליכי עבודה ב-Genkit באמצעות תבניות של הנחיות
- שימוש ב-Nano Banana Pro לעיבוד תמונות
- אריזת תהליכי עבודה של Genkit כאפליקציות של שורת פקודה ושירותי אינטרנט
- פריסת אפליקציות Genkit ב-Cloud Run
אחרי שמסיימים את הבדיקה, חשוב לנקות את הסביבה.
השלבים הבאים
אתם יכולים להמשיך ללמוד ולעיין ב-Codelab נוספים בפלטפורמה הזו, או לשפר את glowUp בעצמכם.
אם אתם רוצים לקבל רעיונות לשיפורים, אתם יכולים לנסות:
- הפעלת glowUp CLI כדי לשחזר קבצים מקומיים
- יצירת קצה קדמי לשירות האינטרנט GlowUp
- זיהוי אוטומטי של סוג ה-MIME מתוך הנתונים
- לבצע סוגים אחרים של עיבוד תמונות (מתמונה לציור, מציור לתמונה, מסקיצה לאומנות סופית וכו').
- יצירה או שיפור של הלקוח (אולי בניית אפליקציה לסמארטפון?)
האפשרויות הן אינסופיות! אם הרעיון של יצירת קוד לבד נראה לכם קצת מפחיד, תמיד תוכלו להיעזר בסוכן קוד כמו Gemini CLI או Antigravity. אם אתם רוצים לעשות עוד דברים עם Genkit, תוכלו להשתמש בסוכני קידוד שמשולבים עם שרת Genkit MCP כדי להקל על עצמכם.
לבסוף, אם אתם רוצים לגשת לקוד המלא של המאגר הזה, תוכלו למצוא אותו כאן.
שיהיה בהצלחה!