- O resultado de um experimento de 2 dias sugere que é apropriado descrever o Claude Fable 5 como "relentlessly proactive"
- Apenas com uma captura de tela e um prompt de uma linha, ele executou um servidor local de desenvolvimento, operou navegadores reais e até inseriu código de medição para rastrear a causa de um bug de CSS
- O Fable tentou reproduzir o bug alternando entre Playwright, Firefox, WebKit e Safari e, após falhar, encontrou uma janela real do navegador e configurou por conta própria uma automação de capturas de tela
- Para testar a caixa de diálogo modal aberta pela tecla
/, ele inseriu JavaScript no template do Datasette e gerou eventos de teclado após o carregamento da janela para criar o estado necessário
- Para obter medições internas da página, ele criou um servidor de coleta com CORS baseado em Python
http.server e salvou em JSON as informações do <textarea> dentro do shadow DOM de um Web Component
- Agentes de código poderosos conseguem fazer no terminal o que um usuário faria, então executá-los fora de um sandbox aumenta os riscos de prompt injection e vazamento de dados
Processo de depuração do Claude Fable 5
- Começou investigando uma barra de rolagem horizontal desnecessária que apareceu no prompt de chat do menu de salto do Datasette Agent
- O Claude Fable 5 mobilizou ativamente várias técnicas para atingir o objetivo
- A entrada consistia em uma captura de tela e um prompt de uma linha:
Look at dependencies to help figure out why there is a horizontal scrollbar here
- Foi solicitado que ele examinasse primeiro o código das dependências, com a hipótese de que a causa do problema poderia estar nas dependências do Datasette Agent, especialmente no próprio Datasette
- O Claude Code, sem instruções explícitas de automação de navegador, abriu uma janela comum do Firefox e foi até a caixa de diálogo em questão; depois abriu também uma janela do Safari para continuar a investigação
Automação de capturas de tela no navegador
- O Fable montou sua própria abordagem para tirar capturas de tela de janelas do navegador usando
uv run --with pyobjc-framework-Quartz
- Em Python, percorreu todas as janelas da máquina e filtrou as janelas do Safari cujo nome continha strings esperadas como
"textarea"
- Depois de encontrar um identificador inteiro de janela, como
153551, salvou um PNG com a CLI screencapture
- Escreveu uma página HTML temporária como
/tmp/textarea-scrollbar-test.html, abriu no Safari e obteve a captura de tela
- O comando de exemplo foi
screencapture -x -o -l 153551 /tmp/safari-cases.png
Execução automática da caixa de diálogo modal
- A modal em teste só podia ser aberta por clique ou atalho de teclado, e não havia um mecanismo claro para executar movimento do mouse ou atalhos de teclado dentro do Safari
- O Claude estava rodando na pasta que continha o código-fonte da aplicação e entendeu a estrutura o suficiente para executar o servidor local de desenvolvimento do Datasette
- Ele adicionou JavaScript ao template do Datasette para simular o pressionamento da tecla
/ depois que a janela fosse aberta
- Esse código dispara um evento
keydown da tecla / 1,2 segundo após o carregamento da janela, acionando o atalho que abre a caixa de diálogo modal
<script>
window.addEventListener("load", function () {
setTimeout(function () {
document.dispatchEvent(new KeyboardEvent("keydown", {key: "/", bubbles: true}));
}, 1200);
});
</script>
Coleta de medições internas da página
- O Claude precisava executar JavaScript na página para obter medições diretamente e, para isso, escreveu sua própria aplicação web para receber informações via CORS
- Usou a biblioteca padrão do Python
http.server para executar um servidor local em 127.0.0.1:9999
- O servidor recebia requisições POST com JSON, registrava os dados em
/tmp/diag.json e enviava o cabeçalho Access-Control-Allow-Origin: * para permitir comunicação com código de outros domínios
- O Claude inseriu JavaScript no template carregado pelo navegador para localizar o
<textarea> dentro do Web Component <navigation-search>
- O código inserido media
devicePixelRatio, scrollWidth, clientWidth, whiteSpace e width, e enviava isso ao servidor local
const host = document.querySelector("navigation-search");
const ta = host.shadowRoot.querySelector("textarea");
const cs = getComputedStyle(ta);
fetch("http://127.0.0.1:9999/diag", {
method: "POST",
body: JSON.stringify({
dpr: window.devicePixelRatio,
scrollWidth: ta.scrollWidth, clientWidth: ta.clientWidth,
whiteSpace: cs.whiteSpace, width: cs.width,
}),
});
Troca para Opus e verificação da correção
- Depois de descobrir várias técnicas, o Fable esbarrou em guardrails invisíveis e foi rebaixado para o Opus
- O Opus tinha acesso a todo o histórico da conversa e continuou usando as técnicas abertas pelo Fable
- Em seguida, o Opus encontrou o problema, testou, validou e concluiu o commit de correção
- O Opus resumiu em
/tmp/automation-report.md as técnicas de automação usadas contra navegadores reais na sessão, com exemplos de código executável
- Esse relatório foi compartilhado em um gist separado, e o registro completo do terminal do Claude Code também foi publicado
Revisão completa do que foi feito
- O Claude Fable 5 e o Claude Code descobriram como executar o servidor local de desenvolvimento e também configuraram variáveis de ambiente fictícias necessárias para isso
- Iniciaram uma sessão Playwright Chrome e ativaram a configuração de barras de rolagem visíveis do Chrome com
defaults write com.google.chrome.for.testing AppleShowScrollBars Always, desligando-a depois
- Também passaram por Firefox e WebKit do Playwright, mas não conseguiram reproduzir o bug
- Identificaram que o navegador padrão era o Safari e criaram o documento HTML
textarea-scrollbar-test.html
- Abriram o documento de teste no Firefox real, mas o acesso via
osascript foi bloqueado por “osascript is not allowed assistive access”
- Encontraram o desvio com
pyobjc-framework-Quartz e montaram um fluxo de capturas de tela baseado em número de janela
- Adicionaram JavaScript ao template do site para disparar a tecla
/ e receberam dados JSON por um servidor CORS em Python
- Passaram pelo shadow DOM do Web Component, encontraram as informações necessárias e confirmaram a causa do bug no Safari
- Aplicaram uma possível correção em um template personalizado, confirmaram o funcionamento e então relataram como resolver o problema
Estimativa de custo
- O plano em uso era o Claude Max de US$ 100 por mês, e a Anthropic informou que daria uma franquia generosa para o Fable até 22 de junho, cobrando depois o preço integral da API
- O AgentsView foi usado para acompanhar os gastos, e, se o preço cheio tivesse sido cobrado, o custo daquela sessão seria de cerca de US$ 12,11
- A saída da sessão foi
68606, o contexto máximo 113178, e os modelos usados foram claude-fable-5 e claude-opus-4-8
- Sem monitorar os custos de perto, o Fable pode gastar facilmente cerca de US$ 12 em tokens criando novos métodos para depurar CSS
Necessidade de sandbox
- Foi impressionante ver que o Fable recorreu até a métodos extremos para obter as informações necessárias para uma correção de CSS de apenas duas linhas
- Agentes de código conseguem executar o que um usuário poderia fazer digitando comandos no terminal, e modelos de fronteira conhecem um número enorme de técnicas
- Se houvesse instruções maliciosas, prompt injection em código ou em threads de issues, ou algo colado no terminal sem cuidado, isso poderia levar a vazamento de dados ou outros danos
- Executar agentes de código fora de um sandbox é sempre uma má ideia e é visto como um forte candidato a causa principal de incidentes de segurança com agentes de código
- O Fable pode ser mais inteligente e mais desconfiado de instruções maliciosas, mas, uma vez enganado, sua proatividade incessante pode ampliar o tamanho do dano
1 comentários
Comentários no Hacker News
Isso parece um caso impressionante de perda fatal de protagonismo humano, e os commits reais também revelam bastante [0]
O autor queria esconder a barra de rolagem horizontal. Qualquer desenvolvedor frontend júnior minimamente decente perguntaria imediatamente: “onde eu coloco
overflow-x: hidden;?”. Uma solução completa seria clicar em “Inspect element” no navegador para encontrar a classe CSS, localizar a posição no código com (rip)grep e adicionar uma linhaUm programador mais proativo também teria perguntado que conteúdo havia na caixa de texto vazia para estar transbordando, por que era preciso colocar em dois lugares um paliativo que mascara o sintoma em vez da causa raiz, e se não seria melhor estilizar o
textareauma única vez[0] https://github.com/datasette/datasette-agent/commit/a75a8b72...
__init__.py[0]Pela minha experiência usando Claude, em geral ele produz código bem estruturado, então isso me surpreende um pouco. Dito isso, o meu uso se aproxima menos de vibe coding propriamente dito e mais de debater amigavelmente, de forma socrática, com outro engenheiro que por acaso é um robô
[0] https://github.com/datasette/datasette-agent/blob/main/datas...
É exatamente isso que eu esperaria de um desenvolvedor júnior: confirmar se o bug realmente existe, descobrir como corrigi-lo e verificar se foi corrigido
O problema, como o post do blog também aponta corretamente, é que em vez de parar e perguntar quando precisa de autoridade superior, ele fica eternamente procurando gambiarras por conta própria. Em termos de um desenvolvedor humano, é como precisar de credenciais para acessar um sandbox de terceiros, mas em vez de pedir as credenciais a um sênior, tentar criar o próprio sandbox do zero
Lembra a época em que se cobrava por minuto para entrar no mundo online. Havia muito incentivo para manter o taxímetro rodando, e isso me parece ser desse tipo
Continua me deixando confuso e surpreso que tanta gente admita claramente que “executar um agente de código fora de um sandbox sempre foi uma má ideia” e ainda assim continue fazendo isso
Parece postar um vídeo sentado no banco do carona com os pés no painel e dizer: “Lembrem-se de que, se eu sofrer um acidente assim, o airbag pode quebrar minhas pernas ou fazer algo pior! Ainda bem que isso não aconteceu comigo!”
O problema é que cada pessoa dá prompts de um jeito muito diferente
Por exemplo, eu posso pedir algo como “teste várias variações desta annotation nos pods k8s deste serviço neste cluster X. Isso comprova a teoria Y”. Já um colega diria “teste a teoria Y”. Se você perguntar assim para dois engenheiros juniores, um pode sair tentando aleatoriamente em produção e o outro pode rodar testes locais. É um pedido sem instruções, do tipo “descubra do jeito que quiser”, e o agente lê isso como um júnior que não recebeu limites, mas sentiu fortemente a pressão para “descobrir”
claudeTem algo parecido com meus dotfiles, mas sem segredos. Meu diretório home é 0700, o
claudetem sua própria chave SSH, eu a adicionei ao meu perfil do GitHub, mas protegida por senha, e eu mesmo faço push/pull. Também há um usuário e banco separados de Postgres para dev/teste, sem privilégios de superusuárioNa prática, trato como outro desenvolvedor do projeto. Se precisar executar algo com sudo, ele me pergunta. Às vezes nós dois até podemos trabalhar em paralelo na mesma coisa. Afinal, o Unix foi feito para ser um sistema multiusuário
Um truque que uso com frequência é ter este remoto extra nos repositórios git dele:
paul ssh://paul@localhost/~/src/example (fetch)paul ssh://paul@localhost/~/src/example (push)Fica fácil colaborar em coisas que ainda não estão prontas para compartilhar
Essa configuração é bem confortável. Ainda assim, me preocupo com bugs de escalonamento de privilégios no Linux. Não confio que a AI entenda que explorar vulnerabilidades não é permitido. Isso me lembra meu primeiro emprego, quando em uma emergência eu usei errado o recurso
:!do vim tentando ampliar permissões limitadas de sudo oficialmente restritas à edição dohttpd.conf. Hoje, mesmo com atualizações automáticas de segurança, acabo atualizando pacotes manualmente com mais frequência. Não acho que o Opus vá se dar ao trabalho de procurar vulnerabilidades de segurança, mas talvez o Fable vá, e recentemente houve muitas dessas vulnerabilidades. Modelos futuros podem descobrir novas vulnerabilidades por conta própria ou instalar um keylogger para aprender a senha da chave SSHUm usuário separado é, tirando uma máquina separada, praticamente a configuração mais paranoica que já ouvi. Então fico me perguntando se não estou sacrificando velocidade e conveniência demais. Mesmo assim, na prática continua sendo muito conveniente, e me parece um jeito eficiente e responsável de trabalhar. Se alguém enxergar falhas nisso, quero ouvir
O Fable parece “um Opus rodando em cima de um harness que não deixa ele parar até ter certeza de que o problema foi corrigido”. Se você quer um modelo melhor em benchmark, faz sentido ir nessa direção
É um modelo muito bom, mas o prêmio é alto. Não só os tokens em si são mais caros, como o modelo quer usar todos eles. Por exemplo, em trabalho com React Native, o Fable não diz “beleza, fiz e acabou”. Ele quer reconstruir o app inteiro do zero, rodar toda a suíte de testes e observar todos os logs e avisos
Foi a primeira vez usando um LLM em que senti que um upgrade de modelo não valia a pena, mesmo que a empresa permitisse, porque builds e testes castigavam demais minha máquina e minha bateria, a ponto de eu não conseguir fazer outras coisas
No momento, parece melhor usar ultracode com Opus. Há menos poluição do contexto principal e a investigação fica mais paralelizável
O Fable tentou validar uma mudança de UI no meu jogo. Eu estava trabalhando em outra janela quando vi o programa abrindo na barra de tarefas. O Fable abriu o jogo pela CLI com a ferramenta movie maker, gravou a saída e capturou o último frame para validar a UI. Como a tela de boas-vindas do jogo cobria a parte que ele queria ver, ele criou um worktree temporário, removeu a tela de boas-vindas e executou o movie maker de novo
Enquanto eu via esse processo, pensei que ele teria economizado tokens se simplesmente tivesse me pedido um screenshot. Ainda assim, não teve como não ficar impressionado. O Opus nunca faria isso
Esse tipo de texto dá a sensação de ter vindo de um universo paralelo. Pela minha experiência anedótica e por um benchmark que eu mesmo fiz, ainda que continue sendo subjetivo (https://pshirshov.github.io/llm-bench-pi-oneshot/), o Fable não é tão impressionante assim
No nível do gpt-5.5 e do opus 4.8, às vezes é melhor e às vezes é pior, certamente é mais caro e, em perguntas sobre React, às vezes se recusa dizendo que química não pode ajudar
Não sei se esse alvoroço tem fundamento mesmo ou se é só hype de AGI antes do IPO
Estou fazendo o Fable coordenar implementações complexas. Dou a ele tickets de nível mais alto no Linear e digo: “olhe os subtópicos deste ticket, determine quais você mesmo pode implementar, em que ordem deve fazer isso e como deve se coordenar com o que outros membros do time estão fazendo no momento”. Esses tickets não são triviais, têm muitas partes móveis e dependências, e se conectam tanto dentro quanto fora do mesmo projeto, por exemplo com o backend
Então o Fable escolhe os tickets e delega cada um a subagentes, que também são Fable. O subagente olha o design no Figma daquele ticket, segue à risca as diretrizes e convenções do repositório, implementa tudo perfeitamente, tira screenshots de cada parte, escreve mensagens de commit detalhadas e descrições de PR, e anexa screenshots como evidência. No final, ele me dá um resumo como “o PR #1283 precisa ser mesclado primeiro. Além disso, esta ou aquela tela não tinha design no Figma, então apliquei o padrão olhando para uma tela parecida já implementada”
Isso provavelmente é só uns 20% do que o Fable consegue fazer. É um modelo realmente poderoso
O Opus 4.8 também conseguia fazer boa parte disso, mas precisava de muito mais condução, e quando encontrava um ponto de bloqueio era bem mais provável que parasse com um “consegui chegar até aqui, mas não consigo avançar mais”
O Fable é um pouco mais inteligente, mas justamente por isso parece uma ferramenta pior no geral
Ele continua transformando um patch de 50 linhas que terminaria com um único prompt numa exploração de 30 minutos, e muitas vezes isso não vale nem um pouco a pena. E ainda por cima frequentemente erra
Testei com uma tarefa bem simples. Era para fazer backfill do cache de deduplicação no Redis quando a função de hash mudou. Bastava rodar a nova função de hash em todos os valores do banco e expandir o cache, mas o Fable implementou uma atualização de cache excessivamente complexa tentando inferir a versão da função de hash de cada valor em cache e recalcular só os hashes antigos. Em alguns contextos isso até pode fazer sentido, mas o resultado de 30 minutos queimando tokens foi um código que eu substituí por um
forloop de 10 linhasIsso me preocupa porque parece uma má notícia para programação em geral. A tecnologia de LLM claramente parece estar batendo numa parede de retornos decrescentes em termos de inteligência, e se a resposta a isso for só deixá-los mais obstinados, então é uma solução péssima para todos os envolvidos. Exceto para quem vende tokens e para quem pode bancar tokens para escanear 0-days
Primeiro, não existe modelo causal. Tudo o que eles conseguem fazer é exploração por tentativa e erro, e isso funciona muito bem para vários problemas, mas muitos outros exigem um modelo causal
Segundo, prompts não são precisos. Linguagens de programação e modelos de máquina foram inventados justamente para resolver esse problema. O inglês é ótimo, mas não é uma linguagem de programação
Antes do IPO, fizeram muita adoção estratégica e manipulação, e nisso foi eficaz
tsc, mas ele ainda escreveu outro script para executartscem cada subagente e consolidar os resultadosFoi realmente irritante. Algo que no máximo levaria 1 ou 2 minutos acabou levando uns 10 minutos porque seguiu esse caminho
Vou tentar tarefas bem mais complexas depois, mas para coisas simples era como dirigir uma Corvette até a caixa de correio
Minha resistência a usar LLM baseado em terminal na minha máquina local continua parecendo cada vez mais justificada
Mesmo sem comportamento malicioso, há coisa demais que pode me fazer perder uma quantidade significativa de trabalho ou estragar minha máquina e minha própria capacidade de trabalhar
Uma empresa de 1 trilhão de dólares não deveria conseguir providenciar isso com relativa facilidade? Parece algo trivial perto do restante do harness
Segurança claramente é uma questão maior, mas enquanto eu lia isso só conseguia pensar em quantos tokens foram gastos para corrigir 2 linhas de CSS
O que se deveria estimar é quanto tempo um humano levaria
As pessoas agora só conseguem ser preguiçosas e ao mesmo tempo parecer produtivas, mas continua sendo preguiça
Agora existem pessoas que precisam de acesso a hardware de centenas de milhares de dólares para escrever um único e-mail. Passo essa. Não quero fritar meu cérebro para ficar dependente da máquina de pensar de um bilionário
Também não vou fritar meu cérebro com uma “máquina que pensa por mim” local. Quero ser alguém mais valioso do que o hardware ao qual tenho acesso
Minha experiência pessoal com o Fable 5 agindo do seu próprio jeito foi muito positiva
Ele tentou encontrar a causa raiz de um crash de módulo Python que não deixava erros em logs nem no console. O Fable escreveu um test harness que simulava cliques na UI e depois fez uma busca binária no meu código para encontrar o ponto em que o crash começava. Em seguida, formulou uma hipótese exagerada sobre a causa do crash e executou em sequência comandos bash de uma linha para criar ambientes virtuais de cada versão desse módulo Python em
/tmp, até encontrar uma versão que não travavaEle investigou a causa raiz com muito mais profundidade do que eu teria conseguido sozinho, e a causa era uma regressão no módulo que provocava um overflow na alocação de heap. Também forneceu informação suficiente e um exemplo simplificado a ponto de eu conseguir abrir um bug report, além de escrever um workaround para impedir que isso acontecesse na minha aplicação
Não deixo totalmente solto. Eu reviso cada comando de CLI que ele pretende executar e acrescento uma resposta quando sigo com “yes”, para evitar uso excessivo de tokens
Ajuda definir limites no prompt ou no Markdown. Por exemplo, se você disser para não usar automação de navegador, vi o Fable seguir tanto a regra quanto a intenção dela. Também não fez nenhuma gambiarra estranha
Ainda assim, parece tratar algumas tarefas simples de depuração como se fossem mais complexas do que realmente são. O post original talvez seja um bom exemplo disso
git bisectpara descobrir por que um módulo Python travava sem deixar erros em logs nem no consoleEntendo gerar o caso de teste e o loop de
git bisect, mas não sei por que isso precisaria passar pela internet, GPU e afins. Parece algo que daria para rodar até num Celeron de núcleo único