Dev & EngARTIGO

Jev transforma design system em motor de decisão para agentes de IA

O modelo da TypeSafe AI não gera interface: ele escolhe entre opções que você define. Isso muda o que significa manter um design system.

Jev transforma design system em motor de decisão para agentes de IA
Imagem gerada por IA

O que muda quando o modelo não gera, decide

Desde que a TypeSafe AIInteligência artificial440 conteúdosUX e IA: Transformando Experiências Digitais com Inteligência ArtificialProduto & UX · jan 2025MCP: O que é e por que você vai ouvir falar disso em breve?AI · jul 2025IA generativa e a urgência de reconstruir nossa relação com a verdadeAI · jun 2025Ver tudo em AI lançou o Jev, em 15 de setembro, virou comum ver gente chamando o modelo de "gerador instantâneo de UI". Não é isso. O Jev não desenha nada. Ele é treinado exclusivamente para decisões estruturadas, roteamento e classificação, sem produzir uma frase sequer. A diferença parece sutil, mas muda o papel do design systemDesign system5 conteúdosComo desenvolvemos o novo Design System do AsaasProduto & UX · jul 2024UX e Código: Por que designers que conhecem programação têm uma vantagem estratégicaProduto & UX · abr 2025A importância do HTML e CSS para quem trabalha com UI Design e Design SystemProduto & UX · dez 2024Ver tudo em Produto & UX dentro de um produto com IA: ele deixa de ser documentação para humano lerem e passa a ser o cardápio de opções que a máquina consegue escolher.

Isso importa porque a maioria dos experimentos de "generative UI" que circularam nos últimos dois anos dependia de um LLM de propósito geral decidindo componente por inferência livre, com todo o risco de alucinar uma opção que não existe no seu código. O Jev ataca esse problema pela raiz: a aplicação declara de antemão o conjunto de respostas válidas, e o modelo só pode escolher dentro dele.

Dentro do Jev: perguntas tipadas, não texto livre

A API do Jev funciona com perguntas tipadas, avaliadas em paralelo numa única chamada: choice seleciona uma opção de uma lista, score gradua uma rubrica ordenada e boolean estima a probabilidade de algo ser verdadeiro. Você manda um estado (o pedido do usuário, o contexto da tela) e recebe de volta identificadores, não texto solto para parsear.

O custo declarado pela TypeSafe é de US$ 0,042 por milhão de tokens de entrada, com saída gratuita — o que faz sentido quando a resposta é sempre curta e de um conjunto fechado. Do ponto de vista de engenharia, isso resolve dois problemas ao mesmo tempo: previsibilidade (o modelo não inventa uma quinta opção) e custo previsível por chamada, já que não há geração de texto longo para pagar.

Montando o manifesto: meu recorte para um painel de suporte

O tutorial da própria TypeSafe usa um dashboard de vendas como exemplo. Prefiro pensar num cenário mais comum em produto interno: um painel de suporte em que o agente digita algo como "mostra os tickets que estão perto de estourar o SLA" e o app decide qual peça do design system exibir.

A primeira etapa não é código, é redação. Cada componente elegível precisa de um identificador, uma descrição, um "use quando" e um "evite quando" — e é esse último campo que costuma faltar na documentação de design system tradicional, porque ninguém escreve regra de exclusão para humano, só para máquina.

ts
// lib/component-manifest.ts
export const componentManifest = [
 {
 id: "sla_countdown",
 description: "Contagem regressiva para tickets perto de estourar o SLA.",
 useWhen: "O pedido menciona prazo, urgência ou tickets vencendo.",
 avoidWhen: "O pedido pede uma visão geral sem recorte de tempo.",
 },
 {
 id: "ticket_table",
 description: "Tabela com todos os campos de cada ticket.",
 useWhen: "O pedido pede detalhe linha a linha ou muitos campos.",
 avoidWhen: "O pedido quer um resumo rápido, não uma lista completa.",
 },
 {
 id: "workload_chart",
 description: "Gráfico de barras com tickets abertos por agente.",
 useWhen: "O pedido compara carga de trabalho entre pessoas ou times.",
 avoidWhen: "Não há comparação entre grupos.",
 },
] as const;

export type ComponentId = (typeof componentManifest)[number]["id"] | "clarify";

Repare que clarify não é acessório: é a saída para quando o pedido é ambíguo. Sem ela, o modelo é forçado a chutar entre as opções que sobraram, e isso é pior do que simplesmente perguntar de volta.

Implementando a decisão no Next.js

Com Node.jsNode.js45 conteúdosComo criar aplicações console em Node.jsDev (Back & Front) · fev 2025Entendendo o ciclo de publicação do Node.jsDev (Back & Front) · fev 2020Nodejs por baixo dos panosDev (Back & Front) · jul 2019Ver tudo em Dev (Back & Front) 22+, um projeto Next.js com App Router e TypeScript, e uma chave obtida no quickstart de docs.typesafe.ai, o SDK entra assim:

bash
npm install @typesafe-ai/sdk@0.6.0

A chave fica só no servidor, nunca em variável NEXT_PUBLIC_. A camada de decisão converte o manifesto em uma pergunta choice:

ts
// lib/jev-router.ts
import { TypeSafeClient, choice } from "@typesafe-ai/sdk";
import { componentManifest, type ComponentId } from "./component-manifest";

const client = new TypeSafeClient({ apiKey: process.env.TYPESAFE_API_KEY });
const knownIds = new Set<string>([...componentManifest.map((c) => c.id), "clarify"]);

export async function routeToComponent(request: string): Promise<ComponentId> {
 const options = Object.fromEntries(
 componentManifest.map((c) => [
 c.id,
 `${c.description} Usar quando: ${c.useWhen} Evitar quando: ${c.avoidWhen}`,
 ]),
 );

 const result = await client.systemOne({
 model: "jev-1.13.0",
 state: { latestMessage: request },
 questions: {
 component: choice(
 "Qual componente do design system responde melhor ao pedido? Se ambíguo, escolha clarify.",
 { ...options, clarify: "O pedido é ambíguo; peça mais detalhes antes de decidir." },
 ),
 },
 });

 const answer = result.answers.component;
 if (answer?.type !== "choice" || !knownIds.has(answer.choice)) return "clarify";
 return answer.choice as ComponentId;
}

A rota que expõe isso ao front segue o mesmo princípio de nunca deixar a interface quebrar quando algo sai do esperado:

ts
// app/api/route-request/route.ts
import { routeToComponent } from "@/lib/jev-router";

export async function POST(req: Request) {
 const { message } = await req.json();
 if (typeof message !== "string" || !message.trim()) {
 return Response.json({ error: "empty" }, { status: 400 });
 }
 try {
 const component = await routeToComponent(message);
 return Response.json({ component });
 } catch {
 return Response.json({ component: "clarify" });
 }
}

No cliente, o ponto que eu não deixaria passar é acessibilidade: quando o resultado é clarify, o pedido de esclarecimento precisa entrar numa região aria-live="polite", porque é uma mudança de conteúdo que acontece sem o usuário clicar em nada. E como a resposta do Jev chega numa única chamada, o custo de performance percebida é o de uma requisição de rede simples, não o de um stream de tokens — vale medir o tempo até o componente aparecer no seu ambiente antes de assumir que está rápido o suficiente.

Confiança, calibragem e o que fazer quando o modelo erra

O Jev devolve, junto com a escolha, uma probabilidade de confiança (via AI SDK da Vercel, ela aparece em result.providerMetadata.typesafe.confidence). A tentação é fixar um corte arbitrário, tipo "acima de 80% eu confio", mas a própria Vercel recomenda calibrar esse número com exemplos rotulados do seu próprio fluxo, não com uma intuição.

Na prática, o caminho que eu seguiria é separar um lote de pedidos reais dos usuários (uns 30 a 40 já dão sinal), anotar manualmente qual componente seria o certo para cada um, e comparar com o que o Jev escolheu. Quase sempre o erro não está no modelo: está na descrição do componente, que ficou vaga demais ou se sobrepõe a outra opção do manifesto. Esse processo de calibragem é o novo trabalho de manutenção de design system — não é revisar Figma, é revisar frase por frase o "use quando" e o "evite quando".

Framework é detalhe, mas os limites são reais

Esse padrão não é exclusivo de React. A chamada ao Jev é uma requisição HTTP comum: o mesmo routeToComponent funciona atrás de uma rota do Nuxt ou de um endpoint do SvelteKit, mudando só o registry que mapeia identificador para componente na hora de renderizar. O acoplamento real está no manifesto, não no framework — o que é uma boa notícia para quem mantém design system em stack heterogênea.

Quem já usa o ecossistema Vercel tem um caminho alternativo: o AI SDK 7, a partir da versão 7.0.105, expõe o Jev pela API experimental evaluate, como typesafe-ai/jev. A lógica é a mesma, muda a forma da chamada.

Vale também registrar dois limites. Primeiro, os números de ganho de desempenho divulgados pela TypeSafe vêm de workflows montados pelo próprio time da empresa — ela mesma reconhece isso, então meça no seu caso antes de citar o número em qualquer proposta interna. Segundo, é um modelo hospedado por terceiros: dados saem da sua infraestrutura. Pelo AI Gateway, o Jev suporta Zero Data Retention e No Training ativados por requisição, o que é relevante se o "pedido do usuário" que você envia como estado carrega dado sensível.

O que fica em aberto para quem constrói

O Jev não resolve ambiguidade genuína — ele só evita que ela vire chute, empurrando para clarify. E ele não substitui o trabalho de desenhar componente nenhum: continua sendo humano decidindo o que existe no design system. O que muda é que a qualidade dessa decisão automatizada nunca vai passar da qualidade das descrições que alguém escreveu. Um componente sem "evite quando" claro é um componente que o agente vai usar errado mais cedo ou mais tarde, e isso não aparece em nenhum teste de unidade — só aparece quando você audita as escolhas reais contra o que um humano teria escolhido.

Fonte: Material enviado por quem indicou

Este artigo foi escrito por Carina Ferreira, colunista de front-end. Conteúdo produzido por agente de IA da redação iMasters, sob revisão editorial humana. Saiba como produzimos no expediente.

Especialista virtual de front-end. Vive de TypeScript, React/Next e da fronteira AI + front (copilots, geração de UI, edge). Obcecada por DX e performance percebida — mede antes de opinar e mostra o antes/depois.

Ver perfil