Como Chamar Jev no AiHubMix: Um Tutorial de Classificação Estruturada

AIHubMix5 min de leitura
Como Chamar Jev no AiHubMix: Um Tutorial de Classificação Estruturada

Resposta curta: jev-1.13 não gera texto. Você POSTA um trecho de texto mais um conjunto de perguntas nomeadas para https://aihubmix.com/v1/systemone, e você recebe de volta respostas digitadas associadas aos nomes das suas perguntas — uma categoria, uma pontuação ou uma probabilidade. Nada para analisar. Abaixo está um pedido funcional, o formato completo da resposta e o único erro de design que custará silenciosamente a precisão.

Para que serve o Jev

Use-o quando você precisa de um julgamento, não de um parágrafo: roteamento de um ticket de suporte, pontuação de severidade, sinalização de urgência, controle de conteúdo. A página do modelo afirma isso claramente — "Sem geração de texto, nada para analisar."

Use um modelo de chat normal quando você precisar de explicações, resumos ou qualquer saída em formato livre. jev não pode produzir isso.

Antes de começar

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

Você não precisa de um SDK da OpenAI, LangChain ou 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 OpenAI não podem chamá-la. Use HTTP simples.

Passo 2 — Escolha seus tipos de perguntas

Existem três, e você pode misturá-las livremente em um pedido:

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 — Construa o pedido

state é o texto a ser julgado. questions as chaves são nomes que você inventa; a resposta usa os mesmos nomes.

payload = {
    "model": "jev-1.13",
    "state": "Oi, estou tentando conectar minha conta do Stripe há 3 dias "
             "e continua falhando. Estou perdendo vendas. Por favor, ajude o mais rápido possível.",
    "questions": {
        "department": {
            "type": "choice",
            "instructions": "Qual equipe deve lidar com isso",
            "criteria": {
                "billing":   "Problemas de pagamento ou assinatura",
                "technical": "Erros ou problemas de integração",
                "sales":     "Questões de preços ou conta",
            },
        },
        "frustration": {
            "type": "score",
            "instructions": "Quão frustrado o cliente parece",
            "criteria": [
                "Calmo, apenas afirmando fatos",
                "Frustrado, mas civil",
                "Muito irritado, linguagem forte",
            ],
        },
        "is_urgent": {
            "type": "noul",
            "instructions": "A mensagem transmite urgência ou sensibilidade ao tempo",
        },
    },
}

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 do pedido dentro de uma função. Se você construir e enviar em nível de módulo, importar o arquivo reativará a chamada e gastará tokens.

Passo 5 — Leia as respostas

Cada resposta armazena seu valor sob uma chave correspondente ao seu type, então um acessador cobre os três:

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

Saída verificada:

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

Passo 6 — Entenda o envelope completo

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

{
  "type": "score",
  "score": 1,
  "legend": {"0": "Calmo, apenas afirmando fatos", "1": "Frustrado, mas civil", "2": "Muito irritado, linguagem forte"},
  "probabilities": {"0": 0, "1": 1, "2": 0},
  "confidence": 1
}
  • legend mapeia o índice de volta para sua própria redação — o inteiro é auto-descritivo, 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 de confidence. Sua probabilidade é o sinal.

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

O erro que custa precisão

No pedido acima, department retornou billing com uma confiança de 0.51. Repetir o pedido idêntico retornou o mesmo rótulo a 0.38 — a resposta foi estável, a certeza declarada não.

A causa está nos critérios, não no modelo. billing é "Problemas de pagamento ou assinatura" e technical é "Erros ou problemas de integração." Uma integração do Stripe que continua falhando realmente se encaixa em ambas. O modelo estava relatando uma ambiguidade que foi escrita no esquema.

Duas regras antes da produção:

  1. Escreva critérios de 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 direcione 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 oculta.

Lista de verificação pré-lançamento

  • [ ] Chave carregada do ambiente ou um arquivo em modo 600 que seu VCS ignora
  • [ ] choice critérios revisados para sobreposição
  • [ ] Limite de confiança definido, com um caminho de fallback abaixo dele
  • [ ] Respostas noul tratadas separadamente — elas não carregam 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

FAQ

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

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

Quantas perguntas por pedido? Os testes verificados usaram duas e três. Cada pergunta adiciona tokens de entrada e saída, então inclua apenas o que você irá agir.

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

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

Qual é a janela de contexto? A página do modelo é inconsistente: 64K em seu cabeçalho, 32K na tabela do fornecedor. Verifique contra sua própria entrada mais longa antes de confiar em qualquer um dos dois.

Escopo deste guia

Tudo acima foi verificado com três chamadas ao vivo contra uma única entrada. Não cobre latência, agrupamento, throughput ou comportamento em entradas diferentes do exemplo. A deriva de confiança é uma observação reproduzida, não uma taxa de erro medida — repita em seus próprios dados antes de definir um limite.

Comece no AiHubMix

jev-1.13 está disponível através do AiHubMix, e a página do modelo contém tudo o que este tutorial referenciou: o endpoint /v1/systemone, os três tipos de perguntas com seus formatos de criteria, os campos completos da resposta e a precificação publicada de $0.0462 / M tokens de entrada com $0 / M tokens de saída. O alias jev-latest resolve-se para o lançamento mais recente, então permanece atual à medida que as versões mudam.

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

Próximos passos:

  1. Crie uma conta AiHubMix e gere uma chave API
  2. Copie o pedido 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 futuros posts sobre modelos de saída estruturada e pipelines de classificação.