Entscheidungen
OpenAI Decisions API
Stell GPT-6 Luna Decisions Klassifizierungs- und Bewertungsfragen zu Text, Bildern oder JSON und erhalte typisierte Antworten, mit denen dein Code direkt arbeiten kann: wie wahrscheinlich eine Aussage stimmt, welcher deiner Werte passt oder wo etwas auf deiner Skala liegt, jeweils mit den zugehörigen Wahrscheinlichkeiten. Viele Fragen in einer Anfrage, meist in unter einer Sekunde, über die Decisions API und die SDKs von OpenAI.
/v1/decisionsGPT-6 Luna Decisions ist das Decision-Modell von OpenAI. Es liest deinen Input und beantwortet die Fragen, die du dazu stellst. Text schreibt es nicht, also ist es kein Chat-Modell: Sende deine Anfragen an /v1/decisions, nicht an /v1/chat/completions. Auf diesem Endpoint funktioniert gpt-6-luna auch als Modell-ID, wie in den SDK-Docs von OpenAI, sodass der Beispielcode von OpenAI unverändert läuft; das model in der Antwort nennt gpt-6-luna-decisions. Zu Jev, dem Decision-Modell von TypeSafe, siehe Entscheidungen (Jev).
Fragen stellen
# pip install --upgrade openaiimport osfrom openai import OpenAIclient = 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 askedfor 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")Richte das SDK von OpenAI auf https://api.zurelay.com/v1 aus, mit /v1 wie bei jedem OpenAI-Modell auf Zurelay, verwende deinen Zurelay-Key und rufe client.decisions.create auf. In Node.js brauchst du dafür openai ab Version 7.30.0; in Python ein openai-Paket, das neu genug ist, um client.decisions zu enthalten (ab 3.41 ist es dabei). Jeder HTTP-Client funktioniert genauso: Sende das JSON per POST und gib deinen Key als Bearer-Token mit.
Die Antwort
{ "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 enthält eine Antwort pro Frage, in der Reihenfolge, in der du sie gestellt hast, jeweils mit type und, falls angegeben, name. usage zeigt, worauf die Anfrage abgerechnet wurde: input_tokens, wobei output_tokens immer 0 ist, und cost die Kosten in US-Dollar. Über den Header x-request-id der Antwort findest du die Anfrage in deinem Request-Log, und x-zurelay-input-tokens wiederholt, worauf abgerechnet wurde.
Parameter
modelstringerforderlichgpt-6-luna-decisionsodergpt-6-lunabei diesem Endpoint.inputString oder Arrayerforderlich- Worüber entschieden werden soll: ein nicht leerer Text oder ein Array von User-Nachrichten,
{ "role": "user", "content": ... }("type": "message"ist optional). Dercontenteiner Nachricht ist ein Text oder ein Array von Teilen, siehe unten. questionsarrayerforderlich- 1 bis 64 Fragen, die in der Reihenfolge beantwortet werden, in der du sie aufführst.
safety_identifierstring- Optional: eine undurchsichtige ID für den Endnutzer, für den die Anfrage gilt, z. B. ein Hash deiner eigenen Nutzer-ID.
prompt_cache_keystring- Wird akzeptiert und ignoriert, genau wie
prompt_cache_options: Caching läuft automatisch, und jeder Input-Token kostet gleich viel.
typestringerforderlichpredicate,choiceoderscore.instructionsstringerforderlich- Die Frage als Text. Bilder gehören in den Input, nicht hierher.
namestring- Optional und innerhalb der Anfrage eindeutig: kommt in der Antwort auf die Frage zurück, damit du Antworten über den Namen auslesen kannst.
choicesarray- Für eine
choice(erforderlich): 2 bis 255 Werte, jeweils{ "value": ..., "description": ... }. Ein Wert ist Text odertrue/false, und jeder muss eindeutig sein; die Beschreibung ist optional. levelsarray- Für eine
score(erforderlich): 2 bis 10 Stufen, die niedrigste zuerst, jeweils{ "label": ..., "description": ... }, die Beschreibung ist optional.
input_text{ text }- Text.
input_image{ image_url, detail }- Ein Bild als PNG, JPEG, WebP oder GIF: eine Base64-Data-URL oder ein öffentlicher
https-Link, den Zurelay herunterlädt.detailist optional:low,high,autooderoriginal. input_json{ data }- Ein Objekt oder Array, z. B. ein Datensatz oder der State deiner App. Das Modell liest es als kompakten JSON-Text, und es wird auch als dieser Text gezählt.
Fragetypen
Eine Anfrage kann alle drei mischen. Der Input wird für alle zusammen nur einmal gelesen, daher kostet es weniger, mehrere Fragen in einer Anfrage zu stellen, als jede in einer eigenen.
Predicate
Eine Aussage oder Ja/Nein-Frage zum Input. Das probability der Antwort gibt an, wie wahrscheinlich sie zutrifft: nahe 1 für Ja, nahe 0 für Nein und dazwischen, wenn der Input es nicht eindeutig sagt.
{ "type": "predicate", "name": "refund", "instructions": "Is the customer asking for a refund?" }{ "type": "predicate", "name": "refund", "probability": 1 }Auswahl
Wählt einen der von dir aufgeführten Werte und gibt die Wahrscheinlichkeit jedes Werts an. Eine Beschreibung erklärt, was ein Wert bedeutet, was hilft, wenn der Wert allein ein Code ist. Werte können auch true und false sein, und der Text "true" und der Boolean true sind verschiedene Werte.
{ "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" } ]}Bewertung
Ordnet den Input deinen Stufen zu, die niedrigste zuerst. score ist die erwartete Stufe: der Index jeder Stufe, bei 0 beginnend, gewichtet mit ihrer Wahrscheinlichkeit. Der Wert kann also zwischen zwei Stufen liegen: In der Beispielantwort oben steht 0.18 größtenteils für die erste Stufe mit einem Anteil der zweiten. Jeder Eintrag in probabilities hat den Index der Stufe als value und ihre label.
{ "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" } ]}Bilder
Schick Bilder im Input, als Teile einer User-Nachricht neben beliebigem Text. Gib eine Base64-Data-URL oder einen öffentlichen https-Link an, den Zurelay herunterlädt und weitergibt: PNG, JPEG, WebP oder GIF. Große Bilder schickst du besser als Links.
import base64, osfrom openai import OpenAIclient = 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)Ein Bild verbraucht je nach Größe und detail zusätzliche Tokens: Ein Bild mit 1200 × 630 sind bei high oder auto etwa 750 Tokens und bei low etwa 150. Nimm low, wenn sich die Frage auf das ganze Bild bezieht und nicht auf Kleingedrucktes. Bilder gehen nur in den Input: Die Anweisungen einer Frage nehmen nur Text.
JSON-Input
Strukturierte Daten kannst du unverändert in einem input_json-Teil neben Text oder Bildern mitschicken. Das Modell liest sie als kompakten JSON-Text, und sie werden auch als dieser Text abgerechnet.
"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" } } ] }]Verweigerungen
Jede Frage kann statt einer Antwort als Verweigerung zurückkommen, während die anderen Fragen der Anfrage trotzdem beantwortet werden. Prüfe das type jeder Antwort, bevor du ihre Felder liest. In unseren Tests kam der Input „Refund requested 38 hours ago.“ mit dem Predicate „Page on-call?“ als Verweigerung zurück.
{ "type": "refusal", "name": "page_on_call" }Eine Verweigerung kommt in einer normalen Antwort, deren usage angibt, worauf die Anfrage abgerechnet wurde. Frag noch einmal mit einer klareren Frage oder gib den Fall an einen Menschen weiter.
Limits
- Bis zu 1.05M Tokens pro Anfrage: der Input und alle Fragen zusammen. Ein Input mit 918K Tokens hat in unseren Tests funktioniert.
- 1 bis 64 Fragen. Eine
choicenimmt 2 bis 255 eindeutige Werte, einescore2 bis 10 Stufen. - Nur User-Nachrichten: System-, Developer- und Assistant-Nachrichten sowie Function- oder Tool-Call-Items werden abgelehnt. Gib Kontext in einer User-Nachricht oder in den Anweisungen einer Frage mit.
- Kein Streaming:
streamwird abgelehnt, und die Antworten kommen komplett zurück. - Eine fehlerhafte Anfrage oder eine mit einem Feld, das die API nicht akzeptiert, wird abgelehnt, bevor sie das Modell erreicht. Du bekommst einen
400, der das Feld nennt (z. B.questions[2].choices), und es kostet nichts. - Ein Key, der auf bestimmte Modelle beschränkt ist, braucht
gpt-6-luna-decisionsin seiner Liste, auch für Anfragen mitgpt-6-luna. Mehr dazu unter Key-Limits und Regeln.
Geschwindigkeit
In unseren Tests kommen Antworten meist nach 0,3 bis 1 Sekunde zurück, mit einem Bild nach etwa einer Sekunde. Eine Eingabe mit 900K Tokens dauerte etwa 10 Sekunden.
Entscheidungen bezahlen
GPT-6 Luna Decisions kostet $0.04 pro 1M Input-Tokens, die Antworten sind kostenlos. Die Tokens sind deine Eingabe, einmal gezählt, plus etwa 110 bis 160 eigene Tokens des Modells pro Frage: Ein kurzes Prädikat auf einem kurzen Text sind insgesamt etwa 160 Tokens, zwei etwa 320, und eine Eingabe mit 2.600 Tokens und vier Fragen etwa 3.200. Bilder kommen mit ihren Tokens wie oben beschrieben dazu. Eine Prüfung mit einer Frage auf einem kurzen Text kostet also etwa $0.0000064, eine Million davon etwa $6.40.
Die Header usage und x-zurelay-input-tokens jeder Antwort zeigen, worauf abgerechnet wurde. Jede Anfrage steht in deinem Request-Log, und fehlgeschlagene Anfragen kosten nichts.
Fehler
Keys, Guthaben, Budgets und Rate Limits liefern dieselben Fehler wie jeder andere Endpoint: siehe Fehler. Die SDKs von OpenAI wiederholen die Anfragen, bei denen sich ein neuer Versuch lohnt.
Probier es zuerst aus
Fragen oder fehlt etwas? Frag unser Support-Team und wir antworten per E-Mail, meist innerhalb einer Minute.