การจัดการพรอมต์ด้วย Dotprompt

การออกแบบพรอมต์เป็นวิธีหลักที่คุณในฐานะนักพัฒนาแอปใช้เพื่อส่งผลต่อเอาต์พุตของโมเดล Generative AI ตัวอย่างเช่น เมื่อใช้ LLM คุณจะสร้างพรอมต์ที่ส่งผลต่อโทน รูปแบบ ความยาว และลักษณะอื่นๆ ของคำตอบของโมเดลได้

วิธีเขียนพรอมต์เหล่านี้จะขึ้นอยู่กับโมเดลที่คุณใช้อยู่ พรอมต์ที่เขียนขึ้นสำหรับโมเดลหนึ่งอาจใช้กับโมเดลอื่นได้ไม่ดี ในทํานองเดียวกัน พารามิเตอร์ของโมเดลที่คุณตั้งค่า (อุณหภูมิ, Top-K และอื่นๆ) จะส่งผลต่อเอาต์พุตแตกต่างกันไปโดยขึ้นอยู่กับโมเดล

การปรับปัจจัยทั้ง 3 รายการนี้ ได้แก่ โมเดล พารามิเตอร์ของโมเดล และพรอมต์ ให้ทำงานร่วมกันเพื่อสร้างเอาต์พุตที่ต้องการนั้นไม่ใช่เรื่องง่าย และมักเกี่ยวข้องกับการทดสอบซ้ำและการทดลองอย่างมาก Genkit มีไลบรารีและรูปแบบไฟล์ที่เรียกว่า Dotprompt ซึ่งมีไว้เพื่อทําให้การปรับปรุงนี้รวดเร็วและสะดวกยิ่งขึ้น

Dotprompt ออกแบบมาโดยยึดหลักที่ว่าพรอมต์คือโค้ด คุณกําหนดพรอมต์พร้อมกับโมเดลและพารามิเตอร์โมเดลที่มีไว้สําหรับพรอมต์แยกต่างหากจากโค้ดแอปพลิเคชัน จากนั้น คุณ (หรือแม้แต่ผู้ที่ไม่ได้เกี่ยวข้องกับการเขียนโค้ดแอปพลิเคชัน) ก็สามารถแก้ไขพรอมต์และพารามิเตอร์โมเดลได้อย่างรวดเร็วโดยใช้ UI สําหรับนักพัฒนาซอฟต์แวร์ของ 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}}.

ส่วนที่เป็นขีดกลาง 3 ขีดคือส่วนหน้า YAML ซึ่งคล้ายกับรูปแบบส่วนหน้าที่ใช้โดย GitHub Markdown และ Jekyll ส่วนที่เหลือของไฟล์คือพรอมต์ ซึ่งอาจใช้เทมเพลต Handlebars ก็ได้ ส่วนต่อไปนี้จะอธิบายรายละเอียดเพิ่มเติมเกี่ยวกับส่วนต่างๆ ที่สร้างไฟล์ .prompt และวิธีใช้

ก่อนเริ่มต้น

ก่อนอ่านหน้านี้ คุณควรทำความคุ้นเคยกับเนื้อหาที่ครอบคลุมในหน้าการสร้างเนื้อหาด้วยโมเดล AI

หากต้องการเรียกใช้ตัวอย่างโค้ดในหน้านี้ ให้ทําตามขั้นตอนในคู่มือเริ่มต้นใช้งานก่อน ตัวอย่างทั้งหมดจะถือว่าคุณได้ติดตั้ง Genkit ไว้เป็น Dependency ในโปรเจ็กต์แล้ว

การสร้างไฟล์พรอมต์

แม้ว่า 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 มี 2 วิธี ได้แก่ การใช้เครื่องมือแก้ไขข้อความหรือใช้ UI ของนักพัฒนาซอฟต์แวร์

การใช้ตัวแก้ไขข้อความ

หากต้องการสร้างไฟล์พรอมต์โดยใช้เครื่องมือแก้ไขข้อความ ให้สร้างไฟล์ข้อความที่มีนามสกุล .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 ในไฟล์พรอมต์

การใช้ UI นักพัฒนาซอฟต์แวร์

นอกจากนี้ คุณยังสร้างไฟล์พรอมต์โดยใช้โปรแกรมรันไทม์โมเดลใน UI ของนักพัฒนาซอฟต์แวร์ได้ด้วย เริ่มต้นด้วยโค้ดแอปพลิเคชันที่นําเข้าไลบรารี 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 {}
}

โหลด UI สําหรับนักพัฒนาซอฟต์แวร์ในโปรเจ็กต์เดียวกัน

genkit start -- go run .

ในส่วนรูปแบบ ให้เลือกรูปแบบที่ต้องการใช้จากรายการรูปแบบที่ปลั๊กอินมีให้

เครื่องมือเรียกใช้โมเดล UI นักพัฒนาซอฟต์แวร์ 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

การใช้ UI นักพัฒนาซอฟต์แวร์

ขณะปรับแต่งพรอมต์ของแอป คุณสามารถเรียกใช้พรอมต์ใน UI สำหรับนักพัฒนาซอฟต์แวร์ Genkit เพื่อแก้ไขพรอมต์และการกำหนดค่าโมเดลได้อย่างรวดเร็วโดยแยกจากโค้ดแอปพลิเคชัน

โหลด UI ของนักพัฒนาแอปจากไดเรกทอรีโปรเจ็กต์

genkit start -- go run .

โปรแกรมเรียกใช้พรอมต์ UI สำหรับนักพัฒนาซอฟต์แวร์ Genkit

เมื่อโหลดพรอมต์ลงใน UI ของนักพัฒนาซอฟต์แวร์แล้ว คุณจะเรียกใช้พรอมต์ด้วยค่าอินพุตที่แตกต่างกันได้ และทดสอบว่าการเปลี่ยนแปลงข้อความพรอมต์หรือพารามิเตอร์การกําหนดค่าส่งผลต่อเอาต์พุตของโมเดลอย่างไร เมื่อพอใจกับผลลัพธ์แล้ว ให้คลิกปุ่มส่งออกพรอมต์เพื่อบันทึกพรอมต์ที่แก้ไขแล้วกลับไปยังไดเรกทอรีโปรเจ็กต์

การกำหนดค่าโมเดล

ในบล็อกส่วนหน้าของไฟล์พรอมต์ คุณระบุค่าการกําหนดค่าโมเดลสําหรับพรอมต์ได้ (ไม่บังคับ) ดังนี้

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

สคีมาอินพุตและเอาต์พุต

คุณสามารถระบุสคีมาอินพุตและเอาต์พุตสำหรับพรอมต์ได้โดยกำหนดไว้ในส่วนเนื้อหาหน้าแรก สคีมาเหล่านี้จะใช้ในลักษณะเดียวกับสคีมาที่ส่งไปยังคําขอ 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.

โค้ดนี้จะสร้าง Structured Data ต่อไปนี้

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 ออบเจ็กต์ อาร์เรย์ และลิสต์แสดงด้วยวงเล็บหลังชื่อช่อง

ออบเจ็กต์ที่ Picoschema กำหนดต้องมีพร็อพเพอร์ตี้ทั้งหมด เว้นแต่จะระบุเป็นไม่บังคับด้วย ? และไม่อนุญาตให้มีพร็อพเพอร์ตี้เพิ่มเติม เมื่อมีการทําเครื่องหมายพร็อพเพอร์ตี้ว่าไม่บังคับ ระบบจะทําให้พร็อพเพอร์ตี้เป็น Nullable ด้วยเพื่อให้ LLM แสดงผล Null ได้มากขึ้นแทนการละเว้นช่อง

ในคําจํากัดความออบเจ็กต์ คุณสามารถใช้คีย์พิเศษ (*) เพื่อประกาศคําจํากัดความฟิลด์ "ไวลด์การ์ด" ซึ่งจะจับคู่กับพร็อพเพอร์ตี้เพิ่มเติมที่ไม่ได้ระบุโดยคีย์ที่ชัดเจน

สคีมา 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 อาจเป็น 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"}),
)

ดูตัวอย่างการสร้าง URL data: ได้ที่อินพุตมัลติโมดัลในหน้าการสร้างเนื้อหาด้วยโมเดล AI

บางส่วน

ข้อความบางส่วนคือเทมเพลตที่ใช้ซ้ำได้ซึ่งรวมไว้ในพรอมต์ใดก็ได้ ชิ้นส่วนจะมีประโยชน์อย่างยิ่งสําหรับพรอมต์ที่เกี่ยวข้องซึ่งมีลักษณะการทํางานแบบเดียวกัน

เมื่อโหลดไดเรกทอรีพรอมต์ ระบบจะถือว่าไฟล์ที่มีขีดล่าง (_) นำหน้าเป็นพรอมต์บางส่วน ดังนั้นไฟล์ _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...}} หากไม่ได้ระบุอาร์กิวเมนต์ให้กับพรอมต์ย่อย ระบบจะดำเนินการโดยบริบทเดียวกับพรอมต์หลัก

ข้อมูลบางส่วนยอมรับอาร์กิวเมนต์ที่มีชื่อหรืออาร์กิวเมนต์ตำแหน่งเดียวที่แสดงถึงบริบท ซึ่งจะมีประโยชน์สำหรับงานต่างๆ เช่น การแสดงผลสมาชิกของรายการ

_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 จะทำงานได้ดีกว่าไหม คุณอาจสร้างไฟล์ 2 ไฟล์ดังนี้

  • myPrompt.prompt: พรอมต์ "baseline"
  • myPrompt.gemini25pro.prompt: ตัวแปรชื่อ gemini25pro

หากต้องการใช้ตัวแปรพรอมต์ ให้ระบุตัวเลือกตัวแปรเมื่อโหลด

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

ชื่อตัวแปรจะรวมอยู่ในข้อมูลเมตาของร่องรอยการสร้าง เพื่อให้คุณเปรียบเทียบประสิทธิภาพจริงระหว่างตัวแปรต่างๆ ในเครื่องมือตรวจสอบร่องรอย Genkit ได้

การกําหนดพรอมต์ในโค้ด

ตัวอย่างทั้งหมดที่พูดถึงจนถึงตอนนี้จะถือว่ามีการกําหนดพรอมต์ในไฟล์ .prompt แต่ละไฟล์ในไดเรกทอรีเดียว (หรือไดเรกทอรีย่อยของไดเรกทอรีนั้น) ซึ่งแอปของคุณเข้าถึงได้เมื่อรันไทม์ Dotprompt ออกแบบมาเพื่อการตั้งค่านี้ และนักเขียนเชื่อว่า Dotprompt เป็นประสบการณ์การใช้งานโดยรวมที่ดีที่สุดสำหรับนักพัฒนาซอฟต์แวร์

อย่างไรก็ตาม หากคุณมี Use Case ที่การตั้งค่านี้รองรับไม่ดีนัก คุณยังกําหนดพรอมต์ในโค้ดได้โดยใช้ฟังก์ชัน 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()