~/ / AI 文章 / 在 VPS 上跑本機 LLM / 用 Ollama 產生 embedding:搜尋與 RAG 的基礎

用 Ollama 產生 embedding:搜尋與 RAG 的基礎

依語意找出段落的搜尋,以及讓聊天模型根據你自己的文件回答的 RAG,都是從 embedding 開始。Ollama 可以在執行聊天模型的同一台伺服器上產生 embedding。本文介紹請求的寫法、Ollama 模型庫列出的模型、會改變結果的設定,以及如何比較向量,內容只取自 Ollama 文件與模型庫頁面所載。本頁有兩個工具,讓你在瀏覽器中試做這些步驟。

發布: · 約 5 分鐘讀完 · 以上內容已於 2026-11-04 對照 Ollama 文件與模型庫頁面確認。模型與欄位會變動,採用前請先查看最新頁面。

什麼是 embedding

Ollama 的 embeddings 頁面指出,embedding 會把文字轉成數值向量,你可以把它存進向量資料庫、用餘弦相似度搜尋,或用在 RAG 流程中。向量的長度取決於模型,該頁面給出的通常是 384 到 1024 維。

搜尋時,會用同一個模型把問題轉成 embedding,再找出已儲存向量中與它最相似的那些。

用 /api/embed 產生 embedding

端點是 POST /api/embed。請求需要 model 與 input,而 input 可以是單一字串,也可以是字串陣列。傳入陣列時,回應的 embeddings 欄位會依相同順序,為每個字串各放一個向量,所以一批段落只需要一次請求。

文件也示範了命令列用法:ollama run embeddinggemma "Hello world" 會把向量以 JSON 陣列印出,也可以用 echo 把文字以管線傳入。

欄位API 參考文件的說明
model必填。模型名稱。
input必填。一段文字,或文字陣列。
truncate預設為 true:超出上下文視窗的輸入會被截斷。若為 false,則會回傳錯誤。
dimensions要產生 embedding 的維度數。
keep_alive模型保持載入的時間長度。
options執行階段選項,例如用來設定上下文長度的 num_ctx。

Ollama 也有與 OpenAI 相容的端點 /v1/embeddings。其文件列出支援 model、為字串或字串陣列的 input、encoding format 與 dimensions,不支援 token 陣列與 user。

Ollama 模型庫中的 embedding 模型

Ollama 模型庫有 embedding 分類。下表列出其中六個模型,以及各模型的標籤頁面為 latest 標籤所給出的大小與上下文視窗。六個之中有四個小於 1GB。

模型latest 標籤的大小上下文視窗
all-minilm46MB512
nomic-embed-text274MB2K
embeddinggemma622MB2K
mxbai-embed-large670MB512
bge-m31.2GB8K
qwen3-embedding4.7GB40K

其他標籤的大小不同:例如模型庫列出 qwen3-embedding:0.6b 為 639MB、上下文視窗 32K,embeddinggemma:300m-qat-q4_0 為 239MB。我們沒有比較這些模型的品質,模型庫頁面也沒有為它們排名。我們在 Ollama 0.40.11 上試用 all-minilm 時,ollama show 顯示上下文長度為 512、參數 num_ctx 為 256,而較長的輸入在 256 個 token 處被截斷。請用 ollama show 確認您使用的模型。

過長的輸入會在沒有錯誤的情況下被截斷

上下文視窗是以 token 計算的。由於 truncate 預設為 true,比模型上下文視窗更長的文字會被縮短,並且仍會回傳向量,不會出現錯誤。把一份很長的文件當成單一輸入送出,結尾就可能因此遺失。

有兩個做法會有幫助。一是把長文件切成較小的區塊(chunk),再為每個區塊產生 embedding,這也能讓搜尋只回傳能回答問題的那一部分。二是送出時把 truncate 設為 false,這樣當區塊仍然太長時,Ollama 會回傳錯誤,而不是把它縮短。

下方的區塊切分工具會依段落、換行、句子與空格切開文字,並加上重疊,然後為所有區塊建立一個 /api/embed 請求。它以字元數而不是 token 數計算,因為每個模型都有自己的分詞器(tokenizer),所以請在上下文視窗之下預留一些餘裕。

動手試試: RAG Text Chunker

長度以字元計算。模型的上下文視窗以 token 計算,而一段文字佔用多少 token 取決於模型,所以請預留一些餘裕。

curl 指令

請在能連到 Ollama 的機器上執行。回應會依此順序,為每個區塊各給一個向量。

curl http://localhost:11434/api/embed -d '{
  "model": "embeddinggemma",
  "input": [
    "Embeddings turn text into numeric vectors. You can store them in a vector database and search them with cosine similarity, or use them in a RAG pipeline.\n\nThe length of each vector depends on the embedding model. Use the same model when you index your documents and when you embed a question.\n\n",
    "Ollama'\''s /api/embed endpoint takes a single string or an array of strings. By default, input that is longer than the model'\''s context window is truncated. Set truncate to false to get an error instead.\n\n",
    "Split long documents into smaller chunks before you embed them, so that each chunk fits in the context window and a search can return the part that answers the question."
  ],
  "truncate": false
}'

區塊

共 3 個區塊,最長的有 294 個字元。

  1. #0 · 294 個字元 · 起始於偏移量 0

    Embeddings turn text into numeric vectors. You can store them in a vector database and search them with cosine similarity, or use them in a RAG pipeline. The length of each vector depends on the embedding model. Use the same model when you index your documents and when you embed a question.

  2. #1 · 202 個字元 · 起始於偏移量 294

    Ollama's /api/embed endpoint takes a single string or an array of strings. By default, input that is longer than the model's context window is truncated. Set truncate to false to get an error instead.

  3. #2 · 169 個字元 · 起始於偏移量 496

    Split long documents into smaller chunks before you embed them, so that each chunk fits in the context window and a search can return the part that answers the question.

/api/embed 的 JSON 內容

{
  "model": "embeddinggemma",
  "input": [
    "Embeddings turn text into numeric vectors. You can store them in a vector database and search them with cosine similarity, or use them in a RAG pipeline.\n\nThe length of each vector depends on the embedding model. Use the same model when you index your documents and when you embed a question.\n\n",
    "Ollama's /api/embed endpoint takes a single string or an array of strings. By default, input that is longer than the model's context window is truncated. Set truncate to false to get an error instead.\n\n",
    "Split long documents into smaller chunks before you embed them, so that each chunk fits in the context window and a search can return the part that answers the question."
  ],
  "truncate": false
}

請求欄位依 Ollama API 參考文件中 /api/embed 所載,於 2026-11-04 確認。 Ollama API: Generate embeddings

所有處理都在你的瀏覽器中完成。工具只負責寫出指令,不會傳送任何東西。

建立索引與搜尋要用同一個模型

embeddings 頁面指出,建立索引與查詢時要使用同一個 embedding 模型。向量長度取決於模型,所以兩個不同模型的向量,維度數甚至可能不一樣。

dimensions 也一樣:如果你在為文件建立索引時設定了它,在為問題產生 embedding 時也要設成相同的值。若你更換了模型或這項設定,就要把已儲存的文件重新產生 embedding。

比較向量

文件建議在大多數語意搜尋的情境中使用餘弦相似度,並指出 /api/embed 會回傳經過 L2 正規化、長度為 1 的向量。對長度為 1 的向量來說,餘弦相似度與內積是同一個數字,因此不論向量資料庫設成哪一種,排出來的結果順序都相同。

想在動手建置之前,用自己的文字檢驗某個模型,可以在一次請求中為一個問題與幾個段落產生 embedding,並把問題放在最前面。把回應貼到下方:段落會依與問題的餘弦相似度排序,工具也會顯示每個向量是否為單位長度、維度是否相同。

動手試試: Embedding Similarity Calculator

範例使用虛構的 4 維單位長度向量,方便閱讀。實際的 embedding 有數百或數千個維度。

已視為Ollama /api/embed 的回應讀取:共 4 個向量,維度為 4。 所有向量的長度都是 1,因此餘弦相似度與內積相等。

依餘弦相似度排名

與 #0 How do I keep a model loaded in Ollama? 比較。數值越高越相似。

名次文字餘弦內積距離
1#1 keep_alive controls how long the model stays in memory0.99620.99620.0876
2#2 Protect Ollama with nginx and a password0.40370.40371.0921
3#3 Tomorrow's weather forecast0.01000.01001.4071

餘弦相似度矩陣

每個儲存格是該列的向量與該欄的向量之間的比較結果。

#0#1#2#3
#01.0000.9960.4040.010
#10.9961.0000.475-0.005
#20.4040.4751.000-0.377
#30.010-0.005-0.3771.000

向量

文字維度長度(L2 範數)單位長度
#0 How do I keep a model loaded in Ollama?41.000000是
#1 keep_alive controls how long the model stays in memory41.000000是
#2 Protect Ollama with nginx and a password41.000001是
#3 Tomorrow's weather forecast41.000000是

依據 Ollama 的 embeddings 文件與 API 參考文件,於 2026-11-04 確認。 Ollama: Embeddings / Ollama API: Generate embeddings

所有計算都在你的瀏覽器中完成,不會傳送到任何地方。

小型伺服器上的記憶體

embedding 模型的載入方式與其他模型相同。Ollama FAQ 指出,OLLAMA_MAX_LOADED_MODELS(在記憶體放得下時,可同時載入的模型數量)預設為 GPU 數量的 3 倍,若是 CPU 推論則為 3。因此在記憶體允許時,聊天模型與 embedding 模型可以一起保持載入。

我們另有一篇監看 Ollama 記憶體的文章,說明 ollama ps、keep_alive 以及其他決定什麼會留在記憶體中的設定。

參考來源

接著閱讀