Skip to main content

driftless

When you change the model behind an LLM app, the prompt that used to work often stops working. Driftless runs your eval on the old model and the new one, repairs only the files you allow, and opens a pull request with the evidence — or blocks the change if quality drops.

You need an eval you can run from the command line. The bundled demo needs no API key. Automatic prompt repair on a real workflow does.

If you know Poetry and Dependabot: driftless.yml is the manifest (model + eval dataset), the prompt is the lockfile, and delivery is a gated PR. LLM behavior is empirical, so Driftless scores candidates on your eval instead of resolving versions.

Status: public alpha0.3.x on PyPI. Upgrading from 0.2.x? Follow the upgrade guide first.

Install

pip install driftless

Python 3.10 or newer. No API key for the steps below.

Quickstart

Copy the bundled support-classifier example and run it. -w is the workflow name from driftless.yml.

driftless copy-example support-classifier --out-dir driftless-classifier-demo
cd driftless-classifier-demo
driftless validate -w support_classifier
driftless compare -w support_classifier --to gpt-4o-mini

validate checks that the project is wired correctly. compare runs the current model and the cheaper target on the same tiny eval. You should see something like:

F1          current 1.000   target 0.000
Total cost  current 0.024   target 0.004
FAIL min_f1: 0.000 >= 0.9

Read that last line as: the new model scored 0.000, you required at least 0.9, so the cheaper swap is not safe to ship. That failure is the point of the demo.

Continue without API keys. --generator none makes no prompt edits, so migration stays blocked. --generator fixture applies the known-good patch shipped with this example and can pass.

driftless migrate -w support_classifier --to gpt-4o-mini --generator none
# Expected: BLOCKED, non-zero exit. Run the next commands anyway.

driftless migrate -w support_classifier --to gpt-4o-mini --generator fixture
# Expected: PASS — bundled patch, still no API key.

driftless report -w support_classifier
driftless open-pr -w support_classifier
# Dry run: prints what it would open. Add --create only when you mean it.

This demo has only 4 eval rows. It proves install, gating, and a key-free pass/block loop. It is not production evidence. For a real workflow use a representative eval and --generator llm (needs a provider key). See eval confidence.

Words you'll see

Term Meaning
Workflow One LLM task in the repo (classifier, RAG answerer, agent).
Contract driftless.yml — how to run the task, what may be edited, what “good” means.
Harness Your command that runs the task and writes one JSON object per line.
Generator Who writes the repair: none (no edits), fixture (bundled demo patch), llm (calls a provider).
Holdout Eval rows saved for a final check; the repair loop never trains on them.

Product proof

This is the actual output of the cold-install quickstart:

Terminal output from Driftless compare showing a cheaper target blocked by the F1 gate

A larger offline migration was also run against the public support-classifier-svc testbed. It produced draft PR #4 with the generated scorecard, holdout evidence, prompt diff, and model update:

Real GitHub pull request created from a passing Driftless migration

PR #4 is historical proof of a 290-label testbed run. The published CLI reproduces a passing four-row repair with --generator fixture; regenerating PR #4's exact patch still needs provider-backed --generator llm (or the testbed's own simulator) and may differ.

Other bundled examples:

driftless copy-example support-classifier-live
driftless copy-example rag-qa
driftless copy-example tool-agent

To put Driftless on an existing app, follow the existing-repository walkthrough. Start with scan and configure --apply, then review the draft contract before repair or CI.

How it works

You describe the workflow once in driftless.yml: the command that runs it, how to switch models, which files may be edited, and the quality bar. Driftless runs your command under different models, compares results, repairs only allowed files, checks the winner on holdout data, and opens a PR with the evidence.

You own the workflow. Driftless orchestrates it.

Not a classifier? Pick a grading mode that matches the task:

  • eval.score_field / eval.pass_field — your command emits a numeric score or a pass/fail per record (summarization, codegen, agents).
  • eval.fields — structured extraction, scored per field against gold labels.
  • eval.judge — an LLM grades free-form output against a rubric. Run driftless judge-check -w <workflow> before optimizing.
CLI reference
Command Purpose
copy-example Copy a bundled example (support-classifier, support-classifier-live, rag-qa, tool-agent).
init Scaffold a driftless.yml.
init-policy Scaffold a .driftless/policy.yml (when to migrate).
init-ci Scaffold .github/workflows/ for scan, migrate, refine, poll, plan, label audit, and judge check.
scan Find probable LLM usage and at-risk models.
plan Discover at-risk workflows and apply the migration policy (CI triage).
plan --act Migrate + open a PR/issue for every actionable trigger.
configure <workflow> Write .driftless/configure/<workflow>.yml; add --apply to create or append root driftless.yml.
calibrate -w <w> Measure the baseline and suggest starting thresholds.
compare -w <w> --to <model> Baseline vs target scorecard; add --enforce to fail CI when gates fail.
migrate -w <w> --to <model> Repair + validate + produce migrated files.
refine -w <w> Re-optimize the prompt for a changed eval dataset (model pinned).
poll [--act] Detect external eval-dataset changes and refine on a meaningful change.
validate -w <w> Check the contract parses and the harness runs.
judge-check -w <w> Measure judge↔human agreement (--enforce to gate).
audit-labels -w <w> Find duplicate inputs with disagreeing gold labels (--fail for CI).
report Render the latest migration report.
view Open the optimization run viewer (charts + attempt log).
open-pr -w <w> Open a PR (or issue) from the latest migration result.
Configuring when to migrate

plan reads an optional .driftless/policy.yml — the “when to propose a change” layer. Scaffold it with driftless init-policy. An empty file behaves like no file. It controls which triggers are enabled (deprecation is on and forced; cost/quality/new_model are optional), thresholds a candidate must clear, a cooldown_days for freshly released models, allow/deny globs, and an ignore list. The engine still decides whether a candidate passes your eval — policy only decides whether to propose it.

GitHub Action

A composite GitHub Action wraps the same CLI so scans and migrations can run in CI. After you have a working local contract:

- uses: driftless-dev/driftless@v0.3.6
  with:
    command: scan

See .github/workflows/ in this repo for scheduled scan, weekly plan --act, and manually triggered migration examples.

Documentation

Start here

When you need them

Download files

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

Source Distribution

driftless-0.3.6.tar.gz (3.4 MB view details)

Uploaded Source

Built Distribution

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

driftless-0.3.6-py3-none-any.whl (2.5 MB view details)

Uploaded Python 3

File details

Details for the file driftless-0.3.6.tar.gz.

File metadata

  • Download URL: driftless-0.3.6.tar.gz
  • Upload date:
  • Size: 3.4 MB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/7.0.0 CPython/3.13.14

File hashes

Hashes for driftless-0.3.6.tar.gz
Algorithm Hash digest
SHA256 bb5eb6eb13526304e42c70ecdc8398d072703d39284c2a6916d2a9bb1005266a
MD5 a4088611513c721e07fa8c41b2b6fc0b
BLAKE2b-256 e0912f7f915e51f40e6e31325dbee674eec1c3a141a24835dd022791b27a529a

See more details on using hashes here.

Provenance

The following attestation bundles were made for driftless-0.3.6.tar.gz:

Publisher: publish.yml on driftless-dev/driftless

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

File details

Details for the file driftless-0.3.6-py3-none-any.whl.

File metadata

  • Download URL: driftless-0.3.6-py3-none-any.whl
  • Upload date:
  • Size: 2.5 MB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/7.0.0 CPython/3.13.14

File hashes

Hashes for driftless-0.3.6-py3-none-any.whl
Algorithm Hash digest
SHA256 1a2d75931cf31dbf13ae2b8ae472a83b35ac612255582289daeda2a478519f4a
MD5 a504425b158d4a1428560f7f1f51717f
BLAKE2b-256 12b20d33a45dd1e2f3b1455ea355296287701c087606baceddca7945d731e1b0

See more details on using hashes here.

Provenance

The following attestation bundles were made for driftless-0.3.6-py3-none-any.whl:

Publisher: publish.yml on driftless-dev/driftless

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