决策

OpenAI Decisions API

向 GPT-6 Luna Decisions 提出关于文本、图片或 JSON 的分类和评分问题,获得代码可以直接处理的类型化答案:一条陈述为真的可能性有多大、你的哪个取值最合适,或它在你的量表上处于什么位置,每个答案都附带概率。一次请求可包含多个问题,通常不到一秒即可返回,通过 OpenAI 自己的 Decisions API 和 SDK 调用。

POST/v1/decisions
模型ID输入,每 1M tokensOpenAI 定价输出
GPT-6 Luna Decisionsgpt-6-luna-decisions$0.04$0.10免费

GPT-6 Luna Decisions 是 OpenAI 的决策模型。它读取你的输入,并回答你针对输入设置的问题,不会生成文本,所以它不是聊天模型:请发送到 /v1/decisions,而不是 /v1/chat/completions。在此端点上,gpt-6-luna 同样可以作为模型 ID,与 OpenAI 自己的 SDK 文档一致,因此 OpenAI 的示例代码无需修改即可运行;回复中的 model 为 gpt-6-luna-decisions。关于 TypeSafe 的决策模型 Jev,请参阅 决策 (Jev)。

提问

# pip install --upgrade openai
import os
from openai import OpenAI
client = OpenAI(
base_url="https://api.zurelay.com/v1",
api_key=os.environ["ZURELAY_API_KEY"],
)
decision = client.decisions.create(
model="gpt-6-luna-decisions",
input="My headphones stopped charging two days after they arrived. I want a refund.",
questions=[
{
"type": "predicate",
"name": "refund",
"instructions": "Is the customer asking for a refund?",
},
{
"type": "choice",
"name": "topic",
"instructions": "What is the ticket about?",
"choices": [
{"value": "billing", "description": "Charges and invoices"},
{"value": "hardware", "description": "A device that is broken or faulty"},
{"value": "shipping", "description": "Delivery and tracking"},
],
},
{
"type": "score",
"name": "sentiment",
"instructions": "How does the customer feel?",
"levels": [
{"label": "very negative"},
{"label": "negative"},
{"label": "neutral"},
],
},
],
)
# One answer per question, in the order asked
for answer in decision.answers:
if answer.type == "refusal":
print(answer.name, "refused")
elif answer.type == "predicate":
print(answer.name, answer.probability)
elif answer.type == "choice":
print(answer.name, answer.choice, answer.confidence)
else:
print(answer.name, answer.score, answer.confidence)
print(decision.usage.input_tokens, "input tokens")

将 OpenAI 的 SDK 指向 https://api.zurelay.com/v1,/v1 的设置与 Zurelay 上所有 OpenAI 模型相同,使用你的 Zurelay 密钥,然后调用 client.decisions.create。在 Node.js 中,需要 openai 7.30.0 或更高版本;在 Python 中,需要足够新、包含 client.decisions 的 openai 包(3.41 已包含)。任何 HTTP 客户端的用法都一样:POST 该 JSON,并将你的密钥作为 Bearer token 传入。

返回结果

响应
{
"id": "req_3Fh8sLq0vW2nTc7yRb5kZp1M",
"model": "gpt-6-luna-decisions",
"answers": [
{ "type": "predicate", "name": "refund", "probability": 1 },
{
"type": "choice",
"name": "topic",
"choice": "hardware",
"confidence": 1,
"probabilities": [
{ "value": "billing", "probability": 0 },
{ "value": "hardware", "probability": 1 },
{ "value": "shipping", "probability": 0 }
]
},
{
"type": "score",
"name": "sentiment",
"score": 0.18,
"confidence": 0.85,
"probabilities": [
{ "value": 0, "label": "very negative", "probability": 0.82 },
{ "value": 1, "label": "negative", "probability": 0.18 },
{ "value": 2, "label": "neutral", "probability": 0 }
]
}
],
"usage": {
"input_tokens": 325,
"input_tokens_details": { "cached_tokens": 0, "cache_write_tokens": 0 },
"output_tokens": 0,
"output_tokens_details": { "reasoning_tokens": 0 },
"total_tokens": 325,
"cost": 0.000013
}
}

answers 为每个问题提供一个答案,顺序与你提问的顺序一致,每个答案包含 type,如果你提供了 name,也会一并返回。usage 是本次请求的计费依据:input_tokens,其中 output_tokens 始终为 0,cost 是以美元计的费用。回复中的 x-request-id 标头可用于在你的请求日志中找到这次请求,x-zurelay-input-tokens 则会重复其计费依据。

参数

modelstring必填
gpt-6-luna-decisions,在此端点上也可以是 gpt-6-luna。
input字符串或数组必填
决策的输入内容:非空文本,或由用户消息组成的数组 { "role": "user", "content": ... }("type": "message" 为可选)。每条消息的 content 可以是文本,也可以是由多个部分组成的数组,详见下文。
questionsarray必填
1 到 64 个问题,按你列出的顺序依次回答。
safety_identifierstring
可选:代表发起请求的终端用户的不透明 ID,例如你自己的用户 ID 的哈希值。
prompt_cache_keystring
该参数会被接受但会被忽略,prompt_cache_options 也一样:缓存是自动的,每个输入 token 的价格都相同。
每个问题
typestring必填
predicate、choice 或 score。
instructionsstring必填
问题以文本形式填写。图片请放在 input 中,不要放在这里。
namestring
可选,且在请求内唯一:会随该问题的答案一起返回,方便你按名称读取答案。
choicesarray
对于 choice(必填):2 到 255 个值,每个值为 { "value": ..., "description": ... }。值可以是文本或 true/false,且每个值必须唯一;描述为可选项。
levelsarray
对于 score(必填):2 到 10 个级别,按从低到高排列,每个级别为 { "label": ..., "description": ... },描述可选。
消息内容的各个部分
input_text{ text }
文本。
input_image{ image_url, detail }
PNG、JPEG、WebP 或 GIF 格式的图片:可以是 base64 data URL,也可以是 Zurelay 会下载的公开 https 链接。detail 为可选项:low、high、auto 或 original。
input_json{ data }
可以是对象或数组,例如一条记录或你的应用状态。模型会将其作为紧凑的 JSON 文本读取,并按该文本计算 token。

问题类型

类型提问内容Answer
predicate关于输入内容的某个陈述为真的可能性probability,取值范围为 0 到 1
choice你的 2 到 255 个值中,哪一个合适choice、一个confidence,以及每个值的probabilities
score它在你设定的 2 到 10 个有序等级中所处的位置score、一个confidence,以及各个级别的probabilities

一次请求可以同时包含这三种内容。输入内容只会被读取一次,供它们共用,所以在一次请求中提出多个问题,比分别用单独的请求提问更省钱。

判断条件

关于输入内容的一个陈述或是非问题。答案的 probability 表示其为真的可能性:回答“是”时接近 1,回答“否”时接近 0,输入内容表述不明确时则介于两者之间。

先问题,后答案
{ "type": "predicate", "name": "refund", "instructions": "Is the customer asking for a refund?" }
{ "type": "predicate", "name": "refund", "probability": 1 }

选择

从你列出的值中选出一个,并给出每个值的概率。描述用来说明某个值的含义,当值本身只是代码时尤其有用。值也可以是 true 和 false,文本 "true" 与布尔值 true 是不同的值。

Question
{
"type": "choice",
"name": "language",
"instructions": "Which language is the message written in?",
"choices": [
{ "value": "en", "description": "English" },
{ "value": "es", "description": "Spanish" },
{ "value": "other", "description": "Any other language" }
]
}

评分

将输入放到你定义的等级上,等级按从低到高排列。score 是期望等级:即各等级的索引(从 0 开始计数)按其概率加权后的结果。因此它可能落在两个等级之间:在上面的示例响应中,0.18 表示主要是第一个等级,略带一点第二个等级。probabilities 中的每一项都包含等级的索引 value 及其 label。

Question
{
"type": "score",
"name": "relevance",
"instructions": "How well does the passage answer the search query?",
"levels": [
{ "label": "irrelevant" },
{ "label": "related", "description": "On the topic, but doesn't answer it" },
{ "label": "answers it" }
]
}

图片

图片可放在输入中,作为用户消息的一部分,与文本并列发送。支持 base64 data URL,或公开的 https 链接(由 Zurelay 下载后转发),格式为 PNG、JPEG、WebP 或 GIF。较大的图片请使用链接发送。

import base64, os
from openai import OpenAI
client = OpenAI(base_url="https://api.zurelay.com/v1", api_key=os.environ["ZURELAY_API_KEY"])
with open("return-photo.jpg", "rb") as file:
photo = "data:image/jpeg;base64," + base64.b64encode(file.read()).decode()
decision = client.decisions.create(
model="gpt-6-luna-decisions",
input=[
{
"role": "user",
"content": [
{"type": "input_text", "text": "Photo sent with a return request for a blender."},
{"type": "input_image", "image_url": photo, "detail": "low"},
],
}
],
questions=[
{
"type": "predicate",
"name": "damaged",
"instructions": "Does the photo show visible damage to the product?",
},
{
"type": "choice",
"name": "product",
"instructions": "What product is in the photo?",
"choices": [
{"value": "blender"},
{"value": "kettle"},
{"value": "other", "description": "Anything else, or no product"},
],
},
],
)
print(decision.answers)

图片会按尺寸和 detail 增加 token:一张 1200 × 630 的图片在 high 或 auto 下约为 750 个 token,在 low 下约为 150 个。如果问题针对整张图片,而不是细小的文字,请使用 low。图片只能放在输入中:问题的指令只接受文本。

JSON 输入

结构化数据可以原样放进 input_json 部分,与文本或图片并列传入。模型会将其作为紧凑的 JSON 文本读取,并按该文本计费。

JSON 输入
"input": [
{
"role": "user",
"content": [
{ "type": "input_text", "text": "A sign-up from our app:" },
{
"type": "input_json",
"data": { "name": "Free Gift Card Giveaway", "email": "win-now@example.net", "bio": "Click my link" }
}
]
}
]

拒绝响应

任何一个问题都可能返回拒答而不是答案,而同一请求中的其他问题仍会正常作答。读取每个答案的字段之前,请先检查它的 type。在我们的测试中,输入“Refund requested 38 hours ago.”搭配判断条件“Page on-call?”时,返回的结果就是拒答。

被拒绝回答的问题
{ "type": "refusal", "name": "page_on_call" }

拒绝回答会出现在正常的响应中,其 usage 会说明该请求的计费依据。你可以换一种更清楚的问法再试一次,或者转交人工处理。

限制

  • 每次请求最多 1.05M 个 token,包括输入和所有问题在内。在我们的测试中,918K token 的输入可以正常运行。
  • 1 到 64 个问题。choice 接受 2 到 255 个不重复的值,score 接受 2 到 10 个级别。
  • 仅支持 user 消息:system、developer 和 assistant 消息,以及函数或工具调用项,都会被拒绝。请把上下文放进 user 消息,或放进问题的 instructions 中。
  • 不支持流式输出:stream 会被拒绝,答案会一次性完整返回。
  • 请求格式有误,或包含 API 不接受的字段时,会在到达模型之前被拒绝,并返回指明该字段(例如 questions[2].choices)的 400,且不收费。
  • 限定了可用模型的密钥,需要在其列表中加入 gpt-6-luna-decisions,包括声明了 gpt-6-luna 的请求。详见密钥限制与规则。

速度

在我们的测试中,答案通常在 0.3 到 1 秒内返回,带图片时约 1 秒。900K token 的输入耗时约 10 秒。

决策计费

GPT-6 Luna Decisions 每 1M 输入 token 收费 $0.04,答案免费。 这里的 token 包括:你的输入(只计一次),加上每个问题模型自身产生的约 110 到 160 个 token。一个针对短文本的简短判断问题总共约 160 个 token,两个问题约 320 个,一段 2,600 token 的输入加四个问题约 3,200 个。图片的 token 按上文所述另行计入。 因此,对一段短文本做一次单问题检查约花费 $0.0000064,一百万次约花费 $6.40。

每条回复的 usage 和 x-zurelay-input-tokens 标头会说明计费依据,每个请求都记录在你的请求日志中,失败的请求不收费。

错误

状态代码触发条件
400invalid_request请求格式有误,或使用了 API 不支持的内容。错误信息会说明具体问题和位置。
400invalid_input图片链接下载失败,或不是 PNG、JPEG、WebP 或 GIF 图片。
400context_length_exceeded输入和问题合计超过 1.05M 个 token。请缩短输入后重试。
503model_unavailable 或 service_unavailable模型暂时不可用。请在 retry-after 标头给出的秒数后重试。

密钥、额度、预算和速率限制的报错与其他所有端点相同,详见错误。OpenAI 的 SDK 会自动重试值得重试的错误。

先试一试

在控制台的调试台中选择 GPT-6 Luna Decisions,粘贴内容或附上图片,并在旁边设置你的问题。点击“获取代码”按钮,即可生成使用 OpenAI SDK(Python 或 Node.js)或 cURL 的相同请求。

有疑问,或发现内容缺失?联系我们的支持团队,我们会通过邮件回复,通常只需一分钟。