Dotprompt ile istemleri yönetme

Firebase Genkit, üretken yapay zeka istemlerinizi yazmanıza ve düzenlemenize yardımcı olmak için Dotprompt eklentisini ve metin biçimini sunar.

Dotprompt, istemlerin kod olduğu ilkesi doğrultusunda tasarlanmıştır. İstemlerinizi noktaprompt dosyaları adı verilen özel olarak biçimlendirilmiş dosyalarda yazar ve yönetirsiniz. Bu dosyalardaki değişiklikleri, kodunuz için kullandığınız sürüm kontrol sistemini kullanarak izler ve bunları üretken yapay zeka modellerinizi çağıran kodla birlikte dağıtırsınız.

Dotprompt'u kullanmak için önce projenizin kök dizininde bir prompts dizini oluşturun, ardından bu dizinde bir .prompt dosyası oluşturun. greeting.prompt olarak adlandırabileceğiniz basit bir örnek verelim:

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

Bu istemi kullanmak için dotprompt eklentisini yükleyin ve @genkit-ai/dotprompt kitaplığından prompt işlevini içe aktarın:

import { dotprompt, prompt } from '@genkit-ai/dotprompt';

configureGenkit({ plugins: [dotprompt()] });

Ardından, prompt('file_name') kullanarak istemi yükleyin:

const greetingPrompt = await prompt('greeting');

const result = await greetingPrompt.generate({
  input: {
    location: 'the beach',
    style: 'a fancy pirate',
  },
});

console.log(result.text());

Dotprompt'ın söz dizimi, Gidonlar şablon diline dayanır. İsteminize koşullu bölümler eklemek veya yapılandırılmış içerik aracılığıyla yineleme yapmak için if, unless ve each yardımcılarını kullanabilirsiniz. Dosya biçimi, şablonla birlikte satır içi bir istem için meta veri sağlamak amacıyla YAML ön bilgisini kullanır.

Picoschema ile Giriş/Çıkış Şemalarını tanımlama

Dotprompt, LLM kullanımı için bir şemanın en önemli özelliklerini tanımlamayı kolaylaştıran Piicoschema adlı, YAML için optimize edilmiş kompakt bir şema tanımı biçimi içerir. Makale şeması örneği:

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

Yukarıdaki şema, aşağıdaki TypeScript arayüzüne eşdeğerdir:

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

Picoschema; string, integer, number ve boolean skaler türlerini destekler. Nesneler, diziler ve numaralandırmalarda bunlar, alan adından sonra parantezle gösterilir.

Picoschema tarafından tanımlanan nesneler, ? ile isteğe bağlı olarak belirtilmediği sürece gerekli tüm özelliklere sahiptir ve ek özelliklere izin vermez.

Picoschema, tam JSON şemasının birçok özelliğini desteklemez. Daha sağlam şemalara ihtiyacınız varsa bunun yerine bir JSON Şeması sağlayabilirsiniz:

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

İstem Meta Verilerini Geçersiz Kılma

.prompt dosyaları, model yapılandırması gibi meta verileri dosyanın kendisine yerleştirmenize olanak tanır. Bununla birlikte, bu değerleri her arama için ayrı ayrı da geçersiz kılabilirsiniz:

const result = await greetingPrompt.generate({
  model: 'google-genai/gemini-pro',
  config: {
    temperature: 1.0,
  },
  input: {
    location: 'the beach',
    style: 'a fancy pirate',
  },
});

Yapılandırılmış çıkış

JSON biçimine zorlamak için bir istemin biçimini ve çıkış şemasını ayarlayabilirsiniz:

---
model: vertexai/gemini-1.0-pro
input:
  schema:
    theme: string
output:
  format: json
  schema:
    name: string
    price: integer
    ingredients(array): string
---

Generate a menu item that could be found at a {{theme}} themed restaurant.

Yapılandırılmış çıkışa sahip bir istem oluştururken istemi almak ve doğrulamak için output() yardımcısını kullanın:

const createMenuPrompt = await prompt('create_menu');

const menu = await createMenuPrompt.generate({
  input: {
    theme: 'banana',
  },
});

console.log(menu.output());

Çoklu mesaj istemleri

Varsayılan olarak, Dotprompt "user" rolüne sahip tek bir mesaj oluşturur. Bazı istemler en iyi şekilde, sistem istemi gibi birden fazla mesajın kombinasyonu olarak ifade edilir.

{{role}} yardımcısı, çoklu mesaj istemleri oluşturmak için basit bir yol sağlar:

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

Çok modlu istemler

Metin yanında resimler gibi çok modlu girişleri destekleyen modeller için {{media}} yardımcısını kullanabilirsiniz:

---
model: vertexai/gemini-1.0-pro-vision
input:
  schema:
    photoUrl: string
---

Describe this image in a detailed paragraph:

{{media url=photoUrl}}

"Satır içi" resim kullanımı için URL, https:// veya base64 kodlu data: URI'ları olabilir. Kodda bu şöyle olur:

const describeImagePrompt = await prompt('describe_image');

const result = await describeImagePrompt.generate({
  input: {
    photoUrl: 'https://example.com/image.png',
  },
});

console.log(result.text());

İstem Varyantları

İstem dosyaları sadece metin olduğundan bunları sürüm kontrol sisteminize kaydedebilirsiniz. Bu şekilde, zaman içindeki değişiklikleri kolayca karşılaştırabilirsiniz. Çoğu zaman, istemlerin değiştirilmiş sürümleri yalnızca bir üretim ortamında mevcut sürümlerle yan yana tam olarak test edilebilir. Dotprompt bunu varyantlar özelliğiyle destekler.

Varyant oluşturmak için [name].[variant].prompt dosyası oluşturun. Örneğin, isteminizde Gemini 1.0 Pro'yu kullanıyor ancak Gemini 1.5 Pro'nun daha iyi performans gösterip göstermeyeceğini öğrenmek istiyorsanız iki dosya oluşturabilirsiniz:

  • my_prompt.prompt: "referans" istemi
  • my_prompt.gemini15.prompt: "gemini" adlı bir varyant

İstem varyantı kullanmak için yükleme sırasında variant seçeneğini belirtin:

const myPrompt = await prompt('my_prompt', { variant: 'gemini15' });

İstem yükleyici bu adın varyantını yüklemeye çalışır ve değişken yoksa referans değere döner. Bu, uygulamanız için anlamlı olan kriterlere göre koşullu yüklemeyi kullanabileceğiniz anlamına gelir:

const myPrompt = await prompt('my_prompt', {
  variant: isBetaTester(user) ? 'gemini15' : null,
});

Varyantın adı, oluşturma izlerinin meta verilerine dahil edilir. Böylece Genkit iz inceleyicide varyantlar arasında gerçek performansı karşılaştırabilir ve aradaki farkları inceleyebilirsiniz.

İstemleri yüklemenin ve tanımlamanın alternatif yolları

Dotprompt, istem dizinindeki organizasyon için optimize edilmiştir. Ancak, istemleri yüklemenin ve tanımlamanın birkaç yolu daha vardır:

  • loadPromptFile: İstem dizinindeki bir dosyadan istem yükler.
  • loadPromptUrl: URL'den istem yükler.
  • defineDotprompt: Kodda bir istem tanımlayın.

Örnekler:

import {
  loadPromptFile,
  loadPromptUrl,
  defineDotprompt,
} from '@genkit-ai/dotprompt';
import path from 'path';
import { z } from 'zod';

// Load a prompt from a file
const myPrompt = await loadPromptFile(
  path.resolve(__dirname, './path/to/my_prompt.prompt')
);

// Load a prompt from a URL
const myPrompt = await loadPromptUrl('https://example.com/my_prompt.prompt');

// Define a prompt in code
const myPrompt = defineDotprompt(
  {
    model: 'vertexai/gemini-1.0-pro',
    input: {
      schema: z.object({
        name: z.string(),
      }),
    },
  },
  `Hello {{name}}, how are you today?`
);