Skip to main content

Serverless Posttraining for Agents - Core AI functionality and tracing

Project description

Synth

Python PyPI Crates.io License

Prompt Optimization

Use the sdk in Python (uv add synth-ai) and Rust (beta) (cargo add synth-ai), or hit our serverless endpoints in any language

Shows a bar chart comparing prompt optimization performance across GPT-4.1 Nano, GPT-4o Mini, and GPT-5 Nano with baseline vs GEPA optimized.

Average accuracy on LangProBe prompt optimization benchmarks.

Demo Notebooks (Colab)

Highlights

  • 🎯 GEPA Prompt Optimization - Automatically improve prompts with evolutionary search. See 70%→95% accuracy gains on Banking77, +62% on critical game achievements
  • 🔍 Zero-Shot Verifiers - Fast, accurate rubric-based evaluation with configurable scoring criteria
  • 🧬 GraphGen - Train custom verifier graphs optimized for your specific workflows. Train custom pipelines for other tasks
  • 🚀 No Code Changes - Wrap existing code in a FastAPI app and optimize via HTTP. Works with any language or framework
  • ⚡️ Local Development - Run experiments locally with tunneled task apps. No cloud setup required
  • 🗂️ Multi-Experiment Management - Track and compare prompts/models across runs with built-in experiment queues

Getting Started

SDK (Python)

pip install synth-ai==0.7.5
# or
uv add synth-ai

SDK (Rust - Beta)

cargo add synth-ai

TUI (Homebrew)

brew install synth-laboratories/tap/synth-ai-tui
synth-ai-tui

The TUI provides a visual interface for managing jobs, viewing events, and monitoring optimization runs.

OpenCode Skills (Synth API)

The Synth-AI TUI integrates with OpenCode and ships a synth-api skill.

# List packaged skills shipped with synth-ai
uvx synth-ai skill list
uvx synth-ai skill install synth-api --dir ~/custom/opencode/skill

LocalAPI Deploy (Cloud)

Deploy a LocalAPI with a Dockerfile and get a stable task_app_url:

export SYNTH_API_KEY=sk_live_...
synth localapi deploy \
  --name my-localapi \
  --app my_module:app \
  --dockerfile ./Dockerfile \
  --context . \
  --wait

Use the emitted task_app_url in training configs. Harbor auth uses SYNTH_API_KEY as the task app API key.

Tunnels

Synth optimization jobs need HTTPS access to your local task app. Two tunnel backends are available:

SynthTunnel (Recommended)

Relay-based tunnel — no external binary required, supports 128 concurrent requests:

from synth_ai.core.tunnels import TunneledLocalAPI

tunnel = await TunneledLocalAPI.create(local_port=8001, api_key="sk_live_...")
print(tunnel.url)            # https://st.usesynth.ai/s/rt_...
print(tunnel.worker_token)   # pass to job config

Use with optimization jobs:

job = PromptLearningJob.from_dict(
    config,
    task_app_url=tunnel.url,
    task_app_worker_token=tunnel.worker_token,
)

Cloudflare Quick Tunnel

Anonymous tunnel via trycloudflare.com — no API key needed:

from synth_ai.core.tunnels import TunneledLocalAPI, TunnelBackend

tunnel = await TunneledLocalAPI.create(
    local_port=8001,
    backend=TunnelBackend.CloudflareQuickTunnel,
)

Requires cloudflared installed (brew install cloudflared). Use task_app_api_key instead of worker_token when configuring jobs.

See the tunnels documentation for the full comparison.

Testing

Run the TUI integration tests:

cd tui/app
bun test

Synth is maintained by devs behind the MIPROv2 prompt optimizer.

Documentation

docs.usesynth.ai

Community

Join our Discord

GEPA Prompt Optimization (SDK)

Run GEPA prompt optimization programmatically:

import asyncio
import os
from synth_ai.sdk.api.train.prompt_learning import PromptLearningJob
from synth_ai.sdk.localapi import LocalAPIConfig, create_local_api

# Create a local task app: app = create_local_api(LocalAPIConfig(app_id="my_app", handler=my_handler))

# Create and submit a GEPA job
pl_job = PromptLearningJob.from_dict({
    "job_type": "prompt_learning",
    "config": {
        "prompt_learning": {
            "gepa": {
                "rollout": {"budget": 100},
                "population_size": 10,
                "generations": 5,
            }
        }
    },
    "task_app_id": "my_task_app",
})

pl_job.submit()
result = pl_job.stream_until_complete(timeout=3600.0)
print(f"Best score: {result.best_score}")

See the Banking77 demo notebook for a complete example with local task apps.

Online MIPRO (SDK, Ontology Enabled)

Run online MIPRO so rollouts call a proxy URL and rewards stream back to the optimizer. Enable ontology by setting MIPRO_ONT_ENABLED=1 and HELIX_URL on the backend, then follow the Banking77 online MIPRO notes.

import os
from synth_ai.sdk.optimization.policy import MiproOnlineSession

# Use the demo config shape from demos/mipro_banking77
mipro_config = {...}

session = MiproOnlineSession.create(
    config_body=mipro_config,
    api_key=os.environ["SYNTH_API_KEY"],
)
urls = session.get_prompt_urls()
proxy_url = urls["online_url"]

# Use proxy_url in your rollout loop, then report rewards
session.update_reward(
    reward_info={"score": 0.9},
    rollout_id="rollout_001",
    candidate_id="candidate_abc",
)

Graph Evolve: Optimize RLM-Based Verifier Graphs

Train a verifier graph with an RLM backbone for long-context evaluation. See the Image Style Matching demo for a complete Graph Evolve example:

from synth_ai.sdk.api.train.graph_evolve import GraphEvolveJob

# Train an RLM-based verifier graph
verifier_job = GraphEvolveJob.from_dataset(
    dataset="verifier_dataset.json",
    graph_type="rlm",
    policy_models=["gpt-4.1"],
    proposer_effort="medium",  # Use "medium" (gpt-4.1) or "high" (gpt-5.2)
    rollout_budget=200,
)
verifier_job.submit()
result = verifier_job.stream_until_complete(timeout=3600.0)

# Run inference with trained verifier
verification = verifier_job.run_verifier(
    trace=my_trace,
    context={"rubric": my_rubric},
)
print(f"Reward: {verification.reward}, Reasoning: {verification.reasoning}")

Zero-Shot Verifiers (SDK)

Run a built-in verifier graph with rubric criteria passed at runtime. See the Crafter VLM demo for verifier optimization:

import asyncio
import os
from synth_ai.sdk.graphs import VerifierClient

async def run_verifier():
    client = VerifierClient(
        base_url=os.environ["SYNTH_BACKEND_BASE"],
        api_key=os.environ["SYNTH_API_KEY"],
    )
    result = await client.evaluate(
        job_id="zero_shot_verifier_single",
        trace={"session_id": "s", "session_time_steps": []},
        rubric={
            "event": [{"id": "accuracy", "weight": 1.0, "description": "Correctness"}],
            "outcome": [{"id": "task_completion", "weight": 1.0, "description": "Completed task"}],
        },
        options={"event": True, "outcome": True, "model": "gpt-5-nano"},
        policy_name="my_policy",
        task_app_id="my_task",
    )
    return result

asyncio.run(run_verifier())

You can also call arbitrary graphs directly with the Rust SDK:

use serde_json::json;
use synth_ai::{GraphCompletionRequest, Synth};

#[tokio::main]
async fn main() -> Result<(), synth_ai::Error> {
    let synth = Synth::from_env()?;

    let request = GraphCompletionRequest {
        job_id: "zero_shot_verifier_rubric_single".to_string(),
        input: json!({
            "trace": {"session_id": "s", "session_time_steps": []},
            "rubric": {"event": [], "outcome": []},
        }),
        model: None,
        prompt_snapshot_id: None,
        stream: None,
    };

    let resp = synth.complete(request).await?;
    println!("Output: {:?}", resp.output);
    Ok(())
}

Project details


Release history Release notifications | RSS feed

This version

0.7.9

Download files

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

Source Distribution

synth_ai-0.7.9.tar.gz (647.1 kB view details)

Uploaded Source

Built Distribution

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

synth_ai-0.7.9-cp313-cp313-macosx_11_0_arm64.whl (10.2 MB view details)

Uploaded CPython 3.13macOS 11.0+ ARM64

File details

Details for the file synth_ai-0.7.9.tar.gz.

File metadata

  • Download URL: synth_ai-0.7.9.tar.gz
  • Upload date:
  • Size: 647.1 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.13.7

File hashes

Hashes for synth_ai-0.7.9.tar.gz
Algorithm Hash digest
SHA256 c3b5728e2312ddc907df6e14da79e0b18d5440bf83e11e10ccf7650d00870a21
MD5 e3f53d157ac5dc1462d7143e71365f4a
BLAKE2b-256 0b02d4989655dcbbb255b6f53eb8c637987fbca4840247ee2c07854f32e2878a

See more details on using hashes here.

File details

Details for the file synth_ai-0.7.9-cp313-cp313-macosx_11_0_arm64.whl.

File metadata

File hashes

Hashes for synth_ai-0.7.9-cp313-cp313-macosx_11_0_arm64.whl
Algorithm Hash digest
SHA256 13d798daa3958e65a17f55b03a7c385d6b92fe622a285419e69cbd3792649081
MD5 0de4748b4d9d29dc60db7c054ff8fc44
BLAKE2b-256 06960bc04db30fdefc628ebf4028ea13bd96954d329b4abd3c2c7753c8175af6

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 Pingdom Monitoring Sentry Error logging StatusPage Status page