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. הגדרת הסביבה
אתם יכולים להריץ את ה-Lab הזה מהמחשב שלכם או לגמרי בענן. גם אם תחליטו להריץ את הקוד באופן מקומי, תצטרכו פרויקט בענן ב-Google Cloud כדי לפרוס את הרכיבים בצד השרת בענן. בקטע הבא מוסבר איך ליצור את מרכז הבקרה הזה.
הגדרת סביבה בקצב אישי
- נכנסים ל-מסוף 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. כשמשתמשים במודלים בגרסת טרום-השקה של 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 בהתייחס לפרויקט שיצרתם בתחילת ה-Lab.
יצירת תהליך של הודעת פתיחה
לפני שנעמיק בתהליך של שיפור התמונות, נבנה תהליך בסיסי כדי להכיר את המושגים ולוודא שההגדרה שלנו פועלת בצורה תקינה.
Flow היא פונקציה מיוחדת של Genkit שעוטפת את הלוגיקה של ה-AI כדי לספק:
- קלטים ופלטים בטוחים מבחינת סוג: הגדרת סכימות באמצעות מבני נתונים (structs) של 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 בדפדפן כדי להפעיל את ממשק המשתמש למפתחים. יוצג מסך כמו זה:

כדאי להקדיש זמן כדי להכיר את ממשק המשתמש למפתחים. אפשר להפעיל את תהליך ההצטרפות פעם אחת רק כדי לראות איך הוא עובד.
שימוש בתבניות של הנחיות
אפשר להגדיר את ההנחיות בהקוד קשיח בקריאות למודל כמו בדוגמה הקודמת, אבל גישה טובה יותר היא ליצור תבניות הנחיות כדי לאחסן את כל ההנחיות של האפליקציה בצורה מרכזית. כך קל יותר למצוא אותם כשמבצעים תחזוקה של הקוד, וגם אפשר להתנסות בהנחיות בנפרד מהזרימות.
כדי להגדיר תבניות של הנחיות, 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 '"Daniela"'
פלט לדוגמה:
$ genkit flow:run greeter '"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. הקוד שלמטה רושם את רכיב ה-Flow 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
אחרי שמסיימים את הבדיקה, חשוב לנקות את הסביבה.
השלבים הבאים
אתם יכולים להמשיך את מסע הלמידה שלכם ולעיין ב-codelabs נוספים בפלטפורמה הזו, או לשפר את glowUp בעצמכם.
אם אתם רוצים לקבל רעיונות לשיפורים, אתם יכולים לנסות:
- הפעלת glowUp CLI כדי לשחזר קבצים מקומיים
- יצירת קצה קדמי לשירות האינטרנט GlowUp
- זיהוי אוטומטי של סוג ה-MIME מתוך הנתונים
- לבצע סוגים אחרים של עיבוד תמונה (מתמונה לציור, מציור לתמונה, מסקיצה לאומנות סופית וכו'
- יצירה או שיפור של הלקוח (אולי בניית אפליקציה לסמארטפון?)
האפשרויות הן אינסופיות! אם הרעיון של יציאה לדרך לבד נראה לכם קצת מפחיד, תמיד תוכלו להיעזר בסוכן קוד כמו Gemini CLI או Antigravity. אם אתם רוצים לעשות עוד דברים עם Genkit, תוכלו להשתמש בסוכני קידוד שמשולבים עם שרת Genkit MCP כדי להקל על עצמכם.
לבסוף, אם רוצים לגשת לקוד המלא של מאגר המידע הזה, אפשר למצוא אותו כאן.
שיהיה בהצלחה!