Gisoo 的 OpenAI 相容端點如何連接 GPT、Claude、Gemini 和 DeepSeek(附 Python 與 Node.js 範例)
One OpenAI-compatible endpoint for GPT, Claude, Gemini and DeepSeek (Python + Node examples)
Gisoo 團隊成員 Aliasghar Ramin 示範以單一 OpenAI 相容端點連接 GPT、Claude、Gemini 和 DeepSeek,並提供 Python 與 Node.js 範例。
Most LLM projects end up talking to more than one vendor: GPT for one job, Claude for another, Gemini or DeepSeek when cost matters. Each vendor has its own SDK, key, billing account and rate limits. An OpenAI-compatible gateway removes most of that: one base URL, one key, and the model is just a string.
This post shows the pattern with Gisoo, the gateway we run (disclosure: I'm on the team). It exposes 680+ models behind the standard OpenAI API shape, so the official openai SDKs work unchanged. The same code works with any OpenAI-compatible gateway; only the base URL and key change.
1. List the models (no key needed)
curl -s https://gisoo.pro/api/v1/models | jq '.data | length'
# 682
curl -s https://gisoo.pro/api/v1/models \
| jq -r '.data[] | select(.type=="chat") | .id' | head
Each entry has an id, an owned_by vendor and a type (chat, image, audio, embedding, video, music). Directly connected models use their own name (gpt-5-mini, deepseek-flash, gemini-3.6-flash); the rest carry an openrouter/ prefix (openrouter/anthropic/claude-sonnet-4.5).
2. Python: same client, three vendors
from openai import OpenAI
client = OpenAI(
base_url="https://gisoo.pro/api/v1",
api_key="sk-gisoo-v1-...", # created in the Gisoo app
)
question = "Explain idempotency keys in two sentences."
for model in ["gpt-5-mini", "gemini-3.6-flash", "deepseek-flash"]:
r = client.chat.completions.create(
model=model,
messages=[{"role": "user", "content": question}],
)
print(f"--- {model}\n{r.choices[0].message.content}\n")
Switching vendor is a one-word change. That makes it cheap to A/B models on your own prompts instead of trusting benchmarks.
3. Node.js with streaming
import OpenAI from "openai";
const client = new OpenAI({
baseURL: "https://gisoo.pro/api/v1",
apiKey: process.env.GISOO_API_KEY,
});
const stream = await client.chat.completions.create({
model: "openrouter/anthropic/claude-sonnet-4.5",
messages: [{ role: "user", content: "Write a haiku about retries." }],
stream: true,
});
for await (const chunk of stream) {
process.stdout.write(chunk.choices[0]?.delta?.content ?? "");
}
Streaming is plain SSE in the OpenAI format, so existing UI code (Vercel AI SDK, LangChain, LiteLLM clients) keeps working.
4. A cheap fallback chain
Because every model sits behind the same endpoint, fallback is a loop, not three SDKs:
from openai import OpenAI, APIError
client = OpenAI(base_url="https://gisoo.pro/api/v1", api_key="sk-gisoo-v1-...")
def ask(messages, models=("deepseek-flash", "gemini-3.6-flash", "gpt-5-mini")):
last = None
for m in models:
try:
return m, client.chat.completions.create(model=m, messages=messages, timeout=60)
except APIError as e:
last = e # vendor busy or refused: try the next one
raise last
model, r = ask([{"role": "user", "content": "Summarise RFC 9110 in one line."}])
print(model, r.choices[0].message.content)
Order the list cheapest-first and you only pay for the expensive model when the cheap one fails.
5. Not only chat
The same key covers the other OpenAI endpoints:
| Task | Endpoint |
|---|---|
| Chat / tools / JSON output |
POST /chat/completions, POST /responses
|
| Embeddings | POST /embeddings |
| Images | POST /images/generations |
| Speech-to-text / text-to-speech |
POST /audio/transcriptions, POST /audio/speech
|
| Video | POST /videos |
There is also an Anthropic-compatible endpoint (https://gisoo.pro/api) for tools that only speak the Anthropic Messages API, and a remote MCP server (https://gisoo.pro/api/mcp) for Claude Code, Cursor and Cline.
Things to check with any gateway
- Data handling. Ask whether prompts are stored. (Gisoo's API stores metadata such as model, tokens and cost, not request or response bodies.)
- Pricing. Per-token prices should match or be close to the vendor's, and be visible per model before you call it.
- Model IDs. Pin exact IDs in production; aliases can move.
- Limits. Per-key rate limits (Gisoo's default is 60 requests/minute) and per-key spend caps are worth setting before you ship.
Why we built it
Gisoo started for developers and teams in Iran, who can't pay OpenAI, Anthropic or Google directly: credit is paid in local currency, and there is an Iran-optimised mirror at ir.gisoo.pro. The API itself is the standard one, so the code above runs from anywhere.
Docs (Persian, code is universal): https://gisoo.pro/docs. Questions and corrections are welcome in the comments.
來源:DEV Community · dev.to