Embeddings
以 OpenAI Embeddings 規格取得 OpenAI 與 Gemini 的文字向量
Hakila 提供 OpenAI 相容的 POST /v1/embeddings,把文字轉成向量,用於語意搜尋、RAG、分群與分類。
OpenAI 的 embedding 模型原樣轉發;Gemini 的 embedding 模型由 Gateway 翻譯成原生 batchEmbedContents,
呼叫端只需要認識 OpenAI 一種格式。
Embeddings 模型與文字生成模型在目錄中是不同類型:GET /v1/models 的每筆回傳帶 type,
embedding 走 /v1/embeddings,chat 走 /v1/chat/completions;用錯端點會回 400 並提示正確端點。
支援的模型
種子目錄目前包含(單價為 USD / 1M input tokens,以 Console「系統模型」為準):
| 模型 id | 供應商 | 輸入上限 | 預設維度 | 單價 |
|---|---|---|---|---|
openai/text-embedding-3-large | OpenAI | 8,192 tokens | 3072 | $0.13 |
openai/text-embedding-3-small | OpenAI | 8,192 tokens | 1536 | $0.02 |
google/gemini-embedding-2 | Gemini | 8,192 tokens | 3072 | $0.20 |
google/gemini-embedding-001 | Gemini | 2,048 tokens | 3072 | $0.15 |
Embeddings 模型的 context_length 代表單次輸入的 token 上限。平台可在 Console 新增其他 embedding 模型
(包含後台新增的 OpenAI 相容供應商,例如 Ollama 的 nomic-embed-text);
Anthropic 沒有 Embeddings API,無法設為 embedding 類型。
快速開始
官方 OpenAI SDK 只要把 base_url 指到 Hakila、api_key 換成 Hakila API Key 就能使用。
裸模型名稱(text-embedding-3-small)會在已啟用的 embedding 模型中比對名稱並補上開發商前綴;有多個同名模型時回 400,找不到時回 404(見不帶前綴的模型名稱)。
curl https://api.hakila.ai/v1/embeddings \
-H "Authorization: Bearer $HAKILA_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"model": "openai/text-embedding-3-small",
"input": "Hakila 是統一的 AI Gateway。"
}'回應與 OpenAI 相同:
{
"object": "list",
"data": [
{ "object": "embedding", "index": 0, "embedding": [0.0023064255, -0.009327292, "..."] }
],
"model": "text-embedding-3-small",
"usage": { "prompt_tokens": 8, "total_tokens": 8 }
}data[i].index 對應請求 input 陣列的位置;model 為上游實際使用的名稱(已剝除 provider 前綴)。
請求欄位
| 欄位 | OpenAI | Gemini | 說明 |
|---|---|---|---|
model | 必填 | 必填 | 目錄中 type: embedding 的 id;不支援 hakila/auto 與 Preset |
input | 字串/字串陣列/token 陣列 | 字串/字串陣列 | Gemini 收到 token 整數陣列會回 400 |
dimensions | text-embedding-3-* 支援 | 映射成 outputDimensionality | 縮短輸出向量;Gemini 建議 768/1536/3072 |
encoding_format | float(預設)/base64 | 同左(由 Hakila 編碼) | base64 為 little-endian float32 陣列的 Base64 |
user | 轉發 | 忽略 | 終端使用者識別 |
task_type | 忽略 | 映射成 taskType | 見下方「Gemini 專屬欄位」 |
title | 忽略 | 帶入 title | task_type 為 RETRIEVAL_DOCUMENT 時的文件標題 |
其他欄位對 OpenAI 相容上游原樣透傳,對 Gemini 會被忽略。
Gemini 專屬欄位
Gemini 的 taskType 會依用途最佳化向量,Hakila 以 OpenAI 風格的 task_type 欄位承接(也接受 taskType):
task_type | 用途 |
|---|---|
SEMANTIC_SIMILARITY | 文字相似度比較 |
CLASSIFICATION | 依既有標籤分類 |
CLUSTERING | 依相似度分群 |
RETRIEVAL_DOCUMENT | 建索引時嵌入文件(可搭配 title) |
RETRIEVAL_QUERY | 查詢時嵌入使用者的問題 |
CODE_RETRIEVAL_QUERY | 用自然語言查程式碼 |
QUESTION_ANSWERING | 問答系統的問題向量 |
FACT_VERIFICATION | 事實查核 |
# 建索引:文件向量
curl https://api.hakila.ai/v1/embeddings \
-H "Authorization: Bearer $HAKILA_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"model": "google/gemini-embedding-2",
"input": ["台北是台灣的首都。", "高雄是台灣南部的港都。"],
"task_type": "RETRIEVAL_DOCUMENT",
"dimensions": 768
}'
# 查詢:問題向量(同一模型、同一維度)
curl https://api.hakila.ai/v1/embeddings \
-H "Authorization: Bearer $HAKILA_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"model": "google/gemini-embedding-2",
"input": "台灣的首都是哪裡?",
"task_type": "RETRIEVAL_QUERY",
"dimensions": 768
}'Gemini 縮短維度(dimensions 小於 3072)後的向量沒有正規化,計算餘弦相似度前請自行正規化;
OpenAI 的向量一律已正規化為長度 1。同一個索引裡的向量必須來自同一個模型與同一個維度。
路由與允許清單
model必須是這把 API Key 在GET /v1/models中看得到、且type為embedding的 id; 不在目錄、未啟用、未被組織或 API Key 允許,一律回400(訊息與 Chat Completions 相同)- 把
chat模型送進/v1/embeddings回400:「模型 'x' 不是 Embeddings 模型,請改用 POST /v1/chat/completions。」; 反過來把embedding模型送進 Chat/Responses 也會回400並指向/v1/embeddings hakila/auto不支援 Embeddings(回400),候選也只會落在chat模型- 金鑰解析順序與 Chat 相同:BYOK → 平台金鑰;沒有金鑰回
502 - Gemini 呼叫原生
https://generativelanguage.googleapis.com/v1beta/models/{model}:batchEmbedContents, 金鑰以x-goog-api-key帶入;OpenAI 相容上游呼叫{BaseUrl}/embeddings,金鑰以Authorization: Bearer帶入
計費與快取
- 只以輸入 tokens 計費:
usage.prompt_tokens× 模型的輸入單價;輸出單價與 Prompt Cache 單價不適用 - OpenAI 回傳實際 usage;Gemini 原生 API 不回 usage,Hakila 以文字長度估算
prompt_tokens, Console 的 Logs 與 Stats 使用同一個數字 - 支援 Response Cache:同一組
input的向量是穩定的, 加上X-Hakila-Cache: true後重複請求直接命中,不呼叫上游、不計費;cache key 含端點,不會與 Chat 混用 - 用量紀錄的 request/response body 會把向量替換為維度數,避免 Logs 被幾千個浮點數塞滿
- 預算與組織儲值的
402檢查與 Chat 相同
錯誤
| 狀態 | 情境 |
|---|---|
400 | 缺少 model/input、input 為空陣列、模型不是 embedding 類型、不在允許清單、供應商沒有 Embeddings API、Gemini 收到 token 陣列 |
401 | API Key 缺少、無效或過期 |
402 | 儲值用盡或預算超標 |
502 | 供應商金鑰缺失,或上游/轉換失敗 |
504 | 上游在首字元逾時(預設 30 秒)內沒有回應 |
錯誤形狀與 Chat Completions 相同(error.message/error.code);上游 4xx/5xx 會原樣轉出,
Gemini 的錯誤會轉成同一形狀。完整欄位與範例請見 API Reference。