First Call¶
The smallest possible round-trip to an LLM: send one message, print the reply. Shown for all three providers we cover — all of them use the same openai client.
Prerequisites¶
- A key from at least one provider. If you don't have one, pick from the Get an API Key page.
-
The key stored in your environment. We'll assume a
.envfile at the project root with whichever you have: -
The
llm-tutorialconda env activated:
The openai SDK is already installed as a project dependency. DeepSeek and Qwen reuse the openai SDK — only base_url and model change.
Hello world¶
SJTU's OpenAI-compatible gateway at models.sjtu.edu.cn exposes deepseek-chat and other models (campus-network / VPN only). Same code shape as DeepSeek — just swap the key env var and the base URL.
import os
from dotenv import load_dotenv
from openai import OpenAI
load_dotenv()
client = OpenAI(api_key=os.environ["OPENAI_API_KEY"])
resp = client.chat.completions.create(
model="gpt-4o-mini",
messages=[
{"role": "user", "content": "Say hi in one short sentence."},
],
)
print(resp.choices[0].message.content)
Expected output:
DeepSeek exposes an OpenAI-compatible endpoint, so the openai client works as-is — just override base_url and pick a DeepSeek model.
import os
from dotenv import load_dotenv
from openai import OpenAI
load_dotenv()
client = OpenAI(
api_key=os.environ["DEEPSEEK_API_KEY"],
base_url="https://api.deepseek.com",
)
resp = client.chat.completions.create(
model="deepseek-chat",
messages=[
{"role": "user", "content": "Say hi in one short sentence."},
],
)
print(resp.choices[0].message.content)
Expected output:
Use model="deepseek-reasoner" for the reasoning model; the response will additionally carry resp.choices[0].message.reasoning_content.
Qwen on Alibaba's DashScope also exposes an OpenAI-compatible endpoint.
import os
from dotenv import load_dotenv
from openai import OpenAI
load_dotenv()
client = OpenAI(
api_key=os.environ["DASHSCOPE_API_KEY"],
base_url="https://dashscope.aliyuncs.com/compatible-mode/v1",
)
resp = client.chat.completions.create(
model="qwen-plus",
messages=[
{"role": "user", "content": "Say hi in one short sentence."},
],
)
print(resp.choices[0].message.content)
Expected output:
Response shape¶
Most fields you'll touch:
resp.choices[0].message.content # the assistant's text
resp.choices[0].finish_reason # "stop", "length", "tool_calls", ...
resp.model # resolved model ID
resp.usage.prompt_tokens # input tokens billed
resp.usage.completion_tokens # output tokens billed
resp.usage.total_tokens
Adding a system prompt¶
Prepend a message with role: "system":
resp = client.chat.completions.create(
model="gpt-4o-mini", # or "deepseek-chat", "qwen-plus"
messages=[
{"role": "system", "content": "You are a concise assistant. Answer in one sentence."},
{"role": "user", "content": "What is a PID controller?"},
],
)
Troubleshooting¶
AuthenticationError/401: your key is wrong, revoked, or scoped to a different workspace / region.- OpenAI
insufficient_quota: the key has no credits; top up at Billing. ConnectionError: check your network / proxy; some provider endpoints are region-blocked.
Next¶
- Unified Client — wrap all three providers behind one function so you can swap with a single line.
- Streaming — return tokens as they're generated.
- Tool Use — let the model call your Python functions.