Apache-2.0 prompt optimization package with GEPA and MIPRO adapters.
Project description
synth-optimizers
Apache-2.0 licensed Python-only prompt optimization package that provides a local offline mirror of the public Synth GEPA/MIPRO SDK surfaces under prompt_opt.sdk.optimization.*.
Repo name: optimizers
PyPI distribution name: synth-optimizers
Python import package: prompt_opt
What is included
prompt_opt.sdk.optimization.policy.v1.PolicyOptimizationOfflineJob- Local drop-in offline job surface for
gepa_offlineandmipro_offline.
- Local drop-in offline job surface for
prompt_opt.sdk.optimization.internal.prompt_learning.PromptLearningJob- High-level local prompt-learning wrapper with candidate/state accessors.
prompt_opt.sdk.optimization.internal.configs.prompt_learning.PromptLearningConfig- Canonical prompt-learning config models with local
proxied -> retrievednormalization.
- Canonical prompt-learning config models with local
prompt_opt.dspy.MIPROv2- DSPy-compatible local MIPRO wrapper routed through the mirrored offline SDK.
prompt_opt.dspy.gepa- GEPA slot-in wrapper routed through the same local offline runtime.
prompt_opt.adapters.synth_container- Container request/response helpers for local rollout integration.
src/gepa/__init__.py- Import compatibility shim so
import gepaworks against this package.
- Import compatibility shim so
Install (editable, local)
cd optimizers
pip install -e .
Quick usage
from prompt_opt.sdk.optimization.policy.v1 import PolicyOptimizationOfflineJob
def task_model(prompt: str) -> str:
if "Return exactly one of" in prompt:
return "paris"
return "rome"
job = PolicyOptimizationOfflineJob.create(
kind="mipro_offline",
system_name="cities-local",
backend_url="local://prompt-opt",
api_key="local",
config={
"prompt_learning": {
"algorithm": "mipro",
"execution_mode": "retrieved",
"task_data": {
"train_examples": [{"input": "Capital of France?", "answer": "paris"}],
"validation_examples": [{"input": "Capital of France?", "answer": "paris"}],
},
"mipro": {
"initial_candidate": {
"stages": [
{
"id": "main",
"name": "main",
"messages": [
{"role": "system", "pattern": "Answer the question.", "order": 0},
{"role": "user", "pattern": "{input}", "order": 1},
],
}
]
},
"num_candidates": 4,
"max_iterations": 3,
},
"local_runtime": {"task_model": task_model},
}
},
)
result = job.stream_until_complete(timeout=30.0, interval=0.05)
best_candidate = job.get_state_envelope()["state"]["candidates"][result["best_candidate_id"]]
print(best_candidate["candidate_content"])
GEPA shim
from gepa import optimize
from prompt_opt.adapters.synth_offline import LocalEvaluator, SynthOfflineLearningAdapter
def score_fn(example, candidate):
expected = str(example.get("answer", "")).strip().lower()
prompt = " ".join(candidate.values()).lower()
return 1.0 if expected and expected in prompt else 0.0
adapter = SynthOfflineLearningAdapter(LocalEvaluator(score_fn=score_fn))
result = optimize(
seed_candidate={"system_prompt": "Answer briefly."},
trainset=[{"input": "Capital of France?", "answer": "paris"}],
adapter=adapter,
max_metric_calls=8,
)
print(result.best_candidate)
print(result.val_aggregate_scores[result.best_idx])
Notes
- This package is local-only and does not call Synth backend APIs.
- Runtime execution is retrieval-based only. Hosted configs that specify
execution_mode="proxied"are accepted and normalized toretrievedlocally. - The local runtime mirrors candidate/state/result payloads and offline job methods;
backend_urlandapi_keyare kept for signature parity but are inert in local mode. - Multi-stage candidates are first-class in both local GEPA and local MIPRO.
Examples
- Local DSPy MIPRO:
examples/mipro_local_example.py
- DSPy GEPA slot-in:
examples/dspy_gepa_slot_example.py
- Local offline Banking77 via Synth
InProcessContainer:examples/banking77_container_example.py
- Local offline GEPA for simple JSONL task files:
examples/gepa_taskfile_container_eval.py
Run the Banking77 local regression harness with:
PYTHONPATH=/Users/joshpurtell/Documents/GitHub/prompt-opt/src:/Users/joshpurtell/Documents/GitHub/synth-ai \
uv run --active /Users/joshpurtell/Documents/GitHub/prompt-opt/examples/banking77_container_example.py \
--algorithms gepa mipro \
--train-per-label 4 \
--held-out-per-label 2 \
--num-generations 2 \
--children-per-generation 8 \
--num-candidates 8 \
--max-iterations 6
The script prints per-algorithm JSON with train_* and held_out_* metrics and raises if held-out improvement does not exceed --min-held-out-delta.
Find simple eval task files and run local taskfile optimization (gepa or mipro) with:
PYTHONPATH=/Users/joshpurtell/Documents/GitHub/prompt-opt/src:/Users/joshpurtell/Documents/GitHub/synth-ai \
uv run --active /Users/joshpurtell/Documents/GitHub/prompt-opt/examples/gepa_taskfile_container_eval.py \
--list-simple-task-files
PYTHONPATH=/Users/joshpurtell/Documents/GitHub/prompt-opt/src:/Users/joshpurtell/Documents/GitHub/synth-ai \
uv run --active /Users/joshpurtell/Documents/GitHub/prompt-opt/examples/gepa_taskfile_container_eval.py \
--algorithm gepa \
--task-file /Users/joshpurtell/Documents/GitHub/evals/mipro/tasks/multimodal_smoke.jsonl \
--train-size 8 \
--num-generations 2 \
--children-per-generation 8 \
--total-rollouts 64
PYTHONPATH=/Users/joshpurtell/Documents/GitHub/prompt-opt/src:/Users/joshpurtell/Documents/GitHub/synth-ai \
uv run --active /Users/joshpurtell/Documents/GitHub/prompt-opt/examples/gepa_taskfile_container_eval.py \
--algorithm gepa \
--task-preset medec_smoke \
--train-size 8 \
--num-generations 2 \
--children-per-generation 8 \
--total-rollouts 64
PYTHONPATH=/Users/joshpurtell/Documents/GitHub/prompt-opt/src:/Users/joshpurtell/Documents/GitHub/synth-ai \
uv run --active /Users/joshpurtell/Documents/GitHub/prompt-opt/examples/gepa_taskfile_container_eval.py \
--algorithm mipro \
--task-preset drugprot_train_public \
--train-size 8 \
--num-candidates 24 \
--max-iterations 16 \
--children-per-generation 16 \
--total-rollouts 256
PYTHONPATH=/Users/joshpurtell/Documents/GitHub/prompt-opt/src:/Users/joshpurtell/Documents/GitHub/synth-ai \
uv run --active /Users/joshpurtell/Documents/GitHub/prompt-opt/examples/gepa_taskfile_container_eval.py \
--algorithm mipro \
--task-preset langprobe_banking77 \
--train-size 32 \
--num-candidates 12 \
--max-iterations 8 \
--children-per-generation 8 \
--total-rollouts 96
PYTHONPATH=/Users/joshpurtell/Documents/GitHub/prompt-opt/src:/Users/joshpurtell/Documents/GitHub/synth-ai \
uv run --active /Users/joshpurtell/Documents/GitHub/prompt-opt/examples/gepa_taskfile_container_eval.py \
--algorithm mipro \
--task-preset langprobe_hotpotqa \
--train-size 8 \
--num-candidates 8 \
--max-iterations 6 \
--children-per-generation 8 \
--total-rollouts 64
PYTHONPATH=/Users/joshpurtell/Documents/GitHub/prompt-opt/src:/Users/joshpurtell/Documents/GitHub/synth-ai \
uv run --active /Users/joshpurtell/Documents/GitHub/prompt-opt/examples/gepa_taskfile_container_eval.py \
--algorithm mipro \
--task-preset langprobe_iris \
--train-size 60 \
--num-candidates 10 \
--max-iterations 8 \
--children-per-generation 8 \
--total-rollouts 96
PYTHONPATH=/Users/joshpurtell/Documents/GitHub/prompt-opt/src:/Users/joshpurtell/Documents/GitHub/synth-ai \
uv run --active /Users/joshpurtell/Documents/GitHub/prompt-opt/examples/gepa_taskfile_container_eval.py \
--algorithm mipro \
--task-preset langprobe_hover \
--train-size 60 \
--num-candidates 10 \
--max-iterations 8 \
--children-per-generation 8 \
--total-rollouts 96
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file synth_optimizers-0.1.0.tar.gz.
File metadata
- Download URL: synth_optimizers-0.1.0.tar.gz
- Upload date:
- Size: 39.4 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.14.2
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
90db81b7b60e0126952aad65ad65a965452977d589e37bfd841e4eb5c5c52d41
|
|
| MD5 |
42128c37e3bba9325da03e6c1c9f41fc
|
|
| BLAKE2b-256 |
9a635713da08c73708d3947de4987c9958ced31440c3e1b14b81d56d8e627e4a
|
File details
Details for the file synth_optimizers-0.1.0-py3-none-any.whl.
File metadata
- Download URL: synth_optimizers-0.1.0-py3-none-any.whl
- Upload date:
- Size: 42.0 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.14.2
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
93ab470821f29b4ad23f280b7fd976b25848dde3c35d374ceae21d0cfc779dac
|
|
| MD5 |
9c50029aa9a68ec107304ad622af3b97
|
|
| BLAKE2b-256 |
06c7fcc2254c32e3aec1a7700981b46b74b4e99b6e4010573a218ea21ba7265a
|