การจัดการพรอมต์ด้วย 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/
├── lib/
├── node_modules/
├── prompts/
│   └── hello.prompt
├── src/
├── package-lock.json
├── package.json
└── tsconfig.json

หากต้องการใช้ไดเรกทอรีอื่น คุณสามารถระบุไดเรกทอรีนั้นเมื่อกําหนดค่า Genkit ดังนี้

const ai = genkit({
  promptDir: './llm_prompts',
  // (Other settings...)
});

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

วิธีสร้างไฟล์ .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 { genkit } from 'genkit';

// Import the model plugins you want to use.
import { googleAI } from '@genkit-ai/googleai';

const ai = genkit({
  // Initialize and configure the model plugins.
  plugins: [
    googleAI({
      apiKey: 'your-api-key', // Or (preferred): export GOOGLE_GENAI_API_KEY=...
    }),
  ],
});

ไม่เป็นไรหากไฟล์มีโค้ดอื่นๆ แต่โค้ดข้างต้นคือโค้ดทั้งหมดที่จำเป็น

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

genkit start -- tsx --watch src/your-code.ts

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

เครื่องมือเรียกใช้โมเดล UI ของนักพัฒนาซอฟต์แวร์ Genkit

จากนั้นทดสอบพรอมต์และการกำหนดค่าจนกว่าจะได้ผลลัพธ์ที่พอใจ เมื่อพร้อมแล้ว ให้กดปุ่ม "ส่งออก" และบันทึกไฟล์ไปยังไดเรกทอรีพรอมต์

พรอมต์ที่กำลังทำงานอยู่

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

import { genkit } from 'genkit';

// Import the model plugins you want to use.
import { googleAI } from '@genkit-ai/googleai';

const ai = genkit({
  // Initialize and configure the model plugins.
  plugins: [
    googleAI({
      apiKey: 'your-api-key', // Or (preferred): export GOOGLE_GENAI_API_KEY=...
    }),
  ],
});

ไม่เป็นไรหากไฟล์มีโค้ดอื่นๆ แต่โค้ดข้างต้นคือโค้ดทั้งหมดที่จำเป็น หากคุณจัดเก็บพรอมต์ในไดเรกทอรีอื่นที่ไม่ใช่ค่าเริ่มต้น โปรดระบุไดเรกทอรีนั้นเมื่อกําหนดค่า Genkit

เรียกใช้พรอมต์จากโค้ด

หากต้องการใช้พรอมต์ ให้โหลดพรอมต์ก่อนโดยใช้เมธอด prompt('file_name') โดยทำดังนี้

const helloPrompt = ai.prompt('hello');

เมื่อโหลดแล้ว คุณจะเรียกใช้พรอมต์ได้เหมือนฟังก์ชัน ดังนี้

const response = await helloPrompt();

// Alternatively, use destructuring assignments to get only the properties
// you're interested in:
const { text } = await helloPrompt();

พรอมต์ที่เรียกใช้ได้จะใช้พารามิเตอร์ที่ไม่บังคับ 2 รายการ ได้แก่ อินพุตของพรอมต์ (ดูส่วนการระบุสคีมาอินพุตด้านล่าง) และออบเจ็กต์การกําหนดค่า ซึ่งคล้ายกับออบเจ็กต์ของเมธอด generate() เช่น

const response2 = await helloPrompt(
  // Prompt input:
  { name: 'Ted' },

  // Generation options:
  {
    config: {
      temperature: 0.4,
    },
  }
);

พารามิเตอร์ที่คุณส่งไปยังการเรียกใช้พรอมต์จะลบล้างพารามิเตอร์เดียวกันที่ระบุไว้ในไฟล์พรอมต์

ดูคำอธิบายตัวเลือกที่ใช้ได้ในส่วนสร้างเนื้อหาด้วยโมเดล AI

การใช้ UI สําหรับนักพัฒนาแอป

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

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

genkit start -- tsx --watch src/your-code.ts

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

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

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

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

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

ค่าเหล่านี้จะจับคู่กับพารามิเตอร์ config ที่พรอมต์ที่เรียกใช้ได้ยอมรับโดยตรง ดังนี้

const response3 = await helloPrompt(
  {},
  {
    config: {
      temperature: 1.4,
      topK: 50,
      topP: 0.4,
      maxOutputTokens: 400,
      stopSequences: ['<end>', '<fin>'],
    },
  }
);

ดูคำอธิบายตัวเลือกที่ใช้ได้ในส่วนสร้างเนื้อหาด้วยโมเดล AI

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

คุณสามารถระบุสคีมาอินพุตและเอาต์พุตสำหรับพรอมต์ได้โดยกำหนดสคีมาในหัวข้อหน้าแรก ดังนี้

---
model: googleai/gemini-1.5-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.

สคีมาเหล่านี้จะใช้ในลักษณะเดียวกับสคีมาที่ส่งไปยังgenerate()คำขอหรือคำจำกัดความของโฟลว์ ตัวอย่างเช่นพรอมต์ที่กําหนดไว้ด้านบนจะสร้างเอาต์พุตที่มีโครงสร้างดังนี้

const menuPrompt = ai.prompt('menu');
const { data } = await menuPrompt({ theme: 'medieval' });

const dishName = data['dishname'];
const description = data['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

สคีมาข้างต้นเทียบเท่ากับอินเทอร์เฟซ TypeScript ต่อไปนี้

interface Article {
  title: string;
  subtitle?: string | null;
  /** true when in draft state */
  draft?: boolean | null;
  /** approval status */
  status?: 'PENDING' | 'APPROVED' | null;
  /** the date of publication e.g. '2024-04-09' */
  date: string;
  /** relevant tags for article */
  tags: string[];
  authors: {
    name: string;
    email?: string | null;
  }[];
  metadata?: {
    /** ISO timestamp of last update */
    updatedAt?: string | null;
    /** id of approver */
    approvedBy?: number | null;
  } | null;
  /** arbitrary extra data */
  extra?: any;
  /** wildcard field */

}

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

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

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

สคีมา JSON

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

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

สคีมา Zod ที่กําหนดไว้ในโค้ด

นอกจากการกำหนดสคีมาโดยตรงในไฟล์ .prompt แล้ว คุณยังอ้างอิงสคีมาที่ลงทะเบียนกับ defineSchema() ตามชื่อได้ด้วย หากคุณใช้ TypeScript แนวทางนี้จะช่วยให้คุณใช้ประโยชน์จากฟีเจอร์การตรวจสอบประเภทแบบคงที่ของภาษาได้เมื่อทำงานกับพรอมต์

วิธีลงทะเบียนสคีมา

import { z } from 'genkit';

const MenuItemSchema = ai.defineSchema(
  'MenuItemSchema',
  z.object({
    dishname: z.string(),
    description: z.string(),
    calories: z.coerce.number(),
    allergens: z.array(z.string()),
  })
);

ระบุชื่อสคีมาที่จดทะเบียนในพรอมต์

---
model: googleai/gemini-1.5-flash-latest
output:
  schema: MenuItemSchema
---

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

const menuPrompt = ai.prompt<
  z.ZodTypeAny, // Input schema
  typeof MenuItemSchema, // Output schema
  z.ZodTypeAny // Custom options schema
>('menu');
const { data } = await menuPrompt({ theme: 'medieval' });

// Now data is strongly typed as MenuItemSchema:
const dishName = data?.dishname;
const description = data?.description;

เทมเพลตพรอมต์

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

คุณได้ดูการใช้งานแล้วในส่วนสคีมาอินพุตและเอาต์พุต

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

ในตัวอย่างนี้ นิพจน์ Handlebars {{theme}} จะแสดงผลเป็นค่าของพร็อพเพอร์ตี้ theme ของอินพุตเมื่อคุณเรียกใช้พรอมต์ หากต้องการส่งอินพุตไปยังพรอมต์ ให้เรียกใช้พรอมต์ตามตัวอย่างต่อไปนี้

const menuPrompt = ai.prompt('menu');
const { data } = await menuPrompt({ theme: 'medieval' });

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

นอกจากนี้เทมเพลต Handlebars ยังรองรับคอนสตรัคต์เชิงตรรกะแบบจํากัดบางอย่างด้วย ตัวอย่างเช่น คุณอาจกำหนดพรอมต์โดยใช้ตัวช่วย #if ของ Handlebars แทนการให้ค่าเริ่มต้น ดังนี้

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

ในตัวอย่างนี้ พรอมต์จะแสดงผลเป็น "สร้างรายการเมนูสำหรับร้านอาหาร" เมื่อไม่ได้ระบุพร็อพเพอร์ตี้ theme

ดูข้อมูลเกี่ยวกับตัวช่วยเชิงตรรกะในตัวทั้งหมดได้ในเอกสารประกอบของ Handlebars

นอกจากพร็อพเพอร์ตี้ที่กําหนดโดยสคีมาอินพุตแล้ว เทมเพลตยังอ้างอิงค่าที่ Genkit กําหนดโดยอัตโนมัติได้ด้วย ส่วนถัดไปจะอธิบายค่าที่กําหนดโดยอัตโนมัติเหล่านี้และวิธีใช้

ข้อความแจ้งแบบหลายข้อความ

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

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

---
model: vertexai/gemini-1.5-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-1.5-flash
input:
  schema:
    photoUrl: string
---
Describe this image in a detailed paragraph:

{{media url=photoUrl}}

URL อาจเป็น URI https: หรือ data: ที่เข้ารหัส Base64 สำหรับการใช้รูปภาพ "ในบรรทัด" โค้ดจะมีลักษณะดังนี้

const multimodalPrompt = ai.prompt('multimodal');
const { text } = await multimodalPrompt({
  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-1.5-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-1.5-flash-latest
input:
  schema:
    destinations(array):
      name: string
      country: string
---
Help the user decide between these vacation destinations:

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

การกําหนดอนุพันธ์บางส่วนในโค้ด

นอกจากนี้ คุณยังกำหนดส่วนย่อยในโค้ดได้โดยใช้ definePartial ดังนี้

ai.definePartial(
  'personality',
  'Talk like a {{#if style}}{{style}}{{else}}helpful assistant{{/if}}.'
);

ข้อความบางส่วนที่กําหนดโดยโค้ดจะใช้ได้ในพรอมต์ทั้งหมด

การกําหนดตัวช่วยที่กําหนดเอง

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

ai.defineHelper('shout', (text: string) => text.toUpperCase());

เมื่อกำหนดตัวช่วยแล้ว คุณจะใช้ตัวช่วยนั้นในพรอมต์ใดก็ได้ ดังนี้

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

HELLO, {{shout name}}!!!

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

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

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

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

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

const myPrompt = ai.prompt('my_prompt', { variant: 'gemini15pro' });

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

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

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

อย่างไรก็ตาม หากคุณมี Use Case ที่การตั้งค่านี้รองรับไม่ดีนัก คุณยังกําหนดพรอมต์ในโค้ดได้โดยใช้ฟังก์ชัน definePrompt() ดังนี้

พารามิเตอร์แรกสำหรับฟังก์ชันนี้คล้ายกับบล็อกส่วนหน้าของไฟล์ .prompt ส่วนพารามิเตอร์ที่ 2 อาจเป็นสตริงเทมเพลต Handlebars เช่นเดียวกับในไฟล์พรอมต์ หรือเป็นฟังก์ชันที่แสดงผล GenerateRequest ดังนี้

const myPrompt = ai.definePrompt(
  {
    name: 'myPrompt',
    model: 'googleai/gemini-1.5-flash',
    input: {
      schema: z.object({
        name: z.string(),
      }),
    },
  },
  'Hello, {{name}}. How are you today?'
);
const myPrompt = ai.definePrompt(
  {
    name: 'myPrompt',
    model: 'googleai/gemini-1.5-flash',
    input: {
      schema: z.object({
        name: z.string(),
      }),
    },
  },
  async (input): Promise<GenerateRequest> => {
    return {
      messages: [
        {
          role: 'user',
          content: [{ text: `Hello, ${input.name}. How are you today?` }],
        },
      ],
    };
  }
);