LiteLLM is an open-source proxy you self-host. Portkey adds enterprise compliance and guardrails. OpenRouter is the simplest managed option, and Helicone sits on top for observability. They solve routing, failover, and cost tracking across providers. qbash covers what comes after: versioned prompts called by slug, structured output that works the same across providers, a test file for prompt assertions, and a managed runtime for the code around them.
LiteLLM, Portkey, and OpenRouter normalize the API surface across providers and handle routing, retries, and fallback. Here is what that covers and where your code still carries the weight.
| Capability | What a gateway handles | What it leaves to you |
|---|---|---|
| Routing | Route by model, cost, or latency. One API for all providers | The logic around the call: parsing the response, branching on the result, chaining multiple calls |
| Failover | Retry with a fallback provider if the primary is down | No structured output. A fallback model still returns free-form text unless your code constrains it |
| Cost tracking | Per-request logging, spend by user or feature, budget caps | No prompt versioning. When cost spikes, you cannot see which prompt change caused it |
| Observability | Request logs, latency metrics, error rates (Helicone, LangSmith) | No prompt testing. You see that a call failed, but you cannot assert it would have worked before deploying |
| Model selection | Switch models by changing a config line | No per-step model selection in a multi-call pipeline. You route all traffic, not individual steps |
| Runtime | The gateway proxies the call | Your code, your server, your deployment. The gateway does not run your application |
A Task is an AI automation written in Python, hosted on a managed runtime. A developer writes the script; anyone runs it from a form. Integrations, model calls, version control, and logging are built in.
Model and provider agnostic.
A qbash Task is a Python script on a managed runtime. Each AI call in the script picks its own model from 110+ options across OpenAI, Anthropic, Gemini, Grok, and OpenRouter, so a classification step can use a fast model and a drafting step can use a capable one. The model is a field on the prompt. Swapping it is a one-field edit that never touches calling code. output_schema constrains the response to your JSON structure regardless of which provider runs it. Every prompt is a versioned object with revision history. When something changes, the diff shows what moved, and rollback is one click.
leads = qbash.integrations.pipedrive.list_deals(status="open") for lead in leads: # Cheap model for classification category = qbash.ai.run_prompt( slug="classify-lead", variables={"title": lead["title"], "notes": lead["notes"]}, ) if category["tier"] == "enterprise": # Capable model for the high-stakes draft brief = qbash.ai.run_prompt( slug="enterprise-brief", variables={"lead": lead, "category": category}, ) qbash.integrations.slack.create_message( "#enterprise", text=brief["summary"], )
Routing and failover get the calls through. After that, you need to know which version of a prompt is live, whether a change will break downstream parsing, and what comes back when you need JSON instead of free text.
Your code calls a prompt by slug. The prompt object holds the model, system message, output schema, and variables. Every edit creates a new version with a visible diff, and rollback is one click. A gateway sees the API request after it leaves your code but cannot track which prompt text, which model, or which schema generated it, because those live in your application layer.
Pass an output_schema on any prompt call and the response is constrained to JSON matching your schema, whether the call runs on OpenAI, Anthropic, or Gemini. The platform handles the provider-specific differences in structured output support. A gateway proxies the API call as-is. If the model returns malformed JSON or free text, that is what your code receives.
SCHEMA = {
"type": "object",
"properties": {
"company": {"type": "string"},
"revenue": {"type": "number"},
"sector": {"enum": ["tech", "finance", "health", "other"]},
},
}
result = qbash.ai.run_prompt(
slug="extract-company-data",
variables={"text": article},
output_schema=SCHEMA,
)Write assertions against prompt calls in a tests.py file. Tests run in a sandbox before deployment without billing a model call. Gateway observability tools like Helicone and LangSmith show you errors and latency after they hit production. A test file catches a prompt regression before deployment.
def test_classify_enterprise(): result = classify_lead( title="Acme Corp renewal", notes="500 seats, enterprise agreement", ) assert result["tier"] == "enterprise" def test_classify_smb(): result = classify_lead( title="Small shop trial", notes="5 seats, monthly plan", ) assert result["tier"] == "smb"
qbash handles what a gateway handles: one call across multiple providers, model selection per step, and failover. It also handles prompt versioning, structured output, testing, integrations, and a managed runtime. If you need a standalone routing proxy to sit in front of your own application code, LiteLLM or Portkey are the right tools. If you need the routing plus the prompt layer and the runtime, qbash covers both.
OpenAI (GPT, o-series), Anthropic (Claude), Google (Gemini), xAI (Grok), and OpenRouter-proxied models. Over 110 models across providers. Each prompt picks its own model.
Yes. The model is a field on the prompt. A classification step can use a fast, inexpensive model. A drafting step can use a capable one. Each step picks what fits.
LiteLLM is an open-source routing proxy you self-host. It normalizes API calls across providers and handles fallback. qbash is a platform that routes calls, manages prompts, constrains output, runs tests, and hosts the code. Different scope, and they can complement each other.
No. The runtime is proprietary. If you need a self-hosted routing proxy, LiteLLM and Portkey have open-source options. qbash is a managed platform, not a component you deploy.
Competitor details reviewed . Vendors change plans and features without notice, so check theirs before deciding.
Pick a model, write a prompt, and call it from code. The platform handles the provider bindings, the versioning, and the runtime.