Sistemas de design para uso agentivo
Este skill informa decisões de design; ele não as impõe. Toda recomendação pode perder para um objetivo legítimo do projeto (expressividade de especialistas, necessidades de marca, limites de plataforma, convenções existentes). Nomeie a troca e delegue a uma escolha contrária deliberada. Os exemplos são React e TypeScript porque é onde os priores do modelo são mais nítidos; o raciocínio se transpõe para qualquer stack.
O objetivo
Um modelo gerador de código é um amostrador. Ele emite o programa que considera mais plausível dado o que aprendeu no treinamento (o prior) e o que está na sessão (o contexto), então mantém o que sobrevive às verificações que pode executar. Uma API voltada para humanos pergunta "a coisa certa pode ser expressa?" Uma API voltada para agentes pergunta "de tudo o que parece certo, quanto é realmente certo?" Portanto, o objetivo tem duas metades: tornar o programa mais provável o correto, e tornar os programas improváveis falharem antes de serem enviados.
Isso é design de API comum (o "fácil de usar corretamente, difícil de usar incorretamente" de Bloch, o "tornar estados ilegais irrepresentáveis" de Minsky, o poço do sucesso) sob duas suposições mais estritas: a familiaridade do consumidor é uma distribuição mensurável sobre código público, e o consumidor verifica apenas o que pode executar.
Três propriedades do consumidor
Tudo abaixo deriva destas. Leia Livro de evidências quando uma afirmação abaixo importar para uma decisão ou você precisar medir localmente; ele tem fontes, ressalvas de escopo e o protocolo de medição.
-
O prior é moldado por frequência, misturado por versão e não corrigível. Um modelo conhece um padrão na proporção de quão frequentemente ele apareceu no treinamento; a precisão aumenta log-linearmente com a frequência no corpus. Cada versão de uma biblioteca que já apareceu é sobreposta em uma única distribuição, e é por isso que os modelos emitem APIs obsoletas 25 a 38% do tempo e obtêm cerca de 50% em tarefas fixadas em versões. Nada que uma biblioteca publique pode editar isso. Só pode ser igualado ou sobreposto.
-
O contexto sobrepõe o prior, mas apenas o contexto que está realmente presente. Prompts extraídos de código desatualizado produziram 70 a 90% de uso obsoleto; prompts extraídos de código atual produziram 9 a 18%. Código irmão no arquivo orienta a saída mais do que qualquer coisa que uma biblioteca publique. Documentação recuperada ajuda; um rótulo de versão simples ajuda um pouco. Documentação publicada que o agente nunca carrega não faz nada.
-
Apenas feedback executável é verificação. O verificador de tipos é determinístico, barato e sempre no loop, e 94% dos erros de compilação em TypeScript gerado por LLM são erros de tipo, então ele pega muita coisa. Renderização é cara, precisa de configuração, e o julgamento visão-linguagem de layout é fraco mesmo com uma captura de tela em mãos. Tudo que os tipos não codificam é enviado se o modelo errar.
Duas consequências. O custo do erro é assimétrico: um humano vê uma falha e a corrige em segundos, a falha de um agente é enviada, então "fácil de corrigir" vale muito menos do que "difícil de errar". E a evolução deve ser aditiva: uma renomeação ou uma mudança de significado custa agentes até o próximo treinamento e a forma antiga nunca sai totalmente da distribuição, então quando você precisar quebrar, coloque a migração nos tipos e na documentação colocalizada, não apenas em um changelog.
Três movimentos
Toda alavanca de design é um destes. Ao avaliar um design, pergunte qual movimento ele faz e qual ele prejudica.
Movimento 1: faça o palpite padrão ser o correto
O primeiro palpite do agente é prior mais contexto visível. Duas coisas o moldam.
Nomes são apostas em distribuições. O valor de um nome é nitidez vezes concordância: quão unívoco é seu uso público, vezes se esse significado é o seu. Nitidez acompanha tamanho do corpus, idade e estabilidade, então vocabulário de especificações HTML e CSS vence padrões de nomes ARIA vence palavras pan-biblioteca (sm/md/lg, primary/danger, solid/outline/ghost) vence idiomas de qualquer biblioteca única; ancore tão fundo quanto a semântica permitir. Concordância é binária, e um nome familiar com comportamento diferente é o pior caso: o modelo aplica o significado aprendido com confiança e o código compila. Quando nenhum nome nítido concorda com sua semântica, componha um novo a partir de gramática aprendida. Page/PageHeader/PageTitle não existe em nenhuma biblioteca importante, mas a conjugação X/XHeader/XTitle carrega hierarquia e ordem de filhos gratuitamente e permanece encontrável em autocomplete e no próprio plano do agente. Uma prop cujo significado depende de outra prop (align sob uma chave direction) são duas apostas acopladas; desacople-as em um componente por eixo ou nomes explícitos. O ganho é um grau de liberdade a menos, não um prior resgatado; modelos lidam bem com a troca de eixo do próprio CSS.
O codebase visível é o prompt. Usos irmãos, o catálogo e o exemplo canônico são o que o agente realmente condiciona. Regularidade comprime esse prompt: se todo componente conjuga os mesmos eixos com o mesmo vocabulário, dois componentes no contexto ensinam o catálogo inteiro, e cada sinônimo ou exceção por componente é um fato separado que precisa ser ensinado e geralmente não é. O catálogo particiona a saída: agentes planejam em unidades como "page header" e "toolbar" antes de ler código e forçam o plano através do que quer que exista, então nomeie componentes conforme essas unidades. O que os exemplos mostram se torna o fluxo de trabalho, incluindo substituições className; mostre o caminho pretendido e mantenha exemplos com versão correspondente e colocalizados com o código que o agente deve tocar.
A força do prior justifica conformar-se na sintaxe que o agente deve escrever. Nunca justifica expor uma decisão que o agente não deveria tomar; isso é o Movimento 3.
Movimento 2: faça a saída errada falhar antes de ser enviada
Qualquer coisa que um renderizador ou runtime teria pego deve falhar mais cedo, ou é enviada.
Onde os tipos podem expressar, coloque no tipo. Uniões fechadas em vez de combinações booleanas que ninguém projetou. Uniões discriminadas para props dependentes de modo. Omit o que uma parte não suporta em vez de documentar "não use isso aqui". Props obrigatórias para as camadas de significado que deixam para o consumidor (títulos de diálogo, rótulos de botões de ícone, texto de erro; Radix e React Aria avisam sobre isso apenas em um console que o agente nunca vê). Erros de compilação para os casos não suportados de asChild/as, ou variantes explícitas não polimórficas como ButtonLink. O teste é o mesmo toda vez: um agente completando a prop vê o vocabulário legal, e o programa ilegal não compila.
Onde os tipos não podem expressar, torne a divergência visível onde o código é escrito. Nomes carregam expectativas de layout que nenhum tipo codifica (um contêiner possui seu padding, um bloco preenche seu pai, espaçamento vem de lacunas do pai; o estudo de caso as lista). Um componente que quebra a expectativa que seu nome cria compila e renderiza silenciosamente errado na única dimensão que o agente não pode ver. Sinalize a quebra no local de chamada (uma prop obrigatória, um nome não conflitante) ou no contexto que o agente carrega de forma confiável (uma regra ao lado do código). Documentação que o agente não encontrará não conta.
Movimento 3: remova a decisão
Uma decisão cuja correção só é visível quando renderizada pertence à biblioteca, não ao local de chamada. Um princípio em quatro granularidades:
- Valores. Quantifique toda magnitude e resolva aparência através de papéis semânticos:
gap="3"etone="danger"no local de chamada, px e hex no tema. Modelos conhecem mecânica de flex e grid; eles não podem escolher 12 versus 16 cegamente, e escolhas independentes derivam entre arquivos em um ritmo que ninguém vê. Palavras-chave de especificação (justify="space-between") mantêm a semântica livre enquanto a escala remove o palpite. - Composição. Possua layout, não apenas widgets. A regra do Braid é a versão limpa: componentes não possuem espaços em branco externos, e componentes de layout possuem todo o espaçamento. Um sistema que para no limite do widget faz todo local de chamada improvisar.
- Padrões. Onde uma composição recorre (
FormField,EmptyState,PageHeader,ConfirmDialog), publique-a. Cada re-derivação de primitivas é uma chance de divergir. - Adaptação. Lide com viewport, comprimento do conteúdo, direção de escrita, preferências de movimento e contraste, e estados de carregamento/vazio/erro por construção, ou exija-os no tipo. Lógica de mídia no local de chamada é uma decisão cega.
Saídas de emergência (className, style, variáveis CSS) devem existir e ficar abaixo do caminho padrão em probabilidade: disponíveis, classificadas, nunca destacadas. Se elas são o fluxo de trabalho demonstrado, o Movimento 1 as tornou o palpite padrão.
O regime decide legibilidade versus contrato
Duas filosofias coerentes existem; shadcn é a declaração mais clara da primeira.
- Legibilidade. Publique código-fonte no repositório. O agente lê e edita, e o estilo é visível onde está escrito. Correto quando o agente possui os componentes: ele abrirá o arquivo, e implementação legível (estilo colocalizado, indireção mínima) é o que ele precisa.
- Contrato. Exponha uma API tipada e esconda a implementação. Correto quando o agente consome os componentes do código da aplicação: ele vê importações, tipos e alguns usos irmãos, e raramente abre a implementação. Estilo legível é estilo editável, e estilo no local de chamada é a entropia que o Movimento 3 remove.
A maioria dos sistemas precisa de ambos, divididos por público: legibilidade para quem mantém components/, contrato para todos que importam dele. Decida em qual regime um arquivo está antes de aplicar os movimentos. Leia Estudo de caso shadcn quando o sistema é construído sobre ou comparado com shadcn; ele trabalha o que manter, o que mudar e por quê.
Tensões
Duas, cada uma com várias faces. Nomeie a troca; não finja que é gratuita.
- Probabilidade concentrada versus expressividade. Cada grau de liberdade removido é a capacidade perdida de alguém. Aparece como componentes de intenção versus primitivas, eixos fechados versus props ortogonais, e esticar um eixo versus dividi-lo (estique enquanto cada valor responde à mesma pergunta; a variante
Buttondo shadcn, fundindo intenção, tratamento e identidade do elemento, é o eixo fundido canônico). A saída de emergência classificada é a resposta usual. - Alinhamento de prior versus propriedade. Corresponder à convenção compra correção gratuita e importa as falhas e mudanças da convenção. Aparece como nomes familiares versus distintos (distintos custam encontrabilidade; nomes novos conformes à gramática recuperam a maior parte) e como favorável ao prior versus melhor projetado. Divergir custa alinhamento uma vez; uma falha mantida custa correção para sempre.
Meça em vez de confiar
As três propriedades são medidas no nível do modelo. Os movimentos são mecanismos consistentes com essas medições, não medidos em nenhuma biblioteca de UI; o arquivo de evidências marca qual é qual. Antes de adotar uma regra, execute-a: 20 a 40 tarefas de UI realistas, amostradas várias vezes por regime (sem contexto, tipos mais dois usos irmãos, fonte completa); pontue compilação na primeira tentativa, mau uso pego pelos tipos versus silencioso, variância de tokens entre locais de chamada irmãos, lint de acessibilidade e uma passada visual curta; mude uma decisão de design; execute novamente. Mantenha o que move os números.
Lista de verificação de revisão
- Movimento 1: um modelo familiar com bibliotecas comparáveis adivinharia isso na primeira tentativa, e se o nome for emprestado, ele se comporta de forma idêntica? O exemplo canônico mostra o caminho pretendido?
- Movimento 2: todo mau uso realista falha ao compilar? Onde a expectativa visual de um nome é quebrada, a quebra é visível onde o código é escrito?
- Movimento 3: algum valor, composição, padrão ou adaptação é deixado para o local de chamada decidir cegamente?
- Regime: este arquivo é possuído ou consumido pelo agente, e a escolha legibilidade/contrato é deliberada?
- Evolução: essa mudança quebraria código escrito a partir do prior do ano passado, e a migração é visível nos tipos e na documentação colocalizada?