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

Firebase Genkit มีปลั๊กอิน Dotprompt และรูปแบบข้อความเพื่อช่วยคุณเขียน และจัดระเบียบพรอมต์ Generative AI

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

หากต้องการใช้ Dotprompt ให้สร้างไดเรกทอรี prompts ในรูทของโปรเจ็กต์ก่อนและ จากนั้นสร้างไฟล์ .prompt ในไดเรกทอรีนั้น ลองดูตัวอย่างง่ายๆ นี้ อาจโทรหา greeting.prompt:

---
model: vertexai/gemini-1.5-pro
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}}.

วิธีใช้ข้อความแจ้งนี้

Go

ติดตั้งปลั๊กอิน dotprompt

go get github.com/firebase/genkit/go/plugins/dotprompt

จากนั้นโหลดข้อความแจ้งโดยใช้ Open

import "github.com/firebase/genkit/go/plugins/dotprompt"
dotprompt.SetDirectory("prompts")
prompt, err := dotprompt.Open("greeting")

คุณสามารถเรียกใช้เมธอด Generate ของพรอมต์เพื่อแสดงผลเทมเพลตและส่งเทมเพลตดังกล่าว กับ API โมเดลในขั้นตอนเดียว

ctx := context.Background()

// The .prompt file specifies vertexai/gemini-1.5-pro, so make sure it's set
// up.
// Default to the project in GCLOUD_PROJECT and the location "us-central1".
vertexai.Init(ctx, nil)
vertexai.DefineModel("gemini-1.5-pro", nil)

type GreetingPromptInput struct {
  Location string `json:"location"`
  Style    string `json:"style"`
  Name     string `json:"name"`
}
response, err := prompt.Generate(
  ctx,
  &dotprompt.PromptRequest{
      Variables: GreetingPromptInput{
          Location: "the beach",
          Style:    "a fancy pirate",
          Name:     "Ed",
      },
  },
  nil,
)
if err != nil {
  return err
}

if responseText, err := response.Text(); err == nil {
  fmt.Println(responseText)
}

หรือเพียงแสดงเทมเพลตเป็นสตริง

Go

renderedPrompt, err := prompt.RenderText(map[string]any{
  "location": "a restaurant",
  "style":    "a pirate",
})

ไวยากรณ์ของ Dotprompt จะอิงตามแฮนด์บาร์ ภาษาเทมเพลต คุณสามารถใช้ตัวช่วยของ if, unless และ each เพื่อเพิ่ม ตามเงื่อนไขในพรอมต์หรือทำซ้ำผ่านเนื้อหาที่มีโครงสร้าง รูปแบบไฟล์ใช้ฟรอนท์เมเตอร์ YAML เพื่อมอบข้อมูลเมตาสำหรับพรอมต์ในบรรทัด ด้วยเทมเพลต

การกำหนดสคีมาอินพุต/เอาต์พุตด้วย Picoschema

Dotprompt มีรูปแบบคำจำกัดความของสคีมาแบบ YAML ขนาดกะทัดรัดที่เรียกว่า Picoschema ช่วยให้กำหนดแอตทริบิวต์ที่สำคัญที่สุดของสคีมาได้อย่างง่ายดาย สำหรับการใช้งาน 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

สคีมาข้างต้นเทียบเท่ากับสคีมา JSON ต่อไปนี้

{
  "properties": {
    "metadata": {
      "properties": {
        "updatedAt": {
          "type": "string",
          "description": "ISO timestamp of last update"
        },
        "approvedBy": {
          "type": "integer",
          "description": "id of approver"
        }
      },
      "type": "object"
    },
    "title": {
      "type": "string"
    },
    "subtitle": {
      "type": "string"
    },
    "draft": {
      "type": "boolean",
      "description": "true when in draft state"
    },
    "date": {
      "type": "string",
      "description": "the date of publication e.g. '2024-04-09'"
    },
    "tags": {
      "items": {
        "type": "string"
      },
      "type": "array",
      "description": "relevant tags for article"
    },
    "authors": {
      "items": {
        "properties": {
          "name": {
            "type": "string"
          },
          "email": {
            "type": "string"
          }
        },
        "type": "object",
        "required": ["name"]
      },
      "type": "array"
    }
  },
  "type": "object",
  "required": ["title", "date", "tags", "authors"]
}

Picoschema รองรับประเภทสเกลาร์ string, integer, number, boolean และ any สำหรับออบเจ็กต์ อาร์เรย์ และ enum จะมีวงเล็บกำกับไว้หลังชื่อช่อง

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

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

Picoschema ไม่รองรับความสามารถหลายอย่างของสคีมา JSON แบบเต็ม หากคุณ ต้องการสคีมาที่แข็งแกร่งมากขึ้น คุณอาจส่งสคีมา JSON แทน:

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

การลบล้างข้อมูลเมตาของข้อความแจ้ง

ในขณะที่ไฟล์ .prompt ให้คุณฝังข้อมูลเมตา เช่น การกำหนดค่าโมเดลใน นอกจากนี้ คุณยังสามารถลบล้างค่าเหล่านี้ตามการเรียกแต่ละครั้ง ดังนี้

Go

// Make sure you set up the model you're using.
vertexai.DefineModel("gemini-1.5-flash", nil)

response, err := prompt.Generate(
  context.Background(),
  &dotprompt.PromptRequest{
      Variables: GreetingPromptInput{
          Location: "the beach",
          Style:    "a fancy pirate",
          Name:     "Ed",
      },
      Model: "vertexai/gemini-1.5-flash",
      Config: &ai.GenerationCommonConfig{
          Temperature: 1.0,
      },
  },
  nil,
)

พรอมต์หลายข้อความ

โดยค่าเริ่มต้น Dotprompt จะสร้างข้อความเดียวที่มีบทบาท "user" ใช้บ้าง พรอมต์ที่ดีที่สุดคือการระบุที่ประกอบด้วยข้อความหลายๆ ข้อความ เช่น ข้อความแจ้งของระบบ

โปรแกรมช่วย {{role}} มีวิธีง่ายๆ ในการสร้างพรอมต์หลายข้อความ ดังนี้

---
model: vertexai/gemini-1.0-pro
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-1.0-pro-vision
input:
  schema:
    photoUrl: string
---

Describe this image in a detailed paragraph:

{{media url=photoUrl}}

URL จะเป็น URI แบบ https:// หรือ data: ที่เข้ารหัสฐาน 64 สำหรับ "ในบรรทัด" ก็ได้ ภาพ ในโค้ดจะเป็น

Go

dotprompt.SetDirectory("prompts")
describeImagePrompt, err := dotprompt.Open("describe_image")
if err != nil {
  return err
}

imageBytes, err := os.ReadFile("img.jpg")
if err != nil {
  return err
}
encodedImage := base64.StdEncoding.EncodeToString(imageBytes)
dataURI := "data:image/jpeg;base64," + encodedImage

type DescribeImagePromptInput struct {
  PhotoUrl string `json:"photo_url"`
}
response, err := describeImagePrompt.Generate(
  context.Background(),
  &dotprompt.PromptRequest{Variables: DescribeImagePromptInput{
      PhotoUrl: dataURI,
  }},
  nil,
)

ตัวแปรพรอมต์

เนื่องจากไฟล์พรอมต์เป็นเพียงข้อความ คุณสามารถ (และควร!) คอมมิตไฟล์เหล่านั้นไว้ใน ระบบควบคุมเวอร์ชัน ช่วยให้คุณเปรียบเทียบการเปลี่ยนแปลงในช่วงเวลาที่ผ่านมาได้โดยง่าย บ่อยครั้งที่พรอมต์เวอร์ชันที่ได้รับการปรับแก้สามารถทดสอบอย่างสมบูรณ์ได้ใน สภาพแวดล้อมเวอร์ชันที่ใช้งานจริงควบคู่กับเวอร์ชันที่มีอยู่ Dotprompt สนับสนุน ผ่านฟีเจอร์รูปแบบ

หากต้องการสร้างตัวแปร ให้สร้างไฟล์ [name].[variant].prompt ตัวอย่างเช่น หาก คุณกำลังใช้ Gemini 1.0 Pro ในพรอมต์ แต่อยากทราบว่า Gemini 1.5 Pro หรือไม่ อาจทำงานได้ดีกว่า คุณอาจสร้างไฟล์ 2 ไฟล์ ได้แก่

  • my_prompt.prompt: "เกณฑ์พื้นฐาน" ข้อความแจ้ง
  • my_prompt.gemini15.prompt: ตัวแปรที่ชื่อ "gemini"

หากต้องการใช้รูปแบบพรอมต์ ให้ระบุตัวแปรขณะโหลด ดังนี้

Go

describeImagePrompt, err := dotprompt.OpenVariant("describe_image", "gemini15")

ตัวโหลดข้อความแจ้งจะพยายามโหลดรูปแบบของชื่อนั้นและเปลี่ยนกลับ ให้กับเกณฑ์พื้นฐาน หากไม่มี ซึ่งหมายความว่าคุณสามารถใช้การโหลดแบบมีเงื่อนไขตาม โดยใช้เกณฑ์ที่เหมาะกับการสมัครของคุณ

Go

var myPrompt *dotprompt.Prompt
var err error
if isBetaTester(user) {
  myPrompt, err = dotprompt.OpenVariant("describe_image", "gemini15")
} else {
  myPrompt, err = dotprompt.Open("describe_image")
}

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