05 / 06 · Best Practices

🔄 Geoffrey Huntley

Open Source Engineer. Ralph Loop и /specs как stdlib — детерминированная итерация вместо хаоса мульти-агентности.

🔄
Geoffrey Huntley
Open Source Engineer · Активный контрибьютор AI-проектов · Независимый исследователь
"Ralph Loop + /specs как stdlib — бесконечная детерминированная итерация"
Ralph Loop /specs Детерминизм Компилятор как верификатор Строгая типизация
⚠️
Частая ошибка новичков: запускают несколько CC-агентов параллельно без изоляции задач, ожидая ускорения. Вместо этого агенты конфликтуют: редактируют одни и те же файлы в разных направлениях, теряют контекст друг друга, создают непредсказуемые состояния. Geoffrey's принцип: детерминизм важнее скорости. Ralph Loop — один агент, одна задача, предсказуемый цикл — надёжнее любой параллельности без изоляции.

🔄 Контекст: философия детерминизма

Geoffrey Huntley — один из самых последовательных критиков «vibe coding» и сторонников детерминированного подхода к CC. Его центральный тезис: недетерминизм — главный враг продуктивности с LLM. Каждый добавленный агент умножает недетерминизм. Каждый динамический язык убирает объективный верификатор.

Его система построена на двух концепциях: Ralph Loop (один агент, одна задача, бесконечный цикл) и /specs как stdlib (библиотека переиспользуемых спецификаций-промптов).

🔁 Практика 1: Ralph Loop — один таск, один цикл

1
Один Claude — одна задача — бесконечный цикл до выполнения

Ralph Loop — базовый паттерн Geoffrey: один Claude-агент получает одну задачу и итерирует (implement → verify → commit → следующий subtask) пока задача не выполнена. Никакой преждевременной мульти-агентности.

Суть в том что каждая дополнительная точка координации между агентами — это источник недетерминизма. Один агент в цикле даёт предсказуемый процесс с ясным состоянием на каждом шаге.

«Non-determinism multiplies with every agent you add» — ключевая цитата Geoffrey. Прежде чем добавить агента спроси: задачи реально независимы или просто кажутся таковыми?

Task

Implement

Verify (компилятор / тесты)

Commit

Next subtask  →  (repeat until done)

Done
"Non-determinism multiplies with every agent you add. One agent in a loop is a deterministic process. Three agents in parallel is a mess."

📚 Практика 2: /specs + stdlib of prompts

2
Библиотека переиспользуемых спецификаций

Geoffrey создаёт директорию specs/ в корне проекта — библиотеку стандартных промптов-спецификаций для типичных задач проекта. Это «стандартная библиотека» вашего рабочего процесса: не изобретать колесо каждый раз, а переиспользовать проверенные спецификации.

Каждый /spec — это детальный промпт для конкретного типа задачи: добавление REST endpoint, создание миграции, написание интеграционного теста, рефакторинг под паттерн Repository. Используется командой одинаково — результат предсказуем.

bash specs/ — структура библиотеки
specs/ add-rest-endpoint.md # Создать новый REST endpoint create-migration.md # Создать миграцию БД write-integration-test.md # Написать интеграционный тест refactor-to-repository.md # Рефакторинг к паттерну Repository add-queue-job.md # Добавить job в очередь security-review.md # Провести security review endpoint # Использование: # "Follow @specs/add-rest-endpoint.md for POST /api/subscriptions/cancel"
md specs/add-rest-endpoint.md — пример /spec
# Spec: Add REST Endpoint ## Требования - Route в routes/ с правильным HTTP методом - Controller action (тонкий — только обработка запроса) - FormRequest для валидации - Resource класс для трансформации ответа - Service method для бизнес-логики - Unit тест для Service - Feature тест для Controller (включая auth, validation, happy path, error cases) ## Запрещено - Бизнес-логика в Controller - Raw json в ответе (только Resource) - SQL-запросы вне Repository/Model

⚙ Практика 3: Компилятор как верификатор

3
Строго типизированные языки = детерминированный feedback

Geoffrey настаивает: используй строго типизированные языки где компилятор или статический анализатор даёт объективный feedback. Claude видит ошибку компилятора → исправляет → снова проверяет. Это детерминированный цикл.

С динамическими языками без статического анализа: «Claude just guesses until it looks right». Нет объективного верификатора кроме тестов — а тесты можно «обмануть» написав код который проходит тест но делает не то.

Для PHP Geoffrey рекомендует declare(strict_types=1) в каждом файле и PHPStan level 8 как минимум. Это превращает PHP в «достаточно строгий» язык для работы с CC.

✅ Строгие языки — детерминированный feedback
TypeScript strict mode
Rust (borrow checker)
Go (строгая типизация)
PHP + declare(strict_types=1) + PHPStan level 8
Python + mypy strict

Компилятор/анализатор говорит «нет» объективно
⚠ Динамические языки — субъективный feedback
PHP без strict_types
Python без mypy
JavaScript без TypeScript
Ruby без Sorbet

Claude угадывает пока «выглядит правильно»
php PHP + строгий режим для работы с CC
<?php // ОБЯЗАТЕЛЬНО в каждом файле declare(strict_types=1); // phpstan.neon — минимум level 8 // parameters: // level: 8 // paths: [app, tests] // Запуск в Claude Loop: // vendor/bin/phpstan analyse --no-progress // Claude видит ошибки → исправляет → повторяет

🚫 Практика 4: Анти-паттерн — преждевременная мульти-агентность

4
"It's a red hot mess of non-determinism"

Geoffrey открыто критикует тренд на мульти-агентность как «решение по умолчанию». Мульти-агентность имеет смысл — но только когда задачи реально независимы и не имеют shared state.

Типичные ошибки: агенты работают с одними файлами → конфликты. Агент A завершил, агент B не знает об этом → дублирование. Ошибка в агенте A влияет на агента B → каскадный сбой который сложно отладить.

Правило Geoffrey: сначала доведи один loop до конца. Если задача всё ещё слишком большая — разбей на sequential subtasks, не на parallel agents.

Красные флаги преждевременной мульти-агентности Агенты обращаются к одним файлам. Нет чёткой границы ownership. Shared database без координации. Нет механизма разрешения конфликтов. «Кажется что задачи независимы» без проверки.
💡
Тонкость для опытных: в системе Geoffrey /specs — это не просто файлы, это «стандартная библиотека» которую CC может вызывать по имени. Когда spec детализирована достаточно (включает примеры input/output, граничные случаи, что делать при ошибке), разные разработчики в команде получают предсказуемо одинаковый результат для одной задачи. Это ключевой момент для командной работы: spec становится языком общения, а не просто документом.

🔑 Ключевой вывод

Детерминизм как архитектурный принцип

Система Geoffrey Huntley оптимизирована для предсказуемости. Ralph Loop — детерминированный процесс. /specs — стандартизированные входные данные. Строгие типы — объективный верификатор. Это не консерватизм — это понимание того что недетерминизм дорого обходится в долгосрочной перспективе: дольше отладка, сложнее review, труднее онбординг.

🔗
Смотрите также: Паттерны экспертов — Specs as stdlib развёрнуто. Мульти-агентность — когда агенты реально независимы. CI/CD — автоматизация loop через pipeline.

📋 Ralph Loop в деталях: пример с реальной задачей

Вот как Geoffrey применяет Ralph Loop к типичной задаче добавления нового endpoint:

markdown Ralph Loop: добавление POST /api/subscriptions/cancel
## Subtask 1: Feature test (RED) Напиши feature test для POST /api/subscriptions/cancel. Test должен быть RED — endpoint не существует. Запусти тест и покажи RED вывод. ## Subtask 2: Route + Controller Добавь route POST /api/subscriptions/cancel. Создай CancelSubscriptionController. Запусти тест — должен стать зелёным по маршруту (но падать на логике). ## Subtask 3: Service method Создай SubscriptionService::cancel(int $id): void. Логика: проверить статус, установить cancelled_at, не удалять запись. Запусти тест — должен стать полностью зелёным. ## Subtask 4: PHPStan проверка Запусти vendor/bin/phpstan analyse --no-progress. Исправь все ошибки статического анализа. Запусти тест ещё раз для верификации. ## Subtask 5: Commit git commit -m "feat(subscription): add cancel endpoint with service logic" Задача завершена.

📚 /specs — живые примеры спецификаций

Geoffrey публично делится несколькими реальными /spec файлами из своих проектов. Принцип: spec должна быть достаточно детальной чтобы разные разработчики получали предсказуемо похожий результат:

markdown specs/write-integration-test.md
# Spec: Write Integration Test ## Структура теста - Extends TestCase (не Unit — Integration) - Использует RefreshDatabase trait - Arrange: создать необходимые fixtures через factories - Act: вызвать метод или HTTP endpoint - Assert: проверить состояние БД + HTTP ответ ## Обязательные cases для любого endpoint - Happy path (корректные данные, авторизован) - Unauthorized (нет токена → 401) - Forbidden (не тот пользователь → 403) - Validation error (некорректные данные → 422 с errors) - Not Found если применимо (→ 404) ## Запрещено - Mocking Repository или Database - Внешние HTTP-вызовы (использовать Http::fake()) - Хардкодить ID — только через созданные factories ## После написания тестов Запусти тесты. Они должны быть RED. Только потом начинай реализацию.

⚙ Настройка strict типизации в PHP проекте

yaml phpstan.neon — конфигурация для CC workflow
parameters: level: 8 paths: - app - tests checkMissingIterableValueType: false reportUnmatchedIgnoredErrors: false # Эти правила делают Claude более предсказуемым checkPhpDocMethodSignatures: true checkPhpDocMissingReturn: true reportMaybes: true

💬 Цитаты Geoffrey об агентном программировании

"Non-determinism multiplies with every agent you add. One agent in a loop is a deterministic process. Three agents in parallel is a mess."
"The compiler doesn't lie. Make it your verifier, not your enemy."
"specs/ is your stdlib. Don't reinvent the wheel every time you need to add an endpoint. Codify the pattern once, reuse forever."
"Finish the loop before spawning another agent. Premature parallelism is the root of all agentic evil."

⚠ Когда мульти-агентность всё же оправдана

Geoffrey не против мульти-агентности в принципе — он против преждевременной мульти-агентности. Вот его критерии когда она оправдана:

Мульти-агентность оправдана когда
  • Задачи реально независимы — нет shared файлов, нет shared state
  • У каждого агента строго определённый ownership (агент А — только frontend, агент Б — только backend)
  • Есть чёткий merge plan — как и когда объединяются результаты
  • Один loop уже завершён и показал что задача слишком большая для одного агента
  • Есть автоматический механизм обнаружения конфликтов (CI/CD)