22 de agosto de 2026
Por que o Barkan lê a tela, e não a documentação
A documentação descreve o produto em geral. O DOM descreve o produto para este usuário, agora. Um olhar por dentro de como o Barkan transforma uma página ao vivo em algo sobre o qual um modelo consegue agir.

Quando começamos a construir o Barkan, a arquitetura óbvia era a que todo mundo já tinha lançado: gerar embeddings da documentação do produto, recuperar os trechos relevantes para uma pergunta e deixar um modelo escrever a resposta. Foi o que construímos primeiro. Funcionava bem o bastante para uma demo e mal o bastante para nunca ir para produção, e a falha era sempre a mesma — a resposta estava certa sobre o produto e errada sobre o usuário. Este post é sobre a decisão que veio depois: ancorar cada resposta na interface renderizada ao vivo, e o que isso exige na prática.
A falha que mudou a arquitetura
A pergunta que derrubou a versão treinada na documentação era banal. Um testador perguntou “como adiciono uma segunda licença?” e recebeu uma resposta limpa, em seis passos, copiada direto da central de ajuda. O quarto passo mandava clicar em Adicionar membro. Na tela do testador, esse botão estava desativado, com um tooltip explicando que o plano Launch é limitado a uma licença.
A resposta não era uma alucinação. Era verdadeira, em geral, e inútil naquele caso específico. O modelo não fazia ideia de que o botão estava desativado, porque nada na documentação podia dizer a ele como estava a tela daquela conta naquele momento.
Essa é a limitação central de qualquer assistente cujo conhecimento vem de textos sobre o produto: ele conhece o produto como foi projetado, não o produto como está renderizado para este usuário. E a distância entre os dois é exatamente onde os usuários travam.
Se uma resposta depende de algo que o usuário vê, o modelo também precisa conseguir ver. A documentação pode explicar o porquê; só a interface ao vivo pode dizer onde.
O que significa “ler a tela”
Não significa capturas de tela, nem despejar o HTML no prompt. As duas opções são tentadoras e as duas falham — capturas de tela perdem a estrutura de que o modelo precisa para agir, e o HTML bruto de um app moderno são centenas de kilobytes de ruído de framework com o sinal útil enterrado no meio.
Em vez disso, quando um usuário pergunta algo, o widget captura um snapshot enriquecido do documento renderizado e o envia à API junto com a pergunta. Em linhas gerais, ele contém:
Camada · O que carrega · Por que importa
Elementos interativos · Botões, links, campos, com uma referência estável e um rótulo acessível · Para que o modelo possa apontar um controle específico e agir sobre ele
Relações · Qual rótulo pertence a qual campo, qual botão pertence a qual formulário · Transforma “o campo de e-mail” em um elemento concreto
Fatos da interface · Estados desativados, abas selecionadas, badges, contadores, erros de validação · A informação “desativado no plano Launch” que a documentação nunca teve
Blocos de conteúdo · Títulos e textos visíveis, sem duplicatas e truncados · Contexto suficiente para entender a página, não a página inteira
Resumos de formulário · O que está preenchido, o que está vazio, o que é inválido · Permite ao modelo retomar um fluxo de trabalho pela metade
Superfícies ativas e estado de rolagem · Modais e painéis laterais abertos, a viewport atual · Distingue “não está na tela” de “não existe”
Metadados da página · Rota, título, atributos de dados de uma lista de permissões · Orientação barata e confiável
Tudo isso é construído para ser pequeno, estável e honesto. Pequeno para caber no orçamento de contexto e ainda sobrar espaço para pensar. Estável para que o mesmo elemento receba a mesma referência de uma rodada para outra, o que torna possível apontar e executar ações de várias etapas. Honesto para que o modelo nunca veja um controle que o usuário não vê.
Os três problemas de engenharia que isso cria
Ancorar as respostas no DOM resolve o problema do “errado sobre o usuário” e cria imediatamente outros três. Todos valem a pena, mas são reais.
1. A interface se mexe
Um índice de documentação muda quando alguém edita um documento. O DOM muda quando qualquer coisa acontece: um dropdown abre, uma notificação aparece, uma lista termina de carregar. Um snapshot tirado um segundo cedo demais descreve uma página que já não existe.
Lidamos com isso de duas formas. O snapshot é capturado depois que a página se estabiliza — esperamos a atividade de rede em andamento e o layout sossegarem, com um limite de tempo para que uma página agitada não trave a resposta para sempre. E, no modo execução, cada ação é seguida de uma nova captura silenciosa antes de decidir o próximo passo, para que o modelo sempre aja sobre a página como ela está, não como estava.

2. Referências estáveis numa árvore instável
Dizer ao modelo “clique no terceiro botão” é frágil. Dizer “clique no elemento com id b17” só funciona se b17 significar a mesma coisa na rodada seguinte. Frameworks modernos renderizam de novo o tempo todo, então não dá para confiar na identidade dos nós do DOM.
Nossas referências derivam do que uma pessoa usaria para reconhecer o elemento — o papel, o rótulo, a posição entre os irmãos, a região (landmark) que o contém — e mantemos um mapa de curta duração da referência para o nó vivo. Quando o mapa fica desatualizado, a ação falha de forma explícita e o modelo relê a página, em vez de clicar na coisa errada. Uma ação que falha à vista é muito melhor do que uma ação bem-sucedida no elemento errado.
3. O que não enviar
Um snapshot enriquecido de um produto real contém dados reais: nomes de clientes numa tabela, o total de uma fatura, um e-mail num campo de formulário. Enviar tudo isso a um modelo por padrão não é aceitável, e “precisamos disso para o contexto” não é um motivo bom o bastante.
O snapshot é minimizado no lado do cliente antes de sair da página. O texto visível é truncado e deduplicado, os valores dos campos são resumidos como preenchido / vazio / inválido em vez de copiados, e só uma lista de permissões de atributos de dados é repassada. O objetivo é que o modelo saiba que existe uma tabela de clientes com 48 linhas e uma caixa de busca acima dela, e não quem são os clientes.
Às vezes, a minimização custa uma resposta. Se o usuário pergunta “por que o total desta fatura está errado?”, o modelo não consegue ver o número. Achamos que esse é o padrão certo: ele pode apontar o campo para o usuário e explicar como o total é calculado, sem que o valor jamais saia da página.
Mostrar em vez de dizer
Quando o modelo está ancorado na mesma interface que o usuário está vendo, torna-se possível algo que nenhum assistente treinado na documentação consegue fazer: ele pode parar de descrever e começar a apontar.
Quando a resposta menciona um elemento, o widget leva um cursor até ele na página de verdade e espera. Num fluxo de trabalho de várias etapas, esse cursor conduz o usuário de controle em controle — inclusive quando ele muda de página, porque o snapshot é refeito na nova rota. A instrução e a interface viram o mesmo objeto, e a etapa de tradução que torna a documentação tão cansativa simplesmente desaparece.
Qualquer assistente consegue dizer onde fica o botão. A diferença é se ele consegue ver que você já está olhando para a página errada.

Onde a documentação ainda importa
Nada disso significa que a documentação seja inútil para o modelo. Significa que ela tem outro papel. A documentação carrega a intenção — para que serve uma funcionalidade, quando usá-la, o que uma configuração significa — e a tela carrega o estado. Uma boa resposta muitas vezes precisa dos dois: a base de conhecimento explica que os webhooks fazem três novas tentativas, e a tela mostra que a última entrega deste webhook falhou.
Então o Barkan consulta, sim, a base de conhecimento, mas só depois de ler a tela, e a tela vence sempre que as duas discordam. Se a documentação diz que existe um botão Adicionar membro e a tela diz que ele está desativado, a resposta é sobre o botão desativado.
– Ancore as respostas na interface renderizada, não na documentação. “Verdadeiro em geral” é o tipo mais caro de erro.
– Envie estrutura, não pixels nem HTML bruto: elementos interativos, relações, fatos da interface, conteúdo resumido.
– Capture depois que a página se estabiliza e capture de novo após cada ação; o DOM é um alvo em movimento.
– Minimize no lado do cliente. O modelo deve conhecer o formato dos dados, não os dados.
– Aponte, não descreva. Se você consegue ver o elemento, consegue mostrá-lo.
A instalação continua sendo uma linha
Uma preocupação razoável é que “lê a interface renderizada” implique uma integração profunda. Não implica. O widget é uma única tag de script no layout que você já renderiza; ele monta a própria raiz num shadow DOM, observa a página de dentro do navegador e não precisa de anotações de rota nem de wrappers de componente.
<script async src="https://trybarkan.com/widget.js" data-barkan-site="site_your_key"></script>Tudo o que foi descrito acima acontece nesse script. O produto onde ele está instalado nem precisa saber que o Barkan existe.
Instale o snippet, abra o seu app e pergunte algo que a sua documentação não sabe responder. US$ 25 em créditos para começar, sem precisar de cartão.
“A maioria dos usuários não quer mais uma resposta. Quer que mostrem o caminho, ou quer a tarefa pronta. O produto inteiro é isso.”
Gabriel Lancelot
Cofundador, Barkan
