LoginSignup
1
0

LLMのプロンプトを自動テスト?!promptfooを使ってみる。

Posted at

LLMのプロンプトって難しいですよね。

ちょっと変えるだけで答えてくれる内容が全然変わります。

LLMから出力されるテキストの品質を評価し、自動でテストできないかなー。と調べていたら、promptfoo なるものを見つけました。

promptfooは、LLMの出力品質を評価するためのCLIとライブラリです。
promptfoo を使うと、以下のことができます:

  • プロンプト、モデル、RAG を定義済みのテストケースで系統的にテストする。
  • LLM出力を並べて比較することにより、品質を評価し、リグレッションを検出する。
  • キャッシュと並行テストによる評価のスピードアップ
  • 期待値を定義することで、出力を自動的にスコアリング
  • CLIとして使用することも、ライブラリとしてワークフローに統合することもできます。
  • OpenAI、Anthropic、Azure、Google、HuggingFace、Llamaのようなオープンソースモデルを使用するか、任意のLLM API用のカスタムAPIプロバイダーを統合します。

簡単に試してみたので、備忘録として残します。

インストール~実行

ドキュメントの内容に沿って進めてみます。

まず npm install promptfoo で promptfooをインストールします。※Node 16以上

npx promptfoo@latest initpromptfooconfig.yaml が作られますので、このファイルを編集していきます。今回、以下のように書き換えました。AOAIのGPT-3.5-turboとGPT-4に対して2種類のプロンプトを評価、テストしてみます。
設定ファイルの記載方法、評価の種類などはドキュメント、GitHubに色々載ってます。

promptfooconfig.yaml
# This configuration compares LLM output of 2 prompts x 2 GPT models across 3 test cases.
# Learn more: https://promptfoo.dev/docs/configuration/guide
description: 'My first eval'

prompts:
  - file://prompt/prompt1.json #プロンプト1
  - file://prompt/prompt2.json #プロンプト2

providers:
  # - openai:gpt-3.5-turbo
  # - openai:gpt-4
  # 今回はAzureOpenAIでテスト...
  - id: azureopenai:chat:gpt-35-turbo # azureopenai:chat:<deploymentName>
    config:
      apiHost: '<azure-openai-service-name>.openai.azure.com'
      temperature: 0.5
      max_tokens: 1000

  - id: azureopenai:chat:gpt-4
    config:
      apiHost: '<azure-openai-service-name>.openai.azure.com'
      temperature: 0.5
      max_tokens: 1000

tests:
  - vars:
      topic: バナナ
    assert:
      # llm-runbric: 言語モデルを使用して出力が指定された要件に一致するかどうかを確認
      - type: llm-rubric
        value: 出力にユーモアが含まれていない事を確認する。尚、「にゃ」が含まれているのはユーモアでは無い。
        provider:
          id: azureopenai:chat:gpt-4
          config:
            apiHost: '<azure-openai-service-name>.openai.azure.com'
      
      # contains: 出力に部分文字列が含まれるか
      - type: contains
        value: にゃ
      
      - type: llm-rubric
        value: 出力の最後の単語が「にゃ」で終わっている事を確認する。
        provider:
          id: azureopenai:chat:gpt-4
          config:
            apiHost: '<azure-openai-service-name>.openai.azure.com'
      
      # similar: コサイン類似度のしきい値を使用して出力の埋め込みが期待値と意味的に類似しているか
      - type: similar
        value: バナナは食物繊維がたっぷりだにゃ
        threshold: 0.85
        provider:
          id: azureopenai:embeddings:text-embedding-ada-002
          config:
            apiHost: '<azure-openai-service-name>.openai.azure.com'
    

プロンプトは以下の2種類を用意します。※JSON以外でも可

prompt1.json
[
  {
    "role": "system",
    "content": "あなたは猫です。{{topic}}の内容について面白おかしく雑学を言ってください。"
  },
  {
    "role": "user",
    "content": "{{topic}}でお願いします。"
  }
]
prompt2.json
[
    {
      "role": "system",
      "content": "あなたは猫です。{{topic}}の内容について簡潔に雑学を答える。内容にはユーモアを含んではいけない。語尾には「にゃ」必ずをつける事。"
    },
    {
      "role": "user",
      "content": "{{topic}}でお願いします。"
    }
]

API_KEYを環境変数に設定しておきます。

bash
export AZURE_OPENAI_API_KEY=<APIKEY>

それでは早速テストを実行してみます。コマンドはnpx promptfoo@latest eval です。
すると以下のように出力されます。 -o オプションで出力形式をcsvなどに変更する事もできます。

image.png

テスト完了後はnpx promptfoo@latest viewコマンドで、localhostサーバーが立ち上がり、ウェブ画面形式で結果を確認することができます。

image.png

虫眼鏡マークをクリックすると、各テストの詳細を確認できます。
image.png

これは、プロンプト1の出力には「にゃ」が含まれておらず、出力の最後の単語は「ですよ!」であり、「にゃ」で終わってないのでテスト失敗になってます。

ちなみに、promptfooはLLMへのAPI呼び出し結果をキャッシュおり、キャッシュを消去する場合は、npx promptfoo@latest cache clear で消去できます。

他、コマンドの詳細はこちらに記載されてます。

GitHub Actions

promptfooのGithub Actionがあるようです。これでプロンプトの自動テストができそうです。

.github/workflows/promptfoo.ymlを作成します。

.github/workflows/promptfoo.yml
name: 'Prompt Evaluation'
on:
  pull_request:
    branches:
      - 'prompts' #ここではpromptsブランチに対して

jobs:
  evaluate:
    runs-on: ubuntu-latest
    permissions:
      contents: read
      pull-requests: write
    steps:
      - uses: actions/checkout@v4

      - name: Set up promptfoo cache
        uses: actions/cache@v3
        with:
          path: ~/.cache/promptfoo
          key: ${{ runner.os }}-promptfoo-v1
          restore-keys: |
            ${{ runner.os }}-promptfoo-

      - name: Run promptfoo evaluation
        uses: promptfoo/promptfoo-action@v1
        with:
          azure-api-key: ${{ secrets.AZURE_API_KEY }}
          github-token: ${{ secrets.GITHUB_TOKEN }}
          prompts: 'promptfoo/prompt/*.json' #プロンプトのファイル指定
          config: 'promptfoo/promptfooconfig.yaml' # 評価設定ファイル指定
          cache-path: ~/.cache/promptfoo

Githubレポジトリの設定からシークレット「AZURE_API_KEY」を追加しておきます。

image.png

該当のブランチへのPRでアクションが走ります。
ローカルの実行と同じように確認用のURLが払い出されるのでweb画面で確認することができます。
image.png

プルリクエストで差分が発生したプロンプトにだけテストが実行されるようです。

最後プロンプトを調整し、全てのテストをクリアしました (一応...)
image.png

さいごに

まだまだpromptfooには色々な評価方法があります。
PyrhonやJavaScriptで独自の評価関数なども作れるようです。場面によって色々使っていってみようかと思います。

1
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
0