OpenAI Decisions API
curl --request POST \
--url https://api.mixroute.ai/v1/decisionsimport requests
url = "https://api.mixroute.ai/v1/decisions"
response = requests.post(url)
print(response.text)const options = {method: 'POST'};
fetch('https://api.mixroute.ai/v1/decisions', options)
.then(res => res.json())
.then(res => console.log(res))
.catch(err => console.error(err));<?php
$curl = curl_init();
curl_setopt_array($curl, [
CURLOPT_URL => "https://api.mixroute.ai/v1/decisions",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "POST",
]);
$response = curl_exec($curl);
$err = curl_error($curl);
curl_close($curl);
if ($err) {
echo "cURL Error #:" . $err;
} else {
echo $response;
}package main
import (
"fmt"
"net/http"
"io"
)
func main() {
url := "https://api.mixroute.ai/v1/decisions"
req, _ := http.NewRequest("POST", url, nil)
res, _ := http.DefaultClient.Do(req)
defer res.Body.Close()
body, _ := io.ReadAll(res.Body)
fmt.Println(string(body))
}HttpResponse<String> response = Unirest.post("https://api.mixroute.ai/v1/decisions")
.asString();require 'uri'
require 'net/http'
url = URI("https://api.mixroute.ai/v1/decisions")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Post.new(url)
response = http.request(request)
puts response.read_body決策模型
OpenAI Decisions API
透過 gpt-6-luna 呼叫 OpenAI 相容 Decisions 介面:判斷、分類、評分的參數、結構化結果與錯誤處理。
OpenAI Decisions API
curl --request POST \
--url https://api.mixroute.ai/v1/decisionsimport requests
url = "https://api.mixroute.ai/v1/decisions"
response = requests.post(url)
print(response.text)const options = {method: 'POST'};
fetch('https://api.mixroute.ai/v1/decisions', options)
.then(res => res.json())
.then(res => console.log(res))
.catch(err => console.error(err));<?php
$curl = curl_init();
curl_setopt_array($curl, [
CURLOPT_URL => "https://api.mixroute.ai/v1/decisions",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "POST",
]);
$response = curl_exec($curl);
$err = curl_error($curl);
curl_close($curl);
if ($err) {
echo "cURL Error #:" . $err;
} else {
echo $response;
}package main
import (
"fmt"
"net/http"
"io"
)
func main() {
url := "https://api.mixroute.ai/v1/decisions"
req, _ := http.NewRequest("POST", url, nil)
res, _ := http.DefaultClient.Do(req)
defer res.Body.Close()
body, _ := io.ReadAll(res.Body)
fmt.Println(string(body))
}HttpResponse<String> response = Unirest.post("https://api.mixroute.ai/v1/decisions")
.asString();require 'uri'
require 'net/http'
url = URI("https://api.mixroute.ai/v1/decisions")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Post.new(url)
response = http.request(request)
puts response.read_body透過 MixRoute 的 OpenAI 相容 Decisions 介面,針對同一份輸入提出具名問題並取得結構化答案。模型使用
任何問題都可能傳回 type=refusal,其他問題仍可正常回應。依 name 或問題順序對應,先判斷 type,再讀取對應欄位,並明確處理拒答。信心分數和機率不保證判斷正確。
圖片使用公開 HTTP(S) URL 或 Base64 data URL,不使用 file_id。detail 可選 auto、low、high、original。developer/system 訊息使用文字;assistant 訊息使用輸出文字或拒答項目。工具結果透過 call_id 與呼叫對應。此協定不接受檔案、音訊或項目參照。以上為協定格式,進階輸入的實際可用性取決於 MixRoute 路由。
將範例圖片網址替換為可公開存取的商品圖片或 Base64 data URL。
結合 usage 與目前模型廣場確認計費。不要假定 Responses 或 Chat Completions 的費率適用於 Decisions;實際費用取決於帳戶倍率和路由定價。
gpt-6-luna;此協定與 Jev System One 不同。
接入方式
POST https://api.mixroute.ai/v1/decisions
請求標頭使用 Authorization: Bearer $MIXROUTE_API_KEY 和 Content-Type: application/json。API Key 僅保存在伺服器端。模型和管道權限取決於帳戶;模型出現在列表中不代表所有介面均可用。
使用
input,不是 state;questions 是可帶 name 的陣列,不是以問題 ID 為鍵的物件。真假判斷用 predicate,不是 noul;分類用 choices,評分用 levels,不是 Jev 的 criteria。回應中的 answers 也是陣列。Jev 協定見 System One。請求參數
| 欄位 | 型別 | 要求 | 說明 |
|---|---|---|---|
model | string | 必填 | 使用 gpt-6-luna;不能直接替換成其他聊天模型或 Jev ID。 |
input | string / array | 必填 | 所有問題共同評估的輸入:文字,或依序排列的訊息、函式呼叫及結果、自訂工具呼叫及結果陣列。 |
questions | object[] | 必填 | 包含 1-400 個 predicate、choice 或 score 問題的陣列。各問題獨立評估;若依賴上一個答案,應分開請求。 |
prompt_cache_key | string / null | 可選 | 呼叫端提供的快取分區識別碼,最多 64 個字元。 |
prompt_cache_options | object / null | 可選 | 可選快取設定。mode 為 implicit(預設)或 explicit;ttl 目前支援 30m。實際快取可用性與計費取決於路由。 |
safety_identifier | string / null | 可選 | 不透明的終端使用者識別碼,最多 128 個字元;建議使用穩定且不含個人資訊的識別碼。 |
問題欄位
| 欄位 | 型別 | 要求 | 說明 |
|---|---|---|---|
type | string | 必填 | predicate、choice 或 score。 |
instructions | string / array | 必填 | 要作出的判斷。使用文字字串或非空的受支援內容項目陣列。文字和圖片項目直接放入 instructions,不加訊息外層。 |
name | string | 可選 | 回應中原樣傳回的名稱,建議每個問題使用不同名稱;未命名的問題可傳回 name=null。 |
choices | object[] | 依型別 | choice 必填,包含 2-255 個互不相同的選項。每項必填 value(字串或布林值),可選 description(字串)。字串 “true” 與布林值 true 是不同值。 |
levels | object[] | 依型別 | score 必填,包含 2-10 個從低到高排列的等級。每項必填 label(字串),可選 description(字串);等級索引從 0 開始。 |
答案型別
| 型別 | 說明 |
|---|---|
predicate | probability 是條件成立的估計機率,範圍 0-1,不是布林值。 |
choice | choice 是給定的字串或布林選項。probabilities 是 value/probability 物件陣列,另有 confidence 欄位。 |
score | score 是等級索引的機率加權平均值,範圍為 0 到 levels.length-1,可為小數。probabilities 包含 value(索引)、label 和 probability。 |
請求範例
呼叫前設定MIXROUTE_API_KEY。範例只提交一次,不自動重試;用戶端逾時不代表伺服器端沒有執行推論。
- cURL
- Python
- JavaScript
curl --request POST "https://api.mixroute.ai/v1/decisions" \
--header "Authorization: Bearer $MIXROUTE_API_KEY" \
--header "Content-Type: application/json" \
--data '{
"model": "gpt-6-luna",
"input": "CSV export fails on every attempt. The customer needs the file today and asks for a human agent.",
"questions": [
{
"type": "choice",
"name": "team",
"instructions": "Which team should handle this ticket?",
"choices": [
{
"value": "engineering",
"description": "Software defects"
},
{
"value": "billing",
"description": "Payments and refunds"
}
]
},
{
"type": "score",
"name": "urgency",
"instructions": "How soon does the customer need help?",
"levels": [
{
"label": "No deadline",
"description": "No deadline is specified."
},
{
"label": "This week",
"description": "Help is needed within a week."
},
{
"label": "Today",
"description": "Help is explicitly required today."
}
]
},
{
"type": "predicate",
"name": "needs_human",
"instructions": "Does the customer request a human agent?"
}
]
}'
import json
import os
import requests
payload = json.loads(r'''{
"model": "gpt-6-luna",
"input": "CSV export fails on every attempt. The customer needs the file today and asks for a human agent.",
"questions": [
{
"type": "choice",
"name": "team",
"instructions": "Which team should handle this ticket?",
"choices": [
{
"value": "engineering",
"description": "Software defects"
},
{
"value": "billing",
"description": "Payments and refunds"
}
]
},
{
"type": "score",
"name": "urgency",
"instructions": "How soon does the customer need help?",
"levels": [
{
"label": "No deadline",
"description": "No deadline is specified."
},
{
"label": "This week",
"description": "Help is needed within a week."
},
{
"label": "Today",
"description": "Help is explicitly required today."
}
]
},
{
"type": "predicate",
"name": "needs_human",
"instructions": "Does the customer request a human agent?"
}
]
}''')
response = requests.post(
"https://api.mixroute.ai/v1/decisions",
headers={"Authorization": "Bearer " + os.environ["MIXROUTE_API_KEY"]},
json=payload,
timeout=60,
allow_redirects=False,
)
response.raise_for_status()
result = response.json()
if not isinstance(result.get("answers"), list):
raise ValueError("Expected an answers array")
for answer in result["answers"]:
kind = answer["type"]
if kind == "refusal":
print(answer.get("name"), "refused")
continue
field = {"predicate": "probability", "choice": "choice", "score": "score"}.get(kind)
if field is None:
raise ValueError("Unexpected answer type: " + kind)
print(answer.get("name"), answer[field])
const apiKey = process.env.MIXROUTE_API_KEY;
if (!apiKey) throw new Error("Set MIXROUTE_API_KEY");
const payload = {
"model": "gpt-6-luna",
"input": "CSV export fails on every attempt. The customer needs the file today and asks for a human agent.",
"questions": [
{
"type": "choice",
"name": "team",
"instructions": "Which team should handle this ticket?",
"choices": [
{
"value": "engineering",
"description": "Software defects"
},
{
"value": "billing",
"description": "Payments and refunds"
}
]
},
{
"type": "score",
"name": "urgency",
"instructions": "How soon does the customer need help?",
"levels": [
{
"label": "No deadline",
"description": "No deadline is specified."
},
{
"label": "This week",
"description": "Help is needed within a week."
},
{
"label": "Today",
"description": "Help is explicitly required today."
}
]
},
{
"type": "predicate",
"name": "needs_human",
"instructions": "Does the customer request a human agent?"
}
]
};
const response = await fetch("https://api.mixroute.ai/v1/decisions", {
method: "POST",
headers: {
Authorization: "Bearer " + apiKey,
"Content-Type": "application/json",
},
body: JSON.stringify(payload),
signal: AbortSignal.timeout(60000),
redirect: "error",
});
const result = await response.json();
if (!response.ok) {
throw new Error(result.error?.message ?? "HTTP " + response.status);
}
if (!Array.isArray(result.answers)) throw new Error("Expected an answers array");
for (const answer of result.answers) {
if (answer.type === "refusal") {
console.log(answer.name, "refused");
continue;
}
const field = { predicate: "probability", choice: "choice", score: "score" }[answer.type];
if (!field) throw new Error("Unexpected answer type: " + answer.type);
console.log(answer.name, answer[field]);
}
回應範例
同步傳回 JSON 物件,不是 Chat Completions 的 choices 陣列,也不是需要輪詢的任務。機率和 token 用量會隨請求變化。{
"model": "gpt-6-luna",
"answers": [
{
"type": "choice",
"name": "team",
"choice": "engineering",
"probabilities": [
{
"value": "engineering",
"probability": 1
},
{
"value": "billing",
"probability": 0
}
],
"confidence": 1
},
{
"type": "score",
"name": "urgency",
"score": 2,
"probabilities": [
{
"value": 0,
"label": "No deadline",
"probability": 0
},
{
"value": 1,
"label": "This week",
"probability": 0
},
{
"value": 2,
"label": "Today",
"probability": 1
}
],
"confidence": 1
},
{
"type": "predicate",
"name": "needs_human",
"probability": 1
}
],
"usage": {
"input_tokens": 416,
"input_tokens_details": {
"cached_tokens": 0,
"cache_write_tokens": 0
},
"output_tokens": 0,
"output_tokens_details": {
"reasoning_tokens": 0
},
"total_tokens": 416
}
}
| 欄位 | 說明 |
|---|---|
model | 實際執行判斷的模型。 |
answers | 與問題順序一致的陣列;先檢查每項的 type 和 name。 |
usage.input_tokens | 本次請求的輸入 token 用量。 |
usage.input_tokens_details | cached_tokens、cache_write_tokens 已包含在 input_tokens 中,不要重複相加。 |
usage.output_tokens / usage.output_tokens_details | 輸出用量及 reasoning_tokens,不代表傳回了聊天文字。 |
usage.total_tokens | 介面報告的總 token 用量。 |
結構化與圖片輸入
user 訊息的 content 可包含 input_text(text)、input_image(image_url)、input_json(data)。JSON data 必須是物件或物件陣列;其中的鍵僅為待判斷的資料,不會觸發圖片擷取或建立訊息。JSON 輸入最多 32 層容器、10,000 個值、256 KiB 的緊湊 UTF-8 JSON。{
"model": "gpt-6-luna",
"input": [
{
"role": "user",
"content": [
{
"type": "input_text",
"text": "Evaluate the ticket record."
},
{
"type": "input_json",
"data": {
"ticket": {
"feature": "CSV export",
"fails": true,
"deadline": "today"
}
}
}
]
}
],
"questions": [
{
"type": "predicate",
"name": "deadline_today",
"instructions": "Does the ticket require action today?"
}
]
}
{
"model": "gpt-6-luna",
"input": [
{
"role": "user",
"content": [
{
"type": "input_text",
"text": "Inspect this product photo."
},
{
"type": "input_image",
"image_url": "https://example.com/product.png",
"detail": "auto"
}
]
}
],
"questions": [
{
"type": "predicate",
"name": "visible_damage",
"instructions": "Does the product show a crack, tear, or dent?"
}
]
}
可選提示詞快取
共享 input 至少達到 1,024 tokens 才具備快取條件;questions 不屬於可重用的輸入前綴。預設使用隱含斷點;明確斷點在共享 input 的文字或圖片項目中設定prompt_cache_breakpoint: {"mode": "explicit"}。prompt_cache_options.mode=explicit 且沒有明確斷點時不使用快取。問題 instructions 不支援快取斷點。不要將上游快取折扣或價格直接視為 MixRoute 費率。
錯誤與計費
先檢查 HTTP 狀態。閘道錯誤可能包含 error.message、error.type、error.code、error.param,其中 param 可能為空。排查時保留 x-oneapi-request-id,不記錄完整 API Key。| HTTP | 說明 |
|---|---|
| 400 invalid_request | 檢查 input 和 questions 陣列;問題物件對映屬於 Jev 格式,不適用於本介面。 |
| 401 / 403 | 檢查認證及介面、模型權限。 |
| 503 model_not_found | 目前 Key/分組沒有此模型的可用管道,不是模型傳回的判斷結果。 |
| 429 / 其他 5xx | 有 Retry-After 時遵循該值,僅在適當情況下有限重試;結果不確定的逾時不要自動重複提交。 |
{
"error": {
"message": "questions must be a non-empty array",
"type": "mixroute_error",
"param": "",
"code": "invalid_request"
}
}