繁中 ▾
取得 API 金鑰

Python 中的 Ollama API 與託管替代方案

Python 中的 Ollama API 約需十行程式碼,且相同的程式碼結構也適用於託管端點。本文將展示兩者,並說明何時選擇哪一種。

更新於

重點摘要

  • Ollama 監聽 11434 連接埠,提供原生 API 以及 OpenAI 風格的 /v1 端點。
  • ollama 套件、一般的 requests 和 OpenAI SDK 均可使用;OpenAI SDK 的移植性最高。
  • 切換到託管 API 意味著更改 base URL、金鑰和模型名稱。
  • 本機最適合離線工作和固定硬體;沒有 GPU 時託管更簡單。
一台透過發光電纜連結到雲端伺服器的電腦,代表本機和託管的 LLM API

簡短版本

如果你搜尋 ollama api python,通常想要其中三件事之一:呼叫在你機器上執行的模型、從中串流輸出 token,或讓相同的腳本在其他地方運作。Ollama 提供所有這些功能。它會在本機伺服器上運行,預設位於 http://localhost:11434,你可以使用 ollama Python 套件、純 HTTP 或指向其 /v1 路徑的任何 OpenAI 用戶端與之通訊。

關鍵在於模型必須在你的硬體上執行。沒有足夠 GPU 的筆記型電腦在處理較大的模型時會很慢,而沒有 GPU 的伺服器則不太適合。在這種情況下,使用託管的 OpenAI 相容 API 是更簡單的選擇,而且由於請求格式相同,切換只需修改三行設定。以下兩種路徑都有涵蓋,並提供可直接貼上的程式碼。

使用 ollama 套件呼叫本機模型

安裝 Ollama、拉取模型,並確保伺服器正在運行。然後安裝 Python 客戶端:

pip install ollama
ollama pull llama3.2

基本的聊天呼叫如下所示。模型名稱是你拉取的任意模型名稱;llama3.2 僅為範例。

import ollama

response = ollama.chat(
    model="llama3.2",
    messages=[{"role": "user", "content": "Explain DNS in two sentences."}],
)
print(response["message"]["content"])

串流輸出

傳入 stream=True 會取得區塊的迭代器,而非單一回覆。每個區塊包含 message.content 中的一段答案。

import ollama

stream = ollama.chat(
    model="llama3.2",
    messages=[{"role": "user", "content": "Write a haiku about servers."}],
    stream=True,
)
for chunk in stream:
    print(chunk["message"]["content"], end="", flush=True)
print()

將客戶端指向另一台機器

如果 Ollama 在不同的主機上運行,請建立帶有明確地址的用戶端,例如 ollama.Client(host="http://192.168.1.20:11434")。預設情況下,伺服器僅在本機機器上監聽,因此遠端存取需要在伺服器端進行明確設定。不要將其暴露在公共網際網路中,除非前面有代理伺服器並進行身份驗證,因為原生 API 本身沒有金鑰檢查。

使用 requests 的純 HTTP

你根本不需要該套件。原生聊天端點是 POST /api/chat。串流輸出是預設選項,且串流是換行分隔的 JSON,而非 SSE。如果你想要單一物件,請設定 "stream": false。

import requests

r = requests.post(
    "http://localhost:11434/api/chat",
    json={
        "model": "llama3.2",
        "messages": [{"role": "user", "content": "Name three HTTP status codes."}],
        "stream": False,
    },
    timeout=120,
)
r.raise_for_status()
print(r.json()["message"]["content"])

設定寬鬆的超時時間。拉取後的第一個請求必須將模型載入記憶體,這可能需要比後續請求長得多的時間。

手動讀取串流輸出只需再多幾行程式碼。呼叫 requests.post(..., stream=True),遍歷 r.iter_lines(),跳過空行,然後對每一行執行 json.loads。每個物件包含回覆的一小部分,最後一個物件包含 "done": true。在小型容器中這很有用,因為你不想安裝其他套件,而且這樣可以清楚顯示程式庫為你做了什麼。託管 API 的串流方式不同,它是從 data: 開頭的 SSE 行,這也是讓 OpenAI SDK 在可攜式程式碼中為你解析串流的另一個理由。

在 Ollama 中使用 OpenAI SDK

Ollama 也在 /v1 下公開 OpenAI 風格的端點。這意味著官方的 openai 套件可以運作,大多數允許您設定自訂 base URL 的軟體也可以運作。SDK 需要金鑰,但本機 Ollama 會忽略它,因此任何字串都可以。

from openai import OpenAI

client = OpenAI(base_url="http://localhost:11434/v1", api_key="ollama")
resp = client.chat.completions.create(
    model="llama3.2",
    messages=[{"role": "user", "content": "Give me a one-line summary of TCP."}],
)
print(resp.choices[0].message.content)

這是最有用的形式,因為它將您的程式碼與伺服器解耦。相同的函式今天可以與本機模型通訊,明天可以與其他服務通訊,這是下一節的內容。

針對託管 API 的相同程式碼

此處的託管選項是一個託管單一模型 uncensored 的 OpenAI 相容 API,由獨立供應商運行,並針對合法成人用途進行調整,使其在回答時不會拒絕生成內容。僅支援文字。基本 URL 為 https://api.ollamaapi.cc/v1,你需透過 API 金鑰頁面 取得的 Bearer 金鑰進行驗證。

這是一個從環境變數讀取目標的版本,託管值作為預設值。要回到您的本機伺服器,只需匯出兩個變數,其他無需更改。

import os
from openai import OpenAI

client = OpenAI(
    base_url=os.getenv("LLM_BASE_URL", "https://api.ollamaapi.cc/v1"),
    api_key=os.getenv("LLM_API_KEY", "YOUR_API_KEY"),
)
MODEL = os.getenv("LLM_MODEL", "uncensored")

resp = client.chat.completions.create(
    model=MODEL,
    messages=[
        {"role": "system", "content": "You are a concise assistant."},
        {"role": "user", "content": "List four uses of a message queue."},
    ],
    temperature=0.7,
)
print(resp.choices[0].message.content)

對於本機運行,設定 LLM_BASE_URL=http://localhost:11434/v1、LLM_API_KEY=ollama 和 LLM_MODEL=llama3.2。快速入門 提供了相同的 curl 和 Node 設定。

託管端的串流輸出、JSON 模式和工具

託管端點支援透過 SSE 串流輸出、JSON 模式、工具呼叫,以及常見的採樣參數(temperature、top_p、stop、seed 和懲罰)。使用 SDK 進行串流輸出與你為任何 OpenAI 風格伺服器編寫的迴圈相同:

stream = client.chat.completions.create(
    model="uncensored",
    messages=[{"role": "user", "content": "Tell a two-paragraph story about a lighthouse."}],
    stream=True,
    stream_options={"include_usage": True},
)
for chunk in stream:
    if chunk.choices and chunk.choices[0].delta.content:
        print(chunk.choices[0].delta.content, end="", flush=True)

對於結構化輸出,設定 response_format={"type": "json_object"} 並在提示詞中說明您想要 JSON。無論如何,請始終在 try 區塊內進行解析;模型仍可能返回您未預期的內容。

與本機使用的一個程式碼差異在於限制。完整金鑰允許 8 個並行請求和每分鐘 300 個請求,串流請求會保留其槽位直到串流結束。如果您使用執行緒進行扇出,請將池限制為 8,並在 HTTP 429 時重試,若存在 Retry-After 標頭則依其指示等待。

保持對話持續

本機和託管的聊天端點在呼叫之間都不記住任何內容。伺服器僅看到您發送的訊息,因此聊天機器人是一個您追加並重新發送的列表。該模式對兩個目標都相同,這也是將 OpenAI 風格的客戶端作為預設值的另一個原因。

history = [{"role": "system", "content": "You are a helpful assistant."}]

def ask(text):
    history.append({"role": "user", "content": text})
    resp = client.chat.completions.create(model=MODEL, messages=history)
    answer = resp.choices[0].message.content
    history.append({"role": "assistant", "content": answer})
    return answer

print(ask("Pick a name for a hiking app."))
print(ask("Give me a tagline for it."))

兩個實用注意事項。首先,本機模型具有您設定的上下文長度,記憶體必須承載;如果歷史記錄超出該長度,較舊的對話輪次會被截斷或呼叫失敗,具體取決於設定。託管模型接受 100,000 個 token 的上下文視窗,包括完成部分,這遠超過大多數聊天所需,但長歷史記錄仍會在每次輪次中產生輸入 token 的成本。其次,一旦歷史記錄變長,請將最舊的輪次摘要為一條短訊息,而不是重新發送所有訊息。這可以保持任一後端的延遲和成本穩定。

禮貌地重試

在託管 API 上,臨時超載會返回帶有 Retry-After: 5 標頭的 HTTP 429。一個小型包裝器處理它:

import time
from openai import RateLimitError

def chat_with_retry(messages, tries=4):
    for attempt in range(tries):
        try:
            return client.chat.completions.create(model=MODEL, messages=messages)
        except RateLimitError:
            time.sleep(5 * (attempt + 1))
    raise RuntimeError("still rate limited")

本機 Ollama 不會對您進行速率限制,但當模型忙碌時會排隊請求,因此相同的包裝器在那裡也沒有害處。

本機或託管:如何決定

沒有哪種選擇在一般情況下更好。使用以下清單作為檢查清單。

  • 選擇本機 Ollama如果您需要離線工作、如果資料必須永不離開機器、如果您已經擁有具備能力的 GPU,或者如果您想快速嘗試許多不同的開放模型。
  • 選擇託管 API如果您沒有 GPU、如果您在小型 VPS 或 CI 中運行、如果多人或服務共用一個後端,或者如果您想要長上下文視窗而不必自行調整記憶體大小。託管模型接受最多 100,000 個 token 的提示詞加上補全。
  • 在開發期間混合兩者:在本機進行迭代,然後透過環境變數將生產環境指向託管 URL。

託管使用按 token 計費,每 1M 輸入 token 為 $0.15,每 1M 輸出 token 為 $0.50,從預付額度扣除。定價頁面 列出了儲值金額,新帳戶可以一鍵領取 $0.50 的免費試用額度,無需信用卡。提示詞不用於訓練。

你會遇到的錯誤

症狀可能原因修復方法
連接埠 11434 連接被拒絕Ollama 伺服器未運行啟動應用程式或執行 ollama serve
找不到模型模型從未拉取,或名稱有錯字執行 ollama list,然後 ollama pull 您使用的名稱
第一次呼叫超時模型仍在載入提高逾時時間,或發送暖機請求
託管 API 的驗證錯誤遺漏或錯誤的 Bearer 金鑰檢查 LLM_API_KEY與 Base URL
HTTP 429 且程式碼為 concurrency超過 8 個進行中的請求(試用金鑰為 2 個)降低執行緒數量
HTTP 429 且程式碼為 rate_limited超過每分鐘請求數限制退避並重試

託管端失敗或遭拒的請求不會計費,因此重試邏輯不會為失敗的請求產生費用。

問答

Ollama API 的預設地址是什麼?

本機 Ollama 伺服器在 http://localhost:11434 上監聽。原生端點位於 /api 下,例如 /api/chat,而 OpenAI 風格的端點則位於 /v1 下。

我可以在 Ollama 上使用 OpenAI Python SDK 嗎?

是的。將 base_url 設定為 http://localhost:11434/v1 並將任意字串作為 API 金鑰傳入。SDK 隨後會向你的本機模型發送標準的聊天完成請求。

我如何從 Ollama 切換到託管 API?

更改基礎 URL、金鑰與模型名稱。如果你的程式碼從環境變數讀取這些設定,則無需修改程式碼。

託管 API 在我的端沒有 GPU 的情況下可以運作嗎?

可以。模型在提供者端運行,因此你的腳本只需要網路連線與 Bearer 金鑰。你將從預付額度中按 token 付費。

只差一張表單,即可取得金鑰

建立帳號、複製金鑰、更改基礎 URL。這就是整個設定過程。

取得 API 金鑰