0d3cb498a3
CI / Shell Format Check (push) Has been cancelled
CI / Check Ruby (3.4) (push) Has been cancelled
CI / CI Config (push) Has been cancelled
CI / Test on Node ${{ matrix.node }} and ${{ matrix.os }}${{ matrix.shard && format(' (shard {0}/3)', matrix.shard) || '' }} (push) Has been cancelled
CI / Build on Node ${{ matrix.node }} (push) Has been cancelled
CI / Style Check (push) Has been cancelled
CI / Generate Assets (push) Has been cancelled
CI / Check Python (3.14) (push) Has been cancelled
CI / Check Python (3.9) (push) Has been cancelled
CI / Build Docs (push) Has been cancelled
CI / Code Scan Action (push) Has been cancelled
CI / Site tests (push) Has been cancelled
CI / webui tests (push) Has been cancelled
CI / Run Integration Tests (push) Has been cancelled
CI / Run Smoke Tests (push) Has been cancelled
CI / Go Tests (push) Has been cancelled
CI / Share Test (push) Has been cancelled
CI / Redteam (Production API) (push) Has been cancelled
CI / Redteam (Staging API) (push) Has been cancelled
CI / GitHub Actions Lint (push) Has been cancelled
CI / Check Ruby (3.0) (push) Has been cancelled
release-please / release-please (push) Has been cancelled
release-please / build (push) Has been cancelled
release-please / publish-npm (push) Has been cancelled
release-please / publish-npm-backfill (push) Has been cancelled
release-please / docker (push) Has been cancelled
release-please / publish-code-scan-action (push) Has been cancelled
release-please / attest-code-scan-action (push) Has been cancelled
Deploy local.promptfoo.app / Deploy to Cloudflare Pages (push) Has been cancelled
Test and Publish Multi-arch Docker Image / test (push) Has been cancelled
Test and Publish Multi-arch Docker Image / build-docker-and-push-digests (map[digest-suffix:linux-amd64 platform:linux/amd64 runner:ubuntu-latest]) (push) Has been cancelled
Test and Publish Multi-arch Docker Image / build-docker-and-push-digests (map[digest-suffix:linux-arm64 platform:linux/arm64 runner:ubuntu-24.04-arm]) (push) Has been cancelled
Test and Publish Multi-arch Docker Image / merge-docker-digests (push) Has been cancelled
Test and Publish Multi-arch Docker Image / Attest Multi-arch Image (push) Has been cancelled
Validate Renovate Config / Validate Renovate Configuration (push) Has been cancelled
5.3 KiB
5.3 KiB
sidebar_label, description
| sidebar_label | description |
|---|---|
| Looper | Automate LLM testing in CI/CD by integrating Promptfoo with Looper workflows. Configure quality gates, caching, and multi-environment evaluations for production AI pipelines. |
Setting up Promptfoo with Looper
This guide shows you how to integrate Promptfoo evaluations into a Looper CI/CD workflow so that every pull‑request (and optional nightly job) automatically runs your prompt tests.
Prerequisites
- A working Looperinstallation with workflow execution enabled
- A build image (or declared tools) that provides Node 22+ and jq 1.6+
promptfooconfig.yamland your prompt fixtures (prompts/**/*.json) committed to the repository
Create .looper.yml
Add the following file to the root of your repo:
language: workflow # optional but common
tools:
nodejs: 22 # Looper provisions Node.js
jq: 1.7
envs:
global:
variables:
PROMPTFOO_CACHE_PATH: '${HOME}/.promptfoo/cache'
triggers:
- pr # run on every pull‑request
- manual: 'Nightly Prompt Tests' # manual button in UI
call: nightly # invokes the nightly flow below
flows:
# ---------- default PR flow ----------
default:
- (name Install Promptfoo) npm install -g promptfoo
- (name Evaluate Prompts) |
promptfoo eval \
-c promptfooconfig.yaml \
--prompts "prompts/**/*.json" \
--share \
-o output.json
- (name Quality gate) |
SUCC=$(jq -r '.results.stats.successes' output.json)
FAIL=$(jq -r '.results.stats.failures' output.json)
echo "✅ $SUCC ❌ $FAIL"
test "$FAIL" -eq 0 # non‑zero exit fails the build
# ---------- nightly scheduled flow ----------
nightly:
- call: default # reuse the logic above
- (name Upload artefacts) |
aws s3 cp output.json s3://your-bucket/promptfoo/output.json
How it works
| Section | Purpose |
|---|---|
tools |
Declares tool versions Looper should provision. |
envs.global.variables |
Environment variables available to every step. |
triggers |
Determines when the workflow runs (pr, manual, cron, etc.). |
flows |
Ordered shell commands; execution stops on the first non‑zero exit. |
Caching Promptfoo results
Looper lacks a first‑class cache API. Two common approaches:
- Persistent volume – mount
${HOME}/.promptfoo/cacheon a reusable volume. - Persistence tasks – pull/push the cache at the start and end of the flow:
Setting quality thresholds
- (name Pass‑rate gate) |
TOTAL=$(jq '.results.stats.successes + .results.stats.failures' output.json)
PASS=$(jq '.results.stats.successes' output.json)
RATE=$(echo "scale=2; 100*$PASS/$TOTAL" | bc)
echo "Pass rate: $RATE%"
test $(echo "$RATE >= 95" | bc) -eq 1 # fail if <95 %
Multi‑environment evaluations
Evaluate both staging and production configs and compare failures:
flows:
compare-envs:
- (name Eval‑prod) |
promptfoo eval \
-c promptfooconfig.prod.yaml \
--prompts "prompts/**/*.json" \
-o output-prod.json
- (name Eval‑staging) |
promptfoo eval \
-c promptfooconfig.staging.yaml \
--prompts "prompts/**/*.json" \
-o output-staging.json
- (name Compare) |
PROD_FAIL=$(jq '.results.stats.failures' output-prod.json)
STAGE_FAIL=$(jq '.results.stats.failures' output-staging.json)
if [ "$STAGE_FAIL" -gt "$PROD_FAIL" ]; then
echo "⚠️ Staging has more failures than production!"
fi
Posting evaluation results to GitHub/GitLab
In order to send evaluation results elsewhere, use:
- GitHub task
- github --add-comment \ --repository "$CI_REPOSITORY" \ --issue "$PR_NUMBER" \ --body "$(cat comment.md)" # set comment as appropriate - cURL with a Personal Access Token (PAT) against the REST API.
Troubleshooting
| Problem | Remedy |
|---|---|
npm: command not found |
Add nodejs: under tools or use an image with Node pre‑installed. |
| Cache not restored | Verify the path and that the files pull task succeeds. |
| Long‑running jobs | Split prompt sets into separate flows or raise timeoutMillis in the build definition. |
| API rate limits | Enable Promptfoo cache and/or rotate API keys. |
Best practices
- Incremental testing – feed
looper diff --name-only prompts/intopromptfoo evalto test only changed prompts. - Semantic version tags – tag prompt sets/configs so you can roll back easily.
- Secret management – store API keys in a secret store and inject them as environment variables.
- Reusable library flows – if multiple repos need the same evaluation, host the flow definition in a central repo and
importit.