SSD Nodes Learn 🎉 VPS desde $5.50/mês
Guias Matt ConnorPor Matt Connor · Atualizado 2026-08-14

Graft: mapa de código para agentes de programação

Veja como o Graft usa tree-sitter e MCP para gerar um mapa persistente do repositório, reduzindo a redescoberta da estrutura a cada sessão do agente.

O que é um mapa da base de código para agentes de programação

Um mapa da base de código para agentes de programação é um índice persistente do seu repositório que o agente consulta, em vez de procurar às cegas desde o início em cada nova sessão. Graft é uma implementação dessa ideia. Analisa o seu código com tree-sitter, escreve uma pasta com nós Markdown interligados e um grafo de ligações por símbolo, e disponibiliza ferramentas de recuperação através de MCP (model context protocol, a interface padrão usada pelos agentes de programação para chamar ferramentas externas).

Graft não é um proxy nem um gateway. Nada fica entre o seu agente e a API do modelo. O mapa é uma pasta no disco que o agente lê. Essa distinção determina qual problema está a resolver: um gateway de tokens autoalojado contabiliza e encaminha os pedidos que já envia, enquanto um mapa altera a quantidade total de pedidos que precisa de enviar.

A técnica é anterior a esta ferramenta e continuará a existir depois dela. Aprenda primeiro a técnica e só depois os mecanismos.

Por que os agentes de programação gastam contexto a redescobrir a estrutura

Observe um agente a começar a trabalhar num repositório que já viu cinquenta vezes. Lista diretórios. Procura um símbolo com grep. Abre três ficheiros para descobrir qual define a função e depois um quarto para descobrir quem a chama. Nada disso faz parte da tarefa. É orientação, paga em tokens de entrada em todas as sessões.

A causa é simples. Um modelo não tem memória entre sessões. Tudo o que o agente aprendeu sobre a sua estrutura ficou numa janela de contexto que foi descartada quando a sessão terminou. Por isso, a mesma descoberta começa novamente do zero, ao preço total. Num repositório grande, a fase de orientação custa mais do que a alteração: dez chamadas a ferramentas para localizar o código e uma para o alterar. A orientação representa apenas metade desse custo e a alteração representa a outra metade. Por isso, uma skill que obriga o agente a fazer a menor alteração que funciona deve ser combinada com um mapa, em vez de se escolher entre os dois.

Um mapa interrompe esse ciclo ao transferir a descoberta do modelo para o disco. Um parser percorre o repositório uma vez, regista onde cada símbolo é definido e que símbolo chama cada outro, e mantém esse registo atualizado à medida que o código muda. O agente faz uma pergunta e obtém uma resposta com o ficheiro e a linha correspondentes. A exploração repetida passa a ser uma consulta barata.

Já utiliza uma versão mais limitada disto. Um AGENTS.md que define as suas convenções impede o agente de voltar a deduzir as suas convenções em cada sessão. Um mapa gerado impede-o de voltar a deduzir a sua estrutura. A diferença está em quem o escreve. O ficheiro de instruções é escrito manualmente, por isso permanece pequeno. Um parser gera o mapa, por isso pode abranger dez mil ficheiros. Para saber como o orçamento é realmente gasto dentro de uma sessão, como o Claude Code utiliza a sua janela de contexto explica essa contabilização.

O que o Graft realmente cria

Dois artefactos, ambos dentro de uma única pasta graft/ na raiz do repositório.

O primeiro é um grafo de nós escrito como Markdown interligado, com um ficheiro por nó. Cada nó contém um resumo em inglês simples, um "crux" com as linhas da lógica importante extraídas do código-fonte, os ficheiros de origem exatos com um hash do conteúdo, wikilinks tipados para outros nós (depends_on, part_of, uses, implements) e uma secção de notas que sobrevive à regeneração, para que possa registar contexto que um analisador não consegue inferir.

O segundo é graft/.graph/wiring.json, o grafo estrutural por símbolo que o tree-sitter extrai: definições, referências e as relações de chamada entre elas.

A separação é importante porque apenas uma das partes precisa de um modelo. graft build usa exclusivamente tree-sitter e nunca chama um LLM (large language model), pelo que é determinístico e não tem custos. graft build --deep adiciona os resumos escritos e os cruxes por símbolo, que são chamadas ao modelo e têm custos associados.

O suporte de linguagens é organizado por níveis, e o nível indica até que ponto pode confiar num grafo de chamadas. TypeScript, JavaScript, Python, Go e Java obtêm resolução entre ficheiros com reconhecimento de escopo. Rust, C, C++, C#, Ruby, PHP, Kotlin, Scala, Swift, Elixir, Solidity, OCaml, Zig e Dart obtêm símbolos e relações de chamada genéricas. Isto significa que uma relação pode resultar da correspondência de um nome, em vez de uma referência resolvida. As relações ao nível do compilador são opcionais com --lsp e um language server, como rust-analyzer ou gopls.

Instalar o Graft e fixar a versão

O Graft requer Node.js 20 ou posterior e é licenciado sob MIT. Em agosto de 2026, a versão atual é 0.10.1, e a primeira versão publicada, 0.1.0, é de julho de 2026. Considere-o software recente.

npm install -g @nanonets/graft@0.10.1
npm ls -g @nanonets/graft

npm ls -g deve apresentar @nanonets/graft@0.10.1. Fixe essa versão intencionalmente. Um npm install -g @nanonets/graft sem versão resolve a tag latest no momento em que é executado. Num projeto que lança várias versões secundárias por mês, isso faz com que tenha uma ferramenta diferente na terça-feira daquela que o seu colega instalou na segunda-feira. Uma versão fixada mantém as flags da CLI e o formato do grafo iguais para todos, para que atualize quando decidir fazê-lo.

Depois, associe-o a um repositório que seja seu:

cd /path/to/your/repo
graft init --dry-run
graft init

graft init pergunta a quais dos seus agentes de programação deve associá-lo e, em seguida, cria o grafo. Execute --dry-run primeiro e leia a lista de ficheiros que ele pretende alterar, porque alguns ficam fora do repositório. graft init é idempotente e não substitui configurações existentes, por isso é seguro executá-lo uma segunda vez.

Em agosto de 2026, a associação abrange Claude Code, Cursor, Codex, GitHub Copilot, Google Gemini, Kiro, Windsurf e AdaL. O Claude Code obtém a integração mais completa: uma entrada de servidor MCP, uma statusline que apresenta o tamanho e a obsolescência do grafo, hooks pós-edição que recriam o grafo e um ficheiro de skill em .claude/. Os restantes recebem um ficheiro de instruções ou regras que informa o agente de que as ferramentas existem. Portanto, "com suporte" significa que o Graft escreve a configuração de associação; se um agente ignorar o seu próprio ficheiro de regras, também ignorará o mapa. Essa é a razão habitual pela qual os agentes ignoram as instruções que lhes escreve, e isto aplica-se aqui tanto como em qualquer outro contexto.

O que entra no seu repositório e o que fica fora do git

Depois de graft init, espere estes itens:

  • graft/: o grafo de nós Markdown e graft/.graph/wiring.json. Adicionado a .gitignore automaticamente.
  • .mcp.json: regista o servidor MCP graft para que o Claude Code o inicie.
  • .claude/settings.json: integrado no local, adicionando a statusline e os hooks post-edit.
  • AGENTS.md, GEMINI.md, .github/copilot-instructions.md, .cursor/rules/graft.mdc, .kiro/steering/graft.md, .windsurf/rules/graft.md e .adal/skills/graft/SKILL.md: secções delimitadas por marcadores, anexadas aos ficheiros correspondentes aos agentes selecionados.
  • ~/.codex/config.toml, ~/.codex/hooks.json e ~/.codex/hooks/graft/graft-hooks.cjs: configurações para todo o sistema, escritas apenas quando seleciona Codex. graft init --no-global ignora-as, e graft init --no-hooks ignora o hook shim por si só.

O grafo é uma cache, tal como node_modules. Não o inclua no commit. É regenerado a partir do código em segundos, muda em quase todas as edições e, quando incluído no commit, transforma uma correção de uma linha num diff de várias centenas de ficheiros que nenhum revisor vai ler. Inclua no commit a configuração de integração, incluindo AGENTS.md e .mcp.json. Um colega clona o repositório, executa graft build e obtém o seu próprio grafo local.

Confirme que a regra de exclusão foi aplicada antes do primeiro commit:

grep -n graft .gitignore
git status --short

grep deve mostrar uma linha que contenha graft/, e git status --short não deve listar nada em graft/. A presença de ficheiros em graft/ nessa saída indica que a entrada de exclusão está ausente ou foi substituída noutro local. Corrija isso antes de fazer o commit, porque o git continua a controlar um ficheiro depois de este ser adicionado, e uma edição posterior de .gitignore não deixa de o controlar.

Se preferir registar manualmente o servidor MCP ou fixá-lo na mesma versão instalada, a entrada é pequena:

{
  "mcpServers": {
    "graft": {
      "command": "npx",
      "args": ["-y", "@nanonets/graft@0.10.1", "mcp"]
    }
  }
}

As ferramentas de consulta que o seu agente usa em vez de grep

O Graft expõe seis ferramentas através de MCP. graft_find_code devolve nós ordenados para uma descrição de tarefa, com ficheiro e linha. graft_file_api devolve todas as assinaturas de um ficheiro sem os corpos. graft_trace_calls percorre os chamadores ou chamados por vários níveis. graft_find_all devolve correspondências de expressões regulares agrupadas por símbolo. graft_repo_map fornece uma primeira visão de um repositório desconhecido. graft_check_freshness indica se o grafo ainda corresponde ao código.

Cada ferramenta tem também um equivalente na CLI. É assim que verifica o que o seu agente está realmente a receber:

graft map .
graft ask "where do we validate the refresh token"
graft skeleton src/auth/session.ts
graft callers validateRefreshToken
graft callers validateRefreshToken --direction out
graft grep "refresh_token" --json

graft ask deve imprimir nós ordenados com referências file:line, em vez do conteúdo dos ficheiros. Esse é todo o mecanismo: o agente recebe um ponteiro e abre um ficheiro, em vez de ler dez para encontrar o correto. graft viz abre um visualizador interativo em localhost se quiser consultar o grafo diretamente. Se graft ask não devolver nada útil para uma pergunta à qual conseguiria responder em trinta segundos, o grafo está desatualizado ou a sua linguagem está no nível amplo, e o mapa também não ajudará o seu agente.

Há um custo fácil de ignorar. As seis definições de ferramentas são injetadas no prompt do sistema de cada pedido durante toda a sessão. Paga esse custo quer o agente use o mapa quer não. Num repositório suficientemente pequeno para caber no contexto, o custo fixo pode ser superior à exploração que evita.

O que acontece com o grafo quando o código muda

A atualização estrutural é barata e automática. O Graft lê a sua árvore de trabalho, não o git, por isso uma edição que ainda não foi commitada e uma edição que foi colocada em staging são igualmente visíveis para ele. Uma consulta volta a analisar apenas os ficheiros cujo stat mudou, o que a documentação do projeto indica como cerca de 3 ms de overhead, e uma reconstrução no fim de cada turno toca apenas nos ficheiros onde o código mudou de lugar. Defina GRAFT_NO_REFRESH=1 ou passe --no-refresh para obter a resposta a partir do grafo no disco sem voltar a analisar os ficheiros. Passe --no-reuse para forçar uma nova análise completa, que é o procedimento indicado depois de atualizar o próprio Graft.

A parte escrita pelo modelo comporta-se de forma diferente, e é aí que os problemas surgem silenciosamente. Os resumos e os pontos centrais ficam em cache. Cada nó regista um hash do conteúdo das suas fontes, por isso, quando um ficheiro de origem muda, o nó é marcado como obsoleto em vez de ser apresentado como atual. Esse sinal só é útil se algo agir sobre ele. Atualize com graft build --deep, que volta a consumir tokens do modelo.

Torne a obsolescência visível:

graft check .
echo $?

O código de saída 0 significa que o grafo corresponde ao código. O código de saída 1 significa que existe divergência. Execute-o a partir de um hook pre-push ou no branch em CI, para que um mapa com seis meses não responda com confiança sobre código que foi reescrito em março.

Leia com atenção os números de benchmark publicados

A principal afirmação do Graft é "até 4x mais barato e 3x mais rápido, com correção igual ou sem perda de correção". Esses números vêm dos próprios benchmarks do projeto, publicados no README. A seguir estão os dois testes completos apresentados no README.

ChartGraft's own published benchmark results, versus a no-map baseline, as of August 2026
The data behind this chart
[
  {
    "label": "Controlled sweep",
    "run_count": 162,
    "token_saving_pct": 42,
    "tool_call_saving_pct": 46,
    "correctness_pct": 93,
    "baseline_correctness_pct": 93
  },
  {
    "label": "SWE-bench Verified",
    "run_count": 50,
    "token_saving_pct": 23,
    "tool_call_saving_pct": 25,
    "correctness_pct": 66,
    "baseline_correctness_pct": 54
  }
]

O teste controlado inclui 162 execuções em dois repositórios, um deles o próprio Graft, com três tentativas por tarefa. O relatório indica 42% menos tokens e 46% menos chamadas de ferramentas. A execução no SWE-bench Verified inclui 50 instâncias com o mesmo modelo nos dois grupos e indica uma redução menor: 23% dos tokens e 25% das chamadas de ferramentas. Uma terceira execução reproduziu cinco pull requests do PocketBase que foram integrados, com um custo de 11.02 dólares americanos, contra 13.91 do baseline.

Considere todos esses números como resultados de um benchmark do fornecedor. Há dois fatores que limitam o que eles podem mostrar. O teste controlado inclui o próprio repositório do Graft, que é a base de código contra a qual os autores ajustaram a ferramenta. O SWE-bench Verified é um dataset público de issues de projetos Python open source conhecidos, e as ferramentas tendem a ser optimizadas para datasets públicos, mesmo que isso não seja intencional. Nenhum dos dois resultados descreve o seu monorepo privado, que tem os seus próprios padrões de nomenclatura e o seu próprio código morto.

A correção exige uma segunda análise. No teste controlado, ela não mudou: 93% com o map, contra 93% sem ele. O aumento para 66%, partindo de 54%, aparece apenas no SWE-bench Verified. Uma ferramenta que reduz a sua fatura de tokens e mantém a qualidade estável ainda oferece uma boa relação custo-benefício. No entanto, não transfira o resultado de correção do SWE-bench para o resultado de tokens do teste controlado, nem apresente ambos como uma única afirmação.

Meça a sua própria variação de tokens antes de acreditar em qualquer resultado

O único número que importa é o do seu repositório. Este método demora uma tarde.

Escolha uma tarefa que possa repetir exatamente. Uma pergunta é melhor do que uma edição, porque uma edição altera o repositório e a segunda execução deixa de ser o mesmo experimento. “Qual módulo aplica o limite de pedidos na rota de login” tem o formato certo.

Ative a telemetria e envie-a para o seu próprio terminal:

export CLAUDE_CODE_ENABLE_TELEMETRY=1
export OTEL_METRICS_EXPORTER=console
claude

O exportador de consola imprime os registos de métricas à medida que são recolhidos. O que pretende é claude_code.token.usage, que contém um atributo type com o valor input, output, cacheRead ou cacheCreation. A orientação aparece em input e cacheRead, porque é aí que fica o conteúdo dos ficheiros. Some esses dois valores.

Execute a tarefa três vezes, cada uma numa sessão nova, com o mapa ligado. Em seguida, remova a entrada de graft de .mcp.json e execute-a mais três vezes. Compare as medianas em vez de execuções individuais, porque as execuções do agente variam muito e uma execução azarada pode indicar o oposto da realidade. Registe também o número de chamadas de ferramentas: as chamadas de ferramentas são o mecanismo e os tokens são o efeito. Portanto, uma redução de tokens sem uma redução nas chamadas de ferramentas significa que outra coisa mudou.

Depois, subtraia os custos que o benchmark não apresenta. graft build --deep consome tokens do modelo em cada atualização completa. Os seis esquemas de ferramentas são enviados em todos os pedidos. Se os seus agentes forem executados num servidor alugado, definir um limite rígido para os custos dos agentes transforma uma surpresa num orçamento, e o que a telemetria de um agente de programação realmente comunica explica o que sai da máquina depois de ativar o exportador.

Onde o mapa da base de código deixa de ser útil?

  • O repositório já cabe no contexto. Um único serviço pequeno não precisa de um mapa, e ainda paga por seis esquemas de ferramentas em cada pedido. Se o seu agente encontra hoje qualquer ficheiro com uma ou duas chamadas de ferramentas, não use o mapa.
  • A sua linguagem está no nível abrangente. As ligações genéricas entre chamadas podem fazer com que graft callers não encontre um chamador ou produza um resultado devido a uma colisão de nomes. Confirme com graft grep antes de confiar no impacto da alteração.
  • O grafo ficou desatualizado e ninguém reparou. graft check termina com o código 1 quando deteta divergências, mas isso só é útil se alguma coisa o executar. Use um hook ou uma etapa de CI, não um procedimento manual.
  • O monorepo precisa de delimitação. Um monorepo num único repositório Git é dividido automaticamente pelo ficheiro de workspace, go.mod, pyproject.toml ou Cargo.toml, e graft ask "..." --in services/billing/ restringe uma consulta a um subprojeto. A mesma lógica que leva a usar ficheiros AGENTS.md aninhados por pacote aplica-se ao mapa.
  • O agente ignora as ligações. Observe as chamadas de ferramentas numa sessão real antes de concluir que o mapa está a ser usado. Um agente que continua a executar grep está a indicar que nunca leu o ficheiro de regras.

FAQ

Devo fazer commit da pasta graft/ no git?

Não. graft build adiciona graft/ automaticamente ao seu .gitignore, porque o grafo é uma cache regenerável, como node_modules. A pasta muda em quase todas as edições, portanto fazer commit dela esconde as diferenças reais sob centenas de ficheiros gerados. Faça commit da configuração que informa aos agentes que o mapa existe, incluindo AGENTS.md e .mcp.json, e deixe cada membro da equipa executar graft build localmente. Verifique com grep -n graft .gitignore e git status --short antes do primeiro commit, porque o git continua a acompanhar um ficheiro depois de este ser adicionado, e editar .gitignore posteriormente não deixa de o acompanhar.

Executar o Graft custa dinheiro?

A parte estrutural não custa. graft build, graft ask, graft check e as seis ferramentas de recuperação MCP são operações do tree-sitter que nunca chamam um modelo. graft build --deep é a parte paga: escreve os resumos em inglês simples e os pontos essenciais por símbolo através de um LLM, configurado com GRAFT_PROVIDER, GRAFT_API_KEY e GRAFT_MODEL, além de GRAFT_BASE_URL para qualquer endpoint compatível com OpenAI. Pode executar o Graft apenas com a estrutura e nunca gastar um token no próprio grafo.

Quanto pode poupar um mapa da base de código no meu repositório?

Ninguém pode dizer sem medir. O projeto indica 42% menos tokens na sua própria varredura de 162 execuções e 23% no SWE-bench Verified, ambos comparados com uma baseline sem mapa. São benchmarks do fornecedor; um deles foi executado parcialmente no próprio repositório do Graft, e nenhum descreve o seu código privado. Execute três vezes a mesma pergunta reproduzível com o mapa e três vezes sem ele, com CLAUDE_CODE_ENABLE_TELEMETRY=1 e OTEL_METRICS_EXPORTER=console definidos. Depois, compare a mediana de claude_code.token.usage para os tipos input e cacheRead.

O que acontece ao grafo quando faço uma refatoração?

A estrutura é analisada novamente de forma automática. O Graft verifica a árvore de trabalho e analisa novamente apenas os ficheiros alterados. Assim, uma renomeação é detetada na consulta seguinte, com cerca de 3 ms de sobrecarga. As alterações não submetidas também são detetadas, porque o Graft lê os ficheiros em vez do histórico do git. Os resumos escritos pelo modelo é que ficam desatualizados: cada nó armazena um hash do conteúdo das suas fontes, e uma fonte alterada marca o nó como desatualizado em vez de o reescrever. Execute graft check . para ver a divergência e depois graft build --deep para atualizar a parte escrita.

Que agentes de programação podem usar o Graft atualmente?

Em agosto de 2026, graft init integra Claude Code, Cursor, Codex, GitHub Copilot, Google Gemini, Kiro, Windsurf e AdaL. O Claude Code recebe a integração mais completa: uma entrada de servidor MCP em .mcp.json, uma linha de estado, hooks pós-edição e um ficheiro de skill em .claude/. O Codex recebe uma secção AGENTS.md e entradas ao nível de toda a máquina em ~/.codex/, que graft init --no-global ignora. Os restantes recebem um ficheiro de regras ou de orientação. Qualquer outro cliente MCP pode usar o servidor diretamente, registando o comando npx -y @nanonets/graft@0.10.1 mcp.