OpenAI Python SDK:安裝、設定與實務整合

OpenAI Python SDK:安裝、設定與實務整合

OpenAI Python SDK(PyPI 上的 openai)是 OpenAI API 的官方 Python 客戶端。它會處理驗證、請求格式、回應解析、串流與重試機制,讓您不必自行實作這些功能。本指南涵蓋安裝、核心 OpenAI 類別、聊天補全、串流、函式呼叫、非同步用法、JavaScript SDK 對應版本、Azure OpenAI 整合,以及如何將同一 SDK 指向 Novita AI 的 OpenAI 相容端點,以使用開放權重模型而無需改寫程式碼。

安裝 OpenAI Python 套件

需要 Python 3.8 或更新版本:

pip install openai

在開發環境中,請將其加入您的 requirements.txtpyproject.toml

pip install openai>=1.0.0

1.x 版(於 2023 年底發布)與 0.x API 的介面有顯著差異。如果您正在遷移舊版程式碼,請注意 openai.ChatCompletion.create() 已不復存在,請改用 client.chat.completions.create()

將您的 API 金鑰設為環境變數,請勿將其寫入原始碼:

export OPENAI_API_KEY="sk-..."

OpenAI 客戶端類別

OpenAI 類別是主要的進入點。它預設會從 OPENAI_API_KEY 環境變數讀取 API 金鑰,或者您也可以明確傳入:

import os
from openai import OpenAI

client = OpenAI(
    api_key=os.environ["OPENAI_API_KEY"],
)

客戶端會管理連線池、重試機制與逾時設定。您應該建立一個實例並在整個應用程式中重複使用,而非每次請求都建立新實例。

初始化時可設定的選項:

參數 預設值 說明
api_key OPENAI_API_KEY 環境變數 驗證憑證
base_url https://api.openai.com/v1 覆寫用於代理或相容 API 的端點
timeout 600 秒 每次請求的逾時時間
max_retries 2 遇到速率限制錯誤時自動重試
http_client None 自訂 httpx 客戶端,用於代理或憑證設定

聊天補全:基本請求

聊天補全是最常見的使用情境。messages 列表的格式與 API 相同:一系列代表對話的角色/內容字典:

import os
from openai import OpenAI

client = OpenAI(api_key=os.environ["OPENAI_API_KEY"])

response = client.chat.completions.create(
    model="gpt-4o",
    messages=[
        {"role": "system", "content": "你是一位樂於助人的程式碼助手。"},
        {"role": "user", "content": "Python 中的 list 和 tuple 有什麼不同?"},
    ],
    temperature=0.3,
    max_tokens=512,
)

print(response.choices[0].message.content)

回應是一個 ChatCompletion 物件。關鍵欄位:

  • response.choices[0].message.content — 文字回應
  • response.usage.prompt_tokens — 輸入消耗的 token 數
  • response.usage.completion_tokens — 輸出消耗的 token 數
  • response.model — 處理請求的模型版本

在正式環境中,請傳入 max_tokens 以避免產生失控的生成成本,並在需要確定性輸出時使用 temperature=0 或較低的值。

串流回應

對於需要即時顯示 token 的互動式介面,請使用 stream=True

import os
from openai import OpenAI

client = OpenAI(api_key=os.environ["OPENAI_API_KEY"])

with client.chat.completions.stream(
    model="gpt-4o",
    messages=[
        {"role": "user", "content": "用白話解釋 Python 的生成器。"},
    ],
) as stream:
    for text in stream.text_stream:
        print(text, end="", flush=True)

使用上下文管理器(with 陳述式)可確保迭代後連線正確關閉。.text_stream 屬性會產生純文字字串;.stream 則會產生原始事件物件,如果您需要每個 chunk 的使用統計等中繼資料。

如果您需要不透過上下文管理器的串流:

stream = client.chat.completions.create(
    model="gpt-4o",
    messages=[{"role": "user", "content": "列出 5 個 Python 最佳實務。"}],
    stream=True,
)
for chunk in stream:
    delta = chunk.choices[0].delta
    if delta.content:
        print(delta.content, end="", flush=True)

函式呼叫

函式呼叫可讓模型決定何時呼叫函式並回傳 JSON 參數物件。您的應用程式執行該函式,然後將結果送回,讓模型將其納入回應:

import os
import json
from openai import OpenAI

client = OpenAI(api_key=os.environ["OPENAI_API_KEY"])

tools = [
    {
        "type": "function",
        "function": {
            "name": "get_weather",
            "description": "回傳指定城市的天氣。",
            "parameters": {
                "type": "object",
                "properties": {
                    "city": {
                        "type": "string",
                        "description": "城市名稱,例如 '台北'",
                    }
                },
                "required": ["city"],
            },
        },
    }
]

messages = [{"role": "user", "content": "東京的天氣如何?"}]

response = client.chat.completions.create(
    model="gpt-4o",
    messages=messages,
    tools=tools,
    tool_choice="auto",
)

choice = response.choices[0]
if choice.finish_reason == "tool_calls":
    tool_call = choice.message.tool_calls[0]
    args = json.loads(tool_call.function.arguments)
    # 在此執行您的實際函式
    result = {"city": args["city"], "temperature": "18°C", "condition": "多雲"}

    messages.append(choice.message)
    messages.append({
        "role": "tool",
        "tool_call_id": tool_call.id,
        "content": json.dumps(result),
    })

    final = client.chat.completions.create(
        model="gpt-4o",
        messages=messages,
    )
    print(final.choices[0].message.content)

當模型想要呼叫函式時,會回傳 finish_reason="tool_calls"。您執行函式、將結果加入訊息列表,然後發出第二次請求。這個兩步驟迴圈是標準模式。

非同步用法:使用 AsyncOpenAI

對於 FastAPI、基於 asyncio 的服務,或任何受益於非阻塞 I/O 的程式碼,請使用 AsyncOpenAI

import os
import asyncio
from openai import AsyncOpenAI

client = AsyncOpenAI(api_key=os.environ["OPENAI_API_KEY"])

async def get_response(prompt: str) -> str:
    response = await client.chat.completions.create(
        model="gpt-4o-mini",
        messages=[{"role": "user", "content": prompt}],
        max_tokens=256,
    )
    return response.choices[0].message.content

async def main():
    result = await get_response("Python 中的 asyncio 是什麼?")
    print(result)

asyncio.run(main())

AsyncOpenAI 是可直接替代的非同步版本;所有方法都是可等待的。這比使用 asyncio.to_thread 包裝同步客戶端更為理想。

OpenAI JavaScript SDK

OpenAI JavaScript SDK(npm 上的 openai)與 Python 介面非常相似。安裝方式:

npm install openai

Node.js 中的基本聊天補全:

import OpenAI from "openai";

const client = new OpenAI({
  apiKey: process.env.OPENAI_API_KEY,
});

const response = await client.chat.completions.create({
  model: "gpt-4o",
  messages: [
    { role: "system", content: "你是一位樂於助人的助手。" },
    { role: "user", content: "解釋 JavaScript 中 promise 與 async/await 的差異。" },
  ],
  max_tokens: 512,
});

console.log(response.choices[0].message.content);

JavaScript 中的串流:

import OpenAI from "openai";

const client = new OpenAI({ apiKey: process.env.OPENAI_API_KEY });

const stream = await client.chat.completions.stream({
  model: "gpt-4o",
  messages: [{ role: "user", content: "用三句話總結 fetch API。" }],
});

for await (const chunk of stream) {
  const text = chunk.choices[0]?.delta?.content ?? "";
  process.stdout.write(text);
}

JavaScript SDK 支援 Node.js 18+、Deno 以及瀏覽器環境(但將 API 金鑰暴露在瀏覽器中不安全,請改用伺服器端代理)。指向相容 API 的 base_url 選項用法與 Python 完全相同。

Azure OpenAI Python 整合

如果您使用的是 Azure OpenAI 服務而非直接使用 OpenAI API,請從同一個套件使用 AzureOpenAI 客戶端:

import os
from openai import AzureOpenAI

client = AzureOpenAI(
    api_key=os.environ["AZURE_OPENAI_API_KEY"],
    azure_endpoint=os.environ["AZURE_OPENAI_ENDPOINT"],
    api_version="2024-02-01",
)

response = client.chat.completions.create(
    model="gpt-4o",  # 您在 Azure 中的部署名稱
    messages=[
        {"role": "user", "content": "如何使用 Python 搭配 Azure OpenAI?"},
    ],
)

print(response.choices[0].message.content)

Azure 所需的環境變數:

  • AZURE_OPENAI_API_KEY:您的 Azure 資源 API 金鑰
  • AZURE_OPENAI_ENDPOINT:您的端點 URL,例如 https://your-resource.openai.azure.com/

在 Azure OpenAI 中,model 參數指的是您的 部署名稱,而非底層模型名稱。請將 api_version 設定為您的部署所使用的 Azure API 版本(請參閱 Azure OpenAI 文件 以了解目前支援的版本)。

若要使用 Microsoft Entra ID(先前為 Azure AD)進行驗證而非 API 金鑰:

from azure.identity import DefaultAzureCredential, get_bearer_token_provider
from openai import AzureOpenAI

token_provider = get_bearer_token_provider(
    DefaultAzureCredential(),
    "https://cognitiveservices.azure.com/.default",
)

client = AzureOpenAI(
    azure_ad_token_provider=token_provider,
    azure_endpoint=os.environ["AZURE_OPENAI_ENDPOINT"],
    api_version="2024-02-01",
)

切換至 Novita AI 的 OpenAI 相容 API

Novita AI 在 https://api.novita.ai/openai 提供 OpenAI 相容端點。您可以使用相同的 openai Python 或 JavaScript SDK,只需更改 base_urlapi_key 即可。無需其他程式碼變更:

import os
from openai import OpenAI

client = OpenAI(
    api_key=os.environ["NOVITA_API_KEY"],
    base_url="https://api.novita.ai/openai",
)

response = client.chat.completions.create(
    model="deepseek/deepseek-v4-pro",
    messages=[
        {"role": "system", "content": "你是一位樂於助人的程式碼助手。"},
        {"role": "user", "content": "解釋 Python 的 GIL 如何影響多執行緒。"},
    ],
    temperature=0.3,
    max_tokens=512,
)

print(response.choices[0].message.content)

novita.ai/settings/key-management 獲取 Novita AI API 金鑰。同一個金鑰可適用於所有 Novita AI API,包括 OpenAI 相容端點。

使用 Novita AI 的 JavaScript:

import OpenAI from "openai";

const client = new OpenAI({
  apiKey: process.env.NOVITA_API_KEY,
  baseURL: "https://api.novita.ai/openai",
});

const response = await client.chat.completions.create({
  model: "qwen/qwen3-coder-30b-a3b-instruct",
  messages: [{ role: "user", content: "寫一份 Python 型別註解速查表。" }],
  max_tokens: 600,
});

console.log(response.choices[0].message.content);

其餘所有功能——串流、函式呼叫、非同步用法、response_formattemperaturemax_tokens——運作方式完全相同。Novita AI 端點遵循 OpenAI 聊天補全 API 規格。

透過 Novita AI 使用開源模型

切換 base_url 即可存取一系列開放權重模型,這些模型在特定任務上已能與封閉源碼前沿模型競爭。對於程式碼工作流程、函式呼叫以及長上下文推理,實務上的差距已大幅縮小。

透過 Novita AI 的 OpenAI 相容端點可使用的模型,值得評估的包括:

DeepSeek V4 Prodeepseek/deepseek-v4-pro):一個大型 MoE 模型(MIT 近似授權),在 SWE-Bench 和函式呼叫基準測試中名列前茅。非常適合用於程式碼代理、程式碼審查,以及原本會使用 GPT-4o 或 Claude Opus 的多步驟工具任務。

Qwen3 Coder 30B A3B Instructqwen/qwen3-coder-30b-a3b-instruct):來自 Qwen Coder 系列的 30B 稀疏 MoE 模型,專為程式碼生成、錯誤分類和拉取請求審查而最佳化。在 Novita AI 上,每 100 萬輸入 token 費用為 0.07 美元,每 100 萬輸出 token 費用為 0.27 美元,對於日常程式碼輔助來說,比大多數封閉 API 便宜得多。

Qwen3 235B A22B Instructqwen/qwen3-235b-a22b-instruct-2507):一個大型 MoE 模型(Apache 2.0),具有強大的推理和多語言程式碼能力。適合目前使用 GPT-4o 進行創意或複雜回應,但希望在大量使用時降低每 token 成本的任務。

Novita AI 上的模型 ID 格式為 provider/model-name。您可以直接將其傳入 SDK 的 model 參數。

對於希望混合使用開放與封閉模型的團隊,一個直接的路由模式:

def get_client(use_novita: bool = False) -> OpenAI:
    if use_novita:
        return OpenAI(
            api_key=os.environ["NOVITA_API_KEY"],
            base_url="https://api.novita.ai/openai",
        )
    return OpenAI(api_key=os.environ["OPENAI_API_KEY"])

# 對成本敏感、高流量的程式碼任務使用開放權重模型
coding_client = get_client(use_novita=True)

# 在封閉模型確實表現更好的任務上使用 OpenAI
openai_client = get_client(use_novita=False)

這讓您可以進行 A/B 測試輸出品質、基準測試每項任務的效能,並將流量轉移至更便宜的模型,而無需觸及請求邏輯。

常見問題

OpenAI Python 套件名稱是什麼?

PyPI 上的套件名稱是 openai。使用 pip install openai 安裝。

OpenAI 客戶端 Python 類別的名稱是什麼?

同步用法的主要類別是 OpenAI,非同步用法是 AsyncOpenAI。兩者都位於 openai 模組中:from openai import OpenAI, AsyncOpenAI

OpenAI Python SDK 是否支援串流?

是的。使用 client.chat.completions.stream() 作為上下文管理器,或將 stream=True 傳遞給 client.chat.completions.create() 並迭代 chunk。

OpenAI JavaScript SDK 套件名稱是什麼?

npm 套件是 openai。使用 npm install openai 安裝。類別和方法簽章與 Python SDK 幾乎相同。

如何使用 Python 搭配 Azure OpenAI?

使用 openai 套件中的 AzureOpenAI 類別。傳入 azure_endpointapi_keyapi_versionmodel 參數指的是您的 Azure 部署名稱,而非底層模型名稱。

我可以將 OpenAI Python SDK 與其他提供者一起使用嗎?

可以。任何實作 OpenAI 聊天補全 API 格式的提供者,都可以透過在客戶端上設定 base_url 來使用。Novita AI 在 https://api.novita.ai/openai 的端點就是一個例子;完整的 SDK 功能——串流、函式呼叫、非同步——無需修改即可運作。

如何確保我的 OpenAI API 金鑰安全?

將金鑰儲存在環境變數(OPENAI_API_KEY)中,並使用 os.environ["OPENAI_API_KEY"] 讀取。切勿將其放入原始碼、公開儲存庫、建置日誌或客戶端 JavaScript 中。

推薦文章