Uruchamiaj równoległe agenty w izolowanych worktree
Worktree Gita daje każdemu równoległemu zadaniu agenta osobny katalog i branch, a wszystkie zadania dzielą jedną historię repozytorium. Worktree izoluje tylko pliki. Przy dwóch do czterech równoległych strumieniach potrzebujesz też bloku portów i lokalnego stanu na strumień, allowlisty lokalnej konfiguracji, bramki zaliczanej przez każdy strumień osobno i sprzątania, które zachowuje niewypchniętą pracę.
Ta strona jest dla deweloperów oraz tech leadów, którzy konfigurują repozytoria zespołu, i odpowiada na pytanie Q13 scorecardu. Uruchamiasz trzy agenty w trzech terminalach tego samego checkoutu. Formatter pierwszego przepisuje plik, który edytuje drugi, serwer deweloperski drugiego po cichu zajmuje następny wolny port, a testy end-to-end trzeciego przechodzą na serwerze drugiego. Każdy raport mówi „gotowe”. Żaden nie dowodzi, który kod był testowany.
Pytanie Q13 scorecardu: Jak uruchamiasz równoległe sesje agentów bez kolizji plików?
Dowód na maksymalną ocenę: skrypt, a nie nawyk, tworzy i usuwa dwa do czterech izolowanych strumieni, z których każdy ma jawną rewizję bazową, własne zasoby runtime i własne zaliczone bramki.
Co daje ci izolacja w worktree
Dział zatytułowany „Co daje ci izolacja w worktree”- Natywne polecenie worktree dla Claude Code, Codeksa i Cursora oraz informację, co każde z nich przenosi do nowego checkoutu, a czego nie.
- Dwa przetestowane skrypty repozytorium: jeden tworzy strumień z blokiem portów i konfiguracją wyłącznie deweloperską, drugi usuwa strumień tylko wtedy, gdy nic nie przepadnie.
- Procedurę dowodową, która pokazuje, z którego checkoutu korzystał działający serwer i przebieg testów oraz które pliki zmieniły dwa strumienie, bez czytania diffów.
- Trzy prompty do skopiowania: podział pracy, start strumienia i raport gotowości do review.
Kiedy warto uruchamiać agenty równolegle?
Dział zatytułowany „Kiedy warto uruchamiać agenty równolegle?”Równoległe strumienie się opłacają, gdy zadania są niezależne i każde ma sprawdzenie, które uruchomi maszyna. Kosztują nadzór: każdy strumień kończy się diffem, który ktoś musi zaakceptować, więc limitem jest zwykle twoja przepustowość review, a nie narzędzie. Przy dwóch do czterech strumieniach jeden deweloper wciąż sprawdzi każdy wynik względem jego bramki. Dziesięć i więcej agentów z terminalem nadzorczym i merge trainem opisuje strona dziesięć agentów naraz.
| Twoja sytuacja | Uruchom jako | Dlaczego |
|---|---|---|
| Dwie lub trzy poprawki w różnych modułach, każda z nieprzechodzącym testem | Równoległe strumienie, jeden worktree na zadanie | Osobne pliki, osobne bramki |
| Jedno trudne zadanie z kilkoma sensownymi projektami rozwiązania | To samo zadanie w dwóch worktree; zostaw to z mniejszym zaliczonym diffem | Porównanie podejść na tych samych testach |
| Dwa zadania zmieniające to samo API, schemat lub plik konfiguracji | Jeden strumień, po kolei | Praca równoległa gwarantuje tu konflikt i drugie review |
| Poboczne rozpoznanie lub review tylko do odczytu | Subagent w jednej sesji | Drugi checkout nie jest potrzebny; zobacz subagenci zakresowi |
Szerszy wybór między worktree, agentami w tle, subagentami i skryptowym fan-outem opisuje strona wzorce orkiestracji pracy agentów.
Co worktree izoluje, a czego nie?
Dział zatytułowany „Co worktree izoluje, a czego nie?”Worktree ma własne pliki robocze, indeks i bieżący branch. Katalog .git (obiekty, refy, git config) dzieli ze wszystkimi innymi worktree repozytorium. Wszystko poza Gitem jest wspólne, dopóki sam tego nie rozdzielisz:
| Zasób | Osobny dla worktree? | Co się psuje, gdy jest wspólny |
|---|---|---|
| Śledzone pliki i branch | Tak | Nic: to właśnie rozwiązuje worktree |
Pliki ignorowane przez Gita (.env, node_modules/) | Brak w nowym worktree | Testy padają na braku konfiguracji albo agent wymyśla wartości |
| Porty serwera deweloperskiego i testów | Nie | Serwer przechodzi na następny wolny port; testy trafiają w serwer innego strumienia |
| Lokalna baza, cache, kolejka | Nie | Dwa strumienie migrują lub seedują te same dane |
git config | Nie | Zapis konfiguracji w jednym worktree zmienia wszystkie |
| Zgody na uprawnienia w Claude Code | Nie | „Yes, and don’t ask again” dla polecenia Bash w jednym worktree trafia do .claude/settings.local.json głównego checkoutu i działa wszędzie (Claude Code v2.1.211 i nowsze; w Windowsie reguła zostaje w danym worktree) |
| Dane produkcyjne, deploye, sekrety, zewnętrzne API | Nie | „Szybkie sprawdzenie” jednego strumienia zapisuje dane na żywo |
Uruchom agenta w osobnym worktree
Dział zatytułowany „Uruchom agenta w osobnym worktree”Wszystkie trzy narzędzia potrafią same utworzyć worktree. Różnią się tym, gdzie go umieszczają, jaki branch mu dają i co kopiują.
# Terminal, w katalogu głównym repozytorium. Jeden terminal na strumień.claude --worktree fix-auth # albo: claude -w fix-authclaude --worktree csv-export --tmux # to samo, otwarte w sesji tmuxclaude --worktree "#1234" # worktree .claude/worktrees/pr-1234 na najnowszym commicie pull requesta 1234Claude Code tworzy worktree w .claude/worktrees/<name>/ na nowym branchu worktree-<name>. Domyślnie odgałęzia się od domyślnego brancha na remote (worktree.baseRef: "fresh"); ustaw "worktree": { "baseRef": "head" } w ustawieniach, żeby startować od bieżącego lokalnego HEAD. Przed pierwszym uruchomieniem:
-
Dodaj
.claude/worktrees/do.gitignore. -
Utwórz
.worktreeincludew katalogu głównym repozytorium, w składni.gitignore. Claude Code kopiuje tylko pliki, które pasują do wzorca i są ignorowane przez Gita, więc wpisz wyłącznie pliki deweloperskie:.env.development.env.test
Przy wyjściu Claude Code sprawdza worktree pod kątem zmian i nowych commitów: czysty worktree sesji bez nazwy jest usuwany razem z branchem, a przy worktree z pracą dostajesz pytanie, czy go zachować. Uruchomienia headless claude -p --worktree nie mają pytania przy wyjściu i zostawiają swoje worktree. Własny subagent z isolation: worktree we frontmatterze zawsze działa we własnym tymczasowym worktree. Sprawdzone w claude --help 2.1.283 i w dokumentacji worktree Claude Code 26 września 2026 r. Aplikacja desktopowa ma tę samą opcję dla każdej sesji; zobacz Claude Code Desktop.
# Terminal, w katalogu głównym repozytorium. Jeden terminal na strumień.codex --worktree "Fix the CSV export header bug. Start with a failing test."
# Bez interakcji, dla skryptu:codex exec --worktree "Fix the CSV export header bug. Start with a failing test."W trwającej sesji /worktree przenosi rozmowę do nowego worktree. Obsługa worktree jest domyślnie włączona od codex-cli 0.156.0, ale sesja korzysta z niego tylko wtedy, gdy o to poprosisz. Zarządzany worktree Codeksa leży w $CODEX_HOME/worktrees/ na odłączonym HEAD i nie zawiera niezacommitowanych zmian, plików nieśledzonych ani plików ignorowanych przez Gita. Codex 0.157.1 nie dokumentuje odpowiednika .worktreeinclude. Utwórz więc branch, zanim agent zacommituje, i dostarcz konfigurację sam albo utwórz checkout skryptem repozytorium opisanym niżej i uruchom w nim codex. Zmierzone szczegóły znajdziesz na stronie izolowane zadania Codeksa w worktree Gita. Sprawdzone w codex --help i codex features list 0.157.1, 26 września 2026 r.
Dokumentacja Cursora opisuje Worktrees jako funkcję, która pozwala „Agent work in isolated Git checkouts” (cursor.com, sprawdzone 28 sierpnia 2026 r.), a Agents Window uruchamia kilka agentów obok siebie. Aktualnych kroków w UI nie dało się ponownie sprawdzić dla tej strony, więc korzystaj ze strony okno Agents i Projects w Cursorze i z dokumentacji Worktrees Cursora.
Gdy potrzebujesz stałej ścieżki, brancha i bloku portów, utwórz checkout skryptem repozytorium opisanym niżej, a potem otwórz ten folder w osobnym oknie Cursora. Agent w tym oknie edytuje wtedy tylko ten checkout.
Natywne polecenia dają osobny checkout. Nie dają portów, bazy na strumień ani zapisu rewizji bazowej. To zadanie repozytorium.
Zapisz kontrakt izolacji jako skrypt repozytorium
Dział zatytułowany „Zapisz kontrakt izolacji jako skrypt repozytorium”Maksimum w Q13 wymaga automatyzacji, którą każdy agent i każda osoba z zespołu uruchamia tak samo. Zacommituj dwa skrypty. Pierwszy tworzy strumień z jawnej bazy, przydziela najniższy wolny blok portów (co 10, więc serwer, który przejdzie na następny port, zostaje we własnym bloku), zapisuje blok w ignorowanym przez Gita pliku .wt-env i kopiuje allowlistę plików deweloperskich. Najpierw dodaj .wt-env i każdy plik z allowlisty do .gitignore; w przeciwnym razie wt-rm.sh widzi je jako nieśledzone i odmawia usunięcia każdego strumienia:
#!/usr/bin/env bash# scripts/wt-new.sh SLUG [BASE]: one agent stream = worktree + branch + port block + local configset -euo pipefailslug="${1:?usage: scripts/wt-new.sh SLUG [BASE]}"base="${2:-origin/main}"main="$(git worktree list --porcelain | awk 'NR==1 {print $2}')" # the main checkout is listed firstdir="$(dirname "$main")/$(basename "$main")-$slug"
# Lowest index no other worktree holds; index 0 is the main checkoutused="$(git worktree list --porcelain | awk '/^worktree /{print $2}' | while read -r w; do sed -n 's/^WT_INDEX=//p' "$w/.wt-env" 2>/dev/null || true; done)"i=1; while grep -qx "$i" <<<"$used"; do i=$((i + 1)); done
git fetch --quiet origingit worktree add --quiet --no-track -b "agent/$slug" "$dir" "$base" # fails if the branch exists: pick a new slug
cat > "$dir/.wt-env" <<ENVWT_INDEX=$iWT_SLUG=$slugWT_BASE=$(git rev-parse "$base")APP_PORT=$((3000 + i * 10))DB_PORT=$((5432 + i * 10))ENV
for f in .env.development .env.test; do # allowlist: development files only if [ -f "$main/$f" ]; then cp "$main/$f" "$dir/$f"; fidone
echo "ready: $dir on agent/$slug from $(git rev-parse --short "$base"), APP_PORT=$((3000 + i * 10))"Drugi usuwa strumień tylko wtedy, gdy worktree jest czysty, a każdy commit jego brancha istnieje na origin. Uruchamiaj go z głównego checkoutu:
#!/usr/bin/env bash# scripts/wt-rm.sh SLUG: remove a stream only when nothing would be lostset -euo pipefailslug="${1:?usage: scripts/wt-rm.sh SLUG}"main="$(git worktree list --porcelain | awk 'NR==1 {print $2}')"dir="$(dirname "$main")/$(basename "$main")-$slug"
if [ -n "$(git -C "$dir" status --porcelain)" ]; then echo "refusing: uncommitted or untracked files in $dir" >&2; exit 1figit fetch --quiet originif [ -n "$(git rev-list "agent/$slug" --not --remotes=origin)" ]; then echo "refusing: agent/$slug has commits that exist on no origin branch; push them first" >&2; exit 1figit worktree remove "$dir"git branch -d "agent/$slug" 2>/dev/null || echo "kept branch agent/$slug (not merged; delete it after the PR lands)"Oba skrypty uruchomiliśmy 26 września 2026 r. na testowym repozytorium: dwa strumienie dostały porty 3010 i 3020, zwolniony indeks został użyty ponownie, a usuwanie odmówiło brancha z niewypchniętym commitem, dopóki go nie wypchnięto. Zastąp origin/main swoim domyślnym branchem, a porty portami swojego stosu, i dopisz po kroku kopiowania instalację zależności, której wymaga twój projekt.
Potem niech narzędzia same czytają ten plik, żeby nikt nie musiał pamiętać o eksporcie. Projekt z Vite i Playwright wyprowadza na przykład każdy URL z jednej wartości i odrzuca port zastępczy:
import { readFileSync } from 'node:fs';import { defineConfig } from '@playwright/test';
const wtEnv = (() => { try { return readFileSync('.wt-env', 'utf8'); } catch { return ''; }})();const port = /^APP_PORT=(\d+)$/m.exec(wtEnv)?.[1] ?? '5173'; // main checkout keeps the defaultconst baseURL = `http://localhost:${port}`;
export default defineConfig({ use: { baseURL }, webServer: { command: `npx vite --port ${port} --strictPort`, // fail instead of moving to another port url: baseURL, reuseExistingServer: !process.env.CI, },});Najważniejsze jest powiązanie webServer.url z portem strumienia: przy zaszytym na sztywno URL-u reuseExistingServer podłącza się do tego, co akurat nasłuchuje na porcie, czyli czasem do serwera innego strumienia, i przebieg raportuje zielony wynik dla kodu, którego nigdy nie testował.
Poprowadź dwa do czterech strumieni od podziału do merge’a
Dział zatytułowany „Poprowadź dwa do czterech strumieni od podziału do merge’a”-
Podziel pracę i sprawdź niezależność. Wklej prompt planistyczny poniżej do jednej sesji w głównym checkoucie. Zostaw tylko zadania, które zmieniają rozłączne pliki i mają własny nieprzechodzący test lub kryterium akceptacji; resztę uszereguj.
-
Utwórz jeden strumień na zadanie. Uruchom
scripts/wt-new.sh fix-auth,scripts/wt-new.sh csv-exporti tak dalej z głównego checkoutu. Rewizja bazowa jest teraz zapisana w każdym.wt-env. -
Uruchom jednego agenta na worktree. Otwórz terminal (lub okno Cursora) w każdym katalogu i uruchom tam agenta z promptem strumienia poniżej. W Claude Code możesz zamiast tego użyć
claude --worktree NAME, o ile.worktreeincludei przydział portów pokrywają to, co robi skrypt. Taki strumień działa na branchuworktree-NAME; sprawdzenie nakładania się poniżej obejmuje już brancheworktree-*. Taki strumień usuwaj przy wyjściu z sesji albo przezgit worktree remove .claude/worktrees/NAME, nie skryptemwt-rm.sh. -
Niech każdy strumień oceniają bramki, nie ty. Agent kończy dopiero wtedy, gdy type check, lint i testy projektu przechodzą w jego worktree. Hooki agenta mogą to wymuszać na końcu każdej tury.
-
Udowodnij każdy strumień przed review. Wykonaj sprawdzenia z następnej sekcji. Strumień, który nie pokaże dowodów, wraca do swojego agenta, a nie do recenzenta.
-
Integruj po jednym strumieniu. Wypchnij branch poleceniem
git push -u origin agent/SLUG, otwórz pull request i pozwól działać CI. Gdy pierwszy pull request zostanie zmergowany, zrób rebase następnego brancha na nowy domyślny branch i uruchom ponownie jego bramki przed merge’em. Kolejka review utrzymuje tę kolejność, gdy robi to kilka osób. -
Usuwaj każdy strumień skryptem.
scripts/wt-rm.sh fix-authodmawia usunięcia brudnej lub niewypchniętej pracy. Od czasu do czasu uruchomgit worktree prune, żeby usunąć wpisy katalogów worktree skasowanych ręcznie.
Jak udowodnić strumień bez czytania jego diffu?
Dział zatytułowany „Jak udowodnić strumień bez czytania jego diffu?”Poproś o dowody wytworzone przez maszynę, a potem czytaj tylko to, co one wskażą. Cztery sprawdzenia pokrywają sposoby, w jakie równoległe strumienie wprowadzają w błąd:
| Pytanie | Sprawdzenie (w terminalu) | Zaliczone, gdy |
|---|---|---|
| Czy strumień wystartował tam, gdzie myślisz? | git -C ../myapp-csv-export merge-base HEAD origin/main porównane z WT_BASE w .wt-env | Baza to zapisana rewizja albo późniejsza, na którą świadomie zrobiono rebase |
| Czy bramki działały w tym checkoucie? | Raport agenta wymienia każde polecenie z kodem wyjścia; sam uruchom ponownie polecenie testów w tym katalogu | Każdy kod wyjścia to 0, a twój przebieg daje to samo |
| Czy działający serwer należy do tego checkoutu? | . ../myapp-csv-export/.wt-env; lsof -a -d cwd -p "$(lsof -tiTCP:"$APP_PORT" -sTCP:LISTEN | paste -sd, -)" | Pokazany cwd to katalog tego strumienia |
| Czy dwa strumienie zmieniły te same pliki? | Sprawdzenie nakładania się poniżej, z głównego checkoutu | Nic nie wypisuje |
# Files changed by two or more stream branches since they left main# (agent/* from the script, worktree-* from claude --worktree)for b in $(git for-each-ref --format='%(refname:short)' refs/heads/agent/ 'refs/heads/worktree-*'); do git diff --name-only "origin/main...$b"done | sort | uniq -dKażdy wypisany plik oznacza, że dwa strumienie zmieniły ten sam plik. Zatrzymaj jeden z nich, zmerguj drugi, a przed wznowieniem zatrzymanego strumienia zrób rebase jego brancha na nowy domyślny branch. Przed pull requestem poproś każdego agenta o raport gotowości poniżej i dołącz go; pull request niesie wtedy własny dowód, jak w pakiecie dowodów. Kto zatwierdza, zostaje bez zmian względem pracy ludzi: recenzent wskazany przez twoje warstwowe review pull requestów, który ocenia dowody i pliki, które one wskazują.
Co się psuje przy agentach w równoległych worktree?
Dział zatytułowany „Co się psuje przy agentach w równoległych worktree?”Testy przechodzą na serwerze innego strumienia. Serwer deweloperski przeszedł na wolny port albo reuseExistingServer podłączył się do sąsiada. Wyjście: zatrzymaj wszystkie serwery deweloperskie, dodaj --strictPort (lub odpowiednik w twoim frameworku), wyprowadź URL testów z .wt-env i ponownie uruchom bramki strumienia. Każdy wcześniejszy zielony przebieg tego strumienia traktuj jako niedowiedziony.
Nowy worktree się nie buduje. Pliki ignorowane przez Gita i zależności nie istnieją w świeżym checkoucie. Wyjście: dodaj plik do .worktreeinclude lub allowlisty skryptu i zainstaluj zależności w worktree. Nigdy nie poszerzaj allowlisty o pliki produkcyjne, żeby „zadziałało”.
Commity Codeksa znikają po sprzątaniu. Commity zrobione na odłączonym HEAD nie należą do żadnego brancha. Wyjście: przed usunięciem worktree uruchom git -C DIR reflog -5, a potem z głównego checkoutu git branch rescue/csv-export SHA. Zapobiega temu linia git switch -c w prompcie strumienia.
Git zgłasza, że branch jest już używany w innym worktree. Git nie pozwala mieć tego samego brancha wybranego (checkout) w dwóch worktree naraz. Wyjście: uruchom git worktree list, żeby znaleźć właściciela; jeśli jego katalog skasowano ręcznie, uruchom git worktree prune i spróbuj ponownie.
Worktree nie daje się usunąć. Uruchomienia headless claude -p --worktree nie mają pytania przy wyjściu i zostawiają swój worktree oraz blokadę, którą Claude Code na nim założył (blokadę zwalnia też przegląd nieaktualnych blokad przy kolejnej sesji Claude Code). Wyjście: potwierdź przez git -C .claude/worktrees/NAME status, że nie ma nic do zachowania (commity, które chcesz zachować, najpierw wypchnij), potem uruchom git worktree unlock .claude/worktrees/NAME, git worktree remove .claude/worktrees/NAME i git branch -d worktree-NAME. Strumień utworzony skryptem usuwaj przez scripts/wt-rm.sh SLUG.
Zgoda udzielona w jednym strumieniu działa we wszystkich. Claude Code zapisuje reguły „don’t ask again” w .claude/settings.local.json głównego checkoutu. Wyjście: po sesji równoległej przejrzyj ten plik, a reguły, które chcesz zachować, przenieś do commitowanego .claude/settings.json.
Dwa strumienie zmieniły ten sam kontrakt. Niezależne testy przechodzą, ale wynik po merge’u już nie. Wyjście: zmerguj jeden, zrób rebase drugiego, uruchom ponownie jego pełną bramkę, a następnym razem dopisz ten kontrakt do listy „must run in sequence” w prompcie planistycznym.
Dokąd dalej z równoległymi agentami
Dział zatytułowany „Dokąd dalej z równoległymi agentami”Worktree należą do etapu Build w cyklu życia AI-native; mapa narzędzi porównuje funkcje równoległości w poszczególnych narzędziach. Poprzedni playbook harnessu to subagenci zakresowi, a następne pytanie scorecardu, Q14, to pętla zwrotna dla sesji. Wszystkie playbooki znajdziesz w przewodniku po scorecardzie dewelopera.