Skip to main content

PromptDrift

CI License: MIT

CI regression testing for LLM prompts.

Catch AI behavior regressions before they reach production.

PromptDrift turns the behavior you need from a prompt into explicit, reviewable contracts. When a prompt changes, it runs those contracts in CI and tells you exactly what broke — without treating every wording change as a regression.

prompt change  →  PromptDrift  →  behavioral contracts  →  PR check
                                                        ↳ PASS · WARN · FAIL

Why PromptDrift?

git diff tells you what changed in the prompt text. PromptDrift tells you whether the AI behavior changed in a way that matters.

Problem PromptDrift's answer
"We changed a prompt and broke 3 customer flows" Behavioral contracts catch regressions before merge
"Every LLM output is different — how do I test that?" Test structure and constraints, not exact wording
"Our prompt tests are flaky because they diff raw output" Contracts pass/fail deterministically on semantics
"We have no idea if a prompt change is safe to deploy" CI gives a clear PASS/FAIL on every PR

Quick Start

pip install promptdrift-ci
promptdrift init
promptdrift test

init creates a fully local example using the deterministic mock provider. No API key needed — validate the workflow first, then connect OpenAI or Ollama.

Capture approved behavior:

promptdrift baseline
git add promptdrift.baseline.json

Define Behavioral Contracts

promptdrift.yaml stays small, readable, and version-controlled:

version: 1

provider:
  type: openai
  model: gpt-4.1-mini
  api_key_env: OPENAI_API_KEY

tests:
  - id: refund_request
    prompt: prompts/support.txt
    variables:
      policy: Refunds are available within 30 days.
      question: Can I get a refund for my order?
    assertions:
      - type: contains
        value: 30 days
      - type: not_contains
        value: guaranteed
      - type: max_length
        value: 600
❌ FAIL refund_request

Assertion: contains
Expected: 30 days
Actual:   You may be eligible for a refund.
Reason:   Required text does not appear in the output.

Contracts, Not Cosmetic Diffs

PromptDrift fails when… PromptDrift does not fail just because…
Required text disappears Wording changes
Forbidden content appears Sentence order changes
JSON is invalid or violates its schema An otherwise-valid answer is phrased differently
A length, token, latency, or cost limit is exceeded Output hashes differ but contracts still pass

Built-in Assertions

exact_match · contains · not_contains · regex · not_regex · json_valid · json_schema · min_length · max_length · max_tokens · latency_ms · cost_usd

Each assertion supports severity: warn for non-blocking warnings.

Run in CI

name: PromptDrift

on:
  pull_request:
    paths:
      - "prompts/**"
      - "promptdrift.yaml"

permissions:
  contents: read

jobs:
  promptdrift:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - uses: tanveer-arch/promptdrift/action@v1
        with:
          config: promptdrift.yaml
        env:
          OPENAI_API_KEY: ${{ secrets.OPENAI_API_KEY }}

The Action writes a Step Summary, uploads a JSON report, and fails only after reports are available. For PR comments, add comment: 'true' and grant pull-requests: write.

Security: Use pull_request for untrusted forks. Never expose provider secrets with pull_request_target while executing code from a pull request.

Commands

Command What it does
promptdrift init Creates an offline starter suite
promptdrift test Runs contracts; auto-compares against baseline
promptdrift baseline Captures approved behavior (requires --force to replace)
promptdrift diff Runs and compares current output with baseline
promptdrift report Generates an offline HTML report
promptdrift doctor Checks config, files, keys, and baseline health
promptdrift version Prints the installed version

All commands support --json for machine-readable output. Exit codes: 0 success, 1 behavioral failure, 2 config/usage error, 3 provider/runtime error.

Architecture

promptdrift.yaml ─→ Config ─→ Template ─→ Provider ─→ Evaluator ─→ Report
                     Loader    Renderer    Adapter     Engine       Formatter
                                                        │
                                                  Baseline ←── Git
                                                  Comparison
  • Providers are isolated adapters (OpenAI, Ollama, Mock) — adding one is a single file
  • Assertions are pure, deterministic functions — same input always produces the same result
  • Baselines store hashes and metrics, never raw outputs or secrets
  • Reports output to terminal, JSON, HTML, or GitHub PR comments

Privacy by Default

  • No telemetry, accounts, or hosted service
  • Prompt content goes only to the provider you configure
  • API keys are environment variables — never config values
  • Baselines contain hashes and metrics, not raw outputs
  • Local SQLite history suppresses prompts and outputs by default

Documentation

Guide Description
Getting Started Install, first run, and connecting a provider
Configuration Full promptdrift.yaml reference
Assertions All contract types with examples
Providers OpenAI, Ollama, and Mock setup
Baselines Create, compare, and update baselines
GitHub Action CI setup, secrets, and fork security
Architecture Module design and data flow
FAQ Common questions and troubleshooting
Contributing Dev setup, testing, and PR process

Roadmap

  • Semantic similarity assertions (embedding-based)
  • LLM-as-judge evaluator
  • Multi-provider comparison (same prompt, different models)
  • Parallel test execution
  • PyPI trusted publisher release
  • Cost tracking dashboard

License

Released under the MIT License.

Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

promptdrift_ci-0.1.0.tar.gz (43.7 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

promptdrift_ci-0.1.0-py3-none-any.whl (25.5 kB view details)

Uploaded Python 3

File details

Details for the file promptdrift_ci-0.1.0.tar.gz.

File metadata

  • Download URL: promptdrift_ci-0.1.0.tar.gz
  • Upload date:
  • Size: 43.7 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/7.0.0 CPython/3.13.1

File hashes

Hashes for promptdrift_ci-0.1.0.tar.gz
Algorithm Hash digest
SHA256 d4a53d7f4a8e4f7ce9c4a1158576f9639ebcbccea7bc1d5fa982c9c9161571fb
MD5 540a67ca7e1fae6efb93875bc179dfb9
BLAKE2b-256 010043e5aa6a7c50297c5083cfa122469b327463f8a122d72e8eabfb6f6df6a7

See more details on using hashes here.

File details

Details for the file promptdrift_ci-0.1.0-py3-none-any.whl.

File metadata

  • Download URL: promptdrift_ci-0.1.0-py3-none-any.whl
  • Upload date:
  • Size: 25.5 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/7.0.0 CPython/3.13.1

File hashes

Hashes for promptdrift_ci-0.1.0-py3-none-any.whl
Algorithm Hash digest
SHA256 4d3acf805a8ef8fedbe5268d00f0ad9ae8d908d1845aef1585648219f359643d
MD5 70380f7f12179343df75f95a3eb5ec5a
BLAKE2b-256 5a55e3be2aa68565a05ee277c48964352d2023bdd873e3fc1ef238bb9d23ae3b

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page