Dotprompt を使用したプロンプトの管理

Firebase Genkit には、Dotprompt プラグインとテキスト形式が用意されているため、 整理する方法を学びました。

Dotprompt は、プロンプトはコードであることを前提として設計されています。データ アナリストが .prompt ファイルと呼ばれる特別な形式のファイルでプロンプトを維持し、 使用しているのと同じバージョン管理システムを使用して、 生成 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 メソッドを呼び出してテンプレートをレンダリングし、それを渡すことができます。 1 ステップでモデル 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 の構文は Handlebars に基づいています 使用できます。ifunlesseach ヘルパーを使用して、 構造化コンテンツを反復処理できます。「 ファイル形式では、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 は、スカラー型 stringintegernumberbooleanany をサポートしています。 オブジェクト、配列、列挙型の場合は、フィールド名の後にかっこで囲みます。

Picoschema によって定義されたオブジェクトには、オプションで示されていない限り、すべてのプロパティが必須である ? で指定され、追加のプロパティは許可されません。プロパティを省略可とマークすると、 また、LLM が null を返すのではなく null を返せるようにするため、 省略できます。

オブジェクト定義では、特殊キー (*) を使用して「ワイルドカード」を宣言できます。 フィールドの定義をご覧ください。これは、UDM イベントで指定されていない されます。

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 は、https://、または「インライン」の場合は base64 でエンコードされた data: URI です。画像 できます。コードは次のようになります。

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 トレース内のバリアント間の実際のパフォーマンスを比較対照できる クリックします。