Bridge by Wekoya / Docs / Improve

Switch to a cheaper model safely

Updated

A cheaper model can often do your job as well as the one you use now, but your instructions were written for the old one. Bridge tests the cheaper model on your own examples, rewrites the instructions until it matches your current results, and tells you plainly whether to switch. In the console this is AI tasks; the API calls them workloads.

1. Say what a good answer is, and add examples

Describe the answer's shape and which fields must be right. Then add real messages your app gets. You don't have to supply the right answers: Bridge can take them from your current model. About 30% of examples are kept for a final check the optimiser never sees.

curl https://wekoya-api.wekoya.tech/v1/workloads \
  -H "Authorization: Bearer $WEKOYA_API_KEY" -H "Content-Type: application/json" \
  -d '{
    "name": "WhatsApp orders",
    "monthly_volume": 200000,
    "contract": {
      "output": "json",
      "schema": { "type": "object", "required": ["phone", "items"], "properties": {
        "phone": { "type": "string" },
        "items": { "type": "array", "items": { "type": "object", "properties": {
          "sku": { "type": "string" }, "quantity": { "type": "integer" } } } } } },
      "fields": [
        { "path": "phone", "match": "exact", "critical": true },
        { "path": "items[*].sku", "match": "set", "critical": true }
      ]
    }
  }'

# Then your examples, one per line. "expected" (the right answer) is optional.
curl https://wekoya-api.wekoya.tech/v1/workloads/$TASK/cases \
  -H "Authorization: Bearer $WEKOYA_API_KEY" -H "Content-Type: application/x-ndjson" \
  --data-binary @examples.jsonl
{"id": "order-1", "slice": "pidgin", "messages": [{"role": "user", "content": "Abeg send 2 carton indomie. 08031234567, I dey Yaba"}]}
{"id": "order-2", "messages": [{"role": "user", "content": "..."}], "expected": {"phone": "+2348031234567", "items": [{"sku": "IND-CTN", "quantity": 2}]}}

2. Find a cheaper model

Bridge tries the cheaper model with your instructions as they are, with worked examples, with similar past examples, and with your current model's habits written down (such as "zone is always 'the mainland'"). Then a strong model reads its mistakes and rewrites the instructions. A rewrite is kept only if it does better without breaking what already worked.

# Your current setup
curl https://wekoya-api.wekoya.tech/v1/workloads/$TASK/configs \
  -H "Authorization: Bearer $WEKOYA_API_KEY" -H "Content-Type: application/json" \
  -d '{ "label": "Current", "spec": { "model": "gemini-3.8-flash", "instructions": "You process WhatsApp orders..." } }'

# Find a cheaper model (POST .../runs/estimate first tells you the likely cost)
curl https://wekoya-api.wekoya.tech/v1/workloads/$TASK/runs \
  -H "Authorization: Bearer $WEKOYA_API_KEY" -H "Content-Type: application/json" \
  -d '{ "kind": "adapt", "source": { "config_id": "'$SETUP'" },
        "target_models": ["gemini-2.5-flash-lite"], "budget": 2000 }'

The result says switch, switch_with_fallback (your current model answers when the cheaper one's answer is unusable), keep_current, or need_more_cases with how many more examples would settle it. It shows the cost per answer and per month, and every answer that failed and why. Mark answers right or wrong: your verdicts replace the grader's and teach it your standard.

3. Go live under a name

Your app calls cfg:<name> like any model. Bridge checks each answer and fixes broken JSON. If an answer is still unusable, your current model (the backup) answers instead. You can try a new version on a share of traffic and undo with one click, without changing your code.

curl https://wekoya-api.wekoya.tech/v1/workloads/$TASK/deployments \
  -H "Authorization: Bearer $WEKOYA_API_KEY" -H "Content-Type: application/json" \
  -d '{ "name": "orders", "config_id": "'$CHEAPER_SETUP'" }'

# Your app uses the name like any model. Tools and streaming work as usual.
reply = client.chat.completions.create(
    model="cfg:orders",
    messages=[{"role": "user", "content": whatsapp_message}],
)

Why not train a small model on the big one's answers? That needs dedicated capacity per customer, costs far more than the saving for most workloads, and has to be retrained whenever the task changes. Learning from similar examples and live traffic gets most of the benefit with no training.