Como chamar o Jev no AiHubMix: um tutorial de classificação estruturada

AIHubMix5 min de leitura
Como chamar o Jev no AiHubMix: um tutorial de classificação estruturada

Resposta curta: o jev-1.13 não gera texto. Você envia um trecho de texto junto com um conjunto de perguntas nomeadas para https://aihubmix.com/v1/systemone e recebe de volta respostas tipadas, indexadas pelos nomes das suas perguntas: uma categoria, uma pontuação ou uma probabilidade. Não há nada para interpretar. Abaixo estão uma requisição funcional, o formato completo da resposta e o erro de design que vai reduzir sua precisão silenciosamente.

Para que serve o Jev

Use-o quando precisar de um julgamento, não de um parágrafo: direcionar um chamado de suporte, avaliar gravidade, sinalizar urgência, filtrar conteúdo. A página do modelo afirma isso de forma clara: "Sem geração de texto, nada para interpretar."

Use um modelo de chat comum quando precisar de explicações, resumos ou qualquer saída em texto livre. O jev não consegue produzir isso.

Antes de começar

  • [ ] Python 3 instalado (a biblioteca padrão é suficiente)
  • [ ] Uma conta no AiHubMix e uma chave de API
  • [ ] Chave exportada como AIHUBMIX_API_KEY, nunca escrita diretamente no código-fonte

Você não precisa do SDK da OpenAI, do LangChain nem do pacote requests.

Passo 1 — Conheça o endpoint

POST https://aihubmix.com/v1/systemone
Authorization: Bearer YOUR_KEY
Content-Type: application/json

Esta é uma rota específica do modelo, não /v1/chat/completions. Clientes compatíveis com a OpenAI não conseguem chamá-la. Use HTTP simples.

Passo 2 — Escolha os tipos de pergunta

Há três, e você pode combiná-los livremente em uma mesma requisição:

TipoUse paraVocê fornece
choiceEscolher uma categoriacriteria como um dicionário: rótulo → definição
scoreAvaliação em uma escala ordenadacriteria como uma lista, do menor para o maior
noulUm julgamento sim/nãonada além de instructions

Passo 3 — Monte a requisição

state é o texto a ser avaliado. As chaves de questions são nomes que você define; a resposta usa os mesmos nomes.

payload = {
    "model": "jev-1.13",
    "state": "Hi, I have been trying to connect my Stripe account for 3 days "
             "and it keeps failing. I am losing sales. Please help ASAP.",
    "questions": {
        "department": {
            "type": "choice",
            "instructions": "Which team should handle this",
            "criteria": {
                "billing":   "Payment or subscription issues",
                "technical": "Bugs or integration problems",
                "sales":     "Pricing or account questions",
            },
        },
        "frustration": {
            "type": "score",
            "instructions": "How frustrated the customer appears",
            "criteria": [
                "Calm, just stating facts",
                "Frustrated but civil",
                "Very angry, strong language",
            ],
        },
        "is_urgent": {
            "type": "noul",
            "instructions": "The message conveys urgency or time-sensitivity",
        },
    },
}

Passo 4 — Envie com a biblioteca padrão

import json, os, urllib.error, urllib.request

def ask(payload):
    req = urllib.request.Request(
        "https://aihubmix.com/v1/systemone",
        data=json.dumps(payload).encode(),
        headers={"Authorization": "Bearer " + os.environ["AIHUBMIX_API_KEY"],
                 "Content-Type": "application/json"},
        method="POST",
    )
    try:
        with urllib.request.urlopen(req, timeout=60) as r:
            return json.loads(r.read())
    except urllib.error.HTTPError as e:
        raise SystemExit(f"HTTP {e.code}: {e.read().decode(errors='replace')[:500]}")

Mantenha a construção da requisição dentro de uma função. Se você montar e enviar no nível do módulo, importar o arquivo dispara a chamada novamente e consome tokens.

Passo 5 — Leia as respostas

Cada resposta armazena seu valor em uma chave correspondente ao seu type, então um único acessor cobre os três tipos:

data = ask(payload)
for name, ans in data["answers"].items():
    kind = ans["type"]
    print(name, kind, ans[kind], ans.get("confidence"))
print("usage:", data.get("usage"))

Saída verificada:

department   choice  billing   0.51
frustration  score   1         1
is_urgent    noul    1         None
usage: {'input_tokens': 424, 'output_tokens': 73}

Passo 6 — Entenda o envelope completo

O loop de impressão oculta campos úteis. O JSON bruto de uma resposta do tipo score:

{
  "type": "score",
  "score": 1,
  "legend": {"0": "Calm, just stating facts", "1": "Frustrated but civil", "2": "Very angry, strong language"},
  "probabilities": {"0": 0, "1": 1, "2": 0},
  "confidence": 1
}
  • legend associa o índice de volta à sua própria redação — o inteiro é autoexplicativo, então você não precisa de uma tabela de consulta no seu código.
  • probabilities fornece a distribuição completa, útil para detectar um empate próximo.
  • noul não tem campo confidence. Sua probabilidade é o sinal.

O nível superior também retorna usage, id, provider (TypeSafe) e a versão do backend resolvida typesafe/jev-1.13-20260917.

O erro que reduz sua precisão

Na requisição acima, department retornou billing com confiança de 0,51. Repetindo a mesma requisição, o mesmo rótulo voltou com 0,38 — a resposta foi estável, mas a certeza declarada não.

A causa está nos critérios, não no modelo. billing é "Problemas de pagamento ou assinatura" e technical é "Bugs ou problemas de integração". Uma integração com o Stripe que continua falhando realmente se encaixa nas duas. O modelo estava refletindo uma ambiguidade que estava escrita no esquema.

Duas regras antes da produção:

  1. Escreva critérios choice que sejam mutuamente exclusivos. Se um humano hesitaria entre dois rótulos, o modelo também hesitará.
  2. Defina um limite de confiança e encaminhe resultados de baixa confiança para uma fila humana, em vez de aceitá-los como decisões. Um modelo que admite incerteza é mais valioso do que um que a esconde.

Checklist pré-lançamento

  • [ ] Chave carregada a partir do ambiente ou de um arquivo com permissão 600 que o seu VCS ignora
  • [ ] Critérios choice revisados quanto à sobreposição
  • [ ] Limite de confiança definido, com um caminho de fallback abaixo dele
  • [ ] Respostas noul tratadas separadamente — elas não têm confidence
  • [ ] Perguntas não utilizadas removidas (3 perguntas custam 424 tokens de entrada; 2 custam 355)
  • [ ] Respostas não 2xx registradas com o corpo bruto

Perguntas frequentes

Posso usar o SDK da OpenAI? Não. /v1/systemone não é uma rota compatível com a OpenAI.

O jev pode retornar uma frase ou resumo? Não. Ele responde apenas às perguntas tipadas que você definir.

Quantas perguntas por requisição? Os testes verificados usaram duas e três. Cada pergunta adiciona tokens de entrada e de saída, então inclua apenas o que você vai usar.

Existe um alias de versão? A página do modelo lista um alias jev-latest junto com jev-1.13. Fixe a versão explícita se a reprodutibilidade for importante.

Quanto custa? A página do modelo publica $0.0462 / M de tokens de entrada e $0 / M de tokens de saída. Esses são valores do fornecedor — confirme os preços atuais antes de planejar o orçamento.

Qual é a janela de contexto? A página do modelo é inconsistente: 64K no cabeçalho e 32K na tabela do provedor. Verifique com a sua entrada mais longa antes de confiar em qualquer um dos dois.

Escopo deste guia

Tudo acima foi verificado com três chamadas reais usando uma única entrada. Não abrange latência, processamento em lote, throughput ou o comportamento com entradas diferentes do exemplo. A variação de confiança é uma observação reproduzida, não uma taxa de erro medida — repita-a com os seus próprios dados antes de definir um limite.

Comece a usar no AiHubMix

jev-1.13 está disponível no AiHubMix, e a página do modelo reúne tudo o que este tutorial citou: o endpoint /v1/systemone, os três tipos de pergunta com os formatos de criteria, todos os campos da resposta e os preços publicados de $0.0462 / M tokens de entrada e $0 / M tokens de saída. O alias jev-latest aponta para a versão mais recente, então se mantém atualizado conforme as versões mudam.

Comece aqui: https://aihubmix.com/model/jev-latest

Próximos passos:

  1. Crie uma conta no AiHubMix e gere uma chave de API
  2. Copie a requisição do Passo 3 e a função ask() do Passo 4
  3. Substitua state por um registro real da sua própria fila
  4. Compare o resultado com a forma como você classifica esse registro hoje

Se este guia foi útil, inscreva-se para receber futuros posts sobre modelos de saída estruturada e pipelines de classificação.

Um só gateway para vários provedores de IA. Feito para produção.

Acessar AIHubMix