Pesquisar código com o grafo de código
Este guia mostra-lhe como colocar um repo no grafo de código e depois usá-lo para responder à pergunta que se impõe antes de uma refatoração: do que é que isto depende?
O grafo de código é uma base de dados de símbolos e arestas construída ao analisar os seus checkouts registados com o tree-sitter. As suas ferramentas são orientadas para agentes — chega-se a elas pedindo a um agente.
Antes de começar
Secção intitulada “Antes de começar”O grafo indexa Dart, JavaScript, TypeScript, TSX, PHP, Python, Rust, Zig, C, C++, Go, Java, Ruby, C#, Swift, Kotlin, R, Assembly, MATLAB e Ada. Os ficheiros em qualquer outra linguagem não são analisados, por isso não aparecem em search_code, code_symbol, code_callers, code_callees ou code_impact.
Há mais duas coisas que determinam o que é indexado:
- Numa árvore de trabalho do git, a enumeração é delegada a
git ls-files --cached --others --exclude-standard, pelo que todos os.gitignore, ficheiros de exclusão aninhados,.git/info/excludee o ficheiro global de exclusões são respeitados. É isso que mantém onode_modulese os artefactos de compilação fora do grafo. - O Dart gerado é descartado de qualquer forma. Os ficheiros gerados são geralmente incluídos em commits, por isso só o git não os excluiria, e eles mudam a cada execução de geração de código.
Indexar um repo
Secção intitulada “Indexar um repo”Registar um checkout desencadeia RepoAdded, que inicia automaticamente o pipeline index_code para ele. Consulte Adicionar repos a um espaço de trabalho.
Para reindexar manualmente:
- Abra Definições → Espaço de trabalho → Repositórios.
- Clique no botão Indexar código na linha do repo.
- Enquanto está a correr, o botão mostra os ficheiros concluídos sobre o total, com um controlo para cancelar. Quando termina, passa a mostrar um visto com a contagem de símbolos.
O grafo é particionado por espaço de trabalho, repo e checkout: o checkout ligado é uma partição, e cada worktree de espaço tem a sua própria (identificada pelo seu id de repo isolado).
Vale a pena conhecer dois limitadores, porque explicam uma espera que parece um bloqueio:
- O observador de ficheiros só admite uma execução de indexação de cada vez no anfitrião — um segundo checkout espera. O pipeline
index_codeestá separadamente limitado a uma execução por espaço de trabalho, pelo que dois repos no mesmo espaço de trabalho ficam em fila; espaços de trabalho diferentes podem indexar em paralelo. O próprio indexador serializa duas execuções do mesmo checkout, para que um arranque de pipeline e uma varredura do observador não o analisem duas vezes. - Os worktrees pertencentes a espaços inativos (sem mensagens na última semana) não são observados nem indexados. Os checkouts ligados continuam a ser observados. Uma decisão de exclusão é revista ao fim de cinco minutos, por isso um espaço que volte a estar ativo é retomado.
Encontrar um símbolo
Secção intitulada “Encontrar um símbolo”Peça a um agente para pesquisar. A ferramenta é search_code e precisa tanto de um espaço de trabalho como de um repo:
search_code(workspace_id: "...", repo_id: "...", query: "authentication middleware")Os ids dos repos vêm de list_repos. O argumento opcional mode é keyword, semantic ou hybrid e a predefinição é hybrid — BM25 sobre nomes, assinaturas e comentários de documentação, fundido com semelhança vetorial.
Cada resultado transporta o id, o nome, o nome qualificado, o tipo, o caminho do ficheiro, a linha de início e de fim do símbolo e a sua assinatura quando a tem. O id é a referência que fornece a todas as outras ferramentas desta página.
Quando sabe o nome exato, procure-o diretamente em vez disso:
code_symbol(workspace_id: "...", repo_id: "...", name: "MyClass")Traçar chamadas
Secção intitulada “Traçar chamadas”Ambas recebem um symbol_id de um resultado de pesquisa, mais um limit opcional (predefinição 50):
code_callers(workspace_id: "...", symbol_id: "...")code_callees(workspace_id: "...", symbol_id: "...")code_callers devolve os símbolos com uma aresta de entrada para este; code_callees devolve aqueles de que este depende.
Ver o que uma alteração iria quebrar
Secção intitulada “Ver o que uma alteração iria quebrar”Esta é a ferramenta que justifica a página inteira:
code_impact(workspace_id: "...", symbol_id: "...", depth: 3)Calcula o raio de dependência inversa: tudo o que depende direta ou transitivamente do símbolo ao longo de arestas calls, extends e implements (imports, mixes-in e referências genéricas são armazenados no grafo, mas não são percorridos aqui). depth é o número máximo de saltos, entre 1 e 6, com a predefinição 2.
O resultado tem três campos:
root— o símbolo sobre o qual perguntouimpacted— o conjunto alcançável, incluindo a raiz a profundidade 0, cada um com o seudeptha partir da raizedgeCount— quantas arestas a travessia atravessou, como contagem e não as próprias arestas
Execute-o antes de renomear ou alterar uma assinatura e dê ao agente a lista de afetados como o seu âmbito.
Os resultados são verificados em relação à cópia de trabalho de quem chama
Secção intitulada “Os resultados são verificados em relação à cópia de trabalho de quem chama”Para um agente que faz a chamada, o id do espaço é injetado automaticamente e os resultados são verificados em relação à cópia de trabalho desse espaço. Um símbolo cujo ficheiro já não existe na árvore de quem chama é omitido, e a resposta transporta uma contagem staleOmitted mais uma nota a dizer que o índice está desatualizado para esses símbolos.
É por isso que você e um agente podem obter respostas diferentes à mesma consulta e que um agente num espaço pode obter uma resposta diferente de um agente noutro. Todas as conversas de um espaço partilham esse mesmo worktree. A verificação falha em aberto: prefere-se uma resposta desatualizada a uma resposta vazia.
Peça a um agente para executar code_impact (ou review_studio.blastRadius) quando quer o raio de impacto de uma alteração. Consulte Computação de revisão.
A pesquisa semântica precisa do modelo de embeddings
Secção intitulada “A pesquisa semântica precisa do modelo de embeddings”Os símbolos e os factos são convertidos em embeddings no momento da escrita e apenas quando o modelo de embeddings no dispositivo está instalado. Até lá, mode: "semantic" e a metade semântica do hybrid não têm nada com que corresponder e a pesquisa é, na prática, apenas por palavra-chave.
Instale o modelo em Definições → Servidor → Diagnóstico e privacidade → Pesquisa semântica antes de indexar. Os símbolos recebem um vetor quando o respetivo ficheiro é ingerido.
Note também que qualquer recompilação do binário do servidor volta a preparar as dylibs das gramáticas e altera os seus mtimes, o que invalida todos os checkpoints de indexação e força uma nova passagem completa por todos os checkouts na execução seguinte. Volta a calcular os hashes, mas não volta a extrair os ficheiros inalterados.
O que está no grafo
Secção intitulada “O que está no grafo”Tipos de símbolo: function, method, class, field, enum, constructor, getter, setter, typedef, extension, mixin, variable.
Tipos de aresta: calls, imports, extends, implements, mixes in, references.
As assinaturas canónicas destas ferramentas estão em Ferramentas MCP.