Modelos de Decisão
Modelos de decisão respondem perguntas estruturadas sobre um estado. Em vez de gerar texto livre, eles retornam uma resposta por pergunta nomeada: um julgamento binário, um rótulo selecionado ou uma pontuação em uma rubrica. A plataforma os serve com a mesma autenticação por Chave API e a mesma cobrança em créditos dos demais tipos de modelo.
O primeiro modelo desse tipo é o Jev (jev-1.13.0), servido pela TypeSafe. Você pode fazer várias perguntas ao mesmo tempo sobre o mesmo estado, e a resposta preserva o tipo de cada pergunta: noul, choice ou score.
Modelos de decisão são um tipo separado da Geração de Texto. Eles não aceitam mensagens de chat, parâmetros de geração nem definições de ferramentas, e não aparecem nos seletores de agente, thread, fala ou embedding.
Para a lista atual de modelos de decisão e seus preços, consulte a página de Preços e o seletor de modelos na plataforma.
Playground Interativo
O Playground de Decisões permite escrever um estado, definir perguntas e inspecionar cada resposta com sua distribuição e confiança.
Estado
O estado é o texto ou JSON sobre o qual o modelo raciocina. Cole uma mensagem de suporte, um trecho de documento ou um objeto JSON. O estado pode ser uma string, um objeto JSON, um array JSON ou null.
Perguntas
Adicione uma ou mais perguntas nomeadas. Cada pergunta tem um editor conforme seu tipo:
| Tipo | O que você fornece | O que retorna |
|---|---|---|
noul | Uma pergunta de instrução, mais descrições opcionais para os resultados sim e não | A probabilidade de uma resposta sim |
choice | Uma pergunta de instrução e um mapa de rótulos para descrições | O rótulo selecionado e a probabilidade de cada rótulo |
score | Uma pergunta de instrução e uma rubrica ordenada com pelo menos dois níveis | A pontuação esperada, a rubrica (legenda) e a probabilidade de cada nível |
Os nomes das perguntas são seus. Use o mesmo nome no editor e na resposta para correlacioná-los.
Execução e Visualização
Execute a requisição para ver um cartão por pergunta:
- A resposta selecionada, destacada na distribuição.
- A distribuição completa em barras ou gráfico, não só a opção vencedora.
- A confiança reportada para respostas
choiceescore. - O uso de tokens e o ID da requisição.
O Playground não simula uma conversa. É uma única requisição sobre um único estado.
TIP
Todas as perguntas rodam na mesma requisição. Perguntar ao mesmo tempo se é seguro, a categoria e a urgência mede uma entrada só, não três chamadas separadas.
Tipos de Pergunta
Uma requisição carrega um estado e um objeto não vazio de perguntas nomeadas. Cada pergunta declara seu type.
Perguntas binárias (noul)
Uma pergunta noul pede um julgamento sim/não e retorna a probabilidade de sim.
{
"state": "I was charged twice for the same subscription. Please fix it.",
"questions": {
"billing_related": {
"type": "noul",
"instructions": "Is this request about billing?",
"criteria": {
"true": "A billing or payment issue",
"false": "Anything else"
}
}
}
}Os critérios são opcionais e descrevem o que significam sim e não. Eles não são traduzidos nem reescritos pela plataforma: envie-os no idioma que você quer que o modelo use.
Perguntas de escolha (choice)
Uma pergunta choice seleciona um rótulo do mapa de critérios e retorna a probabilidade de cada rótulo.
{
"state": "I was charged twice for the same subscription. Please fix it.",
"questions": {
"category": {
"type": "choice",
"instructions": "Pick the support category.",
"criteria": {
"billing": "Payment, invoices and charges",
"technical": "Errors, bugs and outages",
"account": "Login, profile and access"
}
}
}
}As chaves dos critérios são os rótulos. Elas são seus dados e retornam inalteradas em choice e em probabilities.
Perguntas de pontuação (score)
Uma pergunta score atribui uma pontuação em uma rubrica ordenada. A rubrica é um array com pelo menos duas descrições, indexadas a partir de zero. O score retornado é o valor esperado e pode cair entre níveis inteiros.
{
"state": "I need this resolved before tomorrow morning or my account is suspended.",
"questions": {
"urgency": {
"type": "score",
"instructions": "How urgent is this request?",
"criteria": ["Low", "Medium", "High"]
}
}
}A resposta repete a rubrica como legend, com chaves de pontuação como strings numéricas. Use a legenda para rotular a distribuição na sua interface.
Resposta
As respostas são indexadas pelo nome da pergunta enviada. Cada resposta mantém seu tipo.
{
"model": "jev-1.13.0",
"answers": {
"billing_related": {
"type": "noul",
"noul": 0.98
},
"category": {
"type": "choice",
"choice": "billing",
"confidence": 0.91,
"probabilities": {
"billing": 0.91,
"technical": 0.05,
"account": 0.04
}
},
"urgency": {
"type": "score",
"score": 0.78,
"confidence": 0.58,
"legend": { "0": "Low", "1": "Medium", "2": "High" },
"probabilities": { "0": 0.25, "1": 0.72, "2": 0.03 }
}
},
"usage": {
"input_tokens": 367,
"output_tokens": 62
}
}| Campo | Descrição |
|---|---|
model | O modelo que respondeu à requisição |
answers | Uma entrada para cada nome de pergunta enviado |
answers[].type | noul, choice ou score, conforme a pergunta |
answers[].noul | Probabilidade de sim para uma pergunta noul, de 0 a 1 |
answers[].choice | Rótulo selecionado para uma pergunta choice |
answers[].score | Pontuação esperada para uma pergunta score |
answers[].confidence | Confiança reportada para respostas choice e score |
answers[].probabilities | Probabilidade por rótulo ou por nível de pontuação |
answers[].legend | Descrições da rubrica com chaves de pontuação, para respostas score |
usage.input_tokens | Tokens de entrada medidos pelo provedor |
usage.output_tokens | Tokens de saída reportados pelo provedor (não cobrados, veja abaixo) |
Confiança e Probabilidades
Leia a distribuição, não apenas a resposta vencedora.
noulretorna uma única probabilidade.noul: 0.5significa que os dois resultados são igualmente plausíveis, não um sim fraco.- Em
choice,probabilitiessoma 1 entre os rótulos. Umaconfidencede 0,55 com o segundo rótulo em 0,30 é uma decisão bem mais fraca que uma 0,95 com o segundo em 0,02. - Em
score,scoreé o valor esperado eprobabilitiesdescreve a distribuição dos níveis. Uma média alta com probabilidade espalhada por dois níveis distantes não é o mesmo que uma resposta concentrada. - Confiança alta não é prova de acerto. Calibre um limiar com os seus próprios dados antes de agir automaticamente sobre uma resposta.
A plataforma nunca inventa uma distribuição nem um valor de confiança. Se um provedor não consegue reportá-los para um tipo de pergunta, esse tipo não é oferecido.
API REST
As requisições de decisão vão para a rota canônica POST /v1/decisions. O mesmo serviço de execução atende os aliases de compatibilidade usados pelos clientes existentes.
| Base | Rota de execução | Listagem de modelos |
|---|---|---|
https://api.sippulse.ai/v1 | POST /decisions | GET /models |
https://api.sippulse.ai | POST /v1/systemone | GET /v1/models |
https://api.sippulse.ai/api | POST /api/v1/systemone, POST /api/alpha/decisions | GET /api/v1/models |
Todas as rotas de execução aceitam o mesmo corpo e retornam o mesmo formato de resposta. Use a rota canônica em integrações novas.
Autenticação
Envie sua Chave API da SipPulse no cabeçalho api-key, ou como Authorization: Bearer <chave> quando seu cliente espera um token bearer.
Exemplo de requisição
curl -X POST 'https://api.sippulse.ai/v1/decisions' \
-H 'Content-Type: application/json' \
-H 'api-key: $SIPPULSE_API_KEY' \
-d '{
"model": "jev-1.13.0",
"state": "I was charged twice for the same subscription. Please fix it.",
"questions": {
"billing_related": {
"type": "noul",
"instructions": "Is this request about billing?",
"criteria": { "true": "A billing or payment issue", "false": "Anything else" }
},
"urgency": {
"type": "score",
"instructions": "How urgent is this request?",
"criteria": ["Low", "Medium", "High"]
}
}
}'import os
import requests
response = requests.post(
"https://api.sippulse.ai/v1/decisions",
headers={
"Content-Type": "application/json",
"api-key": os.environ["SIPPULSE_API_KEY"],
},
json={
"model": "jev-1.13.0",
"state": "I was charged twice for the same subscription. Please fix it.",
"questions": {
"billing_related": {
"type": "noul",
"instructions": "Is this request about billing?",
"criteria": {"true": "A billing or payment issue", "false": "Anything else"},
},
"urgency": {
"type": "score",
"instructions": "How urgent is this request?",
"criteria": ["Low", "Medium", "High"],
},
},
},
)
response.raise_for_status()
print(response.json()["answers"])const response = await fetch("https://api.sippulse.ai/v1/decisions", {
method: "POST",
headers: {
"Content-Type": "application/json",
"api-key": process.env.SIPPULSE_API_KEY,
},
body: JSON.stringify({
model: "jev-1.13.0",
state: "I was charged twice for the same subscription. Please fix it.",
questions: {
billing_related: {
type: "noul",
instructions: "Is this request about billing?",
criteria: { true: "A billing or payment issue", false: "Anything else" },
},
urgency: {
type: "score",
instructions: "How urgent is this request?",
criteria: ["Low", "Medium", "High"],
},
},
}),
});
if (!response.ok) {
throw new Error(`Erro na API de Decisões: ${response.status}`);
}
const { answers, usage } = await response.json();
console.log(answers.billing_related.noul, usage.input_tokens);Listagem de modelos
A rota de listagem segue o seu SDK. O SDK TypeSafe espera um array models; o cliente no estilo OpenRouter espera um array data. Os dois são servidos pelo mesmo modelo, no formato que cada cliente consegue interpretar.
curl 'https://api.sippulse.ai/v1/models' \
-H 'api-key: $SIPPULSE_API_KEY'{
"models": [
{
"name": "jev-1.13.0",
"description": "Decision model",
"release_date": "2026-09-20"
}
]
}curl 'https://api.sippulse.ai/api/v1/models' \
-H 'api-key: $SIPPULSE_API_KEY'{
"data": [
{
"id": "jev-1.13.0",
"name": "jev-1.13.0"
}
]
}SDKs Compatíveis
O protocolo de decisão é compatível com as convenções dos clientes TypeSafe e OpenRouter. O que muda entre eles é apenas como a URL base e as credenciais são configuradas.
SDK TypeSafe
Aponte o cliente para o host da SipPulse e use sua Chave API da SipPulse. O SDK envia Authorization: Bearer, que a plataforma aceita. client.systemOne(...) e client.models.list() funcionam sem alteração.
import { TypeSafeClient, noul, score } from "@typesafe-ai/sdk";
const client = new TypeSafeClient({
apiKey: process.env.SIPPULSE_API_KEY,
baseURL: "https://api.sippulse.ai",
});
const { answers, usage } = await client.systemOne({
state: "I was charged twice for the same subscription. Please fix it.",
questions: {
billing_related: noul("Is this request about billing?", {
true: "A billing or payment issue",
false: "Anything else",
}),
urgency: score("How urgent is this request?", ["Low", "Medium", "High"]),
},
});
console.log(answers.billing_related.noul, usage.input_tokens);import os
from typesafe_sdk import Noul, Score, TypeSafeClient
with TypeSafeClient(
api_key=os.environ["SIPPULSE_API_KEY"],
base_url="https://api.sippulse.ai",
) as client:
result = client.system_one(
state="I was charged twice for the same subscription. Please fix it.",
questions={
"billing_related": Noul(instructions="Is this request about billing?"),
"urgency": Score(
instructions="How urgent is this request?",
criteria=["Low", "Medium", "High"],
),
},
)
print(result.nouls["billing_related"].noul, result.usage.input_tokens)Cliente OpenRouter
O cliente OpenRouter não aceita serverURL no construtor para a operação de decisões. A chamada alphaDecisionsCreate calcula a URL base a partir de uma opção por chamada serverURL e, sem ela, usa o padrão do OpenRouter. Passe o host da SipPulse por chamada; não existe alias de gateway que contorne essa limitação.
import { OpenRouter } from "@openrouter/sdk";
const openrouter = new OpenRouter({
apiKey: process.env.SIPPULSE_API_KEY,
});
const result = await openrouter.alpha.decisions.create(
{
model: "jev-1.13.0",
state: "I was charged twice for the same subscription. Please fix it.",
questions: {
billing_related: {
type: "noul",
instructions: "Is this request about billing?",
},
},
},
{ serverURL: "https://api.sippulse.ai" },
);Opções de roteamento do provedor não são suportadas
A plataforma responde às perguntas e preserva o contrato de resposta, mas não implementa o roteamento comercial do OpenRouter: políticas de privacidade, retenção de dados, ordem de provedores, fallbacks e seleção de provedor não são honrados. Uma requisição que peça essas preferências é rejeitada em vez de ignorá-las em silêncio, então uma opção que aparece no schema do OpenRouter não é necessariamente suportada aqui.
Vercel AI SDK
O provider do AI SDK deriva o caminho /api/alpha de uma URL base que termina em /api/v1. Configure a URL base do provider de acordo; nenhum override por chamada é necessário.
Uso e Faturamento
Requisições de decisão são cobradas por tokens de entrada apenas, a custo, conforme a política de preço do modelo. A tarifa atual do Jev é US$ 0,042 por milhão de tokens de entrada, e a mesma tarifa vale para todo plano que oferece o modelo. Os tokens de saída reportados pelo provedor são mantidos como metadados de uso e não são cobrados.
É por isso que a resposta sempre traz os dois contadores:
usage.input_tokensé o que é cobrado.usage.output_tokensé reportado para observabilidade e conciliação, e seu custo já está embutido na tarifa de entrada.
Os preços são definidos em USD. A moeda da sua organização aplica o câmbio atual e os impostos aplicáveis quando a plataforma converte o valor, então o valor em moeda local não é um múltiplo fixo do número em USD.
Onde o uso aparece
No Dashboard, uma chamada de decisão gera um item de uso do tipo Decisões com a regra de cobrança Input Token, o identificador canônico do modelo, a quantidade de entrada cobrada e o custo daquela chamada. A tabela de requisições e os detalhes da requisição mostram o mesmo ID da requisição, projeto, solicitante e total.
A contagem de tokens de saída não é uma linha faturável separada. Ao conciliar totais, some os itens de decisão pela quantidade de entrada; não espere um item de saída correspondente.
Valores zero e muito pequenos
Uma chamada de decisão pode ser barata o suficiente para que o valor cobrado seja arredondado para um valor muito pequeno. O relatório de uso mantém a precisão decimal de cada chamada, enquanto o crédito liquida o valor efetivamente debitado. Como a liquidação é por chamada, um número muito grande de chamadas quase zero não tem garantia de somar exatamente ao custo bruto em tokens.
Limites
O modelo declara seus limites de decisão. Os limites cobrem o contexto composto, não só o estado:
| Limite | Descrição |
|---|---|
| Contexto total | Máximo de tokens para o estado mais todas as perguntas, incluindo instruções e critérios |
| Maior pergunta | Máximo de tokens para o estado mais a maior pergunta |
| Opções de escolha | Número máximo de rótulos no mapa de critérios de uma pergunta choice |
| Faixa de pontuação | Número mínimo e máximo de níveis de rubrica em um array de critérios score |
O gateway valida a forma da requisição e a cardinalidade de opções e rubrica antes de rodar a inferência. Uma requisição inválida falha com 400 e não é cobrada. Uma requisição maior que 2 MiB (UTF-8 serializado) é rejeitada antes da inferência com 413; aninhamento acima de 64 níveis é rejeitado com 400. Não há um teto separado para a quantidade de perguntas. Os dois tetos de tokens são enforçados pelo próprio modelo, então uma requisição grande demais é rejeitada lá, e não recontada pela plataforma.
Limites de taxa são aplicados por organização e compartilhados entre todos os aliases do mesmo modelo. latest e nomes de versão fixa não têm contadores nem preços separados.
Erros
| Código | Significado |
|---|---|
400 | Requisição malformada ou parâmetros inválidos, incluindo forma de pergunta inválida e preferências de provedor não suportadas |
401 | Chave API da SipPulse inválida ou ausente |
402 | Créditos insuficientes |
404 | Modelo inexistente ou indisponível para a sua organização |
413 | Corpo da requisição grande demais |
429 | Limite de taxa excedido; respeite o cabeçalho Retry-After |
500 | Erro interno do servidor |
502 / 503 | Erro do provedor upstream ou indisponibilidade temporária |
504 | Tempo esgotado |
As rotas de decisão retornam erros no formato que o SDK OpenRouter consegue validar: code é o status HTTP numérico e platform_code é a string estável do erro da plataforma. Ramifique por platform_code no código; o code numérico espelha o status da resposta.
{
"error": {
"statusCode": 404,
"name": "NotFoundError",
"message": "The model 'jev-does-not-exist' does not exist or is not available for your organization.",
"code": 404,
"platform_code": "model_not_found"
}
}Uma chave SipPulse inválida retorna 401. Um problema com a credencial do provedor upstream não retorna 401: ele é reportado como erro de provedor (5xx), para que um cliente não encerre uma sessão válida por causa de um problema a montante.
const response = await fetch("https://api.sippulse.ai/v1/decisions", {
method: "POST",
headers: { "Content-Type": "application/json", "api-key": key },
body: JSON.stringify(payload),
});
if (!response.ok) {
const { error } = await response.json();
if (error.platform_code === "model_not_found") {
// Trate o erro estável da plataforma.
}
throw new Error(`${error.code}: ${error.platform_code ?? error.message}`);
}resp = requests.post(url, headers=headers, json=payload)
if resp.status_code >= 400:
error = resp.json()["error"]
if error.get("platform_code") == "model_not_found":
pass # Trate o erro estável da plataforma.
raise RuntimeError(f"{error['code']}: {error.get('platform_code', error['message'])}")Identidade do Modelo e Aliases
O identificador canônico do modelo é jev-1.13.0. A plataforma também aceita uma lista curta de aliases documentados, incluindo jev-latest (o padrão do SDK TypeSafe), jev-1.13 e typesafe/jev-1.13. Os aliases são explícitos; prefixos arbitrários e nomes aproximados não são resolvidos.
Um nome de versão fixa nunca redireciona em silêncio para outro modelo. latest só muda quando o catálogo é publicado, com invalidação de cache. A resposta sempre informa a versão que de fato respondeu, então registre as answers junto com o campo model.
Próximos Passos
- Geração de Texto - O tipo de modelo LLM, para respostas livres
- Integração com a API REST - Autenticação e convenções de requisição
- Rastreamento de Requisições - Correlacione um ID de requisição com seu uso
- Dashboard - Entenda como o uso e os custos são exibidos
