ניהול הנחיות באמצעות Dotprompt

תכנון ההנחיות הוא הדרך העיקרית שבה מפתחי אפליקציות יכולים להשפיע על הפלט של מודלים של בינה מלאכותית גנרטיבית. לדוגמה, כשמשתמשים במודלים מסוג LLM, אפשר ליצור הנחיות שמשפיעות על הטון, הפורמט, האורך ומאפיינים אחרים של התשובות של המודלים.

האופן שבו כותבים את ההנחיות האלה תלוי במודל שבו אתם משתמשים. יכול להיות שהנחיה שנכתבה עבור מודל אחד לא תניב ביצועים טובים כשמשתמשים בה עם מודל אחר. באופן דומה, הפרמטרים של המודל שתגדירו (טמפרטורה, top-k וכו') ישפיעו גם הם על הפלט באופן שונה בהתאם למודל.

לרוב, לא קל לשלב את כל שלושת הגורמים האלה – המודל, הפרמטרים של המודל וההנחיה – כדי ליצור את הפלט הרצוי. בדרך כלל התהליך כולל חזרות ניסיוניות רבות. Genkit מספק ספרייה ופורמט קובץ שנקרא Dotprompt, שמטרתם להפוך את התהליך הזה למהיר ונוח יותר.

Dotprompt מבוסס על ההנחה שהנחיות הן קוד. אתם מגדירים את ההנחיות יחד עם המודלים והפרמטרים שלהם בנפרד מקוד האפליקציה. לאחר מכן, אתם (או אולי מישהו שלא מעורב בכתיבת קוד האפליקציה) תוכלו לבצע חזרה מהירה על ההנחיות ועל הפרמטרים של המודל באמצעות ממשק המשתמש של Genkit למפתחים. אחרי שההנחיות יפעלו כמו שרציתם, תוכלו לייבא אותן לאפליקציה ולהריץ אותן באמצעות Genkit.

כל הגדרות ההנחיות נשמרות בקובץ עם סיומת .prompt. דוגמה למראה של הקבצים האלה:

---
model: googleai/gemini-1.5-flash
config:
  temperature: 0.9
input:
  schema:
    location: string
    style?: string
    name?: string
  default:
    location: a restaurant
---

You are the world's most welcoming AI assistant and are currently working at {{location}}.

Greet a guest{{#if name}} named {{name}}{{/if}}{{#if style}} in the style of {{style}}{{/if}}.

החלק שמופיע בין שלוש הקווים המקבילים הוא תוכן קדמי של YAML, בדומה לפורמט התוכן הקדמי שמשמש את GitHub Markdown ו-Jekyll. שאר הקובץ הוא ההנחיה, שאפשר להשתמש בה בתבניות Handlebars. בקטעים הבאים נסביר בפירוט על כל אחד מהחלקים שמרכיבים קובץ .prompt ועל האופן שבו משתמשים בהם.

לפני שמתחילים

לפני שתקראו את הדף הזה, כדאי שתכירו את התוכן שמפורט בדף יצירת תוכן באמצעות מודלים של AI.

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

יצירת קובצי הנחיות

ב-Dotprompt יש כמה דרכים שונות ליצור ולטעון הנחיות, אבל הוא מותאם במיוחד לפרויקטים שבהם ההנחיות מאורגנות כקובצי .prompt בספרייה אחת (או בתיקיות המשנה שלה). בקטע הזה נסביר איך ליצור ולטעון הנחיות באמצעות ההגדרה המומלצת הזו.

יצירת ספרייה של הנחיות

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

your-project/
├── prompts/
│   └── hello.prompt
├── main.go
├── go.mod
└── go.sum

אם רוצים להשתמש בספרייה אחרת, אפשר לציין אותה כשמגדירים את Genkit:

g, err := genkit.Init(ctx.Background(), ai.WithPromptDir("./llm_prompts"))

יצירת קובץ הנחיה

יש שתי דרכים ליצור קובץ .prompt: באמצעות עורך טקסט או באמצעות ממשק המשתמש למפתחים.

שימוש בעורך טקסט

אם רוצים ליצור קובץ הנחיה באמצעות עורך טקסט, יוצרים קובץ טקסט עם הסיומת .prompt בספריית ההנחיות: לדוגמה, prompts/hello.prompt.

דוגמה מינימלית לקובץ הנחיה:

---
model: vertexai/gemini-1.5-flash
---
You are the world's most welcoming AI assistant. Greet the user and offer your assistance.

החלק שמופיע בין הקווים המקווקוים הוא YAML front matter, בדומה לפורמט front matter שמשמש את GitHub markdown ו-Jekyll. שאר הקובץ הוא ההנחיה, שאפשר להשתמש בה באפשרות לתבניות Handlebars. הקטע של תוכן הפתיחה הוא אופציונלי, אבל רוב קובצי ההנחיות יכללו לפחות מטא-נתונים שמציינים מודל. בהמשך הדף מוסבר איך להשתמש בתכונות של Dotprompt בקובצי ההנחיה.

שימוש בממשק המשתמש למפתחים

אפשר גם ליצור קובץ הנחיה באמצעות הכלי להרצת מודלים בממשק המשתמש למפתחים. מתחילים עם קוד אפליקציה שמייבא את ספריית Genkit ומגדיר אותה להשתמש בפלאגין של המודל הרצוי. לדוגמה:

import (
    "context"

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

func main() {
    g, err := genkit.Init(context.Background(), ai.WithPlugins(&googlegenai.GoogleAI{}))
    if err != nil {
        log.Fatal(err)
    }

    // Blocks end of program execution to use the developer UI.
    select {}
}

אין בעיה אם הקובץ מכיל קוד אחר, אבל הקוד שלמעלה הוא כל מה שנדרש.

טעינת ממשק המפתחים באותו פרויקט:

genkit start -- go run .

בקטע Model, בוחרים את המודל שבו רוצים להשתמש מתוך רשימת המודלים שמספקת הפלאגין.

הרצת מודל של ממשק המשתמש למפתחים ב-Genkit

לאחר מכן, אפשר להתנסות בהנחיה ובתצורה עד שמקבלים תוצאות מרוצות. כשתהיו מוכנים, לוחצים על הלחצן 'ייצוא' ושומרים את הקובץ בספריית ההנחיות.

הנחיות לריצה

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

import (
    "context"

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

func main() {
    g, err := genkit.Init(context.Background(), ai.WithPlugins(&googlegenai.GoogleAI{}))
    if err != nil {
        log.Fatal(err)
    }

    // Blocks end of program execution to use the developer UI.
    select {}
}

אין בעיה אם הקובץ מכיל קוד אחר, אבל הקוד שלמעלה הוא כל מה שנדרש. אם אתם שומרים את ההנחיות בספרייה שאינה ברירת המחדל, חשוב לציין אותה כשמגדירים את Genkit.

הרצת הנחיות מקוד

כדי להשתמש בהנחיה, קודם צריך לטעון אותה באמצעות הפונקציה genkit.LookupPrompt():

helloPrompt := genkit.LookupPrompt(g, "hello")

להנחיה של קובץ הפעלה יש אפשרויות דומות לאלה של genkit.Generate(), ואפשר לשנות הרבה מהן בזמן ההפעלה, כולל דברים כמו קלט (ראו הקטע בהמשך בנושא ציון סכימות קלט), הגדרה ועוד:

resp, err := helloPrompt.Execute(context.Background(),
    ai.WithModelName("googleai/gemini-2.0-flash"),
    ai.WithInput(map[string]any{"name": "John"}),
    ai.WithConfig(&googlegenai.GeminiConfig{Temperature: 0.5})
)

כל הפרמטרים שתעבירו לקריאה להנחיה יעקפו את אותם הפרמטרים שצוינו בקובץ ההנחיה.

בקישור הבא מפורטות תיאורים של האפשרויות הזמינות: יצירת תוכן באמצעות מודלים של AI.

שימוש בממשק המשתמש למפתחים

כשאתם משפרים את ההנחיות של האפליקציה, אתם יכולים להריץ אותן בממשק המשתמש של Genkit למפתחים כדי לבצע שינויים מהירים בהנחיות ובהגדרות המודל, בנפרד מקוד האפליקציה.

טוענים את ממשק המשתמש למפתחים מספריית הפרויקט:

genkit start -- go run .

הרצת הנחיות בממשק המשתמש למפתחים של Genkit

אחרי שתטעינו את ההנחיות בממשק המשתמש למפתחים, תוכלו להריץ אותן עם ערכי קלט שונים ולבדוק איך שינויים בניסוח ההנחיה או בפרמטרים של ההגדרה משפיעים על הפלט של המודל. כשתהיו מרוצים מהתוצאה, תוכלו ללחוץ על הלחצן ייצוא ההנחיה כדי לשמור את ההנחיה ששונתה בספריית הפרויקט.

הגדרת מודל

בבלוק של תוכן הפתיחה בקובצי ההנחיה, אפשר לציין ערכי תצורת מודל להנחיה:

---
model: googleai/gemini-2.0-flash
config:
  temperature: 1.4
  topK: 50
  topP: 0.4
  maxOutputTokens: 400
  stopSequences:
    -   "<end>"
    -   "<fin>"
---

הערכים האלה ממפים ישירות לאפשרות WithConfig() שמקבלת ההנחיה להפעלה:

resp, err := helloPrompt.Execute(context.Background(),
    ai.WithConfig(&googlegenai.GeminiConfig{
        Temperature:     1.4,
        TopK:            50,
        TopP:            0.4,
        MaxOutputTokens: 400,
        StopSequences:   []string{"<end>", "<fin>"},
    }))

בקישור הבא מפורטות תיאורים של האפשרויות הזמינות: יצירת תוכן באמצעות מודלים של AI.

סכימות קלט ופלט

כדי לציין את הסכמות הקלט והפלט של ההנחיה, מגדירים אותן בקטע הקדמה:

---
model: googleai/gemini-2.0-flash
input:
  schema:
    theme?: string
  default:
    theme: "pirate"
output:
  schema:
    dishname: string
    description: string
    calories: integer
    allergens(array): string
---
Invent a menu item for a {{theme}} themed restaurant.

האופן שבו נעשה שימוש בסכימות האלה דומה לאופן שבו נעשה שימוש בסכימות שמועברות לבקשת genkit.Generate() או להגדרת תהליך. לדוגמה, ההנחיה שהוגדרה למעלה יוצרת את הפלט המובנה הבא:

menuPrompt = genkit.LookupPrompt(g, "menu")
if menuPrompt == nil {
    log.Fatal("no prompt named 'menu' found")
}

resp, err := menuPrompt.Execute(context.Background(),
    ai.WithInput(map[string]any{"theme": "medieval"}),
)
if err != nil {
    log.Fatal(err)
}

var output map[string]any
if err := resp.Output(&output); err != nil {
    log.Fatal(err)
}

log.Println(output["dishname"])
log.Println(output["description"])

יש כמה אפשרויות להגדרת סכימות בקובץ .prompt: הפורמט של Dotprompt להגדרת סכימות, Picoschema, סכימת JSON רגילה או הפניות לסכימות שהוגדרו בקוד האפליקציה. בקטעים הבאים מוסבר בהרחבה על כל אחת מהאפשרויות האלה.

Picoschema

הסכימות בדוגמה שלמעלה מוגדרות בפורמט שנקרא Picoschema. Picoschema הוא פורמט קומפקטי של הגדרת סכימה שמותאם ל-YAML, שמאפשר להגדיר בקלות את המאפיינים החשובים ביותר של סכימה לשימוש ב-LLM. דוגמה ארוכה יותר לסכימה, שמציינת את המידע שאפליקציה עשויה לאחסן לגבי מאמר:

schema:
  title: string # string, number, and boolean types are defined like this
  subtitle?: string # optional fields are marked with a `?`
  draft?: boolean, true when in draft state
  status?(enum, approval status): [PENDING, APPROVED]
  date: string, the date of publication e.g. '2024-04-09' # descriptions follow a comma
  tags(array, relevant tags for article): string # arrays are denoted via parentheses
  authors(array):
    name: string
    email?: string
  metadata?(object): # objects are also denoted via parentheses
    updatedAt?: string, ISO timestamp of last update
    approvedBy?: integer, id of approver
  extra?: any, arbitrary extra data
  (*): string, wildcard field

הסכימה שלמעלה זהה לסוג Go הבא:

type Article struct {
    Title    string   `json:"title"`
    Subtitle string   `json:"subtitle,omitempty" jsonschema:"required=false"`
    Draft    bool     `json:"draft,omitempty"`  // True when in draft state
    Status   string   `json:"status,omitempty" jsonschema:"enum=PENDING,enum=APPROVED"` // Approval status
    Date     string   `json:"date"`   // The date of publication e.g. '2025-04-07'
    Tags     []string `json:"tags"`   // Relevant tags for article
    Authors  []struct {
      Name  string `json:"name"`
      Email string `json:"email,omitempty"`
    } `json:"authors"`
    Metadata struct {
      UpdatedAt  string `json:"updatedAt,omitempty"`  // ISO timestamp of last update
      ApprovedBy int    `json:"approvedBy,omitempty"` // ID of approver
    } `json:"metadata,omitempty"`
    Extra any `json:"extra"` // Arbitrary extra data
}

ב-Picoschema יש תמיכה בסוגי סקלר string,‏ integer,‏ number,‏ boolean ו-any. אובייקטים, מערכי נתונים וממשקי Enum מסומנים בסוגריים אחרי שם השדה.

אובייקטים שמוגדרים באמצעות Picoschema כוללים את כל המאפיינים הנדרשים, אלא אם הם מסומנים כאופציונליים באמצעות ?, והם לא מאפשרים להוסיף מאפיינים. כשמאפיין מסומן כאופציונלי, הוא הופך גם לאפשרי לאפס (nullable) כדי לספק גמישות רבה יותר למודלים של LLM כדי שיחזירו ערך null במקום להשמיט שדה.

בהגדרת אובייקט, אפשר להשתמש במפתח המיוחד (*) כדי להצהיר על הגדרת שדה 'תו כללי לחיפוש'. כך תוכלו להתאים לכל נכס נוסף שלא סופק על ידי מפתח מפורש.

JSON Schema

ב-Picoschema אין תמיכה בהרבה מהיכולות של סכימה מלאה של JSON. אם אתם זקוקים לסכמות חזקות יותר, תוכלו לספק במקום זאת סכימה של JSON:

output:
  schema:
    type: object
    properties:
      field1:
        type: number
        minimum: 20

תבניות של הנחיות

החלק בקובץ .prompt שמופיע אחרי תוכן הפתיחה (אם הוא קיים) הוא ההנחיה עצמה, שתעבור למודל. ההנחיה הזו יכולה להיות מחרוזת טקסט פשוטה, אבל בדרך כלל כדאי לשלב בה את הקלט של המשתמש. כדי לעשות זאת, אפשר לציין את ההנחיה באמצעות שפת התבניות Handlebars. תבניות של הנחיות יכולות לכלול placeholder שמתייחסים לערכים שמוגדרים לפי סכימה של הקלט של ההנחיה.

כבר ראינו את זה בקטע על סכימות קלט ופלט:

---
model: googleai/gemini-2.0-flash
input:
  schema:
    theme?: string
  default:
    theme: "pirate"
output:
  schema:
    dishname: string
    description: string
    calories: integer
    allergens(array): string
---
Invent a menu item for a {{theme}} themed restaurant.

בדוגמה הזו, הביטוי של Handlebars, {{theme}}, מקבל את הערך של המאפיין theme של הקלט כשמריצים את ההנחיה. כדי להעביר קלט להנחיה, צריך לבצע קריאה להנחיה כמו בדוגמה הבאה:

menuPrompt = genkit.LookupPrompt(g, "menu")

resp, err := menuPrompt.Execute(context.Background(),
    ai.WithInput(map[string]any{"theme": "medieval"}),
)

שימו לב: מאחר שסכימת הקלט הכריזה על המאפיין theme כאופציונלי וסיפקה ערך ברירת מחדל, אפשר היה להשמיט את המאפיין וההנחיה הייתה נפתרת באמצעות ערך ברירת המחדל.

תבניות Handlebars תומכות גם במבנים לוגיים מוגבלים מסוימים. לדוגמה, אפשר להגדיר את ההנחיה באמצעות ה-helper‏ #if של Handlebars, במקום לספק ברירת מחדל:

---
model: googleai/gemini-2.0-flash
input:
  schema:
    theme?: string
---
Invent a menu item for a {{#if theme}}{{theme}}{else}themed{{/else}} restaurant.

בדוגמה הזו, ההנחיה תוצג כ "Invent a menu item for a restaurant" (יצירת פריט תפריט למסעדה) כשלא צוין המאפיין theme.

במסמכי העזרה של Handlebars מפורט מידע על כל הרכיבים המסייעים הלוגיים המובנים.

בנוסף למאפיינים שמוגדרים על ידי הסכימה של הקלט, התבניות יכולות גם להפנות לערכים שמוגדרים באופן אוטומטי על ידי Genkit. בקטעים הבאים מתוארים הערכים שמוגדרים באופן אוטומטי ואופן השימוש בהם.

הנחיות לכמה הודעות

כברירת מחדל, Dotprompt יוצר הודעה אחת עם התפקיד 'משתמש'. עם זאת, הנחיות מסוימות, כמו הנחיה מערכתית, עדיף להביע כשימוש בשילובים של כמה הודעות.

בעזרת הפונקציה {{role}} תוכלו ליצור בקלות הנחיות שמכילות כמה הודעות:

---
model: vertexai/gemini-2.0-flash
input:
  schema:
    userQuestion: string
---
{{role "system"}}
You are a helpful AI assistant that really loves to talk about food. Try to work
food items into all of your conversations.

{{role "user"}}
{{userQuestion}}

הנחיות במגוון מצבים

במודלים שתומכים בקלט רב-מודלי, כמו תמונות לצד טקסט, אפשר להשתמש בעזרה של {{media}}:

---
model: vertexai/gemini-2.0-flash
input:
  schema:
    photoUrl: string
---
Describe this image in a detailed paragraph:

{{media url=photoUrl}}

כתובת ה-URL יכולה להיות מזהי URI מסוג https: או data: בקידוד base64 לשימוש בתמונות 'מוטמעות'. בקוד, זה ייראה כך:

multimodalPrompt = genkit.LookupPrompt(g, "multimodal")

resp, err := multimodalPrompt.Execute(context.Background(),
    ai.WithInput(map[string]any{"photoUrl": "https://example.com/photo.jpg"}),
)

כדאי לעיין גם בקטע קלט במספר מודלים בדף יצירת תוכן באמצעות מודלים של AI, כדי לראות דוגמה ליצירת כתובת URL מסוג data:.

פריטים חלקיים

קטעים חלקיים הם תבניות לשימוש חוזר שאפשר לכלול בכל הנחיה. רכיבים חלקיים יכולים להיות שימושיים במיוחד להנחיות קשורות שיש להן התנהגות משותפת.

כשאתם מעמיסים ספריית הנחיות, כל קובץ עם קו תחתון (_) בתור הקידומת שלו נחשב לקובץ חלקי. לכן, קובץ _personality.prompt עשוי להכיל:

You should speak like a {{#if style}}{{style}}{else}helpful assistant.{{/else}}.

לאחר מכן אפשר לכלול את הנתונים האלה בהנחיות אחרות:

---
model: googleai/gemini-2.0-flash
input:
  schema:
    name: string
    style?: string
---
{{ role "system" }}
{{>personality style=style}}

{{ role "user" }}
Give the user a friendly greeting.

User's Name: {{name}}

הוספת נכסי js חלקיים מתבצעת באמצעות תחביר {{>NAME_OF_PARTIAL args...}}. אם לא סיפקו ארגומנטים ל-partial, הוא יבוצע עם אותו הקשר כמו הבקשה של ההורה.

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

_destination.prompt

-   {{name}} ({{country}})

chooseDestination.prompt

---
model: googleai/gemini-2.0-flash
input:
  schema:
    destinations(array):
      name: string
      country: string
---
Help the user decide between these vacation destinations:

{{#each destinations}}
{{>destination this}}
{{/each}}

הגדרת נכסי חלק בקוד

אפשר גם להגדיר קטעים חלקיים בקוד באמצעות genkit.DefinePartial():

genkit.DefinePartial(g, "personality", "Talk like a {{#if style}}{{style}}{{else}}helpful assistant{{/if}}.")

קטעי טקסט חלקיים שמוגדרים בקוד זמינים בכל ההנחיות.

הגדרת עזרים מותאמים אישית

אפשר להגדיר פונקציות עזר בהתאמה אישית כדי לעבד ולנהל נתונים בתוך הנחיה. עוזרים נרשמים באופן גלובלי באמצעות genkit.DefineHelper():

genkit.DefineHelper(g, "shout", func(input string) string {
    return strings.ToUpper(input)
})

אחרי שמגדירים עוזר, אפשר להשתמש בו בכל הנחיה:

---
model: googleai/gemini-2.0-flash
input:
  schema:
    name: string
---

HELLO, {{shout name}}!!!

וריאציות של הנחיות

קובצי הנחיה הם רק טקסט, ולכן אפשר (וצריך!) לבצע אותם במערכת לניהול גרסאות, כדי שתוכלו להשוות בקלות בין השינויים לאורך זמן. לרוב, אפשר לבדוק גרסאות משופרות של הנחיות רק בסביבת ייצור, לצד גרסאות קיימות. Dotprompt תומך בכך באמצעות התכונה 'וריאנטים'.

כדי ליצור וריאנט, יוצרים קובץ [name].[variant].prompt. לדוגמה, אם השתמשתם ב-Gemini 2.0 Flash בהנחיה אבל רציתם לבדוק אם ביצועי Gemini 2.5 Pro טובים יותר, תוכלו ליצור שני קבצים:

  • myPrompt.prompt: ההנחיה 'baseline'
  • myPrompt.gemini25pro.prompt: וריאנט בשם gemini25pro

כדי להשתמש בגרסת הודעת הנחיה, מציינים את אפשרות הודעת הנחיה בזמן הטעינה:

myPrompt := genkit.LookupPrompt(g, "myPrompt.gemini25Pro")

שם הווריאנט נכלל במטא-נתונים של נתוני המעקב אחרי היצירה, כך שתוכלו להשוות בין הביצועים בפועל של הווריאנטים השונים ב-Genkit trace inspector.

הגדרת הנחיות בקוד

בכל הדוגמאות שצוינו עד עכשיו, הנחנו שההנחיות מוגדרות בקבצים נפרדים מסוג .prompt בתיקייה אחת (או בתיקיות משנה שלה) שזמינות לאפליקציה בזמן הריצה. Dotprompt תוכנן בהתאם להגדרה הזו, והמחברים שלו מתייחסים אליו כאל חוויית הפיתוח הטובה ביותר באופן כללי.

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

type GeoQuery struct {
    CountryCount int `json:"countryCount"`
}

type CountryList struct {
    Countries []string `json:"countries"`
}

geographyPrompt, err := genkit.DefinePrompt(
    g, "GeographyPrompt",
    ai.WithSystem("You are a geography teacher. Respond only when the user asks about geography."),
    ai.WithPrompt("Give me the {{countryCount}} biggest countries in the world by inhabitants."),
    ai.WithConfig(&googlegenai.GeminiConfig{Temperature: 0.5}),
    ai.WithInputType(GeoQuery{CountryCount: 10}) // Defaults to 10.
    ai.WithOutputType(CountryList{}),
)
if err != nil {
    log.Fatal(err)
}

resp, err := geographyPrompt.Execute(context.Background(), ai.WithInput(GeoQuery{CountryCount: 15}))
if err != nil {
    log.Fatal(err)
}

var list CountryList
if err := resp.Output(&list); err != nil {
    log.Fatal(err)
}

log.Println("Countries: %s", list.Countries)

אפשר גם להציג את ההנחיות כ-GenerateActionOptions, שאפשר לעבד ולאחר מכן להעביר ל-genkit.GenerateWithRequest():

actionOpts, err := geographyPrompt.Render(ctx, ai.WithInput(GeoQuery{CountryCount: 15}))
if err != nil {
    log.Fatal(err)
}

// Do something with the value...
actionOpts.Config = &googlegenai.GeminiConfig{Temperature: 0.8}

resp, err := genkit.GenerateWithRequest(ctx, g, actionOpts, nil, nil) // No middleware or streaming

חשוב לדעת שכל אפשרויות ההנחיה מועברות אל GenerateActionOptions, מלבד WithMiddleware(), שצריך להעביר בנפרד אם משתמשים ב-Prompt.Render() במקום ב-Prompt.Execute().