ХЕЛЛОУИН СЕЙЛ-10%
До 31 октября-10%
ХЕЛЛОУИН СЕЙЛ-10%
До 31 октября-10%
ХЕЛЛОУИН СЕЙЛ-10%
До 31 октября-10%
ХЕЛЛОУИН СЕЙЛ-10%
До 31 октября-10%
ХЕЛЛОУИН СЕЙЛ-10%
До 31 октября-10%
ХЕЛЛОУИН СЕЙЛ-10%
До 31 октября-10%

HumanLayer: 12 факторов агентов и человек в цикле

Чему учат 12-Factor Agents Декса Хорти, как устроено одобрение рискованных вызовов тулов, что открыл HumanLayer и что перенести в хуки и режимы разрешений Claude Code.
Guide DAO

Декс Хорти (Dex Horthy, @dexhorthy) делает HumanLayer, стартап из Y Combinator, и пишет о том, как строить AI-агентов, которым можно доверить работу. Его репозиторий 12-Factor Agents с весны 2025 года собрал почти 27 тысяч звёзд. 29 сентября Мэтт Покок назвал Хорти среди трёх лучших авторов скилов, а раздел про сводку в его скиле /pr почти дословно взят из скила show-me Хорти, это указано в CREDITS.md. Как устроены скилы Покока, мы разбирали в отдельной статье.

23 октября Хорти опубликовал пост «Open Sourcing HumanLayer»: весь код продукта теперь лежит в humanlayer/humanlayer под лицензией Apache 2.0. Пост собрал около 1700 лайков. Ниже о том, какие идеи стоят за HumanLayer, как работает одобрение человеком рискованных действий агента и что из этого можно забрать в свой Claude Code уже сегодня.

От декоратора к фабрике

Первая версия HumanLayer в 2024 году была SDK для одного сценария. Самые полезные функции агента, вроде отправки писем от имени компании или правки данных в CRM, оказываются и самыми рискованными. SDK оборачивал такую функцию декоратором @hl.require_approval(), и вызов не выполнялся, пока человек не одобрит его, например ответом в Slack. Ошибку модели это не исправляло, но гарантировало, что рискованный вызов без человека не пройдёт.

Осенью 2025 года команда удалила SDK из репозитория и переключилась на CodeLayer, IDE для параллельной работы с Claude Code. Летом 2026-го в README осталась строчка, что код почти весь устарел, а новая версия живёт на humanlayer.com. 22 октября в репозиторий выложили код этой новой версии целиком. В посте Хорти объясняет решение так: фабрики разработки на агентах (software factories) команды собирают из своих вычислений, харнесов и процессов ревью, и чёрный ящик посреди такого процесса им не нужен.

12 факторов, которые стоит знать

Исходный тезис Хорти такой: хорошие агенты в продакшене в основном состоят из обычного кода, а модель вызывается в нужных точках. По его наблюдениям, команды берут фреймворк, быстро доходят до качества 70–80%, понимают, что клиентам этого мало, и переписывают всё с нуля. Двенадцать факторов описывают, что держать в своих руках с самого начала. Для тех, кто строит агентов, на наш взгляд, важнее всего пять групп.

Первая: вызов тула это просто структурированный ответ модели (факторы 1 и 4). Модель выдаёт JSON с намерением, например create_issue с параметрами, а решает, выполнять ли его, детерминированный код. Отсюда растёт всё остальное: между «модель выбрала действие» и «действие выполнено» есть место для проверки.

Вторая: свои промпты и своё контекстное окно (факторы 2 и 3). Хорти пишет, что всё сводится к контекст-инжинирингу, и показывает формат, где вся история задачи лежит одним сообщением в виде событий с XML-тегами. В README эпохи CodeLayer команда утверждала, что именно этот репозиторий в апреле 2025 года ввёл сам термин context engineering.

Третья: состояние выполнения совпадает с бизнес-состоянием, а агента можно запустить, поставить на паузу и продолжить через простой API (факторы 5, 6 и 12). Если весь ход работы хранится как список событий, его легко сохранить, восстановить с любого места и показать человеку.

Четвёртая: обращение к человеку тоже вызов тула, а управление циклом остаётся у вас (факторы 7 и 8). Об этом следующий раздел.

Пятая: маленькие агенты (фактор 10). Хорти советует ограничивать агента 3–10 шагами, максимум 20, потому что с ростом контекста модель теряет фокус. Когда стоит делить работу между агентами, мы разбирали в статье «Один агент или субагенты».

Как работает одобрение рискованного вызова

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

Решение в факторе 8 выглядит так. Цикл получает от модели следующий шаг. Безопасный шаг, например чтение тегов git, выполняется сразу, и результат возвращается в контекст. Рискованный шаг, например деплой в продакшен, записывается в историю, история сохраняется в базу, человеку уходит запрос, и цикл завершается. Ответ приходит позже вебхуком из Slack или почты, код загружает историю по id, дописывает в неё ответ и продолжает. Наш упрощённый набросок по мотивам кода из репозитория:

while True:
    step = await determine_next_step(thread_to_prompt(thread))
    thread.events.append(step)
    if step.intent == "list_git_tags":
        thread.events.append(await list_git_tags())
        continue
    if step.intent == "deploy_backend":
        await db.save_thread(thread)
        await request_human_approval(step, thread.id)
        break  # ответ придёт вебхуком, цикл продолжится с того же места

Обращение к человеку при этом оформлено как обычный тул, например request_human_input с вопросом, срочностью и форматом ответа: да или нет, выбор из вариантов, свободный текст. Агент сам решает, когда спросить, а инфраструктура доставляет вопрос туда, где человек его увидит. В факторе 11 это названо «trigger from anywhere»: агента можно запускать и отвечать ему из Slack, почты или по крону.

В открытом HumanLayer тот же принцип применён к Claude Code. Демон запускает сессии через Agent SDK и передаёт в canUseTool функцию, которая отправляет запрос на одобрение в приложение. Плагин для сессий, запущенных вручную, ловит событие Claude Code PermissionRequest: в веб-приложении появляется карточка с кнопками Approve и Deny, и засчитывается тот ответ, который пришёл первым, из терминала или из браузера. Комментарий к отказу уходит агенту. С функцией Multiplayer Prompting одобрять вызовы могут и коллеги, которым открыли сессию.

Что выложили и как попробовать

По словам Хорти, в репозитории тот же код, на котором работает HumanLayer Cloud. Это десктопное приложение для macOS на Electron и Tauri, веб-приложение, демон, который запускает сессии Claude Code и Codex на ваших машинах и ставится вместе с CLI humanlayer, облачный API с прокси Electric для синхронизации Postgres, плагины для pi и opencode, скилы RPI (research, plan, implement) и CLI для Linear. При сборке из исходников телеметрии нет, данные уходят наружу, только если вы сами зададите ключи.

Проще всего начать с готового приложения и аккаунта HumanLayer. Первый сценарий в документации рассчитан на Mac с Apple silicon, установленный Claude Code и git. Приложение можно скачать с сайта или поставить через Homebrew:

brew trust --tap humanlayer/humanlayer
brew install --cask humanlayer/humanlayer/humanlayer
open /Applications/HumanLayer.app

После входа нажмите Create Task, выберите репозиторий на чистой тестовой ветке и вставьте описание задачи из туториала:

Create a file named humanlayer-first-task.md in the repository root.
Add a heading named First HumanLayer task.
Add one sentence that says HumanLayer ran this task.
Do not change other files.

В форме выберите воркфлоу ONESHOT, Worktree(s) NEVER и агент Claude Code. HumanLayer запустит сессию, её ход виден в интерфейсе, а в корне репозитория появится один файл. Для настоящих задач есть воркфлоу RPI и PRD-Oriented: агент сначала пишет исследование текущего кода, потом документ с дизайном, потом план из вертикальных срезов, и переходы к дизайну и плану всегда ждут человека.

Чтобы поднять всё у себя, Хорти предлагает открыть репозиторий в агенте и попросить:

walk me through getting the devstack up and running

Пока это сырой путь. Сервисы не стартуют без ключей WorkOS, Slack, Linear и других, и сделать их необязательными команда обещает в первую очередь. В docker-compose.yaml стоят простые пароли по умолчанию, README просит сменить их перед деплоем.

Если приложение не нужно, можно взять только скилы из humanlayer/skills через установщик skills.sh:

npx skills add humanlayer/skills --skill rpi

Дальше задача начинается с /rpi research how the collections connect to the database, в Codex с $rpi. Каждая фаза по умолчанию идёт в свежей сессии, а между ними остаются документы в .agents/artifacts.

Что перенести в свой Claude Code

Остановку между выбором тула и вызовом, на которой держится HumanLayer, Claude Code уже умеет. Первое: правила ask в настройках. Они проверяются после deny и до allow, и вызов под таким правилом Claude Code не одобряет сам ни в одном режиме, даже в bypassPermissions. Наш пример для .claude/settings.json:

{
  "permissions": {
    "ask": ["Bash(git push *)", "Bash(npm publish *)"],
    "deny": ["Read(./.env)"]
  }
}

Второе: хук PreToolUse. Он может вернуть "ask" с причиной, которую вы увидите в запросе, и такой ответ заставляет спросить человека даже в режиме auto. Для своих интерфейсов есть "defer": в запуске claude -p сессия останавливается с stop_reason: "tool_deferred", вызов ждёт в транскрипте, а ваш код продолжает его через claude -p --resume. Это ровно пауза из факторов 6 и 8, но работает она, только когда агент сделал один вызов за ход. Как писать такие хуки, мы разбирали в статье о хуках.

Третье: хук PermissionRequest срабатывает в момент, когда Claude Code собирается спросить разрешения. На нём удобно отправлять уведомление в Slack или в телефон, как в факторе 11. Уведомление типа permission_prompt приходит только после примерно шести секунд ожидания.

Четвёртое: если вы пишете своё приложение на Agent SDK, вопросы о разрешении приходят в колбэк canUseTool, как у демона HumanLayer:

import type { CanUseTool } from "@anthropic-ai/claude-agent-sdk";

const handleToolRequest: CanUseTool = async (toolName, input, options) => {
  // показать запрос человеку и вернуть его ответ
  return { behavior: "deny", message: "User declined" };
};

Колбэк не вызывается для того, что уже разрешено правилом или режимом вроде acceptEdits, поэтому для проверки каждого вызова документация советует хук PreToolUse.

Пятое: режим разрешений под задачу. Для CI подходит dontAsk со списком разрешённых тулов, всё остальное отклоняется без вопросов. bypassPermissions документация оставляет только для изолированных контейнеров и виртуальных машин.

Ещё одна мысль Хорти касается того, где ставить человека. В тексте Advanced Context Engineering for Coding Agents он пишет, что плохая строка в плане может дать сотни плохих строк кода, а ошибка в исследовании тысячи. Поэтому ревью исследования и плана даёт больше, чем ревью кода, а контекст он советует держать заполненным на 40–60%. Как Claude Code расходует контекст, мы рассказывали в статье о контексте и памяти.

Ограничения

12-Factor Agents обновлялся последний раз в сентябре 2025 года, а фактор 12 так и остался заготовкой. Примеры в нём псевдокод на Python и BAML, готовой библиотеки нет: SDK с require_approval удалён, и повторять паттерн придётся в своём коде. Сам HumanLayer командный продукт: без облачного аккаунта остаются скилы и запуск у себя, а он пока требует чужих ключей. README плагина для Claude Code ссылается на маркетплейс humanlayer/humanlayer-claude, но 24 октября этот репозиторий на GitHub не открывался.

Каждое одобрение тормозит агента. Хорти сам пишет, что работу с агентами стоит замедлить и делать меньше параллельно. На наш взгляд, разумный минимум такой: правило ask на необратимые команды, уведомление на PermissionRequest и ревью плана до кода. Полный HumanLayer имеет смысл, когда агентов запускает команда и решения нужно собирать в одном месте.

Поделиться
Интересно погрузиться в крипту?
Поможем выбрать направление!