Guia

Guia Jev em Python

O SDK Python oficial da TypeSafe funciona neste site sem mudanças: instale typesafe-sdk, aponte a base URL para jev-api.org e chame system_one com uma chave do jev-api.org. Este guia cobre instalação, configuração, os três tipos de pergunta, leitura de respostas e o cliente assíncrono.

Atualizado

Instalação

O pacote é typesafe-sdk no PyPI e exige Python 3.10 ou superior. O código está em github.com/typesafe-ai/typesafe-sdk-python.

pip install typesafe-sdk
# or: uv add typesafe-sdk
# requires Python 3.10+

Configure a chave e a base URL

O SDK lê duas variáveis de ambiente. TYPESAFE_API_KEY recebe uma chave do seu painel no jev-api.org — chaves do console da TypeSafe não funcionam aqui — e TYPESAFE_BASE_URL deve ser https://jev-api.org para que as requisições cheguem ao endpoint compatível /v1/systemone em vez de api.typesafe.ai.

# .env — a key from your jev-api.org dashboard
TYPESAFE_API_KEY=jeva_...
TYPESAFE_BASE_URL=https://jev-api.org

Você também pode passá-las diretamente: TypeSafeClient(api_key=..., base_url="https://jev-api.org"). O modelo padrão é jev-latest; mude com TYPESAFE_DEFAULT_MODEL ou o argumento model. O timeout padrão é 10 segundos.

Primeira chamada: Noul, Choice e Score

client.system_one recebe um state — string, objeto ou array — e um mapa questions montado com as classes Noul, Choice e Score. A chamada abaixo retorna dentro da faixa de latência documentada de 70 a 500 ms e usa 1 crédito neste site.

from typesafe_sdk import Choice, Noul, Score, TypeSafeClient

with TypeSafeClient() as client:  # reads TYPESAFE_API_KEY and TYPESAFE_BASE_URL
    response = client.system_one(
        state={"document": "I was charged twice. Please fix this ASAP."},
        questions={
            "billing": Noul(instructions="Is this ticket about billing?"),
            "tone": Choice(
                instructions="What is the customer's tone?",
                criteria={"calm": None, "frustrated": None, "angry": None},
            ),
            "urgency": Score(
                instructions="How urgent is this ticket?",
                criteria=["can wait", "this week", "today"],
            ),
        },
    )

print(response.nouls["billing"].noul)      # 0.0 .. 1.0
print(response.choices["tone"].choice)     # winning option
print(response.scores["urgency"].score)    # fractional level

Lendo as respostas

A resposta expõe visões tipadas: response.nouls, response.choices e response.scores, indexadas pelos seus ids de pergunta. Uma resposta Noul traz .noul, a probabilidade de sim entre 0 e 1. Uma Choice traz .choice, .probabilities e .confidence. Uma Score traz um .score fracionário mais .legend, .probabilities e .confidence.

Use confidence como sinal de repasse. Quando está baixo ou duas opções ficam próximas, encaminhe o caso a uma pessoa ou faça uma pergunta de acompanhamento mais estreita em vez de baixar o limiar às cegas. Você também pode ler o objeto bruto por pergunta em response.answers["id"].

Cliente assíncrono

AsyncTypeSafeClient tem a mesma interface com chamadas aguardáveis — útil dentro de endpoints FastAPI ou workers que disparam vários states ao mesmo tempo.

from typesafe_sdk import AsyncTypeSafeClient, Noul

async with AsyncTypeSafeClient() as client:
    response = await client.system_one(
        state="I was charged twice for my subscription.",
        questions={"refund": Noul(instructions="Is the customer asking for money back?")},
    )
    print(response.answers["refund"])

Sem o SDK: requests puro

Se não quiser a dependência, faça o POST com o JSON você mesmo. O endpoint simples deste site, /api/v1/decisions, aceita o mesmo formato state+questions com o modelo jev-1.13 e limites um pouco mais apertados (1 a 6 perguntas, 2 a 8 opções de Choice).

import os
import requests

res = requests.post(
    "https://jev-api.org/api/v1/decisions",
    headers={"Authorization": f"Bearer {os.environ['JEV_API_KEY']}"},
    json={
        "model": "jev-1.13",
        "state": "I was charged twice for my subscription.",
        "questions": {
            "refund": {"type": "noul", "instructions": "Is the customer asking for money back?"}
        },
    },
    timeout=30,
)
print(res.json()["answers"]["refund"])

Erros e timeouts

O jev-api.org devolve erros JSON com um campo detail. Os códigos que você verá:

  • 401 — chave ausente ou rejeitada. Confira o cabeçalho Authorization: Bearer e se a chave veio deste site.
  • 402 — a chave é válida mas o saldo não cobre a chamada. Adicione créditos na página de preços.
  • 422 — o corpo falhou na validação ou o modelo o rejeitou (por exemplo, acima dos limites de 64k/32k tokens). A mensagem indica o campo.
  • 429 — limite de taxa. Aguarde e tente de novo.
  • 502 — o serviço de decisão não devolveu respostas. Nenhum crédito é usado.

Perguntas frequentes

Posso usar minha chave do console da TypeSafe aqui?

Não. As chaves não são intercambiáveis: as da TypeSafe funcionam em api.typesafe.ai e as do painel do jev-api.org funcionam aqui. Defina TYPESAFE_API_KEY com uma chave do jev-api.org e TYPESAFE_BASE_URL como https://jev-api.org.

Qual endpoint o SDK chama neste site?

Com base_url em https://jev-api.org, o SDK posta em /v1/systemone — o endpoint compatível com TypeSafe, que aceita o conjunto completo de perguntas (até 256 perguntas, 255 opções de Choice, instructions estruturadas) e cobra 1 crédito por chamada bem-sucedida.

O SDK tenta de novo automaticamente?

O SDK da TypeSafe vem com uma política de retry padrão para erros transitórios como 429; você pode sobrescrevê-la pela opção retry do cliente. Erros de validação (422) devem ser corrigidos no corpo, não repetidos.

Qual versão do Python eu preciso?

Python 3.10 ou superior. O pacote typesafe-sdk inclui os clientes síncrono (TypeSafeClient) e assíncrono (AsyncTypeSafeClient).

Como sei qual versão do modelo respondeu?

O campo model da resposta sempre informa o id versionado que serviu a requisição — hoje jev-1.13.0 — mesmo quando você envia um alias como jev-latest.

Envie a primeira decisão

Crie uma chave, defina as duas variáveis de ambiente e rode o snippet acima.