إدارة الطلبات باستخدام Dotprompt

إنّ هندسة الطلبات هي الطريقة الأساسية التي يمكنك من خلالها، بصفتك مطوّر تطبيقات، التأثير في ناتج نماذج الذكاء الاصطناعي التوليدي. على سبيل المثال، عند استخدام النماذج اللغوية الكبيرة، يمكنك إنشاء طلبات تؤثر في الأسلوب والتنسيق والطول والسمات الأخرى لردود النماذج.

تعتمد طريقة كتابة هذه الطلبات على النموذج الذي تستخدمه، فقد لا يحقّق الطلب الذي تم كتابته لنموذج معيّن أداءً جيدًا عند استخدامه مع نموذج آخر. وبالمثل، ستؤثر معلمات النموذج التي تحدّدها (درجة الحرارة وأفضل 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 وكيفية استخدامه.

قبل البدء

قبل قراءة هذه الصفحة، يجب أن تكون على دراية بالمحتوى الذي يتم تناوله في صفحة إنشاء المحتوى باستخدام نماذج الذكاء الاصطناعي.

إذا كنت تريد تنفيذ أمثلة الرموز البرمجية الواردة في هذه الصفحة، عليك أولاً إكمال الخطوات الواردة في دليل البدء. تفترض جميع الأمثلة أنّك سبق أن ثبّت 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، وهي مشابهة لتنسيق المقدمة الذي يستخدمه 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 .

في قسم النموذج، اختَر النموذج الذي تريد استخدامه من قائمة النماذج التي يوفّرها المكوّن الإضافي.

أداة تشغيل نماذج واجهة المستخدم للمطوّرين في Genkit

بعد ذلك، جرِّب الطلب والإعداد إلى أن تحصل على نتائج تُرضيك. عندما تكون مستعدًا، اضغط على الزر "تصدير" واحفظ الملف في ملف directory prompts.

عرض الطلبات

بعد إنشاء ملفات الطلبات، يمكنك تشغيلها من رمز تطبيقك، أو باستخدام الأدوات التي يوفّرها 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})
)

إنّ أي مَعلمات يتم تمريرها إلى طلب الطلب ستلغي المَعلمات نفسها المحدّدة في ملف الطلب.

اطّلِع على مقالة إنشاء محتوى باستخدام نماذج الذكاء الاصطناعي للحصول على أوصاف عن الخيارات المتاحة.

استخدام واجهة مستخدم المطوّر

أثناء تحسين طلبات تطبيقك، يمكنك تشغيلها في واجهة مستخدم المطوّر في 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>"},
    }))

اطّلِع على مقالة إنشاء محتوى باستخدام نماذج الذكاء الاصطناعي للحصول على أوصاف عن الخيارات المتاحة.

مخطّطات الإدخال والإخراج

يمكنك تحديد مخطّطَي الإدخال والإخراج لطلبك من خلال تحديدهما في قسم "مقدّمة". يتم استخدام هذه المخططات بالطريقة نفسها التي يتم بها استخدام تلك التي يتم تمريرها إلى طلب genkit.Generate() أو تعريف عملية:

---
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.

تُنشئ هذه التعليمة البرمجية الإخراج المنظَّم التالي:

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 لتعريف المخططات، ما يسهّل تحديد أهم سمات المخطط لاستخدام نموذج "التعلم الآلي للغات". في ما يلي مثال أطول على مخطّط يحدّد المعلومات التي قد يخزّنها التطبيق حول مقالة:

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. يتم الإشارة إلى الكائنات والمصفوفات وقوائم القيم المحدَّدة بين قوسين بعد اسم الحقل.

تحتوي الكائنات التي تحدّدها Picoschema على جميع السمات المطلوبة ما لم يتم وضع ? عليها للإشارة إلى أنّها اختيارية، ولا تسمح هذه الكائنات بسمات إضافية. عندما يتم وضع علامة على سمة كاختيارية، يتم أيضًا جعلها قابلة للحذف لتوفير المزيد من التساهل لتنسيقات LLMs لعرض قيمة فارغة بدلاً من حذف حقل.

في تعريف العنصر، يمكن استخدام المفتاح الخاص (*) لتعريف ملف شخصي "للعميل المحتمل". سيؤدي ذلك إلى مطابقة أيّ مواقع إضافية لم يتمّ تقديمها بواسطة مفتاح صريح.

مخطّط JSON

لا تتيح Picoschema العديد من إمكانات مخطّط JSON الكامل. إذا كنت تحتاج إلى مخطّطات أكثر فعّالية، يمكنك تقديم مخطّط JSON بدلاً من ذلك:

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

نماذج الطلبات

الجزء من ملف .prompt الذي يلي الجزء الأمامي (إن توفّر) هو الطلب نفسه الذي سيتم تمريره إلى النموذج. على الرغم من أنّ رسالة الطلب هذه يمكن أن تكون سلسلة نصية بسيطة، إلا أنّه غالبًا ما ستحتاج إلى دمج إدخال المستخدم في رسالة الطلب. ولإجراء ذلك، يمكنك تحديد الطلب باستخدام لغة نماذج Handlebars. يمكن أن تتضمّن نماذج الطلبات عناصر نائبة تشير إلى القيم المحدّدة من قِبل مخطّط إدخال طلبك.

لقد شاهدت هذا الإجراء في قسم مخطّطات الإدخال والإخراج:

---
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 أيضًا بعض البنى المنطقية المحدودة. على سبيل المثال، كبديل لتقديم قيمة تلقائية، يمكنك تحديد الطلب باستخدام مساعد #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.

في هذا المثال، يتم عرض الطلب على النحو التالي: "ابتكار عنصر قائمة لمطعم" عندما تكون سمة 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 معرّف 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"}),
)

اطّلِع أيضًا على الإدخال المتعدّد الوسائط في صفحة إنشاء محتوى باستخدام نماذج الذكاء الاصطناعي، للحصول على مثال على إنشاء عنوان 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}}

يتم إدراج العناصر الجزئية باستخدام بنية {{>NAME_OF_PARTIAL args...}}. في حال عدم تقديم أي وسيطات للجزء، يتم تنفيذه بالسياق نفسه الذي تم استخدامه في الطلب الرئيسي.

تقبل العناصر الجزئية وسيطات مُسمّاة أو وسيطة موضعية واحدة represent representing the context. يمكن أن يكون ذلك مفيدًا في مهام مثل عرض عناصر قائمة.

_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: طلب "الأساس"
  • myPrompt.gemini25pro.prompt: صيغة باسم gemini25pro

لاستخدام صيغة طلب، حدِّد خيار الصيغة عند التحميل:

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

يتم تضمين اسم الصيغة في البيانات الوصفية لتتبُّع عمليات الإنشاء، ما يتيح لك مقارنة الأداء الفعلي بين الصيغ في أداة فحص التتبُّع Genkit.

تحديد الطلبات في الرمز البرمجي

افترضت جميع الأمثلة التي تمت مناقشتها حتى الآن أنّ طلباتك محدّدة في ملفات .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().