TL;DR
Promptfoo is an open-source LLM evaluation and red-teaming framework for systematically testing AI applications. It supports 90+ model providers, includes 67+ security attack plugins, and runs locally by default for privacy. Install it with npm install -g promptfoo, then create a starter suite with promptfoo init --example getting-started.
Introduction
An AI-powered customer support chatbot can appear reliable during development, then fail in production when users discover prompt-injection paths, bypass safety controls, or trigger inconsistent answers.
Manual testing does not provide enough coverage for LLM applications. You need repeatable tests that detect regressions, compare models, validate structured outputs, and probe for security weaknesses before deployment.
Promptfoo provides that workflow. It lets you:
- Evaluate prompts across multiple models
- Define automated assertions for quality, latency, and cost
- Run red-team scans for common LLM vulnerabilities
- Track regressions in CI/CD
- Compare model quality using the same test suite
This guide uses promptfoo version 0.121.2 and focuses on setting up practical evaluations, security scans, and CI checks.
If you also validate the APIs behind your LLM application, Apidog can complement promptfoo: use promptfoo for LLM evaluation and Apidog for API design, testing, and documentation.
What Is Promptfoo?
Promptfoo is a command-line tool and Node.js library for evaluating and red-teaming LLM applications.
Traditional tests often depend on deterministic outputs. LLMs are probabilistic: the same input may produce slightly different responses across runs. Promptfoo addresses this with evaluation methods that do not require exact string matches:
- Semantic assertions that validate meaning
- LLM-graded assertions for subjective quality checks
- Multi-model comparisons across providers
- Security plugins that generate adversarial inputs
- Latency and cost assertions for operational constraints
Promptfoo runs locally by default. Prompts and test data remain in your environment unless you explicitly use cloud features.
Problems Promptfoo Solves
Manual LLM testing creates recurring issues:
- No regression detection: Model, prompt, or dependency changes can silently degrade behavior.
- Coverage gaps: A few manually written prompts rarely cover edge cases or adversarial inputs.
- No measurable baseline: Teams cannot objectively compare models, prompts, latency, or cost.
Promptfoo replaces ad hoc checks with repeatable evaluation suites. Define your test cases once, version them with your code, and run them locally or in CI.
Common Use Cases
Teams use promptfoo for:
- Customer support chatbots that need consistent answers
- Content-generation workflows that need brand and style checks
- Healthcare and fintech workflows with compliance constraints
- Security-sensitive applications that must resist prompt injection and data leakage
- Model-selection experiments across hosted and local models
Promptfoo has 1.6 million npm downloads and is used in production by companies serving more than 10 million end users. In March 2026, Promptfoo joined OpenAI while remaining open source and MIT licensed.
Getting Started: Run Your First Eval
You can install promptfoo globally or run it with npx.
1. Install Promptfoo
# Global install
npm install -g promptfoo
# Or run without a global install
npx promptfoo@latest
# macOS
brew install promptfoo
# Python
pip install promptfoo
Set provider API keys as environment variables:
export OPENAI_API_KEY=sk-abc123
export ANTHROPIC_API_KEY=sk-ant-xxx
2. Create an Example Project
Initialize the starter evaluation:
promptfoo init --example getting-started
cd getting-started
This creates a promptfooconfig.yaml file with example prompts, providers, and test cases.
3. Run the Evaluation
promptfoo eval
Open the results UI:
promptfoo view
The UI runs at http://localhost:3000 and shows outputs from each provider alongside assertion results.
Create a Practical Eval Suite
A promptfoo suite is defined in promptfooconfig.yaml.
description: "My First Eval Suite"
prompts:
- prompts/greeting.txt
- prompts/farewell.txt
providers:
- openai:gpt-4o
- anthropic:claude-sonnet-4-5
tests:
- vars:
input: "Hello"
assert:
- type: contains
value: "Hi"
- type: latency
threshold: 3000
The main sections are:
-
prompts: Prompt files or inline prompts to evaluate -
providers: Models to run against -
tests: Variables and assertions for each scenario
Keep this configuration in version control. Add test cases whenever you fix a production issue so it does not regress later.
Core Features
1. Automated Evaluations
Automated evaluations run your prompts against selected models and validate the output using assertions.
Useful Assertion Types
| Assertion | Purpose |
|---|---|
contains |
Output includes a substring |
equals |
Output matches an exact string |
regex |
Output matches a regular expression |
json-schema |
Output has a valid JSON structure |
javascript |
Custom JavaScript pass/fail check |
python |
Custom Python assertion |
llm-rubric |
LLM grades the output against a rubric |
similar |
Semantic similarity score |
latency |
Response stays under a time threshold |
cost |
Request stays under a cost threshold |
For deterministic requirements, use checks such as contains, regex, or json-schema. For subjective requirements such as tone or helpfulness, use an LLM rubric.
Example: Test Quality, Length, Latency, and Cost
tests:
- vars:
question: "What is the capital of France?"
assert:
- type: contains
value: "Paris"
- type: javascript
value: output.length < 100
- type: latency
threshold: 2000
- type: cost
threshold: 0.001
This test verifies that the answer:
- Mentions Paris
- Is shorter than 100 characters
- Responds in under two seconds
- Costs less than
$0.001
Use LLM-Graded Evaluations for Subjective Criteria
Use llm-rubric when exact matching is too restrictive:
assert:
- type: llm-rubric
value: "Response should be helpful, harmless, and honest"
The grader model evaluates the output against the rubric. Use a lower-cost model for grading when appropriate to reduce evaluation cost.
2. Red Teaming and Security Testing
Promptfoo includes a red-team module that generates adversarial inputs and evaluates how your application responds.
Attack Categories
| Category | What It Tests |
|---|---|
| Prompt Injection | Direct, indirect, and context-injection attacks |
| Jailbreaks | DAN, persona switching, and role-play bypasses |
| Data Exfiltration | SSRF, system prompt extraction, and prompt leakage |
| Harmful Content | Hate speech, dangerous activities, and self-harm requests |
| Compliance | PII leakage, HIPAA violations, and financial data exposure |
| Audio/Visual | Audio injection and image-based attacks |
Run a Red-Team Scan
Create a red-team configuration:
promptfoo redteam init
Run the scan:
promptfoo redteam run
Generate a report:
promptfoo redteam report [directory]
The redteam run workflow:
- Generates attack probes tailored to your application.
- Sends probes to your target.
- Scores the resulting vulnerabilities.
Review Critical and High findings before deployment. After implementing mitigations, rerun the scan and keep the exploit cases as regression tests.
Example output:
Vulnerability Summary:
- Critical: 2 (PII leakage, prompt extraction)
- High: 5 (jailbreaks, injection attacks)
- Medium: 12 (bias, inconsistent responses)
- Low: 23 (minor policy violations)
3. Scan Pull Requests
Promptfoo can scan pull requests for LLM-related security issues.
# .github/workflows/promptfoo-scan.yml
name: Promptfoo Code Scan
on: [pull_request]
jobs:
scan:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: promptfoo/promptfoo/code-scan-action@main
with:
github-token: ${{ secrets.GITHUB_TOKEN }}
This can identify issues such as:
- Hardcoded API keys in configuration
- Insecure prompt patterns
- Missing input validation
- Potential prompt-injection vectors
4. Compare Models with the Same Test Cases
Define multiple providers, then run one evaluation suite:
providers:
- openai:gpt-4o
- anthropic:claude-sonnet-4-5
Run and inspect results:
promptfoo eval
promptfoo view
The UI lets you compare:
- Pass/fail rate by provider
- Cost per request
- Average latency
- Qualitative differences in model responses
Use this data to choose models based on your actual workload instead of general benchmarks.
Supported Providers
Promptfoo supports more than 90 LLM providers, including hosted APIs and local models.
| Provider | Examples |
|---|---|
| OpenAI | GPT-4, GPT-4o, GPT-4o-mini, o1, o3 |
| Anthropic | Claude 3.5/3.7/4.5/4.6 and thinking models |
| Gemini 1.5/2.0 and Vertex AI | |
| Microsoft | Azure OpenAI and Phi |
| Amazon | Bedrock, including Claude, Llama, and Titan |
| Meta | Llama 3, 3.1, and 3.2 through supported providers |
| Ollama | Local Llama, Mistral, Phi, and other models |
Create a Custom Provider
If your model is not directly supported, create a provider in Python or JavaScript.
Python Provider
# custom_provider.py
from typing import Any
class CustomProvider:
async def call_api(self, prompt: str, options: dict, context: dict) -> dict:
response = await my_async_api.generate(prompt)
return {
"output": response.text,
"tokenUsage": {
"total": response.usage.total_tokens,
"prompt": response.usage.prompt_tokens,
"completion": response.usage.completion_tokens
}
}
JavaScript Provider
// customProvider.js
export default class CustomProvider {
async callApi(prompt) {
return {
output: await myApi.generate(prompt),
tokenUsage: {
total: 50,
prompt: 20,
completion: 30,
},
};
}
}
Register a custom provider in your configuration:
providers:
- id: file://custom_provider.py
config:
api_key: ${MY_API_KEY}
Essential CLI Commands
# Run evaluations
promptfoo eval -c promptfooconfig.yaml
# Open the local results UI
promptfoo view
# Share results online
promptfoo share
# Initialize and run red-team testing
promptfoo redteam init
promptfoo redteam run
# Create or validate configuration
promptfoo init
promptfoo validate [config]
# Manage saved results
promptfoo list
promptfoo show <id>
promptfoo delete <id>
promptfoo export <id>
# Manage cache and retry runs
promptfoo cache clear
promptfoo retry <id>
Useful Flags
--no-cache Disable caching and force fresh results
--max-concurrency <n> Limit parallel API calls
--output <file> Write results to a JSON file
--verbose Enable debug logging
--env-file <path> Load environment variables from a file
--filter <pattern> Run matching test cases only
Example:
promptfoo eval \
-c promptfooconfig.yaml \
--no-cache \
--max-concurrency 3 \
--output results.json \
--env-file .env
This runs fresh evaluations, limits concurrency to three requests, writes JSON results, and loads credentials from .env.
Add Promptfoo to CI/CD
Run evaluations on every push and pull request to block regressions before deployment.
name: LLM Tests
on: [push, pull_request]
jobs:
eval:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: actions/setup-node@v4
with:
node-version: "22"
- run: npm install -g promptfoo
- run: promptfoo eval -c promptfooconfig.yaml
env:
OPENAI_API_KEY: ${{ secrets.OPENAI_API_KEY }}
ANTHROPIC_API_KEY: ${{ secrets.ANTHROPIC_API_KEY }}
Add a Quality Gate
Set a minimum pass rate in promptfooconfig.yaml:
commandLineOptions:
threshold: 0.8
This fails the CI job if fewer than 80% of assertions pass.
Cache Results in GitHub Actions
Cache repeated evaluation results to reduce API calls and speed up unchanged runs:
- uses: actions/cache@v4
with:
path: ~/.cache/promptfoo
key: ${{ runner.os }}-promptfoo-${{ hashFiles('promptfooconfig.yaml') }}
Review Results in the Web UI
Start the local UI:
promptfoo view
The UI includes:
- An evaluation matrix for side-by-side output comparison
- Filters for provider, test case, and pass/fail status
- Diff views between runs
- Shareable result links
- Live evaluation updates
The UI runs on localhost:3000 by default. It uses CSRF protections based on Sec-Fetch-Site and Origin headers.
Do not expose the local server to untrusted networks. For team access, use promptfoo share or self-host with authentication.
Cache and Database Locations
Cache
| Platform | Location |
|---|---|
| macOS/Linux | ~/.cache/promptfoo |
| Windows | %LOCALAPPDATA%\promptfoo |
The cache stores evaluation results. Use --no-cache during prompt development when you need fresh model responses.
Database
Promptfoo stores historical evaluation runs in SQLite:
~/.promptfoo/promptfoo.db
Keep this database if you need historical comparisons and trend analysis.
Security Model
Promptfoo uses a trust-by-configuration model.
Trusted Inputs
Treat these as code. Only load them from trusted repositories and sources:
promptfooconfig.yaml- Custom JavaScript, Python, or Ruby assertions
- Provider configurations
- Transform functions
Untrusted Inputs
These are treated as data and should not execute code:
- Prompt text
- Test variables
- Model outputs
- Remote content fetched during evaluations
Hardening Checklist
For higher-security environments:
- Run promptfoo in a container or VM with minimal privileges.
- Use dedicated, least-privileged API keys.
- Do not place secrets in prompts or config files.
- Restrict network egress for third-party code.
- Do not expose the local web server to untrusted networks.
Optimize Evaluation Performance
Use these techniques while iterating:
- Keep caching enabled for repeated runs.
- Set
--max-concurrencyaccording to provider rate limits. - Use
--filterto run only relevant test cases during development. - Test with smaller datasets before running a full suite.
- Use
--repeatwith subsets when tuning prompts.
For larger suites with thousands of cases:
- Use the scheduler in
src/scheduler/for distributed runs. - Use remote generation when you need to offload compute.
- Export results to Google Sheets for team visibility.
Create Custom Assertions
Use custom assertions for domain-specific checks.
// assertions/customCheck.js
export default function customCheck(output, context) {
const pass = output.includes("expected");
return {
pass,
score: pass ? 1 : 0,
reason: pass ? "Output matched" : "Missing expected content",
};
}
Reference it in your configuration:
assert:
- type: file://assertions/customCheck.js
Use the MCP Server
Promptfoo includes a Model Context Protocol (MCP) server for AI assistants such as Claude Code.
promptfoo mcp
This enables agents to:
- Run evaluations from chat
- Access red-team capabilities
- Query stored results
- Generate test cases
Example Implementation Patterns
Customer Support Chatbot
A support chatbot evaluation suite might include:
- 500 tests for common support questions
- GPT-4 and Claude comparisons
- Red-team probes for PII leakage and jailbreaks
- CI quality gates that block failed deployments
The goal is to turn production issues into repeatable test cases.
Content Generation Pipeline
For AI-generated marketing content:
- Use
llm-rubricchecks for tone and style. - Add latency thresholds for interactive workflows.
- Add cost assertions for budget control.
- Compare models to find the best quality-to-cost ratio.
Healthcare Application
For a health-focused application:
- Run red-team scans for HIPAA-related risks.
- Add custom assertions for domain-specific requirements.
- Keep evaluations local when handling sensitive data.
- Preserve historical results for audit evidence.
Conclusion
Promptfoo provides a repeatable testing workflow for LLM applications. Instead of relying on manual prompt checks, you can automate quality evaluation, security testing, model comparison, and regression detection.
Start with this workflow:
- Install promptfoo:
npm install -g promptfoo
- Create an example suite:
promptfoo init --example getting-started
Add assertions for correctness, latency, cost, and structured output.
Run red-team scans before deployment.
Add a CI threshold to block regressions.
Compare providers using the same test suite before selecting a production model.
If you also work with APIs, use Apidog alongside promptfoo: Apidog handles API design, testing, and documentation, while promptfoo focuses on LLM evaluation.
FAQ
What is promptfoo used for?
Promptfoo tests and evaluates LLM applications. It runs automated prompt tests, compares outputs across models, and performs red-team security assessments.
Is promptfoo free?
Yes. Promptfoo is open source and MIT licensed for personal and commercial use. Cloud features and enterprise support may require paid plans.
How do I install promptfoo?
Install it globally:
npm install -g promptfoo
You can also run it with npx promptfoo@latest, install it through Homebrew on macOS, or use pip install promptfoo.
What models does promptfoo support?
Promptfoo supports 90+ providers, including OpenAI, Anthropic, Google, Azure OpenAI, Amazon Bedrock, and local models through Ollama.
How do I run a red-team scan?
Initialize a red-team configuration, run it, then generate a report:
promptfoo redteam init
promptfoo redteam run
promptfoo redteam report
Can I use promptfoo in CI/CD?
Yes. Install promptfoo in your pipeline and run:
promptfoo eval -c promptfooconfig.yaml
Set a threshold in the configuration to fail CI when the pass rate is too low.
Does promptfoo send data to external servers?
Promptfoo runs locally by default. Prompts and test data remain on your machine unless you explicitly use cloud features.
How do I compare models with promptfoo?
List multiple providers in promptfooconfig.yaml, run promptfoo eval, then open the comparison UI:
bash
promptfoo view


Top comments (0)