HardТеория11 min

Масштабирование и безопасность автономных агентов

Overnight scheduling, multi-agent координация и системы безопасности

Overnight Scheduling: агенты работают пока вы спите

Обещание и реальность

Идея проста и заманчива: вечером вы назначаете задачи, утром просыпаетесь -- фича готова. AI-агент работает 8 часов без перерыва, без отвлечений, без зарплаты за переработки.

21:00  Инженер: "Вот спецификация, вот fix plan, вот тесты. Работай."
       → Запуск Ralph Loop

21:01  Агент: Итерация 1 — Create User entity ✓
21:04  Агент: Итерация 2 — Create UserRepository ✓
21:07  Агент: Итерация 3 — Create UserService ✓
...
04:30  Агент: Итерация 47 — Final integration test ✓
04:31  Агент: "All 47 tasks complete. 0 remaining."

07:00  Инженер просыпается → git log → 47 коммитов → все тесты зелёные

Реальность: это работает, но только при выполнении жёстких предусловий. Без них ваша "ночная смена" превратится в утреннюю археологию.

Предусловия для overnight runs

Предусловие Почему критично Что будет без него
Комплексный тестовый набор Агент не может спросить человека в 3 AM Код "работает" только визуально, баги скрыты
Однозначная спецификация Нет возможности уточнить Агент интерпретирует по-своему
Git branch isolation Ошибки не должны попасть в main Утром main сломан
Лимиты ресурсов Prevent runaway API costs Утром счёт на $500
Детальный fix plan Агент должен знать порядок Агент делает задачи в случайном порядке

Железное правило: Если вы не можете написать тесты для задачи -- вы не можете запустить её на ночь. Без тестов агент -- это генератор случайного кода.

Настройка overnight run

#!/bin/bash
# overnight-run.sh — Safe overnight Ralph Loop execution
set -euo pipefail

# === Configuration ===
MAX_COST=50          # Maximum API cost in dollars
MAX_TIME=28800       # Maximum runtime: 8 hours (in seconds)
MAX_ITERATIONS=200   # Maximum loop iterations
BRANCH="overnight/$(date +%Y%m%d)"
LOG_FILE="overnight-$(date +%Y%m%d).log"
NOTIFY_CHANNEL="telegram"  # or: slack, email, none

# === Pre-flight ===
echo "$(date): Starting overnight run" | tee "$LOG_FILE"

# Verify tests pass BEFORE starting
echo "Running pre-flight tests..." | tee -a "$LOG_FILE"
npm test >> "$LOG_FILE" 2>&1 || {
  echo "PRE-FLIGHT FAILED: Tests not passing. Aborting overnight run." | tee -a "$LOG_FILE"
  exit 1
}

# Verify fix plan has tasks
TASKS=$(grep -c "\- \[ \]" fix_plan.md 2>/dev/null || echo "0")
if [ "$TASKS" -eq 0 ]; then
  echo "No tasks in fix_plan.md. Nothing to do." | tee -a "$LOG_FILE"
  exit 0
fi
echo "Found $TASKS tasks to complete" | tee -a "$LOG_FILE"

# === Main Loop ===
ITERATION=0
START_TIME=$(date +%s)

while [ $ITERATION -lt $MAX_ITERATIONS ]; do
  ITERATION=$((ITERATION + 1))
  CURRENT_TIME=$(date +%s)
  ELAPSED=$((CURRENT_TIME - START_TIME))

  # Time limit check
  if [ $ELAPSED -gt $MAX_TIME ]; then
    echo "$(date): Time limit reached ($MAX_TIME seconds)" | tee -a "$LOG_FILE"
    break
  fi

  # Check remaining tasks
  REMAINING=$(grep -c "\- \[ \]" fix_plan.md 2>/dev/null || echo "0")
  if [ "$REMAINING" -eq 0 ]; then
    echo "$(date): All tasks complete!" | tee -a "$LOG_FILE"
    break
  fi

  echo "$(date): Iteration $ITERATION | Remaining: $REMAINING | Elapsed: ${ELAPSED}s" | tee -a "$LOG_FILE"

  # Run agent
  cat PROMPT.md | claude --print >> "$LOG_FILE" 2>&1

  # Minimal pause
  sleep 2
done

# === Post-flight ===
echo "" | tee -a "$LOG_FILE"
echo "=== OVERNIGHT RUN COMPLETE ===" | tee -a "$LOG_FILE"
echo "Iterations: $ITERATION" | tee -a "$LOG_FILE"
echo "Duration: $((ELAPSED / 60)) minutes" | tee -a "$LOG_FILE"
echo "Completed: $(grep -c '\[x\]' fix_plan.md 2>/dev/null || echo 0)" | tee -a "$LOG_FILE"
echo "Remaining: $(grep -c '\[ \]' fix_plan.md 2>/dev/null || echo 0)" | tee -a "$LOG_FILE"

# Run full test suite
echo "Running post-flight tests..." | tee -a "$LOG_FILE"
npm test >> "$LOG_FILE" 2>&1 && echo "ALL TESTS PASS" | tee -a "$LOG_FILE" || echo "SOME TESTS FAILING" | tee -a "$LOG_FILE"

# === Notification ===
SUMMARY="Overnight run: $ITERATION iterations, $(grep -c '\[x\]' fix_plan.md 2>/dev/null || echo 0) tasks done, $(grep -c '\[ \]' fix_plan.md 2>/dev/null || echo 0) remaining"

case $NOTIFY_CHANNEL in
  telegram)
    curl -s "https://api.telegram.org/bot${BOT_TOKEN}/sendMessage" \
      -d "chat_id=${CHAT_ID}" \
      -d "text=${SUMMARY}" >/dev/null 2>&1 || true
    ;;
  slack)
    curl -s -X POST "$SLACK_WEBHOOK" \
      -H 'Content-type: application/json' \
      -d "{\"text\": \"$SUMMARY\"}" >/dev/null 2>&1 || true
    ;;
  none)
    # macOS notification as fallback
    osascript -e "display notification \"$SUMMARY\" with title \"Overnight Run\"" 2>/dev/null || true
    ;;
esac

echo "$(date): Overnight run finished" | tee -a "$LOG_FILE"

Утренний workflow ревью

Утром вы не просто "принимаете работу". Вы проводите систематическую проверку:

# Morning Review Checklist

## Step 1: Read the log (5 min)
- How many iterations?
- Any repeated failures?
- Any tasks marked as BLOCKED?
- Total estimated cost?

## Step 2: Check git log (5 min)
```bash
git log --oneline overnight/YYYYMMDD
# Look for:
# - Consistent commit messages
# - Reasonable commit size
# - No "fix fix fix" patterns

Step 3: Run full test suite (2 min)

npm test
# Must be 100% green. If not — do NOT merge.

Step 4: Review the diff (15-30 min)

git diff main..overnight/YYYYMMDD
# Look for:
# - Correct architecture (right layers, right patterns)
# - No hardcoded values
# - No security issues
# - No TODO/FIXME/HACK
# - Consistent style

Step 5: Decision

  • All tests pass AND code quality acceptable → Merge
  • Tests pass but code needs fixes → Fix manually, then merge
  • Tests failing → Do NOT merge, investigate
  • Architecture wrong → Delete branch, redo with better spec

> **Правило:** Никогда не мержите overnight-ветку без ревью. Даже если все тесты зелёные -- проверьте код глазами. AI может генерировать "работающий, но плохой" код.

---

## Multi-Agent координация

### Когда использовать несколько агентов

Один агент (90% случаев): ✓ Последовательная реализация ✓ Простая координация ✓ Предсказуемый результат ✓ Минимальный расход API

Несколько агентов (10% случаев): ✓ Большие фичи с независимыми компонентами ✓ Разная экспертиза (backend + frontend) ✓ Параллельное тестирование и реализация ✗ Сложная координация ✗ Потенциальные конфликты ✗ Расход API x N


### Стратегия: Shared Fix Plan

Все агенты читают и пишут в один fix_plan.md. Требуется механизм блокировки.

```markdown
# fix_plan.md with agent assignment

## Backend Agent
- [x] [backend] Create Order entity
- [x] [backend] Create OrderRepository
- [ ] [backend] Create OrderService
- [ ] [backend] Create OrderController

## Frontend Agent
- [x] [frontend] Create OrderForm component
- [x] [frontend] Create OrderList component
- [ ] [frontend] Create OrderDetail page
- [ ] [frontend] Add API integration

## Test Agent
- [x] [test] Write OrderService unit tests
- [ ] [test] Write OrderController integration tests
- [ ] [test] Write E2E order creation test

Проблема: два агента могут одновременно решить обновить fix_plan.md. Решение -- файловая блокировка или разделение на отдельные файлы:

fix_plans/
├── backend.md     # Only backend agent reads/writes
├── frontend.md    # Only frontend agent reads/writes
└── testing.md     # Only test agent reads/writes

Стратегия: File-Level Locking

Предотвращение модификации одного файла двумя агентами:

# In each agent's PROMPT.md:

## File Ownership
You may ONLY modify files in these directories:
- src/Service/
- src/Repository/
- src/Entity/

You may NOT modify:
- src/Controller/ (owned by API agent)
- resources/views/ (owned by frontend agent)
- tests/ (owned by test agent)

Стратегия: Communication via Files

Агенты общаются через файлы в специальной директории:

.agents/
├── backend-status.md    # Backend agent writes status here
├── frontend-status.md   # Frontend agent writes status here
├── requests.md          # Agents request things from each other
└── interfaces.md        # Shared interface definitions
# .agents/requests.md

## Request from Frontend Agent (2026-03-07 22:30)
Need: OrderResponse DTO with fields: id, status, items[], total, createdAt
For: Frontend OrderDetail component
Priority: Blocking

## Response from Backend Agent (2026-03-07 22:35)
Done: OrderResponse DTO created at src/DTO/OrderResponse.php
Fields: id (UUID), status (string), items (array), totalAmount (int), createdAt (DateTime)
Note: totalAmount is in cents, frontend should divide by 100 for display

Предупреждение

Мнение практиков: Большинство команд, использующих мульти-агентный подход, переоценивают выигрыш от параллелизации и недооценивают стоимость координации. Один хорошо настроенный агент с детальной спецификацией часто быстрее, чем три плохо координированных.


Системы безопасности -- CRITICAL

Безопасность автономных агентов -- это не "best practice", а необходимость. Агент без ограничений -- это root-доступ для вероятностной модели.

Resource Limits (Ограничение ресурсов)

# safety-config.yml

resource_limits:
  # Cost control
  max_api_cost_per_session: 50       # dollars
  max_api_cost_per_iteration: 2      # dollars
  cost_alert_threshold: 25           # alert at 50%

  # Time control
  max_session_duration: 28800        # 8 hours in seconds
  max_iteration_duration: 600        # 10 minutes per iteration
  timeout_action: "stop"             # stop | pause | alert

  # Scope control
  max_iterations: 200                # hard limit
  max_files_modified: 50             # alert if exceeded
  max_lines_changed_per_file: 500    # alert if exceeded
  max_new_files: 30                  # alert if exceeded

Operation Restrictions (Ограничение операций)

Это самый критичный раздел. Автономный агент категорически не должен выполнять определённые операции:

# ABSOLUTE RESTRICTIONS — NEVER ALLOWED

## Git Operations
- NO git push (human reviews and pushes)
- NO git push --force (NEVER, under any circumstances)
- NO git merge to main/master
- NO git rebase of shared branches
- NO git tag (releases are human decision)

## Deployment
- NO deploy to any environment
- NO docker push to registry
- NO kubectl apply to cluster
- NO ssh to production servers
- NO ansible/terraform on production

## Database
- NO migrations on production databases
- NO data deletion on any environment
- NO schema changes on shared databases

## External Services
- NO calls to production APIs
- NO sending emails to real users
- NO payment processing
- NO modifying DNS/CDN configuration

## Secrets
- NO hardcoded API keys, tokens, passwords
- NO committing .env files
- NO logging sensitive data

Реализация ограничений в скрипте:

#!/bin/bash
# safety-wrapper.sh — Wraps claude commands with safety checks

# Override dangerous commands
git() {
  case "$1" in
    push|merge|rebase|tag)
      echo "BLOCKED: 'git $1' is not allowed in autonomous mode"
      echo "$(date): BLOCKED git $1" >> safety.log
      return 1
      ;;
    *)
      command git "$@"
      ;;
  esac
}

# Override deployment commands
docker() {
  case "$1" in
    push)
      echo "BLOCKED: 'docker push' is not allowed"
      return 1
      ;;
    *)
      command docker "$@"
      ;;
  esac
}

# Override SSH
ssh() {
  echo "BLOCKED: SSH is not allowed in autonomous mode"
  return 1
}

export -f git docker ssh

Monitoring and Alerting (Мониторинг и оповещения)

#!/bin/bash
# monitor.sh — Monitor running Ralph Loop

LOG_FILE="ralph.log"
ALERT_THRESHOLD_FAILURES=3
ALERT_THRESHOLD_SAME_ERROR=3

# Watch for repeated failures
CONSECUTIVE_FAILURES=0
LAST_ERROR=""

tail -f "$LOG_FILE" | while read -r line; do
  # Detect test failure
  if echo "$line" | grep -qi "FAIL\|ERROR\|Exception"; then
    CONSECUTIVE_FAILURES=$((CONSECUTIVE_FAILURES + 1))

    # Check for same error repeating
    CURRENT_ERROR=$(echo "$line" | head -c 100)
    if [ "$CURRENT_ERROR" = "$LAST_ERROR" ]; then
      SAME_ERROR_COUNT=$((SAME_ERROR_COUNT + 1))
    else
      SAME_ERROR_COUNT=1
      LAST_ERROR="$CURRENT_ERROR"
    fi

    # Alert on repeated failures
    if [ $CONSECUTIVE_FAILURES -ge $ALERT_THRESHOLD_FAILURES ]; then
      osascript -e "display notification \"$CONSECUTIVE_FAILURES consecutive failures detected\" with title \"Ralph Loop Alert\" sound name \"Basso\"" 2>/dev/null
    fi

    # Alert on same error repeating
    if [ $SAME_ERROR_COUNT -ge $ALERT_THRESHOLD_SAME_ERROR ]; then
      osascript -e "display notification \"Same error $SAME_ERROR_COUNT times. Agent may be stuck.\" with title \"Ralph Loop STUCK\" sound name \"Sosumi\"" 2>/dev/null
    fi
  else
    CONSECUTIVE_FAILURES=0
  fi

  # Detect unexpected file modifications
  if echo "$line" | grep -qi "modified.*\.env\|modified.*config/secrets"; then
    osascript -e "display notification \"Sensitive file modified!\" with title \"SECURITY ALERT\" sound name \"Funk\"" 2>/dev/null
  fi
done

Alerted conditions (Условия для оповещений)

Условие Уровень Действие
3+ последовательных провала Warning Уведомление + пауза
Одна и та же ошибка 3+ раз Critical Уведомление + остановка
Модификация .env / secrets Critical Немедленная остановка
Превышение лимита стоимости Critical Остановка
Превышение лимита времени Warning Остановка
Более 50 файлов изменено Warning Уведомление
git push / deploy попытка Critical Блокировка + уведомление

Rollback Strategy (Стратегия отката)

Каждый агент работает на изолированной ветке. Откат -- тривиальная операция:

# If overnight run produced bad results:

# Option 1: Delete entire branch (nuclear option)
# git checkout main
# git branch -D overnight/20260307

# Option 2: Cherry-pick good commits
# git checkout main
# git cherry-pick <good-commit-hash-1> <good-commit-hash-2>

# Option 3: Reset to last known good state
# git checkout overnight/20260307
# git reset --hard <last-good-commit>
Стратегия безопасности — уровни защиты:

  Level 1: Isolated branch        ← Ошибки не попадают в main
  Level 2: Operation restrictions ← Нет push/deploy/production
  Level 3: Resource limits        ← Ограничение по стоимости и времени
  Level 4: Monitoring + alerts    ← Обнаружение проблем в реальном времени
  Level 5: Human review           ← Финальное решение всегда за человеком

Принцип максимального ущерба: Спроектируйте систему так, чтобы при ХУДШЕМ возможном сценарии максимальный ущерб был: "потеряна одна ветка git + $50 на API". Не больше.


231 пример от Паполини

Книга Паполини содержит 231 полностью рабочий пример. Наиболее практически ценные:

Пример: Safe Loop с трекингом затрат

#!/bin/bash
# From Papalini's patterns — adapted

COST_FILE=".cost_tracker"
echo "0" > "$COST_FILE"

estimate_cost() {
  # Rough estimation: each iteration ~$0.30-0.80
  local iterations=$1
  echo "scale=2; $iterations * 0.50" | bc
}

check_budget() {
  local current=$(cat "$COST_FILE")
  local limit=$1
  if (( $(echo "$current > $limit" | bc -l) )); then
    echo "BUDGET EXCEEDED: \$$current > \$$limit"
    return 1
  fi
  return 0
}

# Main loop with cost tracking
ITERATION=0
MAX_COST=25

while grep -q "\- \[ \]" fix_plan.md; do
  ITERATION=$((ITERATION + 1))

  # Update cost estimate
  ESTIMATED=$(estimate_cost $ITERATION)
  echo "$ESTIMATED" > "$COST_FILE"

  # Check budget
  check_budget $MAX_COST || {
    echo "Stopping: budget limit reached"
    break
  }

  echo "Iteration $ITERATION | Est. cost: \$$ESTIMATED / \$$MAX_COST"

  # Run agent
  cat PROMPT.md | claude --print

  sleep 2
done

Пример: Автоматический откат при неудаче

#!/bin/bash
# Automatic rollback pattern

run_with_rollback() {
  local save_point=$(git rev-parse HEAD)
  local task="$1"
  local max_attempts=3
  local attempt=0

  while [ $attempt -lt $max_attempts ]; do
    attempt=$((attempt + 1))
    echo "Task: $task | Attempt: $attempt"

    # Run agent for this specific task
    echo "Implement this task: $task" | claude --print

    # Verify
    if npm test 2>/dev/null; then
      echo "Task succeeded on attempt $attempt"
      return 0
    fi

    # Rollback to save point
    echo "Rolling back to $save_point"
    git checkout -- .
    git clean -fd
  done

  echo "Task FAILED after $max_attempts attempts: $task"
  return 1
}

# Process each task with rollback safety
while IFS= read -r task; do
  run_with_rollback "$task" || {
    echo "BLOCKED: $task" >> blocked_tasks.md
  }
done < <(grep "\- \[ \]" fix_plan.md | sed 's/- \[ \] //')

Пример: Memory-enhanced Compound Learning Loop

#!/bin/bash
# Compound learning loop — agent improves over iterations

LEARNING_FILE="learned_patterns.md"
touch "$LEARNING_FILE"

ITERATION=0

while grep -q "\- \[ \]" fix_plan.md; do
  ITERATION=$((ITERATION + 1))

  # Build prompt with accumulated learning
  cat <<EOF | claude --print
Read @AGENT.md for project conventions.
Read @spec.md for feature specification.
Read @fix_plan.md for current tasks.
Read @${LEARNING_FILE} for patterns learned in previous iterations.

## Instructions
1. Pick the first unchecked task
2. Check learned_patterns.md for relevant patterns
3. Implement the task
4. Run tests
5. If successful:
   - Mark task done
   - If you discovered a new pattern, append it to ${LEARNING_FILE}:
     ## Pattern: [name]
     **Context**: [when to use]
     **Implementation**: [how to implement]
     **Discovered**: Iteration $ITERATION
6. If failed:
   - Analyze the error
   - Record what you learned in ${LEARNING_FILE}:
     ## Anti-pattern: [name]
     **Mistake**: [what went wrong]
     **Correct approach**: [how to fix]
     **Discovered**: Iteration $ITERATION
EOF

  sleep 2
done

echo "Learning complete. Patterns discovered:"
grep -c "## Pattern:" "$LEARNING_FILE" 2>/dev/null || echo "0"
echo "Anti-patterns recorded:"
grep -c "## Anti-pattern:" "$LEARNING_FILE" 2>/dev/null || echo "0"

Когда НЕ использовать автономных агентов

Категорически не рекомендуется

Ситуация Почему не подходит Что делать вместо
Legacy без тестов Нет верификации, агент сломает что угодно Сначала написать тесты вручную
Security-critical код Аутентификация, криптография, платежи Писать вручную, AI максимум как ассистент
Performance hot paths Агент не профилирует, не оптимизирует Профилировать вручную, AI для черновика
Плохая спецификация "Сделай что-то крутое" -- не spec Сначала написать нормальную спецификацию
Изучение домена Вам нужно понять бизнес, а не написать код Изучить домен, затем автоматизировать

Пограничные случаи

Существующая кодовая база с тестами:
  → Можно, но с осторожностью
  → Обязательно: Selective Context + reference files
  → Риск: агент может не уловить неявные конвенции

Фронтенд (UI/UX):
  → Ограниченно
  → Генерация компонентов — да
  → Визуальный дизайн — нет (агент не "видит" результат)
  → Accessibility — частично (может проверять ARIA-атрибуты)

Рефакторинг:
  → Хорошо подходит для механических рефакторингов
  → Плохо для архитектурных рефакторингов
  → Обязательно: полный тестовый набор до начала

Матрица применимости

                      Тесты есть    Тесты нет
                    ┌─────────────┬─────────────┐
Greenfield          │  ИДЕАЛЬНО   │  ВОЗМОЖНО*  │
                    │  95% успех  │  60% успех  │
                    ├─────────────┼─────────────┤
Existing codebase   │  ХОРОШО     │  ОПАСНО     │
                    │  75% успех  │  20% успех  │
                    ├─────────────┼─────────────┤
Legacy              │  ОСТОРОЖНО  │  НЕ НАДО    │
                    │  50% успех  │  ~0% успех  │
                    └─────────────┴─────────────┘

* Если пишете тесты параллельно с реализацией

Чеклист безопасности для production

Перед запуском автономного агента в любом режиме:

# Safety Checklist

## Environment Isolation
- [ ] Agent works on isolated git branch (not main/master)
- [ ] Agent has NO access to production environment
- [ ] Agent has NO access to production database
- [ ] Agent has NO access to production APIs
- [ ] Agent has NO SSH keys for production servers

## Operation Restrictions
- [ ] git push is blocked or not configured
- [ ] deploy commands are blocked
- [ ] External API calls are mocked or blocked
- [ ] Email sending is disabled or mocked
- [ ] Payment processing is disabled

## Resource Limits
- [ ] Maximum API cost per session is set
- [ ] Maximum runtime is set
- [ ] Maximum iterations is set
- [ ] Cost tracking is enabled

## Monitoring
- [ ] Log file is configured
- [ ] Failure alerts are configured
- [ ] Cost alerts are configured
- [ ] Security alerts are configured (sensitive file modification)

## Rollback Plan
- [ ] I know how to delete the agent's branch
- [ ] I know how to cherry-pick good commits
- [ ] I have a backup of the current main state
- [ ] Maximum possible damage is: lost branch + $X API cost

## Human Review
- [ ] I will review ALL changes before merging
- [ ] I will run full test suite before merging
- [ ] I will NOT merge without visual code review
- [ ] I understand this is MY responsibility, not the agent's

Выводы

  1. Overnight scheduling работает при наличии тестов, спецификации и ограничений. Без них -- это рулетка.

  2. Multi-agent = последнее средство. Один хороший агент > три плохо координированных. Используйте мульти-агент только для по-настоящему независимых задач.

  3. Безопасность -- это 5 уровней: изолированная ветка, ограничение операций, лимиты ресурсов, мониторинг, человеческое ревью. Все пять обязательны.

  4. Принцип максимального ущерба: при самом плохом сценарии потери = одна git-ветка + стоимость API. Не больше. Если потенциальный ущерб больше -- система небезопасна.

  5. Автономность != бесконтрольность. Агент работает автономно, но человек всегда имеет финальное слово. Merge, push, deploy -- это решения человека.

  6. Не автоматизируйте то, что не понимаете. Если вы не можете написать спецификацию для задачи -- вы не готовы отдать её агенту. Сначала поймите, потом автоматизируйте.