Decisions API
A Decisions API permite que um modelo tome decisões tipadas sobre um conteúdo em vez de gerar texto. Você fornece o conteúdo a ser avaliado e um conjunto de perguntas, e o modelo retorna uma resposta estruturada para cada uma: a probabilidade de sim/não, uma única escolha em uma lista de opções ou uma pontuação em uma escala graduada, junto com as probabilidades de cada opção e um valor de confiança.
Ela foi criada para classificação, roteamento, moderação, pontuação, filtragem e qualquer outro caso em que seu código precise ramificar diretamente com base no resultado. O modelo só pode responder com as opções e os níveis que você define, nunca com algo fora deles, então não há texto livre a ser interpretado.
Ao utilizar um modelo de decisão pela primeira vez, recomenda-se ler antes o guia de uso do Jev, que inclui o início rápido, a elaboração de perguntas, a interpretação dos resultados e exemplos de cenários. Esta página é a referência no nível dos campos.
Endpoints
Os três endpoints atendem os mesmos modelos com a mesma cobrança; a diferença está apenas no formato da requisição e da resposta. Escolha o que corresponde ao seu cliente:
A autenticação é a mesma dos demais endpoints: Authorization: Bearer <sua OFOXAI_API_KEY>. Apenas requisições sem streaming são suportadas; cada requisição retorna todas as respostas de forma síncrona.
Modelos disponíveis
A lista completa de modelos que suportam esta API está na página de modelos . Chamá-la com um modelo de chat comum (como openai/gpt-4o) retorna endpoint_not_supported.
Formato unificado: /v1/decisions
Parâmetros da requisição
Formato de entrada
input aceita três formas:
- Texto: uma única string.
"input": "Customer message: I was charged twice, nobody has answered my two emails, and I need a refund today." - Dados estruturados: um objeto JSON, repassado ao modelo sem alterações. As perguntas podem referenciar nomes de campos entre crases, como
`message`."input": { "ticket_id": 4812, "message": "I was charged twice.", "plan": "pro" } - Array de mensagens:
[{ "role", "content" }], em quecontenté uma string ou uma lista de blocos de conteúdo. Apenas os blocosinput_texteinput_imagesão suportados. Imagens só funcionam com modelos capazes de lê-las. O Jev não lê imagens; enviar uma retorna 400.
Objeto de pergunta
Exemplos de requisição
cURL
curl https://api.ofox.ai/v1/decisions \
-H "Authorization: Bearer $OFOX_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"model": "typesafe/jev-latest",
"input": "Customer message: I was charged twice, nobody has answered my two emails, and I need a refund today.",
"questions": [
{ "type": "predicate", "name": "is_frustrated", "instructions": "Is the customer frustrated?" },
{
"type": "choice",
"name": "category",
"instructions": "Which category does this ticket belong to?",
"choices": [
{ "value": "billing", "description": "Charges and refunds" },
{ "value": "bug", "description": "Product issue" },
{ "value": "other", "description": "Other" }
]
},
{
"type": "score",
"name": "urgency",
"instructions": "How quickly does a human need to respond?",
"levels": [
{ "label": "low", "description": "Within a week is fine" },
{ "label": "medium", "description": "Should respond soon" },
{ "label": "high", "description": "Must respond today" }
]
}
]
}'Formato da resposta
{
"model": "typesafe/jev-latest",
"answers": [
{ "type": "predicate", "name": "is_frustrated", "probability": 0.97 },
{
"type": "choice",
"name": "category",
"choice": "billing",
"confidence": 1,
"probabilities": [
{ "value": "billing", "probability": 1 },
{ "value": "bug", "probability": 0 },
{ "value": "other", "probability": 0 }
]
},
{
"type": "score",
"name": "urgency",
"score": 2,
"confidence": 1,
"legend": { "0": "low: Within a week is fine", "1": "medium: Should respond soon", "2": "high: Must respond today" },
"probabilities": [
{ "value": 0, "label": "low", "probability": 0 },
{ "value": 1, "label": "medium", "probability": 0 },
{ "value": 2, "label": "high", "probability": 1 }
]
}
],
"usage": { "prompt_tokens": 407, "completion_tokens": 72, "total_tokens": 479 }
}answers corresponde um a um a questions, na mesma ordem. Campos de cada tipo de resposta:
Formato nativo da TypeSafe: /typesafe/v1/systemone
Os formatos de requisição e resposta são os mesmos da API oficial da TypeSafe , então você pode usar o SDK da TypeSafe diretamente ou migrar código existente. Em relação ao formato unificado, as diferenças são:
curl https://api.ofox.ai/typesafe/v1/systemone \
-H "Authorization: Bearer $OFOX_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"model": "jev-latest",
"state": "Help! My payouts have been failing for 3 days.",
"questions": {
"is_urgent": { "type": "noul", "instructions": "Does this convey urgency?" },
"department": {
"type": "choice",
"instructions": "Which team should handle this?",
"criteria": {
"billing": "Payments, invoicing, refunds",
"technical": "Bugs, outages, integrations",
"sales": "Pricing, upgrades"
}
},
"frustration": {
"type": "score",
"instructions": "How frustrated is the customer?",
"criteria": ["Calm", "Frustrated", "Very angry"]
}
}
}'{
"model": "typesafe/jev-latest",
"answers": {
"is_urgent": { "type": "noul", "noul": 0.95 },
"department": {
"type": "choice",
"choice": "billing",
"confidence": 0.85,
"probabilities": { "billing": 0.9, "technical": 0.1, "sales": 0 }
},
"frustration": {
"type": "score",
"score": 1.03,
"confidence": 0.95,
"legend": { "0": "Calm", "1": "Frustrated", "2": "Very angry" },
"probabilities": { "0": 0, "1": 0.97, "2": 0.03 }
}
},
"usage": { "input_tokens": 399, "output_tokens": 73 }
}Integração com SDK
SDK da OpenAI
O SDK oficial da OpenAI oferece client.decisions.create(). Aponte base_url para https://api.ofox.ai/v1 e use o formato unificado no corpo da requisição. Há um exemplo na aba Python acima. É necessária uma versão do SDK que inclua a Decisions API (testado com openai Python 3.31.0).
SDK da TypeSafe
No SDK oficial da TypeSafe, defina base_url como https://api.ofox.ai/typesafe e substitua api_key pela sua API Key da OfoxAI. O restante do código permanece igual:
Python
# pip install typesafe-sdk
import os
from typesafe_sdk import TypeSafeClient, Noul, Choice, Score
with TypeSafeClient(base_url="https://api.ofox.ai/typesafe", api_key=os.environ["OFOX_API_KEY"]) as client:
r = client.system_one(
model="jev-latest",
state={"message": "I was charged twice, nobody has answered my two emails, and I need a refund today."},
questions={
"urgent": Noul(instructions="Is the customer asking for this to be handled today?"),
"dept": Choice(
instructions="Which team should handle this?",
criteria={"billing": "Charges, invoices, refunds", "technical": "Bugs, integrations", "sales": "Pricing, upgrades"},
),
"anger": Score(instructions="How upset is the customer?", criteria=["Calm", "Upset but polite", "Very angry"]),
},
)
print(r.nouls["urgent"].noul) # 0.98
print(r.choices["dept"].choice) # billing
print(r.scores["anger"].score) # 1.56Probabilidade e confiança
- A probabilidade responde a “qual é a resposta”:
probabilityeprobabilitiessão as probabilidades calibradas do modelo para cada resposta possível. - A confiança responde a “posso confiar nesta decisão”:
confidenceé derivada da distribuição de probabilidades e é maior quanto mais concentrada for a distribuição. Se duas opções ficarem em 0.5 cada,choiceainda retorna uma delas, masconfidenceserá baixa.
Uma prática comum é definir um limiar no código: agir automaticamente quando a confiança for alta e encaminhar para revisão por uma pessoa ou por um modelo mais forte quando for baixa.
Cobrança
A cobrança é por token; os preços estão na página do modelo . O typesafe/jev-latest cobra apenas os tokens de entrada; a saída não é cobrada (completion_tokens / output_tokens continuam sendo retornados).
Todas as perguntas de uma requisição compartilham a mesma entrada, então colocar várias perguntas em uma única requisição é bem mais barato e rápido do que dividi-las em chamadas separadas.
Limites
Erros comuns
Para outros erros gerais, veja Tratamento de erros.