← Todos os artigos

Caderno Basicx / Moda e recomendação

Motor de recomendação de moda:
o LLM propõe, o motor garante.

Como transformar o método de uma especialista em recomendações com peças reais, regras verificáveis e espaço para dizer “não sei”.

Ilustração conceitual: peças de um closet passam por uma validação antes de compor sugestões de looks.
Ilustração conceitual · criada com IA

O que este projeto mostra

  • O modelo propõe cinco candidatos; regras e validações selecionam três looks com peças do closet real.
  • Os resultados são medidos em testes do projeto. Passar nos gates não equivale a comprovar a qualidade em produção.
  • O julgamento de ocasião com Jev está atrás de uma flag, desligada por padrão.

O problema: "com o que eu uso isso?"

Recomendar moda não é prever o próximo clique. É responder uma pergunta que nenhum widget de e-commerce responde: o que funciona junto, para esta pessoa, nesta ocasião — e por quê.

O recomendador clássico de varejo responde outra pergunta: "quem levou A também levou B". Isso é estatística de carrinho. Ela não sabe o que é um look, não conhece "reunião com cliente" e regride ao gosto médio. Também exige histórico, que um cliente novo não tem.

Neste projeto, o ponto de partida foi diferente: um método de consultoria de imagem já existente, criado por uma consultora especializada. A meta não era aprender gosto com cliques. Era codificar o critério de uma especialista e fazê-lo escalar a cerca de US$ 0,05 por recomendação.

Este artigo conta como o motor foi construído, como ele é avaliado e o que os números mostraram — inclusive onde eles contrariaram a intuição.

Arquitetura: o LLM propõe, o motor garante

A regra que organiza tudo: o modelo de linguagem é trocável; a garantia do método fica nas camadas determinísticas. O primeiro experimento mostrou o LLM sozinho errando o básico — inventando peça, formalizando por padrão. Por isso ele nunca tem a última palavra.

Uma recomendação passa por cinco etapas:

  1. Recuperação. Busca no corpus de 147 looks validados os exemplos mais próximos do registro da ocasião (íntimo, social, profissional ou festa). O retrieval é lexical e estruturado, com MMR para variar os exemplos.
  2. Proposta. O LLM recebe o guia do método, os exemplos e o closet da cliente. Devolve um pool de 5 candidatos com peças-âncora variadas.
  3. Normalização. Código puro ancora cada peça no closet real, pontua os candidatos com 12 features derivadas das regras do método e seleciona 3 looks distintos.
  4. Guards. Regras de veto têm a última palavra: tecido × ocasião, cor de calçado, combinações reprovadas pela especialista, lacuna que sugere peça que a cliente já tem.
  5. Pós-validação. Checa invariantes da saída final. Se um guard alterou o look, a justificativa antiga é apagada em vez de mentir.

Só a etapa 2 depende do modelo de linguagem; as três seguintes podem alterar ou vetar o que ele propôs.

A saída é um look com ocasião nomeada, uma linha explicando por que funciona e, quando o acervo não fecha, uma recusa honesta com a peça específica que falta.

O que ficou de fora, com número

Duas apostas óbvias perderam na medição:

  • Embeddings de moda no retrieval. FashionCLIP acertou o registro da ocasião em 65% dos casos; o retrieval lexical e estruturado, em 98%. O espaço visual não conhece "reunião com cliente".
  • Modelo de compatibilidade treinado em Polyvore. Ficou em ~56% no teste de completar o look. Regras derivadas das avaliações da especialista foram melhores, porque codificam um método e não o gosto médio de rede social.

A escolha do LLM virou decisão de preço, não de arquitetura. Com a camada determinística, Claude Sonnet 4.5, Claude Haiku 4.5, GPT-5-mini e até um Qwen 9B local passaram em 100% dos gates. O Haiku fez o mesmo com custo 66% menor e latência 46% menor.

Como avaliar um motor que não tem clique para otimizar

Sem histórico de cliques, a fonte de verdade é o olho da especialista. A primeira rodada de avaliação cobriu 24 células (closet × ocasião) e 42 looks. Dela saíram as regras de veto: nenhuma entra sem 0 falso-positivo contra as avaliações dela e ratificação na rodada seguinte.

O juiz não é um LLM

Testamos um LLM-juiz com exemplos. Ele concordou com a especialista em 72% a 76% dos vereditos — abaixo da linha de base ingênua de "aprovar tudo" no voto por look, e sistematicamente mais severo que ela. Foi estacionado.

No lugar, um juiz determinístico conta padrões-problema conhecidos em cada saída. É menos ambicioso e muito mais útil: estável, auditável e barato de rodar a cada mudança. Os padrões reprovados na primeira rodada estão zerados desde a segunda.

Um eval em camadas

Camadas de avaliação e critérios de aceite
CamadaO que medeBarra
L0 contratopeças existem no closet, 3 looks distintos, sem jargão100% / 0%
L1 regras durasviolações de veto, por um detector independente dos guards0
L2 padrões reprovadoscombinações que a especialista recusou0
L2b honestidaderecusa só quando o closet de fato não cobre100%

O detector da L1 é separado dos guards de propósito. Um guard que se auto-avalia sempre passa.

Onde o eval ainda engana

100% no gate não é qualidade. Os limites que conhecemos:

  • Gold circular. Uma anotadora, uma rodada, e os mesmos looks geraram e validaram as regras.
  • Uma execução por célula num motor estocástico. Algumas células oscilam entre execuções.
  • Testes no motor errado. A maior parte de uma suíte de ~980 testes verdes cobria o motor legado, não o caminho que a usuária vê.

Julgar a ocasião com o Jev

Antes de chamar o LLM, o motor precisa saber em que registro cai a ocasião. Esse registro muda os exemplos recuperados e liga ou desliga o guard contra sobre-formalização. Até aqui, uma tabela de palavras-chave decidia.

A tabela falha de dois jeitos previsíveis. Não devolve nada quando a ocasião não tem palavra da lista ("show de rock", "day off"). E classifica pela palavra errada: "happy hour com colegas depois do trabalho" vira profissional por causa de "trabalho".

Por que um modelo de julgamento, e não mais um prompt

O Jev, da TypeSafe, é um modelo de julgamento tipado. Recebe um estado em JSON e perguntas com critérios escritos. Devolve uma escolha, a distribuição de probabilidade e a confiança — e não gera texto. O código consome a resposta direto, sem parsing.

Cada recomendação faz uma chamada com duas perguntas, nos eixos do próprio método:

  • Onde: casa ou lazer, espaço social, trabalho híbrido, trabalho formal, evento ou cerimônia — ou "não dá para saber".
  • Diante de quem: só íntimos, gente que vê, quem avalia — ou "não dá para saber". O eixo mede exposição, não companhia: família num restaurante ainda é gente que vê.

Uma regra fechada, em código, combina os dois eixos no registro. Trabalho ou alguém que avalia dá profissional; evento dá festa; os dois eixos em aberto dão ambíguo.

O que mediu

Na primeira rodada, com 51 ocasiões rotuladas por uma pessoa, o Jev acertou 92,2% do registro e a tabela, 74,5%. Um segundo revisor reavaliou os casos e endureceu os rótulos. Contra esse gold, a versão em dois eixos marcou 74,5% e a tabela, 58,8%. O número absoluto caiu; a vantagem de ~16 pontos ficou.

Nos casos em que o revisor foi claro, o Jev acertou 87% no eixo "onde" e 93% no "diante de quem". Deu a mesma resposta nas 3 execuções em 50 de 51 casos. O erro mais comum é o oposto do da tabela: onde o revisor disse "não dá para saber", o Jev tende a supor um espaço social.

As 153 chamadas do teste custaram US$ 0,005, a ~0,3 s cada. Com o Jev ligado, os evals de cobertura e de cold start rodaram 3 vezes em cada modo, sem queda: groundedness e recusa correta seguiram em 100%.

Como entrou no motor

  1. Um eixo que o app já informou nunca é sobrescrito.
  2. Nos demais, vale o Jev; eixo com confiança abaixo de 0,5 vira "não dá para saber".
  3. Erro, timeout de 2 s ou falta de chave caem na tabela antiga. O julgamento nunca derruba a recomendação.

O eixo em aberto é o ganho que a tabela não tinha. "Jantar" sozinho sai como ambíguo, e o app pode perguntar à cliente só o que falta — onde vai ser, com quem — em vez de gerar no chute.

A integração está atrás de uma flag, desligada por padrão. O próximo teste usa 30 a 50 ocasiões reais, anonimizadas; é ele que decide se a flag vira padrão.

O que o Jev não faz

  • Não monta look. Não escolhe peça nem substitui guard; as regras validadas ficam em código.
  • Não substituiu tudo que testou. Para classificar atividade física, deu empate com a tabela (90% × 94%), e a tabela ficou.
  • Não dispensa disciplina. O texto do critério é código. Exemplos que coincidiam com o teste inflaram o acerto de 92% para 96%; os critérios em uso não têm nenhum.

Telemetria: medir o que a seleção não mostra

O seletor MMR equilibra relevância e diversidade para escolher 3 looks do pool de 5. Uma revisão externa do motor levantou duas perguntas que a telemetria não respondia.

  1. E se a relevância vira constante? Se o LLM dá notas quase iguais a todos os candidatos, o termo de relevância do MMR some. A seleção degenera em diversidade pura, sem ninguém perceber. Agora cada recomendação registra média, desvio e amplitude da relevância do pool. Se o desvio ficar perto de zero no tráfego real, o plano é trocar notas por posições antes do MMR.
  2. E se os guards colapsam a variedade? Um guard pode trocar a mesma peça em dois looks e torná-los iguais. Esse colapso acontecia depois da seleção e era invisível. Agora é marcado na telemetria de cada recomendação.

O padrão vale para além deste caso: antes de mexer no algoritmo, instrumentar a pergunta. Um A/B de 24 células entre MMR e DPP deu diversidade 0,826 × 0,838 — dentro do ruído. Com um pool de 5, o seletor mais sofisticado não tem espaço para brilhar. O MMR ficou.

O retrieval passou pelo mesmo crivo. Num teste offline com 61 looks, sem LLM, cada look buscou a si mesmo: recall@8 de 1,0 e MRR de 0,958. Os pesos estão saudáveis, e o teste roda de novo a cada mudança de corpus.

Onde isso se encaixa no mercado

O motor não substitui o recomendador de um e-commerce. Ele ocupa um momento que nenhum widget ocupa: "eu levo, mas com o que eu uso isso?" — a dúvida que trava compra de ticket alto.

Comparação das abordagens de recomendação
FamíliaComo decideLimiteO que muda aqui
Filtro colaborativocorrelação de comprasem ocasião, sem porquê, exige históricocritério codificado; funciona com 5 perguntas de perfil
Similaridade visualproximidade no espaço de imagemparecido não é combina98% × 65% no acerto de registro
Complete-the-lookco-ocorrência editorialgenérico, ignora o que a pessoa já temcloset real primeiro, catálogo em complemento
Compatibilidade treinadagosto médio de outfits de rede socialcodifica a média, não um métodoregras da especialista superaram o scorer
LLM-stylisto modelo "acha"alucina peça, não garante nadagroundedness 100% medido
Stylist humanoespecialista realcaro, lento, não escala~US$ 0,05 por recomendação

Dois traços nenhuma dessas famílias tem:

  • Recusa honesta. Todo recomendador empurra algo; o incentivo é encher a vitrine. Este recusa quando o closet não fecha e diz qual peça falta. A especialista aceitou 8 de 8 recusas na validação. Somadas, as recusas viram um mapa do que falta no sortimento.
  • Explicação auditável. Cada decisão tem trilha: qual regra agiu, de onde ela veio e o que mudou no look.

O que os incumbentes fazem melhor também precisa ser dito: personalização comportamental em escala massiva e busca visual. Isso exige volume de cliques que um produto novo não tem.

Lições e próximos passos

Cinco lições valem para qualquer motor de recomendação construído sobre um LLM:

  1. Deixe o LLM propor e o código decidir. A camada determinística tornou o modelo trocável. A escolha de LLM virou uma conta de custo com gate de qualidade.
  2. Meça antes de adotar a técnica da moda. Embeddings, DPP e modelos treinados perderam ou empataram com soluções mais simples, no tamanho de corpus que temos.
  3. Use um juiz que você consegue auditar. Um contador determinístico de padrões reprovados foi mais útil que um LLM-juiz com 72% de concordância.
  4. Cada regra pontual sem eval é uma regressão esperando. Diretrizes "filosóficas" adicionadas ao prompt reintroduziram sobre-formalização; só o eval de cold start pegou.
  5. Saber recusar é produto. A recusa honesta foi o traço mais bem avaliado pela especialista e o que nenhum concorrente quer copiar.

Os próximos passos, em ordem:

  • Extração visual das peças com um modelo de visão (Qwen3-VL). Destrava 72% das 163 regras do método, que hoje dependem de atributos que o cadastro não preenche.
  • Feedback de uso (gostei, não gostei, usei) voltando para o eval e para o gold. É o que fecha o ciclo de personalização.
  • Segunda rodada da especialista sobre o motor de produção, que decide a troca para o Haiku.
  • Um A/B de arquitetura: o LLM propõe × o motor propõe e o LLM só explica. Quando a extração visual chegar, essa é a decisão mais importante do roadmap.
Termos usados neste artigo
LLM
Modelo de linguagem que gera as propostas de looks.
Guards e gates
Guards vetam saídas que violam regras. Gates são critérios de aprovação nos testes.
Gold
Conjunto de avaliações usado como referência para comparar resultados.
MMR e DPP
Abordagens para selecionar opções considerando relevância e diversidade.
Groundedness
Verificação de que as peças recomendadas existem no acervo fornecido.
Flag
Configuração que permite habilitar ou desabilitar uma funcionalidade.

Da regra à aplicação

Seu método pode fazer parte da solução.

Converse sobre recomendações construídas com o conhecimento da sua operação.

Conheça a solução de recomendação
Finalidades