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/
├── lib/
├── node_modules/
├── prompts/
│   └── hello.prompt
├── src/
├── package-lock.json
├── package.json
└── tsconfig.json

अगर आपको किसी दूसरी डायरेक्ट्री का इस्तेमाल करना है, तो Genkit को कॉन्फ़िगर करते समय इसकी जानकारी दी जा सकती है:

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

प्रॉम्प्ट फ़ाइल बनाना

.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 मार्कडाउन और Jekyll में इस्तेमाल किए जाने वाले फ़्रंट मैटर फ़ॉर्मैट जैसा ही है. फ़ाइल का बाकी हिस्सा प्रॉम्प्ट है. इसमें वैकल्पिक रूप से, हैंडलबार टेंप्लेट का इस्तेमाल किया जा सकता है. फ़्रंट मैटर सेक्शन का इस्तेमाल करना ज़रूरी नहीं है. हालांकि, ज़्यादातर प्रॉम्प्ट फ़ाइलों में कम से कम मॉडल की जानकारी देने वाला मेटाडेटा होगा. इस पेज पर आगे बताया गया है कि इस सुविधा के अलावा, अपनी प्रॉम्प्ट फ़ाइलों में Dotprompt की सुविधाओं का इस्तेमाल कैसे किया जा सकता है.

डेवलपर यूज़र इंटरफ़ेस (यूआई) का इस्तेमाल करना

डेवलपर यूज़र इंटरफ़ेस (यूआई) में मॉडल रनर का इस्तेमाल करके भी प्रॉम्प्ट फ़ाइल बनाई जा सकती है. 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 start -- tsx --watch src/your-code.ts

मॉडल सेक्शन में, प्लग इन की दी गई सूची से वह मॉडल चुनें जिसका इस्तेमाल करना है.

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();

कॉल किए जा सकने वाले प्रॉम्प्ट में दो वैकल्पिक पैरामीटर होते हैं: प्रॉम्प्ट का इनपुट (इनपुट स्कीमा तय करना सेक्शन देखें) और कॉन्फ़िगरेशन ऑब्जेक्ट, जो generate() तरीके से मिलता-जुलता है. उदाहरण के लिए:

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

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

प्रॉम्प्ट कॉल में भेजे गए किसी भी पैरामीटर से, प्रॉम्प्ट फ़ाइल में बताए गए पैरामीटर बदल जाएंगे.

उपलब्ध विकल्पों के बारे में जानने के लिए, एआई मॉडल की मदद से कॉन्टेंट जनरेट करना लेख पढ़ें.

डेवलपर यूज़र इंटरफ़ेस (यूआई) का इस्तेमाल करना

अपने ऐप्लिकेशन के प्रॉम्प्ट को बेहतर बनाते समय, उन्हें Genkit डेवलपर यूज़र इंटरफ़ेस (यूआई) में चलाया जा सकता है. इससे, प्रॉम्प्ट और मॉडल कॉन्फ़िगरेशन को तुरंत दोहराया जा सकता है. इसके लिए, ऐप्लिकेशन कोड की ज़रूरत नहीं होती.

अपनी प्रोजेक्ट डायरेक्ट्री से डेवलपर यूज़र इंटरफ़ेस (यूआई) लोड करें:

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

Genkit डेवलपर यूज़र इंटरफ़ेस (यूआई) प्रॉम्प्ट रनर

डेवलपर यूज़र इंटरफ़ेस (यूआई) में प्रॉम्प्ट लोड करने के बाद, उन्हें अलग-अलग इनपुट वैल्यू के साथ चलाया जा सकता है. साथ ही, यह भी देखा जा सकता है कि प्रॉम्प्ट के शब्दों या कॉन्फ़िगरेशन पैरामीटर में किए गए बदलावों से, मॉडल के आउटपुट पर क्या असर पड़ता है. जब आपको नतीजा पसंद आ जाए, तो बदले गए प्रॉम्प्ट को अपनी प्रोजेक्ट डायरेक्ट्री में सेव करने के लिए, प्रॉम्प्ट एक्सपोर्ट करें बटन पर क्लिक करें.

मॉडल का कॉन्फ़िगरेशन

प्रॉम्प्ट फ़ाइलों के फ़्रंट मैटर ब्लॉक में, अपने प्रॉम्प्ट के लिए मॉडल कॉन्फ़िगरेशन की वैल्यू दी जा सकती हैं. हालांकि, ऐसा करना ज़रूरी नहीं है:

---
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>'],
    },
  }
);

उपलब्ध विकल्पों के बारे में जानने के लिए, एआई मॉडल की मदद से कॉन्टेंट जनरेट करना लेख पढ़ें.

इनपुट और आउटपुट स्कीमा

अपने प्रॉम्प्ट के लिए इनपुट और आउटपुट स्कीमा तय किए जा सकते हैं. इसके लिए, उन्हें 'फ़्रंट मैटर' सेक्शन में तय करें:

---
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 के ज़रिए तय किए गए ऑब्जेक्ट में सभी ज़रूरी प्रॉपर्टी होती हैं. हालांकि, अगर ? के ज़रिए किसी प्रॉपर्टी को ज़रूरी नहीं बताया गया है, तो उसे ऑब्जेक्ट में शामिल नहीं किया जा सकता. साथ ही, इसमें अन्य प्रॉपर्टी शामिल नहीं की जा सकतीं. जब किसी प्रॉपर्टी को वैकल्पिक के तौर पर मार्क किया जाता है, तो उसे वैल्यू के बिना भी सबमिट किया जा सकता है. इससे एलएलएम को किसी फ़ील्ड को छोड़ने के बजाय, वैल्यू के बिना सबमिट करने की ज़्यादा छूट मिलती है.

ऑब्जेक्ट की परिभाषा में, स्पेशल बटन (*) का इस्तेमाल करके, "वाइल्डकार्ड" फ़ील्ड की परिभाषा दी जा सकती है. यह उन सभी अतिरिक्त प्रॉपर्टी से मैच करेगा जिन्हें साफ़ तौर पर किसी कुंजी से नहीं दिया गया है.

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

इस उदाहरण में, प्रॉम्प्ट चलाने पर, हैंडलबार एक्सप्रेशन, {{theme}}, इनपुट की theme प्रॉपर्टी की वैल्यू पर रिज़ॉल्व होता है. प्रॉम्प्ट में इनपुट पास करने के लिए, प्रॉम्प्ट को इस उदाहरण में बताए गए तरीके से कॉल करें:

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

ध्यान दें कि इनपुट स्कीमा ने theme प्रॉपर्टी को वैकल्पिक बताया है और इसके लिए डिफ़ॉल्ट वैल्यू दी है. इसलिए, आपके पास प्रॉपर्टी को हटाने का विकल्प होता है. साथ ही, प्रॉम्प्ट को डिफ़ॉल्ट वैल्यू का इस्तेमाल करके हल किया जा सकता है.

हैंडलबार टेंप्लेट, कुछ सीमित लॉजिकल कंस्ट्रक्ट के साथ भी काम करते हैं. उदाहरण के लिए, डिफ़ॉल्ट वैल्यू देने के बजाय, Handlebars के #if हेल्पर का इस्तेमाल करके प्रॉम्प्ट तय किया जा सकता है:

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

"इनलाइन" इमेज के इस्तेमाल के लिए, यूआरएल https: या Base64 एन्कोड किया गया data: यूआरआई हो सकता है. कोड में, यह इस तरह दिखेगा:

const multimodalPrompt = ai.prompt('multimodal');
const { text } = await multimodalPrompt({
  photoUrl: 'https://example.com/photo.jpg',
});

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 बेहतर परफ़ॉर्म करेगा या नहीं, तो दो फ़ाइलें बनाई जा सकती हैं:

  • my_prompt.prompt: "बेसलाइन" प्रॉम्प्ट
  • my_prompt.gemini15pro.prompt: gemini15pro नाम का वैरिएंट

प्रॉम्प्ट वैरिएंट का इस्तेमाल करने के लिए, लोड करते समय वैरिएंट का विकल्प बताएं:

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

वैरिएंट का नाम, जनरेशन ट्रेस के मेटाडेटा में शामिल होता है, ताकि आप Genkit ट्रेस इंस्पेक्टर में वैरिएंट के बीच असल परफ़ॉर्मेंस की तुलना कर सकें.

कोड में प्रॉम्प्ट तय करना

अब तक जिन उदाहरणों के बारे में बताया गया है उनमें यह माना गया है कि आपके प्रॉम्प्ट, एक ही डायरेक्ट्री (या उसकी सबडायरेक्ट्री) में मौजूद अलग-अलग .prompt फ़ाइलों में तय किए गए हैं. साथ ही, ये फ़ाइलें रनटाइम के दौरान आपके ऐप्लिकेशन के लिए ऐक्सेस की जा सकती हैं. Dotprompt को इस सेटअप के हिसाब से डिज़ाइन किया गया है. इसके लेखकों का मानना है कि यह डेवलपर के लिए सबसे अच्छा अनुभव है.

हालांकि, अगर आपके पास ऐसे इस्तेमाल के उदाहरण हैं जो इस सेटअप के साथ ठीक से काम नहीं करते, तो definePrompt() फ़ंक्शन का इस्तेमाल करके, कोड में प्रॉम्प्ट भी तय किए जा सकते हैं:

इस फ़ंक्शन का पहला पैरामीटर, .prompt फ़ाइल के फ़्रंट मैटर ब्लॉक जैसा होता है. दूसरा पैरामीटर, प्रॉम्प्ट फ़ाइल की तरह, हैंडलबार टेंप्लेट स्ट्रिंग या ऐसा फ़ंक्शन हो सकता है जो 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?` }],
        },
      ],
    };
  }
);