Hakila Docs

Responses API

以 OpenAI Responses 規格呼叫 Hakila(含 streaming、tools 與 background)

Hakila 提供與 OpenAI 完全相容的 Responses API,可以呼叫平台上所有 chat 模型:

  • OpenAI 模型:除了模型路由、金鑰、允許清單與記帳,請求、回應與 SSE 事件都原樣透傳, tools、structured outputs、reasoning、background、previous_response_id 等能力由上游 OpenAI 決定。
  • 其他模型(Claude、Gemini、Grok、OpenRouter、地端服務…):Hakila 把請求轉成各家協定, 回應與事件再轉回 Responses 格式,詳見下方非 OpenAI 模型。

只會說 Responses 協定的工具,也能透過這個端點使用 Claude、Gemini、Grok。Codex 例外:Hakila 提供給 Codex 的模型清單只列 GPT 模型與 hakila/auto, 且 hakila/auto 在 Codex 裡只挑 GPT 模型,見 Codex。

端點

方法路徑說明
POST/v1/responses建立回應(支援 stream、background)
POST/v1/responses/input_tokens計算 input token 數(不產生回應、不計費)
GET/v1/responses/{id}取回回應(?stream=true 可續播事件)
DELETE/v1/responses/{id}刪除已存的回應
POST/v1/responses/{id}/cancel取消 background 回應
GET/v1/responses/{id}/input_items列出該回應的 input items

快速開始

官方 SDK 只要把 base_url 指到 Hakila、api_key 換成 Hakila API Key 就能使用; 模型名稱可以照原本的裸名稱寫,目錄中只有一個同名模型時會自動補上開發商前綴(例如 openai/<name>;見不帶前綴的模型名稱)。

curl https://api.hakila.ai/v1/responses \
  -H "Authorization: Bearer $HAKILA_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "model": "openai/gpt-5.6-luna",
    "input": "用一句話介紹 Hakila"
  }'

模型與路由

  • openai/gpt-5.6-luna 這類帶前綴的 id 會剝除前綴後轉發給 OpenAI。
  • 沒有前綴的 gpt-5.6-luna 會正規成 openai/gpt-5.6-luna、claude-sonnet-5 會正規成 anthropic/claude-sonnet-5,讓官方 SDK 不必改 model 名稱。
  • anthropic/*、google/*、x-ai/* 等非 OpenAI 模型走轉換模式。
  • hakila/auto 的候選可落在任何供應商;請求帶 previous_response_id 或 "background": true 時只挑 OpenAI。
  • POST /v1/responses/input_tokens 使用同一套路由與允許清單,但目前只支援 OpenAI 模型。
  • 模型仍須出現在 GET /v1/models:也就是平台目錄已啟用, 並通過組織 ∩ API Key 允許清單。若要用目錄裡還沒有的模型(例如新上架的 OpenAI 模型), 請先請平台管理者在後台「系統模型」新增並啟用,記帳才有正確單價。

非 OpenAI 模型

Claude、Gemini、Grok 等模型沒有 Responses 端點,Hakila 會先把請求轉成 Chat Completions, 經過與 /v1/chat/completions 相同的路由、BYOK、hakila/auto 改道與各家協定轉換, 再把結果轉回 Responses 的回應物件與 SSE 事件。官方 SDK 與 Codex 不需要任何改動。

curl https://api.hakila.ai/v1/responses \
  -H "Authorization: Bearer $HAKILA_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "model": "anthropic/claude-sonnet-5",
    "input": "用一句話介紹 Hakila",
    "reasoning": { "effort": "medium" }
  }'

無狀態

轉換模式不在伺服器端保存任何東西,每次請求都要帶完整的對話歷史(input 陣列):

欄位行為
previous_response_id回 400(param: "previous_response_id")
"background": true回 400(param: "background")
store忽略,回應的 store 一律為 false
GET /v1/responses/{id}轉換模式的 response id 查不到,回 404

Codex 本來就每輪送完整歷史、store: false,不受影響。

工具

工具類型行為
function轉成各家的 function calling;strict 會被忽略
custom(例如 Codex 的 apply_patch)轉成只有一個 input 字串參數的 function,文法寫進說明;結果轉回 custom_tool_call
namespace(MCP 等)子工具攤平成 namespace__name,結果轉回原本的名稱與 namespace
web_search 等 OpenAI 內建工具移除,被移除的類型列在回應 header X-Hakila-Dropped-Tools

推理

reasoning.effort 會換成各家的推理設定:

  • Claude:Claude 4.6 之後(含 Opus 5、Sonnet 5、Fable 5.1)用 adaptive thinking 與原生 effort; xhigh/max 對應到該模型支援的最高等級,none 會關閉思考(模型不允許關閉時改為 low)。 Haiku 4.5 等較早的模型改用 thinking token 預算。開啟思考時 temperature 會被移除。
  • Gemini:low/medium/high;none 只有 Gemini 2.5 支援,其餘改為 low。
  • Grok:依模型支援的等級收斂(例如 Grok 4.6 支援到 xhigh,Grok 4.20 不接受這個參數會直接移除)。

Claude 的思考摘要會以 response.reasoning_summary_text.delta 事件串流,並出現在 reasoning item 的 summary。 Claude 的 thinking 簽章與 Gemini 的 thought signature 需要在下一輪原樣送回,Hakila 會把它們加密放進 reasoning item 的 encrypted_content:只要把上一輪的 output item 原樣放回 input,推理就能延續。 解不開的 encrypted_content(例如 OpenAI 發的)會被靜默略過;切回 OpenAI 模型時,Hakila 發的 reasoning item 也會在轉發前移除,不會讓 OpenAI 回 400。

記帳與快取

  • 依上游實際回報的 usage 計費,usage 一律帶 input_tokens_details.cached_tokens 與 output_tokens_details.reasoning_tokens
  • 串流中途斷線時以已送出的內容估算輸出 tokens
  • 請求紀錄的端點是 /v1/responses、供應商是實際呼叫的那一家,回應內容以 Responses 格式保存
  • Response Cache 照常運作,命中時重播轉換後的內容

Streaming

"stream": true 會以 text/event-stream 回傳 OpenAI 的事件串流。與 Chat Completions 不同的是 沒有 data: [DONE],結尾是 response.completed(或 response.failed、response.incomplete)。

event: response.output_text.delta
data: {"type":"response.output_text.delta","delta":"Hakila"}

event: response.completed
data: {"type":"response.completed","response":{"id":"resp_...","status":"completed","usage":{"input_tokens":12,"output_tokens":8,"total_tokens":20}}}

用量統計取自終止事件裡的 response.usage;output_tokens 已包含 reasoning tokens。

Background 與計費

"background": true 會立刻回 status: "queued"。這一筆在建立時不計費——因為還沒有 token 數。 之後 GET /v1/responses/{id} 拿到 completed 與 usage 時才記一次帳,Hakila 內部以 response id 去重(保留 30 天),所以同一筆回應不論 retrieve 幾次都只會被計費一次。

其他 GET/DELETE/cancel/input_items/input_tokens 一律不計費,但都會寫入請求紀錄可供稽核。 input_tokens 回傳的數字只是計數,不會被當成這次請求的用量。

DELETE /v1/responses/{id} 與 POST /v1/responses/{id}/cancel 會跳過預算檢查: 預算超標時仍然要能取消正在執行的背景任務。其餘端點在超標時照樣回 402。

錯誤形狀

Responses 端點的錯誤與 OpenAI 一致,官方 SDK 可直接解析:

{
  "error": {
    "message": "Missing required parameter: 'model'.",
    "type": "invalid_request_error",
    "param": "model",
    "code": null
  }
}

Chat Completions 仍維持 Hakila 既有的 {"error":{"message":"...","code":400}}。

計算 input tokens

POST /v1/responses/input_tokens 接受與建立回應相同的 input(文字、訊息、圖片、檔案、tools), 回傳這個請求會送進模型的 token 數,不會產生回應,也不計費。官方 SDK 把 base_url 指到 Hakila 即可: Python 用 responses.input_tokens.count,JavaScript 用 responses.inputTokens.count。

curl https://api.hakila.ai/v1/responses/input_tokens \
  -H "Authorization: Bearer $HAKILA_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "model": "openai/gpt-5.6-luna",
    "input": "用一句話介紹 Hakila"
  }'
{
  "object": "response.input_tokens",
  "input_tokens": 12
}

這個端點仍受預算檢查:超支時回 402。目前只支援 OpenAI 模型,其他模型回 400;錯誤形狀和建立回應相同。

完整參數與 Schema 請見 建立回應 與 計算 input tokens。

本頁目錄