Zum Inhalt springen

Code mit dem Code-Graph suchen

Diese Anleitung zeigt, wie du ein Repo in den Code-Graph bekommst und ihn dann für die Frage nutzt, die du vor einem Refactoring wirklich hast: Was hängt davon ab?

Der Code-Graph ist eine Datenbank aus Symbolen und Kanten. Er entsteht, indem deine registrierten Checkouts mit tree-sitter geparst werden. Seine Werkzeuge sind für Agenten — du erreichst sie, indem du einen Agenten fragst.

Der Graph indiziert Dart, JavaScript, TypeScript, TSX, PHP, Python, Rust, Zig, C, C++, Go, Java, Ruby, C#, Swift, Kotlin, R, Assembly, MATLAB und Ada. Dateien in jeder anderen Sprache werden nicht geparst und tauchen deshalb weder in search_code, code_symbol, code_callers, code_callees noch in code_impact auf.

Zwei weitere Dinge bestimmen, was indiziert wird:

  • In einem Git-Arbeitsbaum richtet sich die Aufzählung nach git ls-files --cached --others --exclude-standard, deshalb werden jede .gitignore, jede verschachtelte Ignore-Datei, .git/info/exclude und die globale Excludes-Datei berücksichtigt. Genau das hält node_modules und Build-Ausgaben aus dem Graph.
  • Generiertes Dart fällt in jedem Fall weg. Generierte Dateien sind meist committet, deshalb würde Git sie allein nicht ausschließen, und sie ändern sich bei jedem Lauf der Codegenerierung.

Einen Checkout zu registrieren löst RepoAdded aus, und das startet die Pipeline index_code dafür automatisch. Siehe Repos zu einem Arbeitsbereich hinzufügen.

Zum erneuten Indizieren von Hand:

  1. Öffne Einstellungen → Arbeitsbereich → Repositorys.
  2. Klicke in der Zeile des Repos auf Code indizieren.
  3. Während der Lauf läuft, zeigt die Schaltfläche erledigte Dateien gegenüber der Gesamtzahl, mit einer Steuerung zum Abbrechen. Ist sie fertig, wird daraus ein Häkchen mit der Symbolanzahl.

Der Graph ist nach Arbeitsbereich, Repo und Checkout partitioniert: Der verknüpfte Checkout ist eine Partition, und jeder Worktree eines Bereichs bekommt eine eigene (Schlüssel ist die ID des isolierten Repos).

Zwei Begrenzungen solltest du kennen, denn sie erklären eine Wartezeit, die wie ein Hänger wirkt:

  • Der Dateiwächter lässt auf dem Host nur einen Indexlauf gleichzeitig zu — ein zweiter Checkout wartet. Die Pipeline index_code ist getrennt auf einen Lauf je Arbeitsbereich gedeckelt, deshalb stellen sich zwei Repos im selben Arbeitsbereich an; verschiedene Arbeitsbereiche können parallel indizieren. Der Indexer selbst serialisiert zwei Läufe desselben Checkouts, damit ein Start der Pipeline und ein Durchgang des Wächters ihn nicht doppelt parsen.
  • Worktrees ruhender Bereiche (keine Nachricht in der letzten Woche) werden weder beobachtet noch indiziert. Verknüpfte Checkouts bleiben unter Beobachtung. Eine Entscheidung zum Überspringen wird nach fünf Minuten neu geprüft, deshalb wird ein Bereich, der wieder aktiv wird, doch noch aufgenommen.

Bitte einen Agenten, zu suchen. Das Werkzeug ist search_code, und es braucht einen Arbeitsbereich und ein Repo:

search_code(workspace_id: "...", repo_id: "...", query: "authentication middleware")

Repo-IDs kommen aus list_repos. Das optionale Argument mode ist keyword, semantic oder hybrid und steht standardmäßig auf hybrid — BM25 über Namen, Signaturen und Doc-Kommentare, zusammengeführt mit der Vektorähnlichkeit.

Jedes Ergebnis trägt id, Name, qualifizierten Namen, Art, Dateipfad, Start- und Endzeile des Symbols und seine Signatur, wenn es eine hat. Die id ist der Bezug, den du jedem anderen Werkzeug auf dieser Seite übergibst.

Wenn du den genauen Namen kennst, schlage ihn direkt nach:

code_symbol(workspace_id: "...", repo_id: "...", name: "MyClass")

Beide nehmen eine symbol_id aus einem Suchergebnis und ein optionales limit (Vorgabe 50):

code_callers(workspace_id: "...", symbol_id: "...")
code_callees(workspace_id: "...", symbol_id: "...")

code_callers liefert die Symbole mit einer eingehenden Kante auf dieses; code_callees liefert die, von denen es abhängt.

Für dieses Werkzeug ist die ganze Seite da:

code_impact(workspace_id: "...", symbol_id: "...", depth: 3)

Es berechnet den Radius der umgekehrten Abhängigkeit: alles, was entlang der Kanten calls, extends und implements direkt oder transitiv vom Symbol abhängt (imports, mixes-in und generische references liegen im Graph, werden hier aber nicht durchlaufen). depth ist die Höchstzahl der Sprünge, zwischen 1 und 6, Vorgabe 2.

Das Ergebnis hat drei Felder:

  • root — das Symbol, nach dem du gefragt hast
  • impacted — die erreichbare Menge, die Wurzel bei Tiefe 0 eingeschlossen, jedes mit seiner depth ab der Wurzel
  • edgeCount — wie viele Kanten der Durchlauf gekreuzt hat, als Anzahl statt als die Kanten selbst

Führe es aus, bevor du umbenennst oder eine Signatur änderst, und gib dem Agenten die Liste aus impacted als Umfang.

Ergebnisse werden gegen die eigene Arbeitskopie des Aufrufers geprüft

Abschnitt betitelt „Ergebnisse werden gegen die eigene Arbeitskopie des Aufrufers geprüft“

Bei einem Agenten als Aufrufer wird die Bereichs-ID automatisch eingesetzt, und die Ergebnisse werden gegen die Arbeitskopie dieses Bereichs geprüft. Ein Symbol, dessen Datei im Baum des Aufrufers nicht mehr existiert, wird ausgelassen, und die Antwort trägt eine Anzahl staleOmitted plus einen Hinweis, dass der Index für diese Symbole veraltet ist.

Deshalb können du und ein Agent auf dieselbe Anfrage verschiedene Antworten bekommen, und ein Agent in einem Bereich eine andere als ein Agent in einem anderen. Jede Unterhaltung in einem Bereich teilt sich diesen einen Worktree. Die Prüfung fällt offen aus: eine veraltete Antwort ist einer leeren vorzuziehen.

Bitte einen Agenten, code_impact (oder review_studio.blastRadius) auszuführen, wenn du den Auswirkungsradius einer Änderung willst. Siehe Review-Compute (Kohorten und Achsen).

Symbole und Fakten bekommen ihr Embedding beim Schreiben, und nur, wenn das Embedding-Modell auf dem Gerät installiert ist. Bis dahin finden mode: "semantic" und die semantische Hälfte von hybrid nichts zum Abgleichen, und die Suche ist praktisch nur eine Schlüsselwortsuche.

Installiere das Modell unter Einstellungen → Server → Diagnose und Datenschutz → Semantische Suche, bevor du indizierst. Symbole bekommen einen Vektor, wenn ihre Datei aufgenommen wird.

Beachte außerdem: Jeder Neubau der Server-Binärdatei stellt die Grammatik-dylibs neu bereit und ändert ihre mtimes. Das macht jeden Index-Checkpoint ungültig und erzwingt beim nächsten Lauf einen vollständigen Durchgang über jeden Checkout. Es hasht neu, extrahiert unveränderte Dateien aber nicht noch einmal.

Symbolarten: function, method, class, field, enum, constructor, getter, setter, typedef, extension, mixin, variable.

Kantenarten: calls, imports, extends, implements, mixes in, references.

Die kanonischen Signaturen dieser Werkzeuge stehen in MCP-Tools.