ollama on mac - part 4 - 與應用整合(Python、OpenAI SDK、LangChain、Open WebUI、RAG)

很多人以為要用本地模型,就得把整個 app 打掉重寫、換掉所有 SDK。 於是遲遲不敢動手,繼續每個月付雲端 API 帳單。 事實上,對絕大多數既有專案而言,你只要改一行 base_url模型跑起來只是開始,把它接進你的應用,才是價值真正發生的地方。

在 Part 1 我們把 Ollama 裝起來、跑了第一個模型;Part 2 挑了適合的公開模型;Part 3 玩了 REST API 與 Modelfile。到這裡,你手上已經有一個穩定跑在 localhost:11434 的本機推論服務。但一個孤立的模型沒有意義——真正的價值在於它成為你程式碼裡的一個函式呼叫、你 IDE 裡的自動補全、你知識庫上的問答引擎。

這一篇,我們把「整合」這件事講透。


一、整合的三條路:你其實只需要選一條

先建立心智模型。不管你用什麼語言、什麼框架,把本機模型接進應用永遠是這張圖:

┌──────────────────────────────────────────────────────────────┐
│                        你的應用程式                             │
│         (Web 後端 / CLI 腳本 / 桌面 App / Jupyter)              │
└───────────────┬───────────────┬───────────────┬───────────────┘
                │               │               │
        ┌───────▼──────┐ ┌──────▼───────┐ ┌─────▼────────┐
        │  路線 A       │ │  路線 B       │ │  路線 C       │
        │  官方 SDK     │ │  OpenAI 相容  │ │  框架 / App   │
        │  ollama-py   │ │  /v1/...     │ │  LangChain   │
        │  ollama-js   │ │  base_url    │ │  Open WebUI  │
        └───────┬──────┘ └──────┬───────┘ └─────┬────────┘
                │               │               │
                └───────────────┼───────────────┘
                                │  HTTP
                       ┌────────▼─────────┐
                       │  Ollama 服務      │
                       │  localhost:11434 │
                       └────────┬─────────┘
                                │
                       ┌────────▼─────────┐
                       │  本機模型         │
                       │  llama3.2 / ...  │
                       └──────────────────┘

三條路各有適用場景:

  • 路線 A(官方 SDK):全新專案、想用 Ollama 特有功能(如原生 pspull、embed)、想要最乾淨的 API。
  • 路線 B(OpenAI 相容層):你已經有一個用 OpenAI SDK 寫好的專案,想直接遷移到本機。base_url 就好。
  • 路線 C(框架 / 現成 App):你要做複雜的 RAG / agent pipeline(用 LangChain),或只是想要一個聊天 UI(用 Open WebUI)、想在 IDE 裡寫程式(用 Continue)。

關鍵洞察:這三條路底層都是打 localhost:11434 的 HTTP。 選哪一條純粹取決於「你想要多少抽象層」,而不是能力差異。接下來逐一實戰。


二、官方 Python SDK 實戰

最直接的路。先裝:

1pip install ollama

(前提:Ollama 服務已在跑。Part 1 教過,ollama serve 或 macOS 上開著 app 即可。模型也要先 ollama pull llama3.2。)

基本 chat

1import ollama
2
3resp = ollama.chat(
4    model='llama3.2',
5    messages=[{'role': 'user', 'content': '用一句話解釋什麼是向量資料庫'}],
6)
7print(resp['message']['content'])

回傳是一個 dict,內容在 resp['message']['content']。多輪對話就把歷史訊息一路塞進 messages 陣列——Ollama 本身是無狀態的,對話歷史由你的應用維護

generate:單次文字生成

當你不需要「對話角色」概念,只想給一段 prompt 拿一段輸出(例如摘要、翻譯、分類),用 generate 更直覺:

1import ollama
2
3resp = ollama.generate(model='llama3.2', prompt='把這句翻成英文:今天天氣很好')
4print(resp['response'])   # 注意:generate 的結果在 'response' 鍵

streaming:逐字輸出(必學)

沒有 streaming 的本地 LLM 體驗很糟——使用者要盯著空白畫面等好幾秒。加上 stream=True,回傳就變成一個 generator,逐塊 (chunk) 吐出:

 1import ollama
 2
 3stream = ollama.chat(
 4    model='llama3.2',
 5    messages=[{'role': 'user', 'content': '寫一首關於秋天的短詩'}],
 6    stream=True,
 7)
 8
 9for chunk in stream:
10    print(chunk['message']['content'], end='', flush=True)
11print()  # 收尾換行

end='' 讓片段接在一起,flush=True 強制即時刷新到終端。這幾行是所有本地 CLI 工具的標準寫法,背下來。

管理類 API:list / ps / pull

SDK 不只做推論,還能管模型——這是相容層做不到的 Ollama 專屬能力:

 1import ollama
 2
 3# 列出本機已下載的模型
 4for m in ollama.list()['models']:
 5    print(m['model'])
 6
 7# 看目前載入到記憶體的模型(對應 CLI 的 ollama ps)
 8print(ollama.ps())
 9
10# 用程式碼下載模型(第一次跑腳本可自動備妥)
11ollama.pull('llama3.2')

ollama.pull() 在部署腳本或 Docker entrypoint 裡特別好用:啟動時自動確保模型存在,不用人工先 pull。

Client:連到自訂 host

預設連 localhost:11434。如果 Ollama 跑在別台機器(例如你有一台 Mac Studio 當推論伺服器),用 Client:

1from ollama import Client
2
3client = Client(host='http://192.168.1.50:11434')
4resp = client.chat(model='llama3.2', messages=[{'role': 'user', 'content': 'Hi'}])
5print(resp['message']['content'])

(要讓 Ollama 對外服務,得設 OLLAMA_HOST=0.0.0.0,這在 Part 5 進階部署會細講。)

AsyncClient:高併發場景

如果你在寫 async 的 Web 後端(FastAPI、aiohttp),用 AsyncClient 避免阻塞事件迴圈:

 1import asyncio
 2from ollama import AsyncClient
 3
 4async def main():
 5    client = AsyncClient()
 6    resp = await client.chat(
 7        model='llama3.2',
 8        messages=[{'role': 'user', 'content': '一句話介紹 async 的好處'}],
 9    )
10    print(resp['message']['content'])
11
12    # async streaming
13    async for chunk in await client.chat(
14        model='llama3.2',
15        messages=[{'role': 'user', 'content': '數到五'}],
16        stream=True,
17    ):
18        print(chunk['message']['content'], end='', flush=True)
19    print()
20
21asyncio.run(main())

takeaway:同步腳本用 ollama.chat,Web 服務用 AsyncClient,需要跨機器用 Client(host=...)


三、官方 JavaScript SDK

前端工程師、寫 Node 後端、或做 Electron 桌面 App 的人,用 JS SDK。

1npm install ollama

基本 chat(Node)

1import ollama from 'ollama'
2
3const res = await ollama.chat({
4  model: 'llama3.2',
5  messages: [{ role: 'user', content: '用一句話解釋 event loop' }],
6})
7
8console.log(res.message.content)

注意 JS 版的回傳是物件屬性 res.message.content(不是 Python 的 dict 索引)。

streaming(Node)

 1import ollama from 'ollama'
 2
 3const stream = await ollama.chat({
 4  model: 'llama3.2',
 5  messages: [{ role: 'user', content: '寫三個學 JS 的理由' }],
 6  stream: true,
 7})
 8
 9for await (const chunk of stream) {
10  process.stdout.write(chunk.message.content)
11}
12process.stdout.write('\n')

for await...of 對應 Python 的 async generator,process.stdout.write 對應 print(end='')

何時用 JS? 當你的整合點就在 JS 生態:Next.js API route、Electron 主行程、VS Code extension、瀏覽器擴充。若只是資料處理、RAG、機器學習相關,Python 生態(numpy、LangChain、向量庫)成熟得多,建議用 Python。


四、OpenAI 相容層(本篇最重要一節)

這是讓「遷移零痛苦」成真的魔法。Ollama 內建一個 OpenAI 相容的 HTTP 端點,長得跟 OpenAI 官方 API 一模一樣:

  • Base URL: http://localhost:11434/v1/
  • API key: 任意非空字串(會被忽略,慣例填 "ollama")
  • 端點:/v1/chat/completions/v1/completions/v1/embeddings/v1/models

為什麼「改 base_url 就能接」

OpenAI 的 Python SDK(openai 套件)本質上只是一個 HTTP client,它把請求送到 client.base_url。這個值預設是 https://api.openai.com/v1你把它改成 http://localhost:11434/v1,同一份程式碼就打到本機 Ollama 了。 請求格式相容,回傳格式也相容,上層邏輯一行都不用動。

 1from openai import OpenAI
 2
 3client = OpenAI(
 4    base_url="http://localhost:11434/v1",
 5    api_key="ollama",   # 非空即可,內容被忽略
 6)
 7
 8r = client.chat.completions.create(
 9    model="llama3.2",
10    messages=[{"role": "user", "content": "Hi"}],
11)
12print(r.choices[0].message.content)

這意味著:任何『會講 OpenAI API』的工具或函式庫——LlamaIndex、Vercel AI SDK、各種 agent 框架、你三年前寫的舊專案——都能靠改 base_url + api_key 指向 Ollama,完全不改其他程式碼。 這是 Ollama 整合生態最強大的一點。

streaming(相容層)

streaming 也完全比照 OpenAI 寫法:

 1from openai import OpenAI
 2
 3client = OpenAI(base_url="http://localhost:11434/v1", api_key="ollama")
 4
 5stream = client.chat.completions.create(
 6    model="llama3.2",
 7    messages=[{"role": "user", "content": "數到十"}],
 8    stream=True,
 9)
10
11for chunk in stream:
12    delta = chunk.choices[0].delta.content
13    if delta:                      # 最後一塊 delta 可能是 None
14        print(delta, end="", flush=True)
15print()

注意 chunk.choices[0].delta.content 這個路徑,以及要判斷 None——這是 OpenAI streaming 的標準結構,一字不差搬過來即可。

embeddings(相容層)

 1from openai import OpenAI
 2
 3client = OpenAI(base_url="http://localhost:11434/v1", api_key="ollama")
 4
 5resp = client.embeddings.create(
 6    model="nomic-embed-text",
 7    input="向量檢索的核心是相似度計算",
 8)
 9vec = resp.data[0].embedding
10print(len(vec))   # nomic-embed-text 是 768 維

支援 / 不支援功能一覽

相容不代表 100% 對等。實務上你會踩到的差異整理如下:

功能相容層是否支援備註
/v1/chat/completions主力端點,對話用
/v1/completions舊式單次補全
/v1/embeddings需用 embed 模型如 nomic-embed-text
/v1/models列出本機模型
streamingstream=True 標準運作
JSON moderesponse_format={"type":"json_object"}
tool calling(工具呼叫)視模型而定,Part 5 深講
vision(圖片 base64)需視覺模型如 llava
logprobs不支援
logit_bias不支援
n(一次多個候選)不支援,只回一個
tool_choice⚠️部分支援,行為與雲端不完全一致

takeaway:對話、streaming、embeddings、JSON mode、工具呼叫這些主流功能都能無痛遷移;會出問題的是 logprobsnlogit_bias 這類進階取樣參數。遷移前先確認你有沒有用到它們。

實務:把現有 OpenAI 專案遷到 Ollama

最漂亮的作法是用環境變數,讓同一份程式碼在雲端 / 本機之間切換:

 1import os
 2from openai import OpenAI
 3
 4# 本機:export OPENAI_BASE_URL=http://localhost:11434/v1 ; export OPENAI_API_KEY=ollama
 5# 雲端:export OPENAI_BASE_URL=https://api.openai.com/v1 ; export OPENAI_API_KEY=sk-...
 6client = OpenAI(
 7    base_url=os.environ.get("OPENAI_BASE_URL", "http://localhost:11434/v1"),
 8    api_key=os.environ.get("OPENAI_API_KEY", "ollama"),
 9)
10
11MODEL = os.environ.get("LLM_MODEL", "llama3.2")
12
13r = client.chat.completions.create(
14    model=MODEL,
15    messages=[{"role": "user", "content": "測試"}],
16)
17print(r.choices[0].message.content)

開發用本機模型(免費、離線、隱私),上線切雲端(能力更強)——只換環境變數,程式碼零改動。 這是很多團隊的實際做法。


五、LangChain 整合

當你的需求超出「單次問答」,進入「多步驟 pipeline、記憶、檢索、agent」時,LangChain 提供結構化的抽象。Ollama 有官方整合套件:

1pip install langchain-ollama

三個核心類別:

1from langchain_ollama import ChatOllama, OllamaEmbeddings, OllamaLLM
2
3llm = ChatOllama(model="llama3.2", temperature=0)   # 對話模型
4embeddings = OllamaEmbeddings(model="nomic-embed-text")  # 向量化

一個小 chain:prompt → llm → 輸出

LangChain 的精髓是用 | 把元件串成 pipeline(LCEL 語法):

 1from langchain_ollama import ChatOllama
 2from langchain_core.prompts import ChatPromptTemplate
 3from langchain_core.output_parsers import StrOutputParser
 4
 5llm = ChatOllama(model="llama3.2", temperature=0)
 6
 7prompt = ChatPromptTemplate.from_messages([
 8    ("system", "你是一個專業的技術翻譯,只輸出翻譯結果,不要解釋。"),
 9    ("user", "把這句翻成英文:{text}"),
10])
11
12# prompt 填值 → 丟給 llm → 把回應物件轉成純字串
13chain = prompt | llm | StrOutputParser()
14
15result = chain.invoke({"text": "本地模型讓資料不出你的機器"})
16print(result)

chain.stream({...}) 也支援 streaming,寫法與前面一致。LangChain 的價值在於:當你要接向量庫、加對話記憶、串多個模型時,這套 | 組合語法能讓 pipeline 保持清晰。 但若只是簡單呼叫,直接用官方 SDK 更輕。


六、動手做一個本機 RAG(重頭戲)

RAG(Retrieval-Augmented Generation,檢索增強生成)是本地模型最實用的應用:讓模型根據你自己的文件回答問題,不靠它的內建知識、不會亂編。而且全程在本機跑,你的文件一個 byte 都不外流。

RAG 流程

   ┌──────────────┐
   │  你的文件      │  (筆記 / 手冊 / PDF 文字)
   └──────┬───────┘
          │ 1. 切塊 (chunking)
          ▼
   ┌──────────────┐
   │  文字片段      │  chunk 1, chunk 2, ... chunk N
   └──────┬───────┘
          │ 2. embed (nomic-embed-text)
          ▼
   ┌──────────────┐        ┌───────────────────────────┐
   │  向量庫        │◀───────│  索引階段 (只做一次)         │
   │  [vec1..vecN] │        └───────────────────────────┘
   └──────┬───────┘
          │
   ══════════════════════ 以下是查詢階段 (每次提問) ══════════════════════
          │
   ┌──────▼───────┐  3. 使用者提問
   │  Query 文字   │──────┐
   └──────────────┘      │ 4. embed (同一個模型!)
                         ▼
                  ┌──────────────┐
                  │  Query 向量   │
                  └──────┬───────┘
                         │ 5. cosine 相似度比對
                         ▼
                  ┌──────────────┐
                  │  取 top-k     │  最相關的 k 個 chunk
                  └──────┬───────┘
                         │ 6. 塞進 prompt(當作 context)
                         ▼
                  ┌──────────────┐
                  │  llama3.2    │  7. 依據 context 生成答案
                  └──────┬───────┘
                         ▼
                     最終答案

完整可跑的 Python

以下用 ollama.embed 做向量化、用 numpy 手算 cosine 相似度、用 ollama.chat 生成。刻意不引入重量級向量庫,讓你看清 RAG 的原理骨架——它其實沒有你想的那麼玄。

 1import ollama
 2import numpy as np
 3
 4EMBED_MODEL = "nomic-embed-text"
 5CHAT_MODEL = "llama3.2"
 6
 7# ── 0. 準備知識庫(真實情境:從檔案讀入後切塊) ──
 8documents = [
 9    "Ollama 的預設服務埠是 11434。",
10    "nomic-embed-text 輸出的向量是 768 維,且已做 L2 正規化。",
11    "要讓對話有記憶,必須由應用自己維護 messages 歷史,Ollama 本身無狀態。",
12    "OpenAI 相容端點的 base_url 是 http://localhost:11434/v1,api_key 填任意非空字串。",
13    "Open WebUI 預設跑在 3000 埠,透過 Docker 部署最方便。",
14]
15
16# ── 1 & 2. 索引階段:把每個 chunk embed 成向量 ──
17def embed(text: str) -> np.ndarray:
18    resp = ollama.embed(model=EMBED_MODEL, input=text)
19    return np.array(resp["embeddings"][0], dtype=np.float32)
20
21doc_vectors = np.vstack([embed(d) for d in documents])   # shape: (N, 768)
22
23# ── 5. cosine 相似度(向量已 L2 正規化,點積即 cosine) ──
24def cosine_topk(query_vec: np.ndarray, matrix: np.ndarray, k: int = 2):
25    # 保險起見再正規化一次,避免模型輸出未正規化
26    q = query_vec / (np.linalg.norm(query_vec) + 1e-10)
27    m = matrix / (np.linalg.norm(matrix, axis=1, keepdims=True) + 1e-10)
28    scores = m @ q                       # 每個 doc 與 query 的相似度
29    top_idx = np.argsort(scores)[::-1][:k]
30    return [(int(i), float(scores[i])) for i in top_idx]
31
32# ── 查詢階段 ──
33def rag_answer(question: str, k: int = 2) -> str:
34    # 3 & 4. 把問題 embed(務必用同一個 EMBED_MODEL!)
35    q_vec = embed(question)
36
37    # 5 & 6. 取最相關的 k 個 chunk 當 context
38    hits = cosine_topk(q_vec, doc_vectors, k=k)
39    context = "\n".join(f"- {documents[i]}" for i, _ in hits)
40
41    # 7. 把 context 塞進 prompt,要求模型只依據它回答
42    prompt = f"""請只根據以下資料回答問題,若資料中沒有答案,就說「資料中沒有相關資訊」。
43
44參考資料:
45{context}
46
47問題:{question}"""
48
49    resp = ollama.chat(
50        model=CHAT_MODEL,
51        messages=[{"role": "user", "content": prompt}],
52    )
53    return resp["message"]["content"]
54
55if __name__ == "__main__":
56    print(rag_answer("Ollama 服務跑在哪個埠?"))
57    print("---")
58    print(rag_answer("Open WebUI 用哪個埠?"))

跑起來,第一題會抓到「11434」那條 chunk,第二題會抓到「3000」那條——模型不是憑記憶回答,而是依據你餵的文件回答。這就是 RAG 消除幻覺的機制。

兩個必記重點

  1. index 與 query 一定要用同一個 embedding 模型。 不同模型產生的向量空間不相容,cosine 相似度會變成亂數。這是新手最常見、最難 debug 的錯誤。
  2. 這個 numpy 版本只是教學骨架。 當文件量從幾十條長到上萬條,線性掃描太慢。這時把 doc_vectors + cosine_topk 換成專門的向量庫——Chroma(輕量、內嵌好裝)或 FAISS(高效能)——它們用 ANN 索引把檢索加速幾個數量級。但原理跟上面一模一樣:embed → 存 → 查相似度 → top-k。

takeaway:RAG 的本質就是「用相似度找出相關片段,塞進 prompt」。搞懂 numpy 版,你就搞懂了所有向量庫在做什麼。


七、現成 App:Open WebUI 與其他 GUI

不想寫程式,只想要一個像 ChatGPT 的網頁介面?Open WebUI 是最受歡迎的自架方案,功能齊全(對話歷史、多模型切換、RAG 上傳文件、使用者管理)。

用 Docker 裝(推薦)

1docker run -d -p 3000:8080 \
2  --add-host=host.docker.internal:host-gateway \
3  -v open-webui:/app/backend/data \
4  --name open-webui \
5  ghcr.io/open-webui/open-webui:main

然後打開瀏覽器到 http://localhost:3000。它會自動偵測跑在 host.docker.internal:11434 的 Ollama。

幾個參數解釋:

  • -p 3000:8080:把容器的 8080 對外映射到你機器的 3000 埠。
  • --add-host=host.docker.internal:host-gateway:這行是關鍵。容器內的 localhost 是容器自己,不是你的 Mac。這個參數讓容器能透過 host.docker.internal 連回宿主機上的 Ollama。
  • -v open-webui:/app/backend/data:用 volume 保存對話歷史,容器重建不丟資料。

用 pip 裝(不想碰 Docker)

1pip install open-webui
2open-webui serve

一樣開 http://localhost:3000。pip 版直接跑在你機器上,localhost:11434 就能連到 Ollama,不需要 host.docker.internal 那套。

其他 GUI 選擇

  • Enchanted:macOS 原生 App,介面精緻,支援 iOS,適合只想要純本機聊天體驗的人。
  • Msty:跨平台桌面 App,開箱即用,內建模型下載與 RAG,對非工程師友善。
  • LM Studio 風格的客戶端:一堆桌面 client 都能連 Ollama 或走 OpenAI 相容層。

takeaway:要團隊共用、要 RAG、要 Web 存取 → Open WebUI;只要個人本機聊天、要最輕 → Enchanted / Msty。


八、編輯器 / 開發整合:在 IDE 裡用本機模型寫程式

把本機模型接進 IDE,你就有了一個離線、免費、程式碼不外流的 AI 助手。

VS Code + Continue

Continue 是最成熟的開源 AI coding 擴充。裝好擴充後,在它的設定裡把 model provider 指向 ollama:

 1{
 2  "models": [
 3    {
 4      "title": "Llama 3.2 (local)",
 5      "provider": "ollama",
 6      "model": "llama3.2"
 7    }
 8  ],
 9  "tabAutocompleteModel": {
10    "title": "Autocomplete",
11    "provider": "ollama",
12    "model": "qwen2.5-coder:1.5b"
13  }
14}

對話用大一點的模型、自動補全用小而快的模型(補全對延遲極敏感,1.5b 這種小模型才跟得上打字速度)。

ollama launch

Ollama 也提供 ollama launch 協助設定 Claude Code / VS Code 等工具接上本機模型,省去手動填設定的功夫。

隱私 vs 能力的取捨

在 IDE 用本機模型,核心是一筆權衡:

  • 隱私 / 成本 / 離線贏面:程式碼永遠不離開你的機器(對受規範的產業、機密專案是硬需求),沒有 API 費用,飛機上也能用。
  • 能力輸面:本機能跑的模型(7B–14B 為主)在複雜重構、跨檔案推理上,仍不如頂級雲端模型。

務實建議:日常補全、樣板、小函式、regex、解釋程式碼——本機模型完全夠用,體驗又快又免費;真正燒腦的架構級任務,再切雲端。 兩者不衝突,Continue 可以同時配置多個 provider,隨時切換。


九、整合選型:情境 → 建議方式

一張表收斂前面所有選擇:

你的情境建議整合方式為什麼
寫個快速腳本 / 自動化任務官方 SDK(ollama / ollama-js)API 最乾淨,還能用 pull/ps 等專屬功能
已有 OpenAI 專案要遷本機OpenAI 相容層(改 base_url)幾乎零改動,一行搞定
前端 / Node / Electron官方 JS SDK貼合 JS 生態
複雜 RAG / agent / 多步 pipelineLangChain(langchain-ollama)結構化組合,好接向量庫與記憶
要客製 RAG 又想懂原理官方 SDK + numpy / Chroma完全掌控檢索邏輯
只想要聊天 UI(團隊共用)Open WebUI功能全、自架、支援多人
個人本機聊天(最輕)Enchanted / Msty原生 App,開箱即用
在 IDE 寫程式VS Code + Continue補全 / 對話都指向本機

takeaway:沒有「最好」的整合方式,只有「最貼合你場景」的。既有專案優先走相容層,新專案優先走官方 SDK,要 pipeline 才上 LangChain。


十、常見整合陷阱:症狀 → 解法

這些坑幾乎每個人都會踩一次,提前記住省下好幾小時 debug:

症狀原因解法
相容層報 404 / 路徑錯誤base_url 尾斜線或缺 /v1http://localhost:11434/v1,不要重複斜線
相容層報 401 / 認證失敗api_key 傳了空字串填任意非空字串,如 "ollama"
model not found模型還沒下載ollama pull llama3.2,或程式裡 ollama.pull()
Connection refusedOllama 服務沒跑確認 ollama serve 或 macOS app 開著,curl localhost:11434
streaming 只拿到片段 / 卡住沒逐 chunk 處理,或忘了 flushfor chunk in stream 逐塊處理,flush=True
Docker 容器連不到 Ollama容器內 localhost 是容器自己--add-host=host.docker.internal:host-gateway,連 host.docker.internal:11434
瀏覽器前端呼叫被擋(CORS)跨來源請求被拒OLLAMA_ORIGINS 允許來源,或後端代理
長文丟進去記憶體爆掉 / 變超慢context 超過模型上限或機器 RAM縮短 context、RAG 只塞 top-k、選 context window 較大的模型
RAG 檢索結果像亂數index 與 query 用了不同 embedding 模型兩端統一用同一個 embed 模型

最容易忽略的兩個:base_url/v1 與尾斜線、以及 RAG 的「同一個 embedding 模型」。 這兩個錯誤不會噴 exception,只會給你安靜的錯誤結果,最難查。


十一、小結

這一篇我們把「本機模型 → 真實應用」的整條路走完:

  • 三條整合路:官方 SDK、OpenAI 相容層、框架/現成 App——底層都是打 localhost:11434
  • 官方 Python SDK:chat / generate / streaming / list / ps / pull / Client / AsyncClient 全套。
  • OpenAI 相容層:改一行 base_url + 非空 api_key,既有 OpenAI 專案零痛苦遷移。
  • LangChain:複雜 pipeline 的結構化組合。
  • 本機 RAG:embed → cosine → top-k → 塞 prompt → 生成,用 numpy 看清原理,量大再換 Chroma/FAISS。
  • 現成 App / IDE:Open WebUI 給你聊天 UI,Continue 給你離線 coding 助手。

你現在有能力把本機模型接進任何應用了。但目前的模型還只是「回答問題」——下一步,是讓它主動呼叫工具、查資料、執行動作,變成真正的 agent。

Part 5 我們進入進階實踐:工具呼叫(tool/function calling)、多模型服務、以及生產級部署的調校。這是把 Ollama 從「玩具」變成「基礎設施」的最後一哩路。


系列導覽

參考連結

  • Ollama 官方文件:https://docs.ollama.com/
  • OpenAI 相容性說明:https://docs.ollama.com/api/openai-compatibility
  • Ollama Python SDK:https://github.com/ollama/ollama-python
  • Open WebUI:https://github.com/open-webui/open-webui
Yen

Yen

Yen