A superfície da API do Jev é pequena de propósito: um endpoint de avaliação e um corpo JSON com três campos. Vale aprender esse corpo mesmo se você for usar um SDK, porque os SDKs são conveniência tipada em cima exatamente disto.
O endpoint
POST https://api.typesafe.ai/v1/systemone
Authorization: Bearer <SUA_CHAVE>
Content-Type: application/json
Há também GET https://api.typesafe.ai/v1/models, que devolve os nomes que a
sua conta pode enviar no campo model, com descrição e data de lançamento de
cada um.
Os três campos do corpo
state— o conteúdo a avaliar. String, objeto JSON ou lista de textos.model— qual modelo atende a requisição. Os exemplos oficiais usamjev-latest.questions— um mapa de perguntas tipadas. Você escolhe cada chave, e a resposta volta sob a mesma chave.
Um detalhe que muita gente não percebe e que a documentação afirma com todas as
letras: a chave que você escolhe não é enviada ao modelo nem usada na
inferência. Ela é só o seu identificador. Quem carrega o sentido da pergunta
é o campo instructions.
O menor corpo válido possível:
{
"state": "Help! My payouts have been failing for 3 days.",
"model": "jev-latest",
"questions": {
"is_urgent": {
"type": "noul",
"instructions": "Does this convey urgency?"
}
}
}
As três perguntas, por inteiro
Os três tipos compartilham type e instructions; cada um acrescenta o seu
criteria.
{
"state": "Help! My payouts have been failing for 3 days.",
"model": "jev-latest",
"questions": {
"is_urgent": {
"type": "noul",
"instructions": "Does this convey urgency?",
"criteria": {
"true": "Explicitly time-sensitive",
"false": "No urgency expressed"
}
},
"department": {
"type": "choice",
"instructions": "Which team should handle this?",
"criteria": {
"billing": "Payments, invoicing, refunds",
"technical": "Bugs, outages, integrations",
"sales": "Pricing, upgrades, new accounts"
}
},
"frustration": {
"type": "score",
"instructions": "How frustrated is the customer?",
"criteria": ["Calm", "Frustrated", "Very angry"]
}
}
}
Regras de forma que a referência estabelece: em Noul o criteria é opcional e
tem as chaves true e false; em Choice é um mapa de opção para descrição,
com null permitido quando a opção dispensa detalhe; em Score é uma lista
ordenada com pelo menos dois níveis. Os três campos aceitam também objeto ou
lista no lugar da string, como descrito em
estrutura avançada.
A resposta
A resposta tem model, answers e usage. Cada resposta traz o type que
casa com a pergunta, e Choice e Score trazem confidence entre 0 e 1 derivado
da distribuição.
{
"model": "jev-latest",
"answers": {
"is_urgent": {
"type": "noul",
"noul": 0.92
},
"department": {
"type": "choice",
"choice": "technical",
"probabilities": { "billing": 0.08, "technical": 0.85, "sales": 0.07 },
"confidence": 0.82
},
"frustration": {
"type": "score",
"score": 1.6,
"legend": { "0": "Calm", "1": "Frustrated", "2": "Very angry" },
"probabilities": { "0": 0.05, "1": 0.3, "2": 0.65 },
"confidence": 0.78
}
},
"usage": { "input_tokens": 312, "output_tokens": 48 }
}
Três observações práticas:
- Noul não tem
confidence. Não é omissão: confiança é uma estatística sobre uma distribuição, e Noul devolve um número só. A leitura correta está em probabilidade não é confiança. legendvem junto no Score. Você não precisa guardar a régua em outro lugar para saber o que o nível 1 significa naquela resposta.usage.input_tokensé a sua fatura. O Jev cobra entrada e a saída é gratuita. A conta em reais está em quanto custa uma decisão.
Com curl
curl -sS https://api.typesafe.ai/v1/systemone \
-H "Authorization: Bearer $TYPESAFE_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"state": "Fiz a atualização ontem e o sistema não abre. Preciso disso hoje.",
"model": "jev-latest",
"questions": {
"categoria": {
"type": "choice",
"instructions": "Qual o assunto principal deste ticket?",
"criteria": {
"duvida_tecnica": "Algo não funciona, dá erro ou o cliente não sabe usar.",
"cobranca": "Fatura, valor, estorno ou forma de pagamento.",
"outro": "Não se encaixa nas categorias acima."
}
},
"pede_reembolso": {
"type": "noul",
"instructions": "O cliente pede estorno ou reembolso?"
}
}
}'
Para listar os modelos disponíveis:
curl -sS https://api.typesafe.ai/v1/models \
-H "Authorization: Bearer $TYPESAFE_API_KEY"
O que você assume ao não usar SDK
A retentativa passa a ser sua. A própria referência recomenda repetir com backoff exponencial em 429 e 529, e observa que os SDKs oficiais fazem isso sozinhos com a política padrão. Se você chama direto, precisa implementar — a política e os valores padrão estão em retentativas e tempo limite.
A tipagem passa a ser sua. Sem o SDK, answers.department.choice é uma
string qualquer para o seu compilador.
A leitura de erro passa a ser sua. Os quatro códigos e o que fazer com cada um estão em erros e exceções.
Em troca, você fica com um contrato que cabe em uma página e funciona em qualquer linguagem. O índice da integração está em como usar.
Perguntas frequentes
Qual é o endpoint do Jev?
POST https://api.typesafe.ai/v1/systemone, com o cabeçalho Authorization: Bearer mais a sua chave e Content-Type: application/json. Existe também GET /v1/models para listar os nomes que a sua conta pode enviar no campo model.
Quais campos são obrigatórios no corpo?
Três: state, que é o conteúdo a avaliar; model, que escolhe o modelo; e questions, o mapa de perguntas tipadas. Cada chave do mapa é um nome que você escolhe, e a resposta volta sob a mesma chave.
A chave da pergunta é enviada ao modelo?
Não. A documentação diz que a chave que você escolhe não é enviada ao modelo nem usada na inferência: ela serve para você casar pergunta e resposta. Quem carrega o sentido é instructions, não o nome da chave.
Como sei quantos tokens gastei?
Pelo campo usage da resposta, que traz input_tokens e output_tokens. O Jev cobra apenas a entrada, a US$ 0,042 por milhão de tokens segundo a documentação, e a saída é gratuita.
Vale a pena chamar sem SDK?
Vale quando a sua linguagem não tem SDK oficial, quando você está dentro de um serviço que já tem cliente HTTP próprio, ou quando quer entender o contrato antes de adotar a biblioteca. Em contrapartida, você passa a ser responsável pela retentativa com backoff, que os SDKs já fazem por padrão.