DEV Community

Cover image for One key, two ecosystems: routing between DeepSeek/Kimi/Qwen and Claude/GPT/Gemini by task
Seven
Seven

Posted on

One key, two ecosystems: routing between DeepSeek/Kimi/Qwen and Claude/GPT/Gemini by task

Picking a single model family for an app is a false choice. Some Chinese-origin models are strong and cost-efficient at certain tasks; some Western models lead at others. If you're building outside mainland China, the practical move isn't to bet on one — it's to route each request to the right one, and make switching a one-line change instead of a new integration.

This guide shows how to do that through a single OpenAI-compatible endpoint, so DeepSeek, Kimi, Qwen, Claude, GPT and Gemini all sit behind one key and one bill — and how to choose between them per task without guessing.

Disclosure & scope: I work on daoxe, an OpenAI-compatible gateway. It is not available in mainland China — this article is written for developers outside it (overseas devs, overseas Chinese, and users in Russia, Brazil, Vietnam, Turkey and elsewhere) who want access to both ecosystems in one place. Everything here is standard OpenAI-compatible config; point it at any endpoint that carries the models you want.


Why route at all

Three reasons a single-model app leaves value on the table:

  1. Task fit. Models have uneven strengths — reasoning, long-context, code, multilingual, structured output, vision. The best model for summarizing a 200-page PDF isn't necessarily the best for a tricky refactor.
  2. Cost. For high-volume, low-stakes calls (classification, extraction, routing itself), a cheaper model is often good enough, and the savings compound. Reserve the expensive model for the calls that need it.
  3. Resilience. If one provider is rate-limited or degraded, being able to fail over to another family keeps you shipping.

The blocker has always been integration cost: different SDKs, keys, billing, and response quirks per vendor. An OpenAI-compatible endpoint removes it — model choice becomes a string.


The mechanism: model choice is a string

Every call uses the same shape; only the model field changes:

curl https://daoxe.com/v1/chat/completions \
  -H "Authorization: Bearer $DAOXE_API_KEY" -H "Content-Type: application/json" \
  -d '{"model":"<MODEL_ID>","messages":[{"role":"user","content":"..."}]}'
Enter fullscreen mode Exit fullscreen mode

List what your key can actually call — the authoritative, account-scoped source is:

curl https://daoxe.com/v1/models -H "Authorization: Bearer $DAOXE_API_KEY"
Enter fullscreen mode Exit fullscreen mode

Use those exact ids. Families you'll typically see include Chinese-origin ones (DeepSeek, Kimi, Qwen, and others) and Western ones (Claude, GPT, Gemini). Don't hardcode ids from this post — they drift; read them from /v1/models.


A simple task-based router (Python)

You don't need a framework. A dict from task → model id gets you 90% of the value:

import os, httpx

BASE = "https://daoxe.com/v1"
KEY = os.environ["DAOXE_API_KEY"]

# Map task types to EXACT ids from GET /v1/models (examples — replace with yours).
ROUTES = {
    "cheap_bulk":   "deepseek-...",     # high-volume extraction/classification
    "long_context": "kimi-k2.5",        # very long inputs
    "reasoning":    "claude-sonnet-4-6",# hard multi-step problems
    "code":         "gpt-5.5",          # tricky refactors
    "default":      "claude-haiku-...", # fast, inexpensive fallback
}

def ask(task: str, prompt: str) -> str:
    model = ROUTES.get(task, ROUTES["default"])
    r = httpx.post(f"{BASE}/chat/completions",
        headers={"Authorization": f"Bearer {KEY}"},
        json={"model": model, "temperature": 0,
              "messages": [{"role": "user", "content": prompt}]}, timeout=60)
    r.raise_for_status()
    return r.json()["choices"][0]["message"]["content"]

print(ask("cheap_bulk", "Extract the invoice total as JSON."))
print(ask("reasoning",  "Prove or disprove: ..."))
Enter fullscreen mode Exit fullscreen mode

Because it's one endpoint and one key, adding a route is adding a dict entry — no new SDK, no new credential. Add a try/except that falls back to another family on error and you've got cheap resilience too.


How to choose the route (without vibes)

Don't route on reputation — route on evidence for your workload:

  • Build a tiny eval set of real prompts per task type with known-good answers.
  • Run each candidate model through it, and record accuracy alongside latency (p50/p95) and token cost. (A small harness does this; I wrote up a reproducible gateway benchmark separately.)
  • Pick the cheapest model that clears your quality bar for each task — not the most expensive one you can afford.
  • Re-check periodically. New model versions ship constantly; a route that was optimal last quarter may not be now.

On price specifically: I'm not going to quote numbers here because they change. Check the provider's pricing page and put real $/1M figures next to your latency and accuracy — the right route is a three-way trade-off, not a single-axis choice.


Don't forget to verify what you're getting

Routing across families makes verification more important, not less: with several models behind one endpoint, you want to confirm each id actually serves what it claims and isn't being silently swapped or truncated. Test behavior, not the model's self-report — a tokenizer fingerprint, a capability-floor check, and a long-context needle test catch the common cheats. (There are open-source probes for this; I covered the method in a separate post.) A good endpoint is fine with you running these against it.


Honest positioning

A few things to be straight about:

  • This is for outside mainland China. daoxe doesn't serve mainland China; the audience here is overseas developers and users in regions where getting both ecosystems in one place — and paying for it — is otherwise fiddly.
  • "Chinese vs Western" is about model origin, not a quality ranking. Route on measured task fit and cost, not on where a model came from.
  • One key is a convenience, not magic. It removes integration and billing friction; it doesn't make a small model into a big one. Match the model to the task.

daoxe is the endpoint I use for this — OpenAI-compatible at https://daoxe.com/v1, native Anthropic Messages for Claude-native tools, one key across many models (Chinese-origin and Western), one bill, and a design meant to be verified. See the pricing page for current models and prices; use GET /v1/models for what your key can call.


TL;DR

  • Don't pick one family — route each task to the best/cheapest model.
  • One OpenAI-compatible endpoint makes model choice a string: one key, one bill, no per-vendor SDKs.
  • Choose routes on a small eval set (accuracy + p50/p95 + $/1M), not reputation; re-check as versions ship.
  • Verify each model behaviorally, and remember this is for use outside mainland China.

Top comments (0)