Skip to main content

PromptDrift

CI PyPI Python 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.1.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.1-py3-none-any.whl (25.5 kB view details)

Uploaded Python 3

File details

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

File metadata

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

File hashes

Hashes for promptdrift_ci-0.1.1.tar.gz
Algorithm Hash digest
SHA256 db9ab6f00ae1613759bca717f685ab456763b94f7dc2d93505f843e825dbcb06
MD5 b952739131f6945c0bd1bc47636126b6
BLAKE2b-256 b38fcba0ba05fd0ef77003723812efaf2e5bb4d15eb69d9216ae6278ee8f16af

See more details on using hashes here.

Provenance

The following attestation bundles were made for promptdrift_ci-0.1.1.tar.gz:

Publisher: release.yml on tanveer-arch/promptdrift

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

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

File metadata

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

File hashes

Hashes for promptdrift_ci-0.1.1-py3-none-any.whl
Algorithm Hash digest
SHA256 6d69557c7ada888575fff8856beafd0643b84b75f9ec91da4c15e0f75431b6e5
MD5 806857f45f9e7593db8abc1a2f22b2a5
BLAKE2b-256 f2b41788a0945dfadbb58fb4373d52f3d5f257151d8e5004647ba08e6e511b6c

See more details on using hashes here.

Provenance

The following attestation bundles were made for promptdrift_ci-0.1.1-py3-none-any.whl:

Publisher: release.yml on tanveer-arch/promptdrift

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

Supported by

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