「勘」に頼るのはもう終わり:Promptfooでプロンプトテストを自動化する

AI tutorial - IT technology blog
AI tutorial - IT technology blog

「なんとなく」なプロンプトエンジニアリングの罠

ほとんどの開発者は、プレイグラウンドでプロンプトを微調整することからAIアプリの開発を始めます。文章を少し変え、「実行」を押し、出力が良さそうならリリースする。このワークフローが通用するのはせいぜい一日だけです。いずれ、特定のエッジケースを修正するために一言変えただけで、他の3つの機能が壊れてしまうことに気づくでしょう。これがプロンプトのデグレード(退行)であり、ユーザーの信頼を失う最も手っ取り早い方法です。

私にも経験があります。50個のモデルの回答が並んだスプレッドシートを4時間も眺め、なぜトーンが変わってしまったのかを特定しようとする作業。それは魂を削るような作業です。Promptfooはプロンプトをコードのように扱うことで、この問題を解決します。手動の監査を自動化されたユニットテストやベンチマークに置き換え、推測をデータに基づいた判断へと変えてくれます。

クイックスタート (5分)

Promptfooは、一連のテストケースに対してプロンプトを実行するために設計されたCLIツールです。結果を自動的に評価してくれるため、人間が確認する必要はありません。さっそく動かしてみましょう。

1. インストール

npx経由で実行するか、グローバルにインストールしてどこでも使えるようにします。

npm install -g promptfoo

2. プロジェクトの初期化

評価用の専用フォルダを作成し、設定ファイルを生成します。

mkdir prompt-tests && cd prompt-tests
promptfoo init

このコマンドを実行すると、promptfooconfig.yamlファイルが生成されます。このファイルはコントロールセンターの役割を果たし、テストするモデルや「成功」の定義を記述します。

3. 初めての評価を実行する

初期化コマンドには、すぐに試せるプレースホルダーのテストが含まれています。ターミナルセッションでAPIキーがエクスポートされていることを確認してください。

export OPENAI_API_KEY=your_api_key_here
promptfoo eval

実行が完了したら、ローカルWeb UIを立ち上げて結果を確認しましょう。

promptfoo view

ディープダイブ:実践的なテストスイートの構築

基本も重要ですが、本当の力は複雑なロジックをテストする際に発揮されます。1日に500件のリクエストを処理する企業の「サポートチケット分類器」を構築していると仮定しましょう。

ステップ 1: プロンプトの定義

複数のプロンプトバージョンを同時に比較できます。指示を記述するprompts.txtを作成します。

以下のサポートチケットを次のカテゴリのいずれかに分類してください:Technical、Billing、General。
チケット内容: {{ticket_body}}
カテゴリ:

ステップ 2: プロバイダーの設定

GPT-4o-mini(100万トークンあたり0.15ドル)で十分な精度が出るのか、それとも GPT-4o(100万トークンあたり5.00ドル)のパワーが必要なのかを確認したい場合もあるでしょう。promptfooconfig.yamlを更新します。

providers:
  - openai:gpt-4o-mini
  - openai:gpt-4o

prompts:
  - file://prompts.txt

ステップ 3: テストケースとアサーションの追加

アサーション(検証)こそが、Promptfooがスプレッドシートに勝るポイントです。テキストを目視する代わりに、成功のための厳格なルールを定義します。

tests:
  - vars:
      ticket_body: "パスワードをリセットしてもアカウントにログインできません。"
    assert:
      - type: icontains
        value: Technical
  - vars:
      ticket_body: "今月、サブスクリプション料金が2回請求されました。"
    assert:
      - type: icontains
        value: Billing
  - vars:
      ticket_body: "こんにちは、素晴らしいサービスをありがとうございます!"
    assert:
      - type: llm-rubric
        value: "出力は 'General' であり、攻撃的な表現を含まないこと。"

llm-rubricは、安価なモデルを採点するために、より賢いモデルを雇うようなものだと考えてください。LLMを呼び出して、トーン、感情、正確性などの定性的な基準を判断します。正規表現では対応できないチェックに最適です。

高度なワークフロー:本番環境への導入準備

ローカルテストの枠を超え、実際の開発サイクルにPromptfooを組み込みましょう。

1. CI/CD 連携

「ゴールデン・データセット」を壊すようなプロンプトの変更をマージしてはいけません。GitHub ActionsでPromptfooを実行すれば、精度スコアがしきい値を下回った場合にプルリクエスト(PR)を自動的にブロックできます。

# .github/workflows/prompt-test.yml
jobs:
  test:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - run: npx promptfoo eval
        env:
          OPENAI_API_KEY: ${{ secrets.OPENAI_API_KEY }}

2. レッドチーミングとセキュリティ

Promptfooにはセキュリティ監査機能が組み込まれています。何百もの敵対的な入力を生成し、プロンプトを騙してシステム指示を漏洩させたり、有害なコンテンツを生成させたりしようと試みます。promptfoo redteam initを実行して、脆弱性のスキャンを開始しましょう。

3. モデル比較

プロバイダーのロックインはリスクです。Promptfooを使えば、OpenAIとAnthropicのClaude 3.5 Sonnet、あるいはOllama経由のLlama 3などのローカルモデルを簡単に比較できます。コスト、速度、インテリジェンスの最適なバランス(スイートスポット)を見つけることができます。

現場で役立つ実践的なヒント

  • プロンプトのバージョン管理: プロンプトの .txt ファイルを、ロジックのすぐ隣の Git で管理しましょう。これにより、コードとプロンプトの同期が保たれます。
  • 「ゴールデン・データセット」の構築: 20個程度の実際の入力例と理想的な出力例から始めましょう。これが将来のすべての改善の基準(ベースライン)になります。
  • キャッシュの活用: LLMの呼び出しは高価です。Promptfooはデフォルトで結果をキャッシュします。プロンプトやテストケースを変更しない限り、再実行されないため、費用と時間の両方を節約できます。
  • LLMによる採点を最小限にする: llm-rubricは強力ですが、コストがかかります。可能な限り、is-jsonjavascriptアサーションのような決定論的なチェックを使用してください。
  • レイテンシ(遅延)の監視: latencyに関するアサーションを追加しましょう。精度が100%でも、応答に15秒かかるプロンプトは、リアルタイムなUIでは役に立たないことが多いです。

体系的なテスト自動化の有無が、「おもちゃ」のようなAIプロジェクトと本番グレードのアプリケーションを分ける境界線です。Promptfooのようなツールを使い、手動の監査から脱却することで、ユーザー体験を損なう恐怖を感じることなく改善を繰り返す自由が得られます。ぜひ試してみてください。デバッグ時間を大幅に短縮できたことに、将来の自分も感謝するはずです。

Share: