О себе Портфолио Кейсы Услуги Блог Контакт 🎙 Поговорить с AI
EN DE RU
🎙 Поговорить с AI
November 11, 2026 · 5 min read

Ваш AI-агент зависает без человека? Фоновые автолупы доводят задачи до конца и зовут вас только на спорных шагах

Я — Denis Shokhirev, Agentic AI Systems Architect из Freiburg im Breisgau, Germany, и в DennisCraft AI Studio я собираю production-grade AI-системы на Claude, Supabase, n8n, Doppler и self-hosted Postgres. Самая частая поломка, которую я вижу не в демо, а в живом контуре, проста: агент делает 80% работы, доходит до неоднозначного шага, останавливается и ждет человека часами, хотя 15 предыдущих шагов он мог спокойно дожать сам в фоне. Проблема не в том, что модели "недостаточно умные". Проблема

Denis Shokhirev
Denis Shokhirev
Agentic AI Systems Architect
Telegram LinkedIn

Я — Denis Shokhirev, Agentic AI Systems Architect из Freiburg im Breisgau, Germany, и в DennisCraft AI Studio я собираю production-grade AI-системы на Claude, Supabase, n8n, Doppler и self-hosted Postgres. Самая частая поломка, которую я вижу не в демо, а в живом контуре, проста: агент делает 80% работы, доходит до неоднозначного шага, останавливается и ждет человека часами, хотя 15 предыдущих шагов он мог спокойно дожать сам в фоне.

Проблема не в том, что модели "недостаточно умные". Проблема в архитектуре управления задачей. Если у вас один синхронный вызов модели и один блок "approve / reject", вы строите чат-бота с дорогой обвязкой, а не автономную систему. В production я почти всегда заменяю такой паттерн на фоновые autoloops: агент берет задачу, сам проходит повторяемые этапы, пишет состояние в Postgres, ставит таймеры, валидирует промежуточные артефакты и зовет человека только там, где реально есть спорное решение, доступ к чувствительным данным или риск для бизнеса.

Почему агент зависает и почему человек оказывается в каждом цикле

Типичный сценарий выглядит так: агент получил задачу, сходил в API, собрал данные, подготовил SQL, сформировал письмо клиенту, а затем уперся в неполный контекст. Вместо того чтобы запросить недостающий факт, перейти к следующему безопасному шагу или поставить задачу в retry, система блокируется на "manual review". После этого SLA уже зависит не от архитектуры, а от того, кто и когда увидит уведомление в Slack.

Что именно ломается

СимптомПричинаЧто делать
Задача висит после 1 ошибки APIНет retry и backoffВынести шаги в loop с ограничением попыток
Человек подтверждает очевидные шагиНет классификации рискаРазделить safe / review / blocked действия
Потеря контекста после рестартаСостояние хранится в памяти процессаХранить state machine в Postgres или Supabase
Нельзя понять, почему агент всталНет event logПисать transition и reason_code на каждом шаге

На практике агенту не нужен человек "на всякий случай". Ему нужен человек на ограниченном наборе развилок. Например: подтвердить платеж, одобрить изменение договора, выбрать между 2 правдоподобными интерпретациями клиентского запроса, дать доступ к таблице с персональными данными. Все остальное должно идти через цикл планирования, выполнения, проверки и повторной попытки.

Как я строю фоновые autoloops в production

Autoloop — это не магия и не отдельный продукт. Это pattern: задача живет как запись в БД, воркер периодически подбирает активные задачи, выполняет 1 шаг, фиксирует новый статус и либо продолжает, либо эскалирует человеку. Такой подход проще тестировать, проще объяснять аудитору и проще восстанавливать после сбоя.

Минимальная state machine

Я обычно начинаю с 6 состояний: queued, running, waiting_external, waiting_human, done, failed. Поверх них добавляю поля risk_level, attempt_count, next_run_at, reason_code. Этого хватает, чтобы агент не жил "внутри prompt", а был наблюдаемой системой.

import os, time, psycopg
from anthropic import Anthropic

client = Anthropic(api_key=os.environ["ANTHROPIC_API_KEY"])
conn = psycopg.connect(os.environ["DATABASE_URL"])

with conn.cursor() as cur:
    cur.execute("""
        select id, payload, attempt_count
        from agent_tasks
        where status in ('queued','running')
          and next_run_at <= now()
        order by created_at
        limit 10
        for update skip locked
    """)
    tasks = cur.fetchall()

for task_id, payload, attempts in tasks:
    msg = client.messages.create(
        model="claude-sonnet-4-5",
        max_tokens=400,
        messages=[{"role": "user", "content": payload}]
    )
    outcome = msg.content[0].text
    next_status = "waiting_human" if "NEEDS_APPROVAL" in outcome else "done"
    with conn.cursor() as cur:
        cur.execute(
            "update agent_tasks set status=%s, result=%s, attempt_count=%s where id=%s",
            (next_status, outcome, attempts + 1, task_id)
        )
    conn.commit()

Этот пример короткий, но идея в нем правильная: модель не завершает "всю работу мира", а двигает задачу на 1 контролируемый шаг. Если нужен еще шаг, его берет следующий проход loop. Если решение спорное, задача уходит в waiting_human.

Где ставить границы: что агент делает сам, а что эскалирует

Без этого autoloop превращается либо в дорогой ручной процесс, либо в неконтролируемый автомат. Я использую матрицу по риску и обратимости действия.

Тип действияАвтономноС человеком
Сбор данных из внутренних APIДаТолько при ошибке доступа
Классификация входящих заявокДа, с логированиемПри низкой уверенности
Черновик письма клиентуДаЕсли есть юридические формулировки
Изменение записей в PostgresДа, через allowlist SQLПри массовом обновлении
Платеж, контракт, удаление данныхНетВсегда

Если работаете в regulated market, не передавайте модели право на необратимое действие без явного policy gate. Для SQL это может быть allowlist таблиц и запрет на drop, truncate, массовые update без фильтра. Для сообщений клиентам — обязательный human review при определенных тегах.

#!/usr/bin/env bash
set -euo pipefail

bandit -r app/ -f json -o bandit.json
gitleaks detect --source . --report-format json --report-path gitleaks.json
semgrep --config p/owasp-top-ten --json --output semgrep.json

if jq -e '.results | length > 0' semgrep.json >/dev/null; then
  echo "Semgrep found issues"
  exit 1
fi

echo "Static checks passed"

Я часто ставлю такие проверки не только в CI, но и как gate перед тем, как агент применяет сгенерированный код или SQL. Это особенно полезно там, где агент пишет вспомогательные скрипты, миграции или integration glue.

Наблюдаемость важнее красивого prompt

Когда команда говорит "агент иногда тормозит", почти всегда оказывается, что никто не может ответить на 3 вопроса: на каком шаге он остановился, почему он остановился, и сколько раз до этого он уже пытался. Хороший autoloop отвечает на это без чтения логов контейнера.

Что логировать обязательно

  • task_id, step_name, status_before, status_after
  • reason_code для каждого перехода
  • attempt_count и next_run_at
  • какие tools были вызваны и с какими правами
  • кто одобрил human escalation и за сколько минут

Для команд, которые работают с европейскими клиентами, это еще и вопрос аудита. OWASP в LLM Top 10 2025 отдельно указывает на risks around excessive agency, prompt injection и insecure output handling: https://genai.owasp.org/. Если ваш агент может вызвать tool, изменить запись и отправить письмо, но вы не видите цепочку решений, у вас не AI-система, а черный ящик с привилегиями.

Практический контур на n8n, Supabase и Postgres

Если нужен быстрый и понятный контур, я обычно делаю так: входящая задача падает в Supabase/Postgres, n8n ставит событие и wake-up, Python-воркер вызывает модель через Anthropic SDK, затем пишет результат обратно в БД. Для секретов — Doppler. Для публично наблюдаемых контуров — отдельный read-only слой и вычищенные event payloads.

name: agent-loop
on:
  schedule:
    - cron: "*/2 * * * *"
jobs:
  run-loop:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - uses: actions/setup-python@v5
        with:
          python-version: "3.12"
      - run: pip install anthropic psycopg[binary]
      - run: python workers/run_loop.py
        env:
          ANTHROPIC_API_KEY: ${{ secrets.ANTHROPIC_API_KEY }}
          DATABASE_URL: ${{ secrets.DATABASE_URL }}

Это не единственный способ, но он дает важное свойство: задача переживает рестарт, очередь не теряется, а человек видит реальное состояние. Именно поэтому такие системы доживают до production, а не заканчиваются на красивом скриншоте в Notion.

FAQ

Когда вообще нужен autoloop, а не обычный чат?

Когда задача длится дольше 1 запроса, зависит от внешних API, требует retry или промежуточных проверок. Если у вас есть статусы и побочные эффекты, вам почти всегда нужен loop.

Можно ли сделать это только на n8n?

Для простых процессов — да. Но как только появляются ветвления, retries, policy gates и аудит, я советую хранить состояние в Postgres, а n8n использовать как orchestration layer, а не как единственный source of truth.

Нужен ли human-in-the-loop всегда?

Нет. Нужен human-on-uncertainty или human-on-risk. Человек должен приходить туда, где цена ошибки выше цены задержки.

Какой самый частый анти-паттерн?

Хранить весь state в prompt или в памяти одного процесса. После рестарта вы теряете трассировку и не можете безопасно продолжить задачу.

Как измерять, что autoloop реально помог?

Смотрите на 4 метрики: median time to completion, доля задач без участия человека, время до эскалации и доля повторных попыток, завершившихся успешно. Если метрик нет, вы спорите мнениями, а не управляете системой.

В каком месте вашего LLM-контура задачи чаще всего зависают в production: на tool calls, на retries внешних API, на policy gate или на человеческом согласовании? Мне правда интересно сравнить это с тем, что я вижу у DACH B2B команд. I run a free 30-min stack audit for DACH founders building AI in regulated markets. DM me on LinkedIn or write to @ger_dennis_ai.

Для вашего бизнеса

Такие агенты я делаю для бизнеса в Германии и ЕС.

Опишите в двух предложениях, что отнимает у команды время, — отвечу в течение суток.

Разработка ИИ-агентов (страница на немецком) →
Читать дальше
AI-агент ломает репозиторий и выдумывает факты? Как дать Claude Code память, доступ к данным и безопасные рефлексы
Почему один агент уже не справляется: как оркестрировать Claude Code, Codex и Kiro без хаоса в tmux
Claude Code в проде может утечь в Slack, WordPress и .env: 10 базовых guardrails, которые нужно включить до первого запуска
AI-агент без доступа к вебу упирается в потолок: зачем командам нужен один MCP-шлюз вместо 20 хрупких интеграций
Все статьи →
Где это применяется
Услуги — что мы делаем
Поговорить с голосовым агентом
Кейсы
Готовы к следующему шагу?

Превратить процесс в систему, которая работает

Продакшн-качество, а не демо.

Обсудить проект → ← Все статьи