jpskill.com
🛠️ 開発・MCP コミュニティ

ai-observability-promptfoo

LLMのプロンプトやアプリケーションを、設定ファイルや評価基準を用いてテスト・評価し、モデルによる評価や脆弱性検証、CI/CD連携、比較評価などを実施することで、品質向上を図るSkill。

📜 元の英語説明(参考)

Testing and evaluation framework for LLM prompts and applications -- promptfooconfig.yaml, assertions, model-graded evals, red teaming, CI/CD integration, custom providers, and comparative evaluation

🇯🇵 日本人クリエイター向け解説

一言でいうと

LLMのプロンプトやアプリケーションを、設定ファイルや評価基準を用いてテスト・評価し、モデルによる評価や脆弱性検証、CI/CD連携、比較評価などを実施することで、品質向上を図るSkill。

※ jpskill.com 編集部が日本のビジネス現場向けに補足した解説です。Skill本体の挙動とは独立した参考情報です。

⚡ おすすめ: コマンド1行でインストール(60秒)

下記のコマンドをコピーしてターミナル(Mac/Linux)または PowerShell(Windows)に貼り付けてください。 ダウンロード → 解凍 → 配置まで全自動。

🍎 Mac / 🐧 Linux
mkdir -p ~/.claude/skills && cd ~/.claude/skills && curl -L -o ai-observability-promptfoo.zip https://jpskill.com/download/10211.zip && unzip -o ai-observability-promptfoo.zip && rm ai-observability-promptfoo.zip
🪟 Windows (PowerShell)
$d = "$env:USERPROFILE\.claude\skills"; ni -Force -ItemType Directory $d | Out-Null; iwr https://jpskill.com/download/10211.zip -OutFile "$d\ai-observability-promptfoo.zip"; Expand-Archive "$d\ai-observability-promptfoo.zip" -DestinationPath $d -Force; ri "$d\ai-observability-promptfoo.zip"

完了後、Claude Code を再起動 → 普通に「動画プロンプト作って」のように話しかけるだけで自動発動します。

💾 手動でダウンロードしたい(コマンドが難しい人向け)
  1. 1. 下の青いボタンを押して ai-observability-promptfoo.zip をダウンロード
  2. 2. ZIPファイルをダブルクリックで解凍 → ai-observability-promptfoo フォルダができる
  3. 3. そのフォルダを C:\Users\あなたの名前\.claude\skills\(Win)または ~/.claude/skills/(Mac)へ移動
  4. 4. Claude Code を再起動

⚠️ ダウンロード・利用は自己責任でお願いします。当サイトは内容・動作・安全性について責任を負いません。

🎯 このSkillでできること

下記の説明文を読むと、このSkillがあなたに何をしてくれるかが分かります。Claudeにこの分野の依頼をすると、自動で発動します。

📦 インストール方法 (3ステップ)

  1. 1. 上の「ダウンロード」ボタンを押して .skill ファイルを取得
  2. 2. ファイル名の拡張子を .skill から .zip に変えて展開(macは自動展開可)
  3. 3. 展開してできたフォルダを、ホームフォルダの .claude/skills/ に置く
    • · macOS / Linux: ~/.claude/skills/
    • · Windows: %USERPROFILE%\.claude\skills\

Claude Code を再起動すれば完了。「このSkillを使って…」と話しかけなくても、関連する依頼で自動的に呼び出されます。

詳しい使い方ガイドを見る →
最終更新
2026-05-18
取得日時
2026-05-18
同梱ファイル
1

📖 Skill本文(日本語訳)

※ 原文(英語/中国語)を Gemini で日本語化したものです。Claude 自身は原文を読みます。誤訳がある場合は原文をご確認ください。

Promptfoo のパターン

クイックガイド: LLM の体系的な評価には promptfoo を使用します。プロンプト、プロバイダー、テストケースを promptfooconfig.yaml で定義します。アサーションの種類 (contains, is-json, llm-rubric, similar, cost, latency) を使用して出力を検証します。promptfoo eval を使用して実行します (テスト失敗時にコード 100 で終了)、promptfoo view で結果 UI を表示します。主観的な品質には、モデル評価アサーション (llm-rubric, factuality) を使用します。セキュリティスキャンには promptfoo redteam run を使用します。結果を共有するには、--share フラグまたは promptfoo share を使用します。すべてのプロバイダー API キーは環境変数から取得します。ハードコードしないでください。


<critical_requirements>

重要: この Skill を使用する前に

すべてのコードは CLAUDE.md のプロジェクト規約に従う必要があります (kebab-case, 名前付きエクスポート, インポート順, import type, 名前付き定数)

(明示的な assert 配列を持つテストケースを定義する必要があります -- アサーションのないテストは、検証せずにキャプチャするだけです)

(主観的な品質評価には llm-rubric を使用する必要があります -- 自然言語出力に対して決定論的なアサーションだけに頼らないでください)

(類似性およびモデル評価アサーションに threshold を設定する必要があります -- しきい値を省略すると、品質基準に一致しないデフォルト値が使用されます)

(すべての API キーに環境変数を使用する必要があります -- promptfooconfig.yaml またはプロバイダー構成にキーをハードコードしないでください)

(CI パイプラインで promptfoo eval の終了コードを検証する必要があります -- テスト失敗時に終了コード 100、その他のエラー時に終了コード 1 を返します)

</critical_requirements>


自動検出: promptfoo, promptfooconfig, promptfooconfig.yaml, promptfoo eval, promptfoo view, promptfoo redteam, llm-rubric, model-graded-closedqa, promptfoo share, promptfoo cache, assertion type, LLM evaluation, prompt testing, red teaming, PROMPTFOO_CONFIG

使用する場合:

  • 1 つ以上のプロバイダーにわたる LLM プロンプトの作成または評価
  • LLM を利用した機能の自動テストスイートのセットアップ
  • モデル出力の並列比較 (GPT vs Claude vs Gemini)
  • モデル評価による評価の実行 (LLM を審査員として)
  • セキュリティ脆弱性に対する LLM アプリケーションのレッドチーム
  • LLM 品質ゲートを CI/CD パイプラインに統合
  • LLM からの構造化された出力 (JSON, 関数呼び出し) の検証

カバーされる主なパターン:

  • promptfooconfig.yaml の構造 (プロンプト, プロバイダー, テスト, defaultTest)
  • アサーションの種類 (決定論的, モデル評価, パフォーマンス)
  • カスタム TypeScript プロバイダー
  • レッドチーム構成 (プラグイン, 戦略)
  • GitHub Actions との CI/CD 統合
  • プログラムによる API (evaluate() 関数)
  • 結果の共有とキャッシュ

使用しない場合:

  • アプリケーションコードのユニットテスト (テストランナーを使用)
  • API スループットの負荷テスト/ベンチマーク (負荷テストツールを使用)
  • 本番 LLM 呼び出しのランタイム監視 (可観測性ツールを使用)

例のインデックス


<philosophy>

哲学

Promptfoo は LLM アプリケーションにテスト駆動開発 をもたらします。手動で出力を確認する代わりに、期待される動作をアサーションとして定義し、プロンプトとプロバイダーにわたって体系的に実行します。

コア原則:

  1. 宣言的なテスト定義 -- 命令的なテストスクリプトよりも YAML 設定。プロンプト、プロバイダー、テストケース、およびアサーションを promptfooconfig.yaml で定義します。標準的な評価にはコードは不要です。
  2. アサーション駆動の検証 -- すべてのテストケースにはアサーションが必要です。構造化された出力には決定論的なアサーション (contains, is-json, equals)、主観的な品質にはモデル評価アサーション (llm-rubric, factuality) を使用します。
  3. 比較評価 -- 複数のプロバイダーまたはプロンプトバリアントにわたって同じテストを同時に実行します。結果マトリックスは、どの組み合わせが最適に機能するかを示します。
  4. LLM テストのシフトレフト -- プロンプトのリグレッションを CI でキャッチしてから、本番環境に到達させます。promptfoo eval はテスト失敗時にコード 100 で終了するため、自然な CI 品質ゲートになります。
  5. 第一級の関心事としてのレッドチーム -- プロンプトインジェクション、PII リーク、有害コンテンツ、およびジェイルブレイクの脆弱性に対するセキュリティスキャンは、組み込まれており、後付けではありません。

</philosophy>


<patterns>

コアパターン

パターン 1: 基本的な構成

すべての promptfoo プロジェクトは promptfooconfig.yaml から始まります。3 つの必須セクション: prompts, providers, tests

# promptfooconfig.yaml
description: "翻訳品質の評価"

prompts:
  - "次の内容を {{language}} に変換してください: {{input}}"

providers:
  - openai:gpt-4o
  - anthropic:messages:claude-sonnet-4-6

tests:
  - vars:
      language: French
      input: Hello world
    assert:
      - type: icontains
        value: "bonjour"
      - type: llm-rubric
        value: "出力は単語ごとの翻訳ではなく、自然なフランス語の翻訳です"

良い理由: 宣言的な構成、マルチプロバイダー比較、決定論的アサーションとモデル評価アサーションの両方

# 悪い例: アサーションのないテスト
tests:
  - vars:
      language: French
      input: Hello world
  # assert 配列がありません -- 出力はキャプチャされますが、検証されません

悪い理由: アサーションのないテストは出力をログに記録するだけで、決して失敗しません -- 自動評価のポイント全体を失います

参照: ファイルからのプロンプト、プロバイダー構成、defaultTest、CSV からの変数ロードについては、examples/core.md を参照してください。


パターン 2: 決定論的なアサーション

予測可能で検証可能な構造を持つ出力に使用します。

(原文はここで切り詰められています)

📜 原文 SKILL.md(Claudeが読む英語/中国語)を展開

Promptfoo Patterns

Quick Guide: Use promptfoo for systematic LLM evaluation. Define prompts, providers, and test cases in promptfooconfig.yaml. Use assertion types (contains, is-json, llm-rubric, similar, cost, latency) to validate outputs. Use promptfoo eval to run (exits with code 100 on test failures), promptfoo view for results UI. Use model-graded assertions (llm-rubric, factuality) for subjective quality. Use promptfoo redteam run for security scanning. Use --share flag or promptfoo share to share results. All provider API keys come from environment variables -- never hardcode them.


<critical_requirements>

CRITICAL: Before Using This Skill

All code must follow project conventions in CLAUDE.md (kebab-case, named exports, import ordering, import type, named constants)

(You MUST define test cases with explicit assert arrays -- tests without assertions only capture output without validating it)

(You MUST use llm-rubric for subjective quality evaluation -- do NOT rely solely on deterministic assertions for natural language output)

(You MUST set threshold on similarity and model-graded assertions -- omitting thresholds uses defaults that may not match your quality bar)

(You MUST use environment variables for all API keys -- never hardcode keys in promptfooconfig.yaml or provider configs)

(You MUST verify promptfoo eval exit code in CI pipelines -- it returns exit code 100 on test failures, exit code 1 on other errors)

</critical_requirements>


Auto-detection: promptfoo, promptfooconfig, promptfooconfig.yaml, promptfoo eval, promptfoo view, promptfoo redteam, llm-rubric, model-graded-closedqa, promptfoo share, promptfoo cache, assertion type, LLM evaluation, prompt testing, red teaming, PROMPTFOO_CONFIG

When to use:

  • Writing or evaluating LLM prompts across one or more providers
  • Setting up automated test suites for LLM-powered features
  • Comparing model outputs side-by-side (GPT vs Claude vs Gemini)
  • Running model-graded evaluations (LLM-as-a-judge)
  • Red teaming LLM applications for security vulnerabilities
  • Integrating LLM quality gates into CI/CD pipelines
  • Validating structured output (JSON, function calls) from LLMs

Key patterns covered:

  • promptfooconfig.yaml structure (prompts, providers, tests, defaultTest)
  • Assertion types (deterministic, model-graded, performance)
  • Custom TypeScript providers
  • Red teaming configuration (plugins, strategies)
  • CI/CD integration with GitHub Actions
  • Programmatic API (evaluate() function)
  • Result sharing and caching

When NOT to use:

  • Unit testing application code (use your test runner)
  • Load testing / benchmarking API throughput (use a load testing tool)
  • Runtime monitoring of production LLM calls (use observability tooling)

Examples Index


<philosophy>

Philosophy

Promptfoo brings test-driven development to LLM applications. Instead of manually checking outputs, you define expected behaviors as assertions and run them systematically across prompts and providers.

Core principles:

  1. Declarative test definitions -- YAML config over imperative test scripts. Define prompts, providers, test cases, and assertions in promptfooconfig.yaml. No code required for standard evaluations.
  2. Assertion-driven validation -- Every test case should have assertions. Deterministic assertions (contains, is-json, equals) for structured output; model-graded assertions (llm-rubric, factuality) for subjective quality.
  3. Comparative evaluation -- Run the same tests across multiple providers or prompt variants simultaneously. The results matrix shows which combination performs best.
  4. Shift-left LLM testing -- Catch prompt regressions in CI before they reach production. promptfoo eval exits with code 100 on test failures, making it a natural CI quality gate.
  5. Red teaming as a first-class concern -- Security scanning for prompt injection, PII leakage, harmful content, and jailbreak vulnerabilities is built in, not bolted on.

</philosophy>


<patterns>

Core Patterns

Pattern 1: Basic Configuration

Every promptfoo project starts with promptfooconfig.yaml. Three required sections: prompts, providers, tests.

# promptfooconfig.yaml
description: "Translation quality evaluation"

prompts:
  - "Convert the following to {{language}}: {{input}}"

providers:
  - openai:gpt-4o
  - anthropic:messages:claude-sonnet-4-6

tests:
  - vars:
      language: French
      input: Hello world
    assert:
      - type: icontains
        value: "bonjour"
      - type: llm-rubric
        value: "Output is a natural French translation, not word-for-word"

Why good: Declarative config, multi-provider comparison, both deterministic and model-graded assertions

# BAD: Tests without assertions
tests:
  - vars:
      language: French
      input: Hello world
  # No assert array -- output is captured but never validated

Why bad: Tests without assertions only log output, they never fail -- you lose the entire point of automated evaluation

See: examples/core.md for prompts from files, provider config, defaultTest, variable loading from CSV


Pattern 2: Deterministic Assertions

Use for outputs with predictable, verifiable structure.

assert:
  # String matching
  - type: contains
    value: "error"
  - type: icontains # case-insensitive
    value: "success"
  - type: not-contains
    value: "internal server error"
  - type: starts-with
    value: "{"
  - type: regex
    value: "\\d{4}-\\d{2}-\\d{2}" # date pattern

  # Structured output
  - type: is-json
  - type: contains-json
  - type: is-valid-openai-tools-call

  # Performance
  - type: cost
    threshold: 0.01 # max $0.01 per call
  - type: latency
    threshold: 5000 # max 5 seconds

Why good: Fast, deterministic, no LLM cost for evaluation, catches structural regressions immediately

# BAD: Using llm-rubric for JSON validation
assert:
  - type: llm-rubric
    value: "Output must be valid JSON"

Why bad: Expensive (requires LLM call), slower, non-deterministic -- is-json does this deterministically for free

See: examples/core.md for all deterministic assertion types with examples


Pattern 3: Model-Graded Assertions

Use for subjective quality where deterministic checks cannot capture intent.

assert:
  - type: llm-rubric
    value: "Response is helpful, accurate, and conversational in tone"
    provider: openai:gpt-4o

  - type: factuality
    value: "The capital of France is Paris. It has a population of ~2.1 million."
    provider: openai:gpt-4o

  - type: similar
    value: "The weather in Paris is sunny today"
    threshold: 0.8

  - type: model-graded-closedqa
    value: "Paris is the capital of France"
    provider: openai:gpt-4o

Why good: Evaluates subjective quality that deterministic assertions cannot capture, configurable grading provider

# BAD: No threshold on similar assertion
assert:
  - type: similar
    value: "expected output"
    # Missing threshold -- uses default which may be too lenient or strict

Why bad: Default similarity threshold may not match your quality bar, always set it explicitly

See: examples/model-graded.md for llm-rubric with custom providers, context evaluation, factuality, custom grading prompts


Pattern 4: Red Teaming

Use redteam section to scan for security vulnerabilities.

# promptfooconfig.yaml
targets:
  - openai:gpt-4o

redteam:
  purpose: "Customer support chatbot for an e-commerce platform"
  numTests: 10
  plugins:
    - harmful
    - pii
    - contracts
    - hallucination
    - prompt-extraction
  strategies:
    - jailbreak
    - prompt-injection

Why good: Declarative security scanning, purpose provides context for realistic attacks, composable plugins and strategies

# BAD: Red team without purpose
redteam:
  plugins:
    - harmful
  # Missing purpose -- attacks will be generic and less effective

Why bad: Without purpose, the red team generator creates generic attacks that miss application-specific vulnerabilities

See: examples/red-teaming.md for presets (OWASP, NIST), advanced strategies, multi-turn attacks


Pattern 5: Custom TypeScript Provider

Use when your LLM integration is not a direct API call (RAG pipelines, agent chains, custom middleware).

// providers/my-app.ts
import type {
  ApiProvider,
  ProviderOptions,
  ProviderResponse,
  CallApiContextParams,
} from "promptfoo";

// NOTE: default export required by promptfoo's file:// provider loader
export default class MyAppProvider implements ApiProvider {
  private config: Record<string, unknown>;

  constructor(options: ProviderOptions) {
    this.config = options.config || {};
  }

  id(): string {
    return "my-app-provider";
  }

  async callApi(
    prompt: string,
    context?: CallApiContextParams,
  ): Promise<ProviderResponse> {
    // Call your application's LLM pipeline
    const result = await myApp.processQuery(prompt);

    return {
      output: result.answer,
      tokenUsage: {
        total: result.totalTokens,
        prompt: result.promptTokens,
        completion: result.completionTokens,
      },
      cost: result.cost,
    };
  }
}
# promptfooconfig.yaml
providers:
  - file://providers/my-app.ts

Why good: Type-safe, full control over LLM pipeline, reports token usage and cost for assertions

See: examples/custom-providers.md for inline function providers, programmatic API, CI/CD integration


Pattern 6: CI/CD Integration

Run evaluations in CI with quality gates.

# .github/workflows/llm-eval.yml
name: LLM Eval
on:
  pull_request:
    paths:
      - "prompts/**"
      - "promptfooconfig.yaml"
jobs:
  evaluate:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - uses: actions/setup-node@v4
        with:
          node-version: "22"
      - uses: actions/cache@v4
        with:
          path: ~/.cache/promptfoo
          key: ${{ runner.os }}-promptfoo-v1
      - name: Run eval
        env:
          OPENAI_API_KEY: ${{ secrets.OPENAI_API_KEY }}
        run: npx promptfoo@latest eval -o results.json --share

Why good: Caches LLM responses across runs, promptfoo eval exits with code 100 on test failures (CI fails automatically), --share generates a shareable results URL

See: examples/custom-providers.md for npm scripts, quality gate thresholds, programmatic evaluation

</patterns>


<decision_framework>

Decision Framework

Which Assertion Type to Use

What are you validating?
+-- Exact or structural match?
|   +-- Exact text -> equals
|   +-- Contains substring -> contains / icontains
|   +-- Regex pattern -> regex
|   +-- Valid JSON -> is-json
|   +-- Valid function call -> is-valid-openai-tools-call
|   +-- Cost under budget -> cost (with threshold)
|   +-- Response time -> latency (with threshold)
+-- Subjective quality?
|   +-- General quality criteria -> llm-rubric
|   +-- Factual accuracy against ground truth -> factuality
|   +-- Semantic similarity -> similar (with threshold)
|   +-- Closed-domain QA accuracy -> model-graded-closedqa
|   +-- RAG context fidelity -> context-faithfulness
+-- Custom logic?
    +-- JavaScript function -> javascript
    +-- Python function -> python
    +-- External service -> webhook

When to Use Red Teaming vs Eval

What are you testing?
+-- Prompt quality and correctness?
|   +-- Use promptfoo eval with test cases and assertions
+-- Security vulnerabilities?
|   +-- Use promptfoo redteam run with plugins and strategies
+-- Both?
    +-- Run eval for quality, redteam for security -- separate configs or sections

Provider Selection

How does your LLM integration work?
+-- Direct API call to OpenAI/Anthropic/etc?
|   +-- Use built-in provider: openai:gpt-4o, anthropic:messages:claude-sonnet-4-6
+-- Custom pipeline (RAG, agents, middleware)?
|   +-- Use custom TypeScript provider: file://providers/my-app.ts
+-- HTTP endpoint?
|   +-- Use HTTP provider: id: https://api.example.com/chat
+-- Multiple providers to compare?
    +-- List all in providers array -- promptfoo runs tests against each

</decision_framework>


<red_flags>

RED FLAGS

High Priority Issues:

  • Tests without assert arrays (output is captured but never validated -- tests always "pass")
  • Not checking promptfoo eval exit code in CI (promptfoo eval exits 100 on test failures -- ensure your CI pipeline treats non-zero exit codes as failures)
  • Hardcoded API keys in promptfooconfig.yaml (use environment variables)
  • Using llm-rubric for checks that is-json or contains can do deterministically (wastes money and adds non-determinism)
  • Red teaming without purpose (generic attacks miss application-specific vulnerabilities)

Medium Priority Issues:

  • Missing threshold on similar assertions (default may not match your quality bar)
  • Not caching in CI (every run makes full API calls -- expensive and slow)
  • Using model-graded-closedqa when llm-rubric would be simpler (closedqa is for specific ground-truth QA)
  • Not setting provider on model-graded assertions (uses default which may not be the grader you want)
  • Running red team with default numTests: 5 in production scans (too few for comprehensive coverage)

Common Mistakes:

  • Confusing prompts (the LLM prompt templates) with tests (the evaluation cases) -- prompts define what to send, tests define what to check
  • Using equals for natural language output (LLM output is non-deterministic, use llm-rubric or similar)
  • Forgetting {{variable}} syntax in prompts (promptfoo uses Nunjucks templating, not ${variable})
  • Putting assertions in defaultTest that should only apply to specific tests (assertions in defaultTest apply to ALL tests)
  • Using file:// paths without the prefix (promptfoo treats bare paths as literal strings, not file references)

Gotchas & Edge Cases:

  • promptfoo eval caches LLM responses by default -- use promptfoo cache clear or --no-cache to force fresh calls
  • --share uploads results to promptfoo's servers -- do not use with sensitive data unless self-hosting
  • Red team strategies wrap plugins output -- a plugin generates the malicious content, a strategy delivers it (e.g., via jailbreak encoding)
  • defaultTest.assert merges with per-test assertions, it does not replace them -- both arrays run
  • CSV test files map column headers to variable names -- header input becomes {{input}} in prompts
  • transform in test options runs JavaScript on the output before assertions -- useful for extracting JSON from markdown-wrapped responses
  • Provider configs in YAML use config: key for model parameters (temperature, max_tokens), not top-level fields
  • The weight property on assertions affects scoring in the results UI but does not change pass/fail behavior

</red_flags>


<critical_reminders>

CRITICAL REMINDERS

All code must follow project conventions in CLAUDE.md (kebab-case, named exports, import ordering, import type, named constants)

(You MUST define test cases with explicit assert arrays -- tests without assertions only capture output without validating it)

(You MUST use llm-rubric for subjective quality evaluation -- do NOT rely solely on deterministic assertions for natural language output)

(You MUST set threshold on similarity and model-graded assertions -- omitting thresholds uses defaults that may not match your quality bar)

(You MUST use environment variables for all API keys -- never hardcode keys in promptfooconfig.yaml or provider configs)

(You MUST verify promptfoo eval exit code in CI pipelines -- it returns exit code 100 on test failures, exit code 1 on other errors)

Failure to follow these rules will produce untested, insecure, or falsely-passing LLM evaluation pipelines.

</critical_reminders>