Skip to main content

melvil

Labeled examples + a label taxonomy in → an optimized, versioned classifier prompt out.

melvil wraps the GEPA reflective prompt-evolution engine with a classification-specific layer that generic prompt optimizers lack: confusion-driven reflection, a per-label prompt codebook, and hard-example mining. It is a pure Python library — the API is the product.

Named for Melvil Dewey, who gave libraries a system for putting things in the right category.

import melvil as mv

examples = mv.load_csv("tickets.csv")                  # text,label columns
train, dev = mv.train_dev_split(examples, dev_size=100, seed=0)
spec = mv.TaskSpec.from_examples("ticket-intents", examples)
cfg = mv.Config(task_model="openai/gpt-4.1-mini",
                reflection_model="openai/gpt-4.1", budget="light")
artifact = mv.optimize(spec, train, dev, cfg)
print(artifact.render())                               # deployable prompt string
artifact.save("ticket_intents.v1.json")

Install

pip install pymelvil             # the PyPI distribution is `pymelvil`; you `import melvil`
pip install 'pymelvil[hf]'       # + HuggingFace dataset loaders

From a checkout:

pip install -e '.[hf,dev]'       # + test/lint tooling

Model names are LiteLLM ids (openai/..., anthropic/..., openrouter/...); set the matching API key env var (OPENAI_API_KEY, OPENROUTER_API_KEY, ...).

What the benchmarks say (read this before choosing features)

We benchmark honestly, including against ourselves — full protocol and numbers in benchmarks/RESULTS.md. The pre-registered confirmation pass (8 public datasets, fresh seeds, light budget, gpt-4.1-mini) found:

  • Vanilla GEPA over melvil's rendered prompt is the strongest configuration (mean test accuracy 0.781 vs 0.755 for the full classification layer and 0.762 for MIPROv2; seed prompt 0.703). At light budgets, prefer features=mv.Features.none().
  • The classification layer's per-component updates trade whole-prompt coverage for structure; at ~6–10 accepted proposals per run that trade loses, especially on hard small-taxonomy tasks. Whether it wins at medium/heavy budgets is an open question.
  • Hard-example mining, behind its (strict, quarantined) accept gate, kept exemplars in 0/24 confirmation runs — treat it as a safety-gated no-op at light budgets.

What the classification layer does

Each feature is independently toggleable via mv.Features (all off by default — the default is the benchmark-strongest vanilla-GEPA configuration; enable the layer with mv.Features.all() or per-flag; Features.none() is an explicit alias for the default):

  1. Per-label codebook — the prompt is not a free-text blob but named components: a task instruction, one definition per label, and boundary rules. GEPA evolves them per-component.
  2. Confusion-driven reflection — every full dev evaluation updates a confusion matrix; reflection rounds are pointed at the label components on both sides of the currently worst confused boundary, and the reflection LM is shown the top confused pairs with concrete misclassified examples.
  3. Hard-example mining — dev examples that stay misclassified across the run become candidate few-shot exemplars, selected to cover the top confused boundaries, and kept only if they don't hurt dev accuracy. (Exemplars come from dev, so dev scores of exemplar-augmented artifacts are mildly optimistic — judge them on test.)

The rendered prompt always ends with a fixed, non-evolvable output-format contract, so the optimizer can never break parseability.

Everything else you get

  • PromptArtifact — versioned JSON: components, models, budget and cost actually spent, dev scores + confusion matrix, the dev-score-vs-budget curve, config hash, lineage (parent_id). artifact.diff(other) gives a per-component diff with score deltas.
  • evaluate(artifact, data, model=...) — accuracy, macro-F1, per-label P/R/F1, confusion, cost; pass a different model for a transfer evaluation. report(...) renders it as markdown.
  • Cost estimation before spendingestimate_optimize_cost(spec, train, dev, cfg) is a dry-run upper bound; measured spend comes from the LM call history and lands in the artifact.
  • Run directories & resume — every run writes runs/<task>/<hash>-s<seed>/ (config, engine state, reflection traces, artifact); optimize(..., resume=True) continues an interrupted run.
  • Progress — pass on_round=lambda info: ... for live dev score / spend after every full dev evaluation, or just read the default logging.
  • Offline testingmelvil.testing ships fake LMs with a real optimization gradient; the whole test suite runs with no API keys.

Worked example & docs

Development

pip install -e '.[dev]'
pytest          # green with no API keys — fake-LM offline suite
ruff check .

License: MIT.

Release files for pymelvil 0.3.0

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for pymelvil 0.3.0
File Size Uploaded
pymelvil-0.3.0.tar.gz 628.8 kB Details

Built distribution (wheel)

Table of built distributions (wheels) for pymelvil 0.3.0
File Interpreter ABI Platform
pymelvil-0.3.0-py3-none-any.whl Python 3 none any Details

Total release size: 670.5 kB

Release files / pymelvil-0.3.0.tar.gz

Download URL pymelvil-0.3.0.tar.gz
Size 628.8 kB
Tags Source
SHA-256 checksum
How to use checksums
7daa6a6afb4ae807129e91613c0b05882e1e681e9ea801a0ec5df75038061cf8
BLAKE2b-256 checksum
How to use checksums
3ccb6b28e13454fe67e078af251a3fdc116fdadf8ae832119aec917b8c1aaa6d
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/6.1.0 CPython/3.13.14

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Jul 19, 2026.

Transparency log

Release files / pymelvil-0.3.0-py3-none-any.whl

Download URL pymelvil-0.3.0-py3-none-any.whl
Size 41.7 kB
Tags Python 3
SHA-256 checksum
How to use checksums
4fea10ba69e89242b0c47944cfe35976542350f67d84d7e554686e6db20db395
BLAKE2b-256 checksum
How to use checksums
7f27d2b33ce9aed84ab70c0bc9f7ead1046d5db2098b9d2fcc99ebc010b83690
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/6.1.0 CPython/3.13.14

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Jul 19, 2026.

Transparency log

Release history Release notifications | RSS feed

This release

0.3.0 This release

2 release files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page