Decisões
API OpenAI Decisions
Faça ao GPT-6 Luna Decisions perguntas de classificação e pontuação sobre texto, imagemns ou JSON e receba respostas tipadas que seu código pode usar: qual a probabilidade de uma afirmação ser verdadeira, qual dos seus valores se encaixa ou onde algo fica na sua escala, cada uma com suas probabilidades. Várias perguntas em uma única requisição, em geral em menos de um segundo, pela Decisions API e pelos SDKs da própria OpenAI.
/v1/decisionsO GPT-6 Luna Decisions é o modelo de decisão da OpenAI. Ele lê sua entrada e responde às perguntas que você define sobre ela, e não escreve texto, então não é um modelo de chat: envie para /v1/decisions, não para /v1/chat/completions. Neste endpoint, gpt-6-luna também funciona como ID do modelo, como na documentação do SDK da própria OpenAI, então o código de exemplo da OpenAI roda sem alterações; o model da resposta diz gpt-6-luna-decisions. Para o Jev, o modelo de decisão da TypeSafe, veja Decisões (Jev).
Faça perguntas
# 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")Aponte o SDK da OpenAI para https://api.zurelay.com/v1, com /v1 como em todos os modelos da OpenAI na Zurelay, use sua chave da Zurelay e chame client.decisions.create. No Node.js, isso exige openai 7.30.0 ou posterior; no Python, um pacote openai recente o bastante para ter client.decisions (a 3.41 tem). Qualquer cliente HTTP funciona do mesmo jeito: faça um POST do JSON com sua chave como token Bearer.
A resposta
{ "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 traz uma resposta por pergunta, na ordem em que você as fez, cada uma com seu type e, quando você informou, seu name. usage é a base da cobrança da requisição: input_tokens, com output_tokens sempre 0, e cost o custo em dólares americanos. O cabeçalho x-request-id da resposta localiza a requisição no seu log, e x-zurelay-input-tokens repete a base da cobrança.
Parâmetros
modelstringobrigatóriogpt-6-luna-decisions, ougpt-6-lunaneste endpoint.inputstring ou arrayobrigatório- Sobre o que decidir: um texto não vazio ou um array de mensagens do usuário,
{ "role": "user", "content": ... }("type": "message"é opcional). Ocontentde uma mensagem é um texto ou um array de partes, abaixo. questionsarrayobrigatório- De 1 a 64 perguntas, respondidas na ordem em que você as listar.
safety_identifierstring- Opcional: um ID opaco do usuário final para quem a requisição é feita, como um hash do seu próprio ID de usuário.
prompt_cache_keystring- Aceito e ignorado, assim como
prompt_cache_options: o cache é automático e todo token de entrada custa o mesmo.
typestringobrigatóriopredicate,choiceouscore.instructionsstringobrigatório- A pergunta, em texto. As imagens vão no input, não aqui.
namestring- Opcional e único na requisição: volta na resposta da pergunta, para que você possa ler as respostas pelo nome.
choicesarray- Para um
choice(obrigatório): de 2 a 255 valores, cada um{ "value": ..., "description": ... }. Um valor pode ser texto outrue/false, e cada um precisa ser único; a descrição é opcional. levelsarray- Para
score(obrigatório): de 2 a 10 níveis, do mais baixo ao mais alto, cada um{ "label": ..., "description": ... }, com descrição opcional.
input_text{ text }- Texto.
input_image{ image_url, detail }- Uma imagem PNG, JPEG, WebP ou GIF: uma data URL em base64 ou um link
httpspúblico que a Zurelay baixa.detailé opcional:low,high,autoouoriginal. input_json{ data }- Um objeto ou um array, como um registro ou o estado do seu app. O modelo lê o conteúdo como texto JSON compacto, e ele é contado como esse texto.
Tipos de pergunta
Uma única requisição pode combinar os três. A entrada é lida uma só vez para todos, então fazer várias perguntas em uma requisição custa menos do que fazer cada uma em uma requisição separada.
Predicado
Uma afirmação ou pergunta de sim/não sobre a entrada. Na resposta, probability indica a probabilidade de isso ser verdade: perto de 1 para sim, perto de 0 para não e um valor intermediário quando a entrada não deixa isso claro.
{ "type": "predicate", "name": "refund", "instructions": "Is the customer asking for a refund?" }{ "type": "predicate", "name": "refund", "probability": 1 }Escolha
Escolhe um dos valores que você listar e informa a probabilidade de cada um. Uma descrição diz o que cada valor significa, o que ajuda quando o valor sozinho é um código. Os valores também podem ser true e false, e o texto "true" e o booleano true são valores diferentes.
{ "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" } ]}Pontuação
Posiciona a entrada nos seus níveis, começando pelo mais baixo. score é o nível esperado: o índice de cada nível, contando a partir de 0, ponderado pela probabilidade dele. Por isso, o valor pode cair entre dois níveis: na resposta de exemplo acima, 0.18 é em grande parte o primeiro nível, com um pouco do segundo. Cada item em probabilities traz o índice do nível como value e o respectivo 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" } ]}Imagens
Envie imagens no input, como partes de uma mensagem de usuário junto com qualquer texto. Use uma data URL em base64 ou um link https público, que a Zurelay baixa e repassa: PNG, JPEG, WebP ou GIF. Envie imagens grandes como 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)Uma imagem adiciona tokens de acordo com o tamanho e detail: uma imagem de 1200 × 630 equivale a cerca de 750 tokens em high ou auto, e a cerca de 150 em low. Use low quando a pergunta for sobre a imagem como um todo, e não sobre texto pequeno. As imagens entram apenas na entrada: as instruções de uma pergunta aceitam somente texto.
Entrada JSON
Dados estruturados podem ser enviados como estão, em uma parte input_json, junto com texto ou imagens. O modelo lê esses dados como texto JSON compacto, e a cobrança é feita sobre esse texto.
"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" } } ] }]Recusas
Qualquer pergunta pode voltar como uma recusa em vez de uma resposta, enquanto as outras da mesma requisição continuam sendo respondidas. Verifique o type de cada resposta antes de ler os campos dela. Em nossos testes, a entrada “Refund requested 38 hours ago.” com o predicado “Page on-call?” voltou recusada.
{ "type": "refusal", "name": "page_on_call" }Uma recusa vem em uma resposta normal, e usage informa com base em que a solicitação foi cobrada. Pergunte de novo com uma pergunta mais clara ou encaminhe o caso para uma pessoa.
Limites
- Até 1.05M tokens por requisição: a entrada e todas as perguntas somadas. Nos nossos testes, uma entrada de 918K tokens funcionou.
- De 1 a 64 perguntas. Um
choiceaceita de 2 a 255 valores únicos e umscore, de 2 a 10 níveis. - Somente mensagens de usuário: mensagens de sistema, de desenvolvedor e de assistente, além de itens de chamada de função ou ferramenta, são recusadas. Coloque o contexto em uma mensagem de usuário ou nas instruções de uma pergunta.
- Sem streaming:
streamé recusado, e as respostas voltam completas. - Uma requisição malformada, ou com um campo que a API não aceita, é recusada com um
400que indica o campo (comoquestions[2].choices) antes de chegar ao modelo, e não gera custo. - Uma chave limitada a alguns modelos precisa ter
gpt-6-luna-decisionsna lista, inclusive para requisições que informamgpt-6-luna. Veja Limites e regras das chaves.
Velocidade
Nos nossos testes, as respostas costumam voltar em 0,3 a 1 segundo, e em cerca de 1 segundo quando há imagemm. Uma entrada de 900K tokens levou cerca de 10 segundos.
Cobrança por decisões
O GPT-6 Luna Decisions custa $0.04 por 1M de tokens de entrada, e as respostas são gratuitas. Os tokens são a sua entrada, contada uma só vez, mais cerca de 110 a 160 do próprio modelo para cada pergunta: um predicado curto sobre um texto curto dá cerca de 160 tokens no total, dois dão cerca de 320, e uma entrada de 2.600 tokens com quatro perguntas dá cerca de 3.200. As imagens somam seus tokens como descrito acima. Assim, uma verificação com uma pergunta sobre um texto curto custa cerca de $0.0000064, e um milhão delas, cerca de $6.40.
Os headers usage e x-zurelay-input-tokens de cada resposta informam em que base ela foi cobrada, toda requisição fica no seu log de requisições, e requisições que falham não geram custo.
Erros
Chaves, crédito, orçamentos e limites de taxa geram os mesmos erros de todos os outros endpoints: veja Erros. Os SDKs da OpenAI repetem automaticamente as requisições que vale a pena repetir.
Experimente primeiro
Tem dúvidas ou falta algo? Fale com nossa equipe de suporte e responderemos por e-mail, geralmente em até um minuto.