Dotprompt ile istemleri yönetme

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

Dotprompt, istemlerin kod olduğu ilkesi doğrultusunda tasarlanmıştır. Siz yazar, istemlerinizi noktaprompt dosyaları adı verilen özel olarak biçimlendirilmiş dosyalarda tutma, izleme için kullandığınız sürüm kontrol sistemini kullanarak ve bunları üretken yapay zekanızı çağıran kodla birlikte dağıtabilirsiniz modeller.

Dotprompt'ı kullanmak için önce proje kökünüzde bir prompts dizini oluşturun ve daha sonra, bu dizinde bir .prompt dosyası oluşturun. Basit bir örnek verelim. greeting.prompt adlı kişiyi arayabilir:

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

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

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

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

Ardından prompt('file_name') komutunu 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, Handlebars'a (İşleyici Çubukları) bağlıdır. şablon oluşturma dili. Aşağıdakileri eklemek için if, unless ve each yardımcılarını kullanabilirsiniz koşullu bölümleri yönlendirmenize veya yapılandırılmış içerikte yineleme yapmanıza olanak tanır. İlgili içeriği oluşturmak için kullanılan dosya biçimi, satır içi istem için meta veri sağlamak üzere YAML ön iletişimini kullanır şablonla deneyin.

Giriş/Çıkış Şemalarını Tanımlama

Dotprompt; Bir şemanın en önemli özelliklerini tanımlamayı kolaylaştıran Picoschema göz önünde bulundurun. Aşağıda, bir makale şeması örneği verilmiştir:

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

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

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 skaler türleri destekler: string, integer, number, boolean ve any. Nesneler, diziler ve sıralamalar, alan adından sonra parantez içinde gösterilir.

Picoschema tarafından tanımlanan nesneler, isteğe bağlı olarak belirtilmediği sürece gereken tüm özelliklere sahiptir ve ek mülklere izin vermeyin.? Bir tesis isteğe bağlı olarak işaretlendiğinde LLM'lerin atlatıyoruz.

Nesne tanımında, "joker karakter" tanımlamak için (*) özel anahtarı kullanılabilir alan tanımıdır. Bu, açık anahtar.

Picoschema, tam JSON şemasının birçok özelliğini desteklemez. Şu durumda: daha sağlam şemalar gerekiyorsa bunun yerine bir JSON Şeması sağlayabilirsiniz:

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

Yeniden Kullanılabilir Şemalardan Yararlanma

Şemaları doğrudan .prompt dosyasında tanımlamaya ek olarak, defineSchema adına adıyla kayıtlı bir şema. Bir şemayı kaydetmek için:

import { defineSchema } from '@genkit-ai/core';
import { z } from 'zod';

const MySchema = defineSchema(
  'MySchema',
  z.object({
    field1: z.string(),
    field2: z.number(),
  })
);

İsteminizde kayıtlı şemanın adını belirtebilirsiniz:

# myPrompt.prompt
---
model: vertexai/gemini-1.5-flash
output:
  schema: MySchema
---

Dotprompt kitaplığı, adı otomatik olarak temel kayıtlı Zod şeması. Daha sonra bir Dotprompt çıktısı:

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

const myPrompt = await prompt("myPrompt");

const result = await myPrompt.generate<typeof MySchema>({...});

// now strongly typed as MySchema
result.output();

İstem Meta Verilerini Geçersiz Kılma

.prompt dosyaları, model yapılandırması gibi meta verileri bu değerleri her arama için ayrı ayrı da geçersiz kılabilirsiniz:

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

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

Bir istemin biçimini ve çıkış şemasını JSON'a zorlamak için ayarlayabilirsiniz:

---
model: vertexai/gemini-1.5-flash
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ışla istem oluştururken output() yardımcısını kullanarak alın ve doğrulayın:

const createMenuPrompt = await prompt('create_menu');

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

console.log(menu.output());

Çıktı uygunluğu, kontrol paneline ek talimatlar eklenerek sağlanır. tıklayın. Varsayılan olarak, oluşturulan son iletinin sonuna eklenir tıklayın. {{section "output"}} öğesini kullanarak manuel olarak yeniden konumlandırabilirsiniz yardımcı olur.

This is a prompt that manually positions output instructions.

== Output Instructions

{{section "output"}}

== Other Instructions

This will come after the output instructions.

Çoklu mesaj istemleri

Varsayılan olarak Dotprompt, "user" rolüyle tek bir mesaj oluşturur. Biraz istemlerin en iyi şekilde ifade edilmesi, birden fazla mesajın bir kombinasyonu tıklayın.

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

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

Çoklu Dönüş İstemleri ve Geçmiş

Dotprompt, history seçeneğini generate yöntemi:

const result = await multiTurnPrompt.generate({
  history: [
    { role: 'user', content: [{ text: 'Hello.' }] },
    { role: 'model', content: [{ text: 'Hi there!' }] },
  ],
});

Varsayılan olarak geçmiş, tarafından oluşturulan son mesajdan önce eklenir tıklayın. Ancak, {{history}} kullanarak geçmişi manuel olarak konumlandırabilirsiniz. yardımcı:

{{role "system"}}
This is the system prompt.
{{history}}
{{role "user"}}
This is a user message.
{{role "model"}}
This is a model message.
{{role "user"}}
This is the final user message.

Çok modlu istemler

Metnin yanında görüntü gibi çok modlu girişleri destekleyen modellerde {{media}} yardımcısını kullanın:

---
model: vertexai/gemini-1.5-flash
input:
  schema:
    photoUrl: string
---

Describe this image in a detailed paragraph:

{{media url=photoUrl}}

URL, "inline" (satır içi) için https:// veya base64 kodlu data: URI'leri olabilir. resim bazı yolları da görmüştük. Kodda bu aşağıdaki gibidir:

const describeImagePrompt = await prompt('describe_image');

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

console.log(result.text());

Kısmiler

Kısmiler, herhangi bir istemin içine eklenebilen yeniden kullanılabilir şablonlardır. Kısmiler özellikle de ortak davranışları paylaşan benzer istemler için yararlı olabilir.

Bir istem dizini yüklenirken _ ön ekine sahip tüm dosyalar bir istem dizini olarak kabul edilir kısmidir. Yani bir _personality.prompt dosyası şunları içerebilir:

You should speak like a {{#if style}}{{style}}{{else}}helpful assistant.{{/else}}.

Bu, daha sonra diğer istemlere dahil edilebilir:

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

Kısmiler {{>NAME_OF_PARTIAL args...}} söz dizimi kullanılarak eklenir. Yanıt hayır ise: bağımsız değişkenler sağlandığında, bu komut, ebeveyn istemine dokunun.

Kısmiler, yukarıdaki gibi adlandırılmış her iki bağımsız değişkeni veya tek bir konum bağımsız değişkenini kabul eder temsil eder. Bu, şunun için faydalı olabilir: bir listenin üyelerini oluşturur.

# _destination.prompt
- {{name}} ({{country}})

# chooseDestination.prompt
Help the user decide between these vacation destinations:
{{#each destinations}}
{{>destination this}}{{/each}}

Kodda Kısmileri Tanımlama

Ayrıca, definePartial kullanarak kodda kısmi değerler tanımlayabilirsiniz:

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

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

Kod tanımlı kısmi öğeler, tüm istemlerde kullanılabilir.

İstem Varyantları

İstem dosyaları yalnızca metin olduğundan, bunları kendi zaman içindeki değişiklikleri kolayca karşılaştırmanızı sağlar. Çoğu zaman, istemlerin değiştirilmiş versiyonları yalnızca tek bir mevcut sürümlerle yan yana görmelerini sağlamalısınız. Dotprompt destekler varyantları özelliği aracılığıyla test edebilirsiniz.

Varyant oluşturmak için [name].[variant].prompt dosyası oluşturun. Örneğin, isteminizde Gemini 1.5 Flash kullanıyordunuz ancak Gemini 1.5 Flash'ın Pro daha iyi performans gösterirse iki dosya oluşturabilirsiniz:

  • my_prompt.prompt: "referans" istem
  • my_prompt.gemini15pro.prompt: "gemini15pro" 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: 'gemini15pro' });

Varyantın adı, oluşturma izlerinin meta verilerine dahil edildiğinden Genkit izindeki varyantların gerçek performansını karşılaştırabilir. denetleyicidir.

Özel Yardımcılar Tanımlama

Bir istem içindeki verileri işlemek ve yönetmek için özel yardımcılar tanımlayabilirsiniz. Yardımcılar dünya genelinde defineHelper kullanılarak kaydedilmiştir:

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

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

Tanımlanan yardımcıları herhangi bir istemde kullanabilirsiniz:

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

HELLO, {{shout name}}!!!

Yardımcılara aktarılan bağımsız değişkenler hakkında daha fazla bilgi için Oluşturma hakkında giderme çubuğu dokümanları yardımcı olan araçlardır.

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

Dotprompt, istem dizinindeki organizasyon için optimize edilmiştir. Ancak, İstemleri yükleyip tanımlamanın birkaç farklı 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.5-flash',
    input: {
      schema: z.object({
        name: z.string(),
      }),
    },
  },
  `Hello {{name}}, how are you today?`
);