- E se o agente já tivesse um mapa? 🗺️
- Duas camadas, dois tipos de custo 🧠
- O projeto fica dentro do próprio projeto 📁
- O que dá para perguntar ao grafo? 🔎
- Um bug de permissão mostrou o ponto forte 🚨
- A função existia. O problema era outro. 🕵️
- E depois da correção?
- Nem todo código cabe em um mapa 🧱
- Então vale testar? 🤔
Principais destaques
- Código com contexto: o Graft cria um grafo de funções, arquivos, imports e chamadas para evitar que agentes reconstruam a arquitetura a cada tarefa.
- Sem IA para começar: a camada estrutural usa tree-sitter, não exige chave de API e armazena o grafo localmente em uma pasta
.graft.
- Bug de permissão expõe a vantagem: ao rastrear quem chamava uma função, a ferramenta revelou que a checagem de exportação existia, mas nunca era aplicada pelo serviço responsável.
Agentes de programação ficaram muito bons em escrever código. O problema é que ainda precisam gastar uma quantidade considerável de tempo entendendo onde esse código deveria ser escrito.
Em um projeto pequeno, isso parece banal. Em uma aplicação com dezenas ou centenas de arquivos, vira outra história.
O agente recebe uma tarefa aparentemente simples, começa a procurar referências, segue imports, abre arquivos, reconstrói dependências e tenta montar mentalmente a arquitetura. Depois, algumas mensagens mais tarde, pode fazer praticamente a mesma investigação de novo.
É justamente esse trabalho de arqueologia que o Graft, projeto open source da Nanonets, tenta reduzir.
E se o agente já tivesse um mapa? 🗺️
A proposta é relativamente direta: em vez de obrigar o agente a descobrir a estrutura do código apenas lendo os arquivos, o Graft constrói um code graph, ou grafo do código.
Esse mapa registra elementos como:
• arquivos e funções
• imports
• relações entre funções
• quem chama determinada função
• onde uma determinada lógica está implementada
A diferença parece pequena, mas muda a natureza da busca.
🔎 Não é apenas encontrar uma palavra: a ideia é descobrir relações. Se uma função de permissões for alterada, por exemplo, interessa saber quais serviços dependem dela, e não apenas em quais arquivos o nome aparece.
É uma distinção importante porque muitos bugs reais não estão em uma linha isolada. Eles aparecem no caminho entre várias linhas, arquivos e componentes.
Duas camadas, dois tipos de custo 🧠
O Graft trabalha essencialmente em duas camadas.
A primeira é a estrutural. Ela usa tree-sitter para analisar o código e extrair funções, imports e conexões entre os elementos.
Aqui está uma das partes mais interessantes da proposta: não é preciso fornecer uma chave de API de IA.
Como a análise é estática, a construção do grafo e suas consultas não dependem de inferência de um modelo. Isso também significa que as consultas estruturais não adicionam uma nova cobrança de API.
💰 Mas atenção ao detalhe: isso não significa que o agente de programação utilizado junto com o Graft seja gratuito. Se o modelo ou agente cobrar pelo uso, essa conta continua existindo separadamente.
A segunda camada é a deep layer, que acrescenta resumos gerados por IA e nós conceituais ao grafo. Nesse caso, um provedor de modelos é necessário e podem existir custos de API.
💡 A aposta do Graft é interessante justamente porque a parte mais útil pode funcionar sem IA: primeiro vem o mapa, depois a inteligência adicional.
O projeto fica dentro do próprio projeto 📁
O Graft é distribuído como CLI e pode ser executado com npx @nanonets/graft. A versão usada no fluxo descrito é a 0.18.0, que exige Node 20 ou superior.
O processo básico é curto:
1️⃣ Instalar e construir: executar o Graft no repositório e rodar graft build, sem precisar de chave de provedor para a camada estrutural.
2️⃣ Consultar: usar comandos como graft map, graft skeleton e consultas direcionadas para investigar a arquitetura.
3️⃣ Verificar mudanças: executar graft check para descobrir se o mapa ficou desatualizado em relação ao código.
Os arquivos gerados ficam em uma pasta .graft dentro do projeto. A pasta é adicionada automaticamente ao .gitignore, já que o grafo pode ser reconstruído a partir do código-fonte.
Isso elimina a necessidade de manter um banco de dados separado apenas para guardar o mapa.
O que dá para perguntar ao grafo? 🔎
A ferramenta oferece diferentes maneiras de explorar o projeto.
🧩 Primeiro, a visão geral: graft map apresenta uma visão da estrutura do código.
🎯 Depois, a busca direcionada: consultas com --source podem localizar onde determinada lógica está implementada e retornar funções, arquivos e trechos relevantes.
🦴 E existe o esqueleto: graft skeleton lista assinaturas de funções de um arquivo sem despejar todos os corpos de código. É uma maneira rápida de entender a superfície de uma API.
Há ainda o rastreamento de chamadas, no qual um parâmetro de profundidade determina quantos níveis de relações devem ser percorridos.
Isso é especialmente útil para perguntas do tipo: “quem chama esta função?”
E talvez seja justamente aí que o Graft se diferencia de uma busca textual convencional.
Um bug de permissão mostrou o ponto forte 🚨
O exemplo mais revelador envolve uma aplicação de documentos.
A regra era simples: visualizadores podiam ler documentos compartilhados, mas não exportá-los. Editores e proprietários podiam realizar as duas ações.
Um teste, porém, encontrou o problema: um usuário com permissão de visualização conseguia exportar um documento e deveria ter recebido um erro 403.
Até aqui, nada extraordinário.
A investigação ficou interessante quando o Graft foi usado para perguntar onde as permissões de exportação eram verificadas.
O resultado reuniu a função de exportação, o helper específico de permissão, o manipulador da rota e a função responsável por carregar o documento.
Era um pequeno mapa do problema.
A função existia. O problema era outro. 🕵️
O graft skeleton aplicado ao arquivo de permissões mostrou as verificações para leitura, edição e exportação.
Ou seja, a política aparentemente estava lá.
Mas então veio a pergunta mais importante: quem chama o helper de permissão de exportação?
O resultado apontou apenas para o arquivo de testes.
Não para o serviço de exportação.
⚠️ Esse era o buraco: a regra existia e tinha testes isolados, mas o caminho real de exportação nunca passava por ela.
Ao seguir o código-fonte, a razão apareceu. O serviço carregava o documento usando uma verificação de acesso de leitura, que o visualizador conseguia passar. Em seguida, gerava o CSV sem executar a checagem mais restritiva de exportação.
É exatamente o tipo de problema que pode escapar de uma busca por palavras.
O código responsável pela política existe. O código responsável pela ação também existe. O erro está na ausência da conexão entre os dois.
💡 O grafo não consertou o bug. Ele mostrou onde a política deixava de virar comportamento.
E depois da correção?
A solução foi importar o helper de permissões para o serviço de exportação e rejeitar solicitações não autorizadas.
Depois, graft check detectou que o grafo estava desatualizado.
A atualização seguinte ficou limitada ao arquivo alterado, em vez de exigir uma reconstrução completa. Uma nova consulta de chamadas mostrou então a função de exportação conectada ao helper de permissões.
Os nove testes do exemplo passaram.
Isso não transforma o Graft em uma ferramenta de validação automática. O grafo mostra relações, mas uma relação correta não significa que a implementação esteja correta.
Testes e revisão de código continuam sendo necessários.
Nem todo código cabe em um mapa 🧱
A abordagem também tem limites.
Análise estática não enxerga perfeitamente comportamentos dinâmicos, e o nível de suporte pode variar entre linguagens e bases de código. Um resultado ambíguo ainda exige que alguém abra o código e leia o que realmente acontece.
Há outra ressalva importante na atualização automática.
O graft check pode atualizar a camada estrutural quando detecta alterações. Isso não significa que os resumos pagos da camada deep sejam automaticamente regenerados da mesma maneira.
Quem depender dos resumos gerados por IA precisa verificar se eles foram efetivamente produzidos pelo provedor configurado.
📊 E os números de economia? O Graft também apresenta estimativas de redução de tokens em algumas consultas. Os mantenedores relatam 42% menos tokens e 60% menos tempo em seus próprios testes controlados.
Mas esses números são do benchmark deles. Não devem ser tratados como uma promessa de desempenho para qualquer projeto.
| Camada | Como funciona | Custo de IA |
|---|---|---|
| Estrutural | tree-sitter + relações do código | Não exige provedor |
| Deep | resumos e conceitos gerados por IA | Pode gerar custos |
Então vale testar? 🤔
Para equipes que usam agentes de código constantemente e enfrentam tarefas que atravessam vários arquivos, a resposta parece ser sim, pelo menos para a camada estrutural.
O risco de experimentar é relativamente baixo: o projeto é MIT, não exige chave de provedor para o grafo estrutural, não precisa de um servidor de banco separado e o mapa pode ser regenerado a partir do código.
A melhor estratégia é começar pequeno.
Escolha algumas tarefas reais do seu projeto. Pergunte onde determinada lógica está, descubra quem chama uma função crítica, use o skeleton para entender arquivos maiores e veja se o agente chega mais rápido ao contexto relevante.
Se funcionar, a camada deep pode entrar depois.
O ponto central é que agentes de código talvez não precisem apenas de modelos melhores. Eles também precisam de ferramentas melhores para enxergar o território onde estão trabalhando.
Um agente sem mapa pode continuar chegando ao destino. Só precisa abrir várias portas no caminho.
Com um grafo, a pergunta passa a ser outra: quanto tempo de investigação ainda é necessário antes de ele realmente começar a programar?
