Jev 与 Laya 实测:决策模型和 LLM 各自擅长什么
Jev e Laya além do hype: o que modelos de decisão fazem que o LLM não faz
作者分享在个人 Agent 工作流中用 TypeSafe 的决策模型 Jev 和开源引擎 Laya 做任务分类、再用 LLM 写作的路由实践。Jev 输出有限标签加校准置信度,托管价 $0.042/百万输入 token,Laya 可本地离线运行但阈值需单独调校;作者估计决策评估比 GPT-4 便宜约 50 到 100 倍,并强调这只是 POC 结论,未上生产。
No meu setup de agentes, eu fiz o que todo dev faz no começo: cada subagente acordava com o melhor modelo do SWE-bench por padrão. Typo no README, rename de variável, tudo rodando no topo do ranking. Com 5 spawns por dia, parecia produtividade. Quando o volume cresceu, veio a fatura e a inconsistência: a mesma tarefa simples consumia o modelo caro, e o custo por tarefa só subia. Traduzindo para produto: cada pedido simples pagava preço de especialista, e ninguém sabia dizer por quê.
A saída foi o Downshift: separar quem decide de quem resolve. Antes de qualquer modelo caro rodar, uma camada fina olha e despacha. Tarefa corporativa vai para um lado, dev pessoal para outro, admin para outro. Resposta curta, sempre igual: um destino. O modelo que resolve entra depois, com contexto. Produto lê assim: triagem antes do especialista. Dev lê assim: gateway antes do serviço. O erro era pedir para o serviço fazer o trabalho do gateway o dia inteiro.
A virada para mim foi separar as duas funções no desenho: Jev e Laya para decidir, LLM para escrever quando precisa. O Jev é o decision model da TypeSafe e a Laya é o engine open-source que fala o mesmo protocolo. Nenhum dos dois gera texto. Eles escolhem entre opções finitas. E essa separação deixa o resultado mais determinístico e a conta mais barata. Até o fim, você sai com as três respostas sem hype: o que cada um faz, quando cada um vence e quanto custa decidir.
Transparência de escopo, antes de continuar: com Jev e Laya eu só fiz POCs até aqui, nada em produção. Os números de preço e protocolo são reais e verificados, mas as conclusões de operação vêm de experimento local, não de tráfego pagante. O que já roda de verdade no meu dia a dia é o Downshift, e é de lá que vêm os exemplos da seção 8.
Índice
- 1. LLM adivinha a próxima palavra, Jev escolhe uma porta
- 2. Jev na prática: saída finita, confiança e log
- 3. Quando texto livre vence: o LLM entra depois da decisão
- 4. A dupla que economiza token: Jev filtra, LLM só entra quando precisa
- 5. Trade-offs honestos de modelo de decisão contra LLM
- 6. Antes de mandar pro modelo caro
- 7. Evidência: o que a pesquisa sustenta
- 8. Jev e Laya no seu harness pessoal
1. LLM adivinha a próxima palavra, Jev escolhe uma porta
LLM é um modelo generativo. Ele prevê a próxima palavra dada a sequência anterior. Por isso ele escreve, resume, traduz e explica bem. E por isso a mesma pergunta pode gerar três respostas diferentes, com temperatura, ordem e contexto mudando o resultado.
Jev é o oposto: um modelo classificador e de decisão. Ele é produto real, o System One decision model da TypeSafe, disponível como typesafe/jev-1.13 no OpenRouter. Ele recebe um estado e devolve uma entre N classes que você definiu antes, com probabilidade calibrada e tipos nativos como noul, choice e score. Exemplos reais que vejo no dia a dia:
entrada: "minha fatura veio dobrada, quero estorno"
Jev -> { label: "reembolso", confidence: 0.94 }
entrada: "onde acompanho minha entrega?"
Jev -> { label: "rastreio", confidence: 0.91 }
entrada: "quero falar do plano anual para 40 pessoas"
Jev -> { label: "comercial", confidence: 0.88 }
Nada de parágrafo. Só etiqueta mais confiança. E Laya também não é apelido: é um engine System One open-source que expõe o mesmo protocolo /v1/systemone do Jev, com modelos english, multilingual e typed-decisions (ver guia de uso), para decidir local sem API key. Quem redige a resposta final para o cliente é um LLM comum, que entra depois que a rota já foi decidida.
A diferença que importa para um mid-level recontar em uma frase: LLM escreve texto aberto e varia; Jev aponta uma porta entre poucas portas e repete.
2. Jev na prática: saída finita, confiança e log
Um classificador simples resolve sem GPU, sem prompt de 2 mil tokens, sem retry criativo. Exemplo mínimo em Python, que qualquer dev roda local:
from sklearn.feature_extraction.text import TfidfVectorizer
from sklearn.linear_model import LogisticRegression
texts = [
"quero reembolso da fatura",
"cobrança duplicada no cartão",
"onde está minha entrega",
"rastrear meu pedido",
"orçamento para empresa",
"plano anual para time",
]
labels = ["reembolso", "reembolso", "rastreio", "rastreio", "comercial", "comercial"]
vec = TfidfVectorizer()
X = vec.fit_transform(texts)
jev = LogisticRegression().fit(X, labels)
def jev_decide(frase: str) -> dict:
proba = jev.predict_proba(vec.transform([frase]))[0]
idx = proba.argmax()
return {"label": jev.classes_[idx], "confidence": round(float(proba[idx]), 2)}
print(jev_decide("fui cobrado duas vezes"))
# {"label": "reembolso", "confidence": 0.81}
Três propriedades que o LLM não te dá de graça:
-
Saída finita: só existem
reembolso,rastreio,comercial. Dá para validar comenum, testar com tabela, auditar no Grafana. - Confiança calibrável: abaixo de 0.70 você manda para revisão humana ou para o LLM com contexto extra. Acima, segue o fluxo automático.
- Determinismo: mesma entrada, mesma saída. Sem temperatura para tunar, sem prompt que quebra porque alguém mudou uma vírgula.
É por isso que time de suporte e pagamento gosta de decisor: dá para escrever teste unitário em cima. Com LLM puro, cada teste vira aproximação semântica.
Isso não é opinião. Em intenção com rótulo fixo, pequeno fine-tuned ainda vence grande generativo: em Banking-77 e CLINC-150, DistilBERT superou Phi-2 e Llama-3-8B com PEFT, com F1 em torno de 0.92 contra 0.88 e 0.83, treinando e inferindo mais rápido. Em CLINC-150 com 151 intenções, DistilBERT marcou 0.889 de acurácia com 5.3ms contra 0.888 da RoBERTa. Para tabular, CatBoost, LightGBM e XGBoost seguem no topo do benchmark amplo com 20 modelos, à frente de MLP e ResNet na maioria dos datasets.
3. Quando texto livre vence: o LLM entra depois da decisão
Seria desonesto dizer que Jev resolve tudo. Quando a resposta precisa de nuance, contexto longo ou empatia, texto livre vence.
Cena que o classificador não resolve sozinho:
cliente: "assinei o anual ontem, mas meu sócio saiu hoje
e vamos reduzir de 40 para 6 pessoas. Consigo ajustar
sem multa? Estou preocupado com o orçamento."
Jev -> { label: "comercial", confidence: 0.83 }
LLM -> redige proposta com 2 opções, cita cláusula
de redução, sugere data de vigência e pergunta qual prefere.
O Jev acertou a rota em milissegundos. Mas só o modelo generativo monta a resposta com tom, condição e alternativa. Tentar fazer isso com regra e template vira um ninho de if que ninguém mantém depois de três meses.
Regra prática que uso: Jev e Laya decidem o quê fazer; o LLM decide como dizer.
4. A dupla que economiza token: Jev filtra, LLM só entra quando precisa
O ganho de token não vem de mágica. Vem de não chamar o modelo caro para o trabalho barato. Em uma frase: o roteador tira do LLM a triagem, a classificação e o gate de confiança, e deixa para ele só a redação final. O resto desta seção mostra como isso fica em código.
Padrão que tenho aplicado, roteador antes do gerador:
type Rota = "reembolso" | "rastreio" | "comercial" | "revisao_humana";
async function atender(ticket: string): Promise<string> {
const decisao = await jevDecide(ticket); // Jev via API ou Laya local: milissegundos, custo quase zero
if (decisao.confidence < 0.7) {
return filaRevisao(ticket, decisao); // humano decide, sem gastar LLM
}
if (decisao.label === "rastreio") {
return respostaTemplateRastreio(ticket); // nem chama LLM
}
// só aqui o LLM entra, já com rota e contexto enxuto
return llmResponder(ticket, decisao.label);
}
Por que isso corta custo de verdade:
- Ticket de rastreio nunca acorda o LLM: lookup mais template.
- Ticket ambíguo vai para humano antes de gastar retries; quando o LLM entra, o prompt já vem curto e com a intenção resolvida.
- Sem chave de API ou offline, a Laya decide local no mesmo protocolo, sem mudar o request.
Laya no seu dia a dia: o mesmo request, sem API key. Suba o laya-serve local e aponte o cliente para ele. O protocolo é o mesmo do Jev, então o código que você testa na máquina é o que falaria com o gerenciado:
// TYPESAFE_BASE_URL=http://localhost:8002 TYPESAFE_API_KEY=local-test (Laya local)
// TYPESAFE_BASE_URL=https://api.typesafe.ai (Jev gerenciado)
const res = await fetch(`${process.env.TYPESAFE_BASE_URL}/v1/systemone`, {
method: "POST",
headers: {
"Authorization": `Bearer ${process.env.TYPESAFE_API_KEY}`,
"Content-Type": "application/json",
},
body: JSON.stringify({
model: "typed-decisions", // na Laya: english, multilingual ou typed-decisions
state: { ticket: "fui cobrado duas vezes na fatura" },
questions: {
rota: {
type: "choice",
instructions: "Para qual fila vai este ticket?",
labels: ["reembolso", "rastreio", "comercial"],
},
confianca_baixa: {
type: "noul",
instructions: "O pedido está ambíguo ou fora do escopo das filas?",
labels: { yes: "Ambíguo", no: "Claro" },
},
},
}),
});
const { answers } = await res.json(); // tipado, com probabilidade: sem parsing de texto
Três usos que a POC me pagou:
-
Dev local sem key: testo o roteador no
localhostantes de gastar um token sequer. -
CI: o teste do roteador vira assert em cima de
answers.rota, igual teste deenum. - Fallback: sem rede ou sem verba de API, a Laya decide local; com chave, o mesmo código fala com o Jev.
Esquema completo de campos no comparativo Laya vs Jev. E re-tune não é conselho vago, é número: para a distribuição {0.91, 0.04, 0.03, 0.02}, a Laya reporta confiança ~0.71, onde a fórmula de probabilidade máxima daria ~0.88. Mesmo request, gate diferente. Calibre o corte por fonte:
const corte = fonte === "laya" ? 0.6 : 0.7; // Laya e Jev não compartilham threshold
if (decisao.confidence < corte) return filaRevisao(ticket, decisao);
Em termos de harness: Jev é guia computacional antes da geração. Ele é barato, testável e roda no PR e CI como qualquer código. O LLM fica como passo inferencial depois do gate, com trilha de auditoria do que o decisor escolheu. Se um dia o decisor errar, você tem label, confiança e entrada no log, não um prompt gigante para adivinhar o que aconteceu.
Quanto custa decidir, em números verificados:
-
Jev gerenciado: $0.042 por milhão de tokens de entrada, saída grátis (preço do Jev 1.13). Cada resposta traz
usage.costem dólar: dá para logar custo por rota junto com label e confiança. - Laya local: custo marginal perto de zero. Você paga a máquina que já tem mais o download do modelo, e decide offline quantas vezes quiser.
- Ordem de grandeza (estimativa da minha POC, não benchmark): avaliação via decisor sai cerca de 50 a 100x mais barata que a mesma avaliação via GPT-4, que custa por token de entrada e de saída a cada retry.
Por isso a conta fecha: o roteador tira do LLM as chamadas baratas e repetidas (triagem, classificação, gate de confiança) e deixa para ele só a redação final. Cada ticket de rastreio que nunca acorda o LLM é token que não aparece na fatura.
O número que sustenta esse desenho vem de roteamento entre modelos: RouteLLM economizou até 3.66x no MT-Bench mantendo 95% da qualidade do GPT-4, e FrugalGPT em cascata economizou de 50% a 98% mantendo a acurácia do melhor modelo isolado. A lógica é a mesma do Jev: não acordar o modelo caro para o trabalho barato.
5. Trade-offs honestos de modelo de decisão contra LLM
Visão Staff, sem hype de mercado. Cada linha abaixo já me mordeu ao menos uma vez.
| Dimensão | Jev (decisão) | LLM generativo |
|---|---|---|
| Determinismo | Alto, mesma entrada repete | Baixo, varia por temperatura e contexto |
| Custo por chamada | Quase zero, roda local | Pago por token, cada retry conta |
| Latência | Milissegundos | Centenas de ms a segundos |
| Dados para começar | Precisa de exemplos rotulados | Funciona com zero ou poucos exemplos |
| Mudança de escopo | Exige retreino ou nova regra | Muda com prompt, sem retreino |
| Texto aberto | Não faz | Faz bem |
| Falha típica | Erra calado fora da distribuição | Inventa com confiança |
Três cuidados que o hype esconde:
- Decisor apodrece em silêncio. Se surge um produto novo ou um golpe novo, o Jev continua classificando com confiança alta no vocabulário velho. Sem monitoramento de distribuição e re-rotulagem periódica, vira débito técnico.
- Rótulo custa gente. LLM aceita 5 exemplos no prompt. Jev pede centenas de exemplos revisados para ficar estável. Esse custo aparece no planejamento, não na demo.
- LLM cobre o buraco do decisor. Classe nova, idioma novo, caso raro: o LLM atende no improviso enquanto você coleta dados para treinar o Jev. Arquitetura boa usa os dois, não elege um vencedor.
Deixar claro, porque já vi confusão em review: Jev e Laya não são mini ChatGPTs. Eles não conversam, não resumem, não escrevem. Laya cai na mesma coluna do Jev, com duas diferenças práticas: roda local e open-source, e os thresholds precisam ser re-tunados porque a confiança é calculada de outro jeito. Se você pedir texto para eles, vai receber etiqueta. Se pedir decisão auditável para o LLM puro, vai receber parágrafo bonito que muda amanhã.
6. Antes de mandar pro modelo caro
Antes de colar a tarefa no chat, pergunta o seguinte. Se você não usa roteador nenhum, a pergunta ainda vale: o modelo caro precisa mesmo desta conversa?
- [ ] A resposta cabe numa palavra só? "typo", "bug pequeno", "feature", "arquitetura". Se cabe, não peça um parágrafo para descobrir isso.
- [ ] Você precisa de texto de verdade? Descrição de PR, explicação, plano. Aí sim o modelo escreve, depois que o tipo da tarefa já está claro.
- [ ] Dá para conferir a resposta como você confere um teste? Se a saída certa é sempre a mesma, não deixe o modelo inventar uma versão nova a cada retry.
- [ ] Você ainda não tem exemplos guardados? Usa o modelo caro agora, anota o que ele classificou, e na próxima vez essa nota vira a regra.
- [ ] A tarefa mexe em algo que não dá para desfazer fácil? Push, deploy, migration, pagamento. Na dúvida, você confirma. O modelo não aplica sozinho.
- [ ] Semana que vem você vai lembrar dos erros? Se ninguém olha quando a classificação errou, ela continua errando no mesmo lugar.
É a pausa de dez segundos antes de pedir para o modelo mais caro corrigir um typo.
7. Evidência: o que a pesquisa sustenta
Sem prometer número do seu ticket. Estes são os benchmarks nos datasets deles, que uso como limite do que dá para afirmar:
- Tabular: benchmark com 20 modelos coloca CatBoost, LightGBM e XGBoost no topo, à frente de deep learning na maioria dos datasets (completo, XGBoost vs LightGBM).
- Intenção: DistilBERT fine-tuned vence Phi-2 e Llama-3-8B em Banking-77 e CLINC-150, com F1 0.92 contra 0.88 e 0.83 (Intent Recognition using DistilBERT). Em CLINC-150, 0.889 de acurácia com 5.3ms de inferência (avaliação BERT, RoBERTa e DistilBERT). Híbrido encoder mais LLM mantém precisão com cerca de 50% menos latência (Intent Detection in the Age of LLMs).
- Few-shot: TabLLM vence com 8 exemplos ou menos, mas com ajuste de split o LightGBM melhora 290% e a vantagem cai 84.5%. A partir de 16 a 64 exemplos, GBDT empata por fração do tempo (GBDT and LLMs for few-shot). Fusão LLM mais GBDT vence no meio do caminho (LLM-Boost).
- Roteamento: RouteLLM com 3.66x no MT-Bench, 1.41x no MMLU e 1.49x no GSM8K, ver também blog LMSYS.
- Jev real: documentação no OpenRouter, tutorial de primeira chamada e preço e providers do Jev 1.13 ($0.042/M tokens de entrada, saída grátis).
- Laya real: comparativo Laya vs Jev (mesmo protocolo, confiança com cálculo próprio, re-tunar thresholds) e guia de uso no Spring AI.
- Cascata: FrugalGPT com 50% a 98% de economia, paper final em TMLR.
Onde tenho segurança para recomendar Jev: saída em enum, alto volume, precisa de auditoria e latência baixa. Onde não prometo número: economia exata no seu fluxo. Meça acerto, confiança e custo por rota por um mês antes de cravar.
8. Jev e Laya no seu harness pessoal
Tudo acima usou o cenário de suporte ao cliente. No seu Cursor ou Kiro do dia a dia, o mesmo desenho economiza token de outro jeito, em três pontos:
1. Roteador de modelo. Antes de chamar o modelo caro, o Jev classifica a tarefa: typo e rename vão para o barato, code review vai para o intermediário, gate de PRD vai para o Opus. É o model routing por harness: a decisão custa fração de centavo e evita que tarefa simples acorde o modelo mais caro.
2. Juiz local em vez de LLM-judge. Revisar o próprio draft com outro LLM custa uma segunda chamada cheia de contexto. Com a Laya local, você pontua o rascunho com perguntas noul e score (foi o que a skill humanizar faz com jev_questions.json): determinístico, offline, custo marginal zero. O LLM só volta se a nota ficar abaixo do corte.
3. Gate antes do loop do agente. Classifique o pedido antes de montar o contexto: leitura (grep, git log) libera na hora; escrita (push, deploy) pede confirmação e carrega a skill do domínio. Skill é texto sob demanda, agente com contexto gordo é token queimado. O decisor mantém o prompt magro.
pedido -> Jev/Laya classifica -> barato ou caro? -> leitura ou escrita?
simples + leitura -> modelo barato, tools livres
complexa + escrita -> modelo forte, skill do domínio, confirmação humana
No seu setup, cada linha dessa tabela que vira default economiza um acionamento do modelo caro por dia. Em um mês, é a diferença entre "IA ficou cara" e "IA se paga".
No Downshift, o estudo virou decisão. O roteador aplica exatamente o que este artigo prega: classifica a tarefa e despacha para o tier mais barato que dá conta. Exemplo real, sem mock:
$ downshift try "fix a typo in the README"
Task: fix a typo in the README
Complexity: TRIVIAL
Needs tier: small
Recommend: claude-haiku-4-5
→ TRIVIAL task → use claude-haiku-4-5 (small tier)
$ downshift try "rearchitect the payment flow across services"
Task: rearchitect the payment flow across services
Complexity: COMPLEX
Needs tier: frontier
Recommend: claude-opus-4-8
→ COMPLEX task → use claude-opus-4-8 (frontier tier)
Typo vai de Haiku, re-arquitetura vai de Opus, e nenhum LLM participou da classificação. E aqui a jornada fecha o círculo: as POCs com Jev e Laya me apresentaram o mundo dos mini-LMs. Estudando eles, a camada de classificação do Downshift ficou plugável: o hook continua igual, o backend de decisão troca sem tocar no resto. Entre as opções, eu optei por um classificador local por similaridade a protótipos, no mesmo desenho do MiniLM. O que o Downshift liga por padrão hoje é um embedding hash determinístico (hash-embed-v1), sem Python e sem GPU. Ele só sobe a classe quando o regex não está confiante, e nunca rebaixa. O MiniLM de verdade entra se você apontar DOWNSHIFT_MINILM_EMBED para um comando. Sem o comando, o hash segura o hook.
O teste do MiniLM de verdade, à parte do binário, foi assim. Peguei o modelo pequeno all-MiniLM-L6-v2 (roda em CPU, formato ONNX, sem GPU) e pedi para ele transformar cada prompt num ponto num espaço. Depois calculei o "endereço médio" de cada classe com 200 exemplos já rotulados: um ponto para TRIVIAL, um para SIMPLE, um para MEDIUM, um para COMPLEX. Na hora de classificar, o prompt novo vai para a classe cujo endereço está mais perto. Isso é o argmax: escolhe o vizinho mais próximo, sem desempate.
Separei 300 prompts que o modelo não viu no treino, todos em inglês, e medi.
- Acertou 287 de 300, 95,7%.
- Quando a classe vencedora estava claramente mais perto que a segunda (margem de 0,02), isso aconteceu em 94,7% dos casos, e aí o acerto subiu para 97,9%. A margem é a folga entre o primeiro e o segundo lugar. Folga pequena significa dúvida, e dúvida não deveria trocar o regex.
- Cada prompt levou 1,87 ms na mediana. 95% deles ficaram abaixo de 2,96 ms.
- Onde erra: MEDIUM, 85,3%. TRIVIAL 97,3%. SIMPLE e COMPLEX, 100%. O meio é o que se confunde com os vizinhos.
Esse número é desse modelo, não do hash que o binário usa hoje. Quando o dataset tiver português, o teste precisa ser refeito com um MiniLM multilingual. Decisor decide, gerador escreve, humano veta.
Curtiu sair do hype e ver o que Jev, Laya e esses micro-LMs fazem de verdade? Então me conta nos comentários: na sua próxima tarefa, o modelo vai escrever ou só escolher? E o que você vai mudar a partir de amanhã?
来源:Google AI:DEV 作者专属(RSS) · dev.to