Przejdź do głównej zawartości

Zarządzanie dużymi bazami kodu

Prosisz agenta, aby „zmienił nazwę pola User.role na User.accountType w całej aplikacji”. Z pełnym przekonaniem edytuje trzy pliki w packages/web, ogłasza sukces, a ty wdrażasz zmiany. Dwie godziny później usługa billing-worker wyrzuca błąd na produkcji, bo czytała role z tego samego współdzielonego schematu Drizzle, którego agent nigdy nie otworzył. W monorepo z 500 tys. linii kodu model nie myli się dlatego, że jest głupi. Myli się, bo nigdy nie zobaczył pliku, który miał znaczenie.

Rozwiązaniem nie jest większe okno kontekstu. To przepływ pracy: ujawnij właściwe pliki, zanim model zacznie wprowadzać zmiany, zaindeksuj repozytorium tak, by działało wyszukiwanie semantyczne, i rozłóż duże zmiany tak, by każdy krok dało się przejrzeć.

  • Prompt do odkrywania kontekstu, który mapuje promień rażenia zmiany, zanim powstanie choć linijka kodu
  • Prompt do dekompozycji, który zamienia „zrefaktoryzuj system uwierzytelniania” w listę kontrolną gotową do przeglądu
  • Konfigurację indeksowania i plików ignorowania osobno dla Cursora, Claude Code i Codeksa
  • Plan ratunkowy na nieaktualne indeksy, przepełnienie okna kontekstu i ograniczenia skali monorepo

Ruchem o największej dźwigni w dużym repozytorium jest zmuszenie agenta, by znalazł i zaraportował pliki, których zmiana dotyczy, zanim cokolwiek wyedytuje. To wyłapuje zależność między pakietami, którą agent w innym wypadku by przeoczył, a kosztuje grosze: przebieg w trybie tylko do odczytu to ułamek ceny spartaczonej refaktoryzacji.

Jeśli raport pomija usługę, o której wiesz, że istnieje, twój indeks jest niekompletny albo jego reguły ignorowania są zbyt agresywne. Napraw to (następny krok), zanim ruszysz dalej. Raport jest też twoim artefaktem przeglądu: trzymaj go otwarty i odhaczaj pliki w miarę wprowadzania zmiany.

Krok 2: zaindeksuj repozytorium i dostrój pliki ignorowania

Dział zatytułowany „Krok 2: zaindeksuj repozytorium i dostrój pliki ignorowania”

Indeksowanie semantyczne buduje embeddingi wektorowe twojego kodu, dzięki czemu agent potrafi odpowiedzieć na pytanie „gdzie obsługiwane jest przetwarzanie płatności?” bez otwierania pliku. W dużym repozytorium to różnica między agentem rozumującym o całym systemie a agentem zgadującym na podstawie trzech zakładek, które akurat masz otwarte. Każde narzędzie indeksuje inaczej, a pliki ignorowania, które utrzymują indeks szybkim i trafnym, są specyficzne dla danego narzędzia.

Cursor indeksuje przestrzeń roboczą automatycznie i wylicza embeddingi do wyszukiwania semantycznego. Utrzymuj indeks szczupły dzięki plikom ignorowania:

  • .cursorignore blokuje pliki przed indeksowaniem oraz przed dostępem agenta (używaj go do sekretów, node_modules/, wyników budowania).
  • .cursorindexingignore wyklucza pliki tylko z indeksu — pozostają dostępne przez jawne @-wskazanie. Używaj go do dużych plików generowanych (lockfile’i, dist/, snapshoty), które zaśmiecają wyniki wyszukiwania.
.cursorindexingignore
dist/
**/*.snap
pnpm-lock.yaml

Następnie zawężaj kontekst symbolami, a nie całymi plikami: @accountType (symbol) daje ciaśniejszy, mniej zaszumiony kontekst niż @user-service.ts (plik z 2000 linii).

Nigdy nie dawaj dużemu repozytorium otwartego zadania w stylu „zrefaktoryzuj cały system uwierzytelniania”. Model rozprasza się, gubi wątek w połowie, a ty dostajesz diff na 40 plików, którego nie da się przejrzeć. Zamiast tego zmuś go, by wypisał listę kontrolną, a następnie wykonuj po jednym elemencie na turę, tak by każdy krok był na tyle mały, że da się go zweryfikować.

Gdy plan zostanie zatwierdzony, realizuj go przyrostowo i weryfikuj po każdym kroku. Odwołuj się do konkretnego symbolu, żeby agent trzymał się celu, zamiast od nowa wyprowadzać zakres:

Po każdym kroku uruchamiaj odpowiednie testy. Ta przyrostowa pętla sprawia, że dużą migrację da się przejrzeć i cofnąć, podczas gdy pojedyncza zmiana „big bang” nie daje ani jednego, ani drugiego. Po pełną dyscyplinę planowania zajrzyj do PRD → plan → todo.

W długiej sesji sama historia rozmowy staje się nieaktualnym kontekstem — agent wciąż „pamięta” błąd, który naprawiłeś godzinę temu. Resetuj świadomie, gdy zmieniasz zadanie. Mechanika różni się w zależności od narzędzia:

Rozpoczynaj nowy czat dla każdego odrębnego zadania (nowa funkcja, nowy błąd). Cursor trzyma kontekst każdego czatu osobno, więc świeży czat oznacza, że agent rozumuje wyłącznie o zadaniu, które ma przed sobą. Używaj punktów kontrolnych, by cofnąć czat, jeśli eksploracyjna edycja pójdzie nie tak.

  • Nieaktualny indeks po dużym merge’u. Tuż po scaleniu dużej gałęzi lub regeneracji generowanego kodu wyszukiwanie semantyczne zwraca ścieżki, które się przesunęły lub już nie istnieją. Ponów indeksowanie (Cursor: reindeksuje przy zmianie, ale wymuś resync z Ustawień, jeśli wyniki wyglądają źle; Claude Code/Codex: czytają na żywo, więc problemem jest zwykle nieaktualny CLAUDE.md/AGENTS.md — uruchom ponownie /init).
  • Przepełnienie okna kontekstu na ogromnych plikach. Pojedynczy generowany klient lub plik migracji liczący 8000 linii potrafi sam wysadzić okno. Nie @-wskazuj całego pliku — wskaż symbol albo poproś agenta, by zgrepował odpowiednią funkcję i wczytał tylko ten zakres. Dodaj plik do .cursorindexingignore, żeby przestał dominować w wyszukiwaniu.
  • Ograniczenia indeksowania monorepo. Bardzo duże monorepo mogą przekroczyć limity indeksowania albo zaindeksować tyle, że precyzja wyszukiwania spada. Zawężaj agresywnie plikami ignorowania, trzymaj generowane wyniki poza indeksem i preferuj AGENTS.md/CLAUDE.md osobno dla każdego pakietu, żeby kontekst pozostawał lokalny dla pakietu, nad którym pracujesz.
  • Agent edytuje niewłaściwą warstwę. Jeśli model wciąż edytuje reeksportowany wrapper zamiast źródła, zgubił kierunek zależności. Uruchom ponownie prompt odkrywczy z kroku 1 i jawnie wskaż plik będący źródłem prawdy.