Pętla Ralph: jak uruchamiam autonomiczne agenty AI na noc
Zbudowałem system autonomicznych agentów, który wykorzystuje hooki zatrzymania do przechwytywania prób zakończenia, pamięć opartą na systemie plików do zachowania stanu między oknami kontekstowymi oraz budżety spawnowania, aby zapobiec niekontrolowanej rekurencji. System dostarczył moją infrastrukturę deliberacji obejmującą 9 PRD (3455 linii Python, 141 testów) w ciągu wielu nocnych sesji.1
TL;DR
Architektura Ralph umożliwia długotrwałe autonomiczne tworzenie oprogramowania przez AI, rozwiązując jednocześnie trzy problemy: wyczerpanie okna kontekstowego (rozwiązane przez świeży kontekst w każdej iteracji), trwałość stanu (rozwiązane przez system plików jako pamięć) oraz ciągłość zadań (rozwiązane przez pętle hooków zatrzymania, które uniemożliwiają agentowi zakończenie pracy przed ukończeniem zadania). Zaimplementowałem ten wzorzec w moim systemie hooków Claude Code i wykorzystałem go do budowy mojej infrastruktury deliberacji wieloagentowej. System działa, ale nauczył mnie trudnych lekcji o budżetach spawnowania, jakości kryteriów i zanieczyszczaniu systemu plików.
Problem okna kontekstowego
Każda konwersacja z AI operuje w ramach okna kontekstowego: bufora o stałym rozmiarze, przechowującego historię rozmowy, prompty systemowe, wyniki narzędzi i pamięć roboczą. Okno kontekstowe Claude mieści około 200 000 tokenów. Złożona sesja programistyczna może je wyczerpać w ciągu 30–60 minut intensywnej pracy.2
Zmierzyłem to bezpośrednio podczas budowy systemu deliberacji. Sesje, które zaczynały się od precyzyjnych edycji wielu plików w 8 modułach Python, degradowały się do tunelowego widzenia pojedynczego pliku po około 90 minutach. Agent przestawał odwoływać się do architektury, którą wcześniej przeczytał, ponieważ ten kontekst został skompresowany.3
Degradacja przebiega według przewidywalnej krzywej:
Iteration 1: [200K tokens] → writes code, creates files
Iteration 2: [200K tokens] → reads files from disk, continues
Iteration 3: [200K tokens] → reads updated files, continues
...
Iteration N: [200K tokens] → reads final state, verifies criteria
Porównajmy to z pojedynczą długą sesją:
Minute 0: [200K tokens available] → productive
Minute 30: [150K tokens available] → somewhat productive
Minute 60: [100K tokens available] → degraded
Minute 90: [50K tokens available] → significantly degraded
Minute 120: [compressed, lossy] → errors accumulate
Agent ze świeżym kontekstem w każdej iteracji przewyższa agenta pracującego w ciągłej sesji, ponieważ każda iteracja przydziela pełne zasoby poznawcze do bieżącego stanu, zamiast dźwigać ciężar wcześniejszego rozumowania.
Moja implementacja
Hook zatrzymania
Mój system ochrony przed rekurencją przechwytuje próby zatrzymania agenta i sprawdza kryteria ukończenia:
#!/bin/bash
# From recursion-guard.sh - simplified
CONFIG_FILE="${HOME}/.claude/configs/recursion-limits.json"
STATE_FILE="${HOME}/.claude/state/recursion-depth.json"
# Safe defaults with config override
MAX_DEPTH=2
MAX_CHILDREN=5
DELIB_SPAWN_BUDGET=2
DELIB_MAX_AGENTS=12
# Load config with validation
load_config() {
if [[ -f "$CONFIG_FILE" ]] && command -v jq &>/dev/null; then
config_depth=$(jq -r '.max_depth // 2' "$CONFIG_FILE")
if [[ "$config_depth" =~ ^[0-9]+$ ]] && [[ "$config_depth" -gt 0 ]]; then
MAX_DEPTH="$config_depth"
fi
fi
}
Hook odczytuje plik kryteriów definiujący warunki sukcesu. Warunki muszą być weryfikowalne maszynowo: wynik testów (pass/fail), dane wyjściowe lintera, kody statusu HTTP, sprawdzanie istnienia plików.4
System plików jako trwała pamięć
Kluczowe spostrzeżenie: pliki przetrwają między oknami kontekstowymi. Mój katalog .claude/ służy jako trwała pamięć agenta:
| Katalog | Zawartość | Rola w pętli Ralph |
|---|---|---|
state/ |
recursion-depth.json, agent-lineage.json |
Śledzi liczbę iteracji, relacje rodzic-dziecko |
configs/ |
14 plików JSON | Kodują progi, budżety, reguły (nie na sztywno w kodzie) |
handoffs/ |
49 dokumentów kontekstowych | Zachowują decyzje architektoniczne z wielu sesji |
hooks/ |
95 obsług cyklu życia | Wymuszają bramki jakości między iteracjami |
Każda nowa iteracja odczytuje bieżący stan z dysku i kontynuuje od miejsca, w którym zakończyła się poprzednia. Hook startu sesji inicjalizuje czysty stan:
# From session-start.sh - recursion state initialization
RECURSION_STATE_FILE="$RECURSION_STATE_DIR/recursion-depth.json"
# Initialize with safe defaults
{
"depth": 0,
"agent_id": "root",
"parent_id": null,
"initialized_by": "session-start"
}
Jeśli stan ulegnie uszkodzeniu (co zdarzyło się dwa razy podczas rozwoju), wzorzec odzyskiwania odtwarza go z bezpiecznych wartości domyślnych zamiast powodować awarię:
if ! jq -e '.depth' "$RECURSION_STATE_FILE" &>/dev/null; then
# Corrupted state file, recreate with safe defaults
echo "- Recursion state recovered (was corrupted)"
fi
Format specyfikacji zadania
Skuteczne zadania Ralph zawierają trzy elementy: cel, kryteria ukończenia i wskaźniki kontekstu:
OBJECTIVE: Implement multi-agent deliberation with consensus validation.
COMPLETION CRITERIA:
- All tests in tests/test_deliberation_lib.py pass (81 tests)
- post-deliberation.sh validates consensus above 70% threshold
- recursion-guard.sh enforces spawn budget (max 12 agents)
- deliberation-pride-check.sh passes 5 quality checks
- No Python type errors (mypy clean)
CONTEXT:
- Follow patterns in lib/deliberation/state_machine.py
- Consensus thresholds in configs/deliberation-config.json
- Spawn budget model: agents inherit budget, not increment depth
Co zbudowałem z wykorzystaniem tego wzorca
Infrastruktura deliberacji (9 PRD)
Największy projekt w pętli Ralph: 9 dokumentów wymagań produktowych (PRD) zaimplementowanych w wielu sesjach.
| PRD | Rezultat | Testy |
|---|---|---|
| PRD 1–4 | Hooki, konfiguracja, rozszerzenia recursion-guard | Commit 3cad08c |
| PRD-5 | 48 testów integracyjnych bash (7 zestawów) | Commit 10df724 |
| PRD 7–8 | Podłączenie hooków + 81 testów jednostkowych Python | Commit fbf1a0d |
| PRD-9 | 12 testów E2E symulacji pipeline | Commit 32bd711 |
Łączny wynik: 3455 linii Python w 8 modułach, 141 testów, 4 commity. Każda sesja kontynuowała pracę od stanu systemu plików pozostawionego przez poprzednią. Świeży kontekst oznaczał, że każde PRD otrzymywało pełną uwagę agenta bez obciążenia historią konwersacji z wcześniejszych PRD.5
System jakości bloga (12 modułów)
Linter bloga zaczynał jako skrypt z 3 modułów i rozrósł się do 12 modułów poprzez iteracyjne pętle Ralph. Każda iteracja dodawała moduł, uruchamiała pełny zestaw testów i weryfikowała zero regresji. Kryteria ukończenia ewoluowały:
- Iteracja 1: „Wszystkie 77 testów przechodzi”
- Iteracja 5: „Wszystkie 77 testów przechodzi ORAZ linter raportuje 0 błędów we wszystkich 33 postach”
- Iteracja 8: „Wszystkie testy przechodzą ORAZ 0 błędów ORAZ 0 ostrzeżeń ORAZ wynik głębokości ≥2 we wszystkich postach”
Porażki i lekcje
Porażka 1: katastrofa budżetu spawnowania
Na początku budowy systemu deliberacji uruchomiłem sesję bez limitów budżetu spawnowania. Agent utworzył 3 podagenty eksploracyjne. Każdy podagent utworzył własne podagenty. W ciągu kilku minut hook recursion-guard przechwytywał dziesiątki prób spawnowania. Sesja zużywała tokeny API w tempie 10-krotnie wyższym niż normalnie, zanim ręcznie ją zakończyłem.6
Rozwiązanie: Dodałem model budżetu spawnowania do recursion-limits.json. Agenty dziedziczą budżet od swojego rodzica zamiast inkrementować głębokość. Agent główny z budżetem=12 może utworzyć łącznie do 12 agentów na wszystkich poziomach rekurencji. To było kluczowe spostrzeżenie architektoniczne: dziedziczenie budżetu zapobiega wykładniczemu wzrostowi, jednocześnie pozwalając na głębokie łańcuchy agentów.
Porażka 2: kryteria spełniane trywialnie
Wczesne zadanie prosiło agenta o „napisanie testów, które przechodzą”. Agent napisał minimalne testy: assert True, assert 1 == 1. Technicznie kryteria zostały spełnione. Wynik był bezwartościowy.
Rozwiązanie: Kryteria muszą określać zarówno ilość, jak i jakość:
| Jakość kryteriów | Przykład | Rezultat |
|---|---|---|
| Niejasne | „Testy przechodzą” | Agent pisze trywialne testy |
| Mierzalne, ale niepełne | „Testy przechodzą ORAZ pokrycie >80%” | Agent pisze testy pokrywające linie, ale nietestujące nic znaczącego |
| Kompleksowe | „Wszystkie testy przechodzą ORAZ pokrycie >80% ORAZ brak błędów typów ORAZ linter czysty ORAZ każda klasa testowa testuje odrębny moduł” | Wynik jakości produkcyjnej |
Porażka 3: zanieczyszczanie systemu plików
Iteracje eksplorujące ślepe zaułki zostawiały artefakty: częściowo zaimplementowane funkcje, przestarzałe pliki, sprzeczne konfiguracje. Iteracja 5 mogła budować na niedokończonym podejściu z iteracji 3, które zostało porzucone w iteracji 4.
Rozwiązanie: Dodałem krok czyszczenia do kryteriów hooka zatrzymania: „Nie istnieją pliki, które nie są referencjonowane przez importy lub testy”. To zmusza agenta do posprzątania ślepych zaułków, zanim iteracja może zostać ukończona.
Porażka 4: incydent z ((VAR++))
Podczas testów integracyjnych bash hook recursion-guard zawiódł po cichu w pierwszej iteracji. Błąd: ((VAR++)) zwraca kod wyjścia 1, gdy VAR wynosi 0 (ponieważ 0++ ewaluuje się do 0, co bash traktuje jako fałsz). Z włączonym set -e zabijało to skrypt.
Rozwiązaniem było VAR=$((VAR + 1)) zamiast ((VAR++)). Ten pułapka bash, udokumentowana w moim MEMORY.md, zapobiegła temu samemu błędowi w 6 kolejnych skryptach hooków.7
Kiedy Ralph działa, a kiedy nie
Dobre dopasowanie
- Implementacja od zera z jasnymi specyfikacjami (nowe API, nowy moduł, nowy zestaw testów)
- Automatyczna weryfikacja istnieje (testy, sprawdzanie typów, lintery, kompilacja)
- Ograniczony zakres, który można opisać w pojedynczym pliku zadania
Słabe dopasowanie
- Subiektywna jakość („niech UI ładnie wygląda”) nie ma maszynowo weryfikowalnych kryteriów
- Praca eksploracyjna, gdzie kierunek zależy od odkryć na etapach pośrednich
- Refaktoryzacja na dużą skalę, wymagająca zrozumienia globalnych relacji w kodzie w dziesiątkach plików
Kluczowe wnioski
Dla programistów budujących systemy autonomicznych agentów: - Należy zainwestować w maszynowo weryfikowalne kryteria ukończenia przed uruchomieniem autonomicznych pętli; mój system deliberacji odniósł sukces, ponieważ każde PRD miało testowalne kryteria sukcesu (łącznie 141 testów) - Budżety spawnowania należy wdrożyć od pierwszego dnia; model dziedziczenia budżetu (a nie inkrementacji głębokości) zapobiega wykładniczemu spawnowaniu agentów, jednocześnie umożliwiając głębokie łańcuchy - Do kryteriów ukończenia należy dodać czyszczenie systemu plików; artefakty ze ślepych zaułków porzuconych iteracji będą zanieczyszczać kolejne iteracje
Dla zespołów inżynierskich oceniających autonomiczne tworzenie oprogramowania przez AI: - Architektura Ralph zamienia czas ludzkiej implementacji na czas ludzkiej specyfikacji; ROI zależy od tego, czy wąskim gardłem jest zdolność implementacyjna czy jasność specyfikacji - Wyniki autonomicznej pracy należy audytować z taką samą rygorem, jaki stosuje się do kodu od zewnętrznych wykonawców; moje 141 testów istnieje, ponieważ nauczyłem się, że spełnienie kryteriów ukończenia nie gwarantuje gotowości produkcyjnej
Źródła
-
Author’s implementation of the Ralph Loop pattern using Claude Code hooks. Deliberation infrastructure: 3,455 lines of Python, 8 modules, 141 tests across 4 commits (2025-2026). ↩
-
Anthropic, “Claude Models,” 2025. ↩
-
Liu, Nelson F. et al., “Lost in the Middle: How Language Models Use Long Contexts,” TACL, 2024. ↩
-
Anthropic, “Claude Code Documentation,” 2025. Hook lifecycle events. ↩
-
Author’s git log. Commits
3cad08c,10df724,fbf1a0d,32bd711spanning the full deliberation infrastructure build. ↩ -
Author’s experience with unbudgeted agent spawning. Documented in
~/.claude/projects/*/memory/MEMORY.mderror entries. ↩ -
Author’s bash debugging.
((VAR++))exit code behavior withset -edocumented as a cross-session learning in MEMORY.md. ↩