Tutorial
On this page Пошаговое описание четырёх сценариев использования, для которых была спроектирована система Kanban Hermes, с открытой панелью мониторинга в браузере. Если вы ещё не читали обзор Kanban, начните с него — здесь предполагается, что вы знаете, что такое задача, запуск, исполнитель и диспетчер.
Настройка¶
[code]
hermes kanban init # необязательно; первый hermes kanban <что-либо> инициализирует автоматически
hermes dashboard # открывает http://127.0.0.1:9119 в вашем браузере
# нажмите Kanban в левой навигации
[/code]
Панель мониторинга — самое удобное место для вас, чтобы наблюдать за системой. Агенты-работники, которых порождает диспетчер, никогда не видят панель мониторинга или CLI — они управляют доской через специальный набор инструментов kanban_* (kanban_show, kanban_complete, kanban_block, kanban_heartbeat, kanban_comment, kanban_create, kanban_link). Все три интерфейса — панель мониторинга, CLI и инструменты работников — проходят через одну и ту же SQLite-базу данных на доску (~/.hermes/kanban.db для доски по умолчанию, ~/.hermes/kanban/boards/<slug>/kanban.db для любой доски, созданной позже), поэтому каждая доска консистентна независимо от того, с какой стороны было сделано изменение.
В этом руководстве используется доска default (по умолчанию). Если вам нужны несколько изолированных очередей (по одной на проект / репозиторий / домен), см. Доски (мультипроектные) в обзоре — одни и те же потоки CLI / панели мониторинга / работников применяются к каждой доске, и работники физически не видят задачи на других досках.
На протяжении всего руководства блоки кода с пометкой bash — это команды, которые выполняете вы. Блоки кода с пометкой # worker tool calls — это вызовы инструментов, которые генерирует модель порождённого работника — показаны здесь, чтобы вы могли увидеть цикл целиком, а не потому что вы когда-либо будете выполнять их самостоятельно.
Доска вкратце¶
Обзор Kanban-доски Шесть колонок слева направо: * Triage — сырые идеи; специалист доработает спецификацию, прежде чем кто-то начнёт над ними работать. * Todo — созданные, но ожидающие зависимостей или ещё не назначенные. * Ready — назначенные и ожидающие, пока диспетчер их заберёт. * In progress — работник активно выполняет задачу. Если включён режим «Lanes by profile» (по умолчанию), эта колонка дополнительно группируется по исполнителю, чтобы вы могли сразу видеть, чем занят каждый работник. * Blocked — работник запросил ввод от человека, или сработал автоматический выключатель. * Done — выполненные.
В верхней панели находятся фильтры для поиска, тенанта и исполнителя, а также переключатель Lanes by profile и кнопка Nudge dispatcher, которая запускает один такт диспетчеризации немедленно, вместо ожидания следующего интервала демона. При нажатии на любую карточку открывается её боковая панель справа.
Плоский вид¶
Если полосы профилей создают шум, отключите «Lanes by profile», и колонка In Progress свернётся в единый плоский список, упорядоченный по времени захвата: Доска с отключёнными полосами профилей
История 1 — Разработчик-одиночка, выпускающий функциональность¶
Вы разрабатываете функциональность. Классический поток: спроектировать схему, реализовать API, написать тесты. Три задачи с зависимостями родитель→потомок. [code] SCHEMA=$(hermes kanban create "Design auth schema" \ --assignee backend-dev --tenant auth-project --priority 2 \ --body "Design the user/session/token schema for the auth module." \ --json | jq -r .id)
API=$(hermes kanban create "Implement auth API endpoints" \
--assignee backend-dev --tenant auth-project --priority 2 \
--parent $SCHEMA \
--body "POST /register, POST /login, POST /refresh, POST /logout." \
--json | jq -r .id)
hermes kanban create "Write auth integration tests" \
--assignee qa-dev --tenant auth-project --priority 2 \
--parent $API \
--body "Cover happy path, wrong password, expired token, concurrent refresh."
[/code]
Поскольку API имеет SCHEMA в качестве родителя, а tests имеет API в качестве родителя, только SCHEMA начинается в состоянии ready. Остальные две находятся в todo, пока их родители не будут завершены. Это работа механизма продвижения зависимостей — ни один другой работник не возьмётся за написание тестов, пока нет API для тестирования.
При следующем такте диспетчера (60 с по умолчанию или немедленно, если вы нажмёте Nudge dispatcher) профиль backend-dev порождает работника с HERMES_KANBAN_TASK=$SCHEMA в его окружении. Вот как выглядит цикл вызовов инструментов работника изнутри агента:
[code]
# worker tool calls — НЕ команды, которые вы выполняете
kanban_show()
# → возвращает заголовок, тело, worker_context, родителей, предыдущие попытки, комментарии
# (работник читает worker_context, использует инструменты terminal/file для проектирования схемы,
# пишет миграции, запускает свои проверки, делает коммит — реальная работа происходит здесь)
kanban_heartbeat(note="schema drafted, writing migrations now")
kanban_complete(
summary="users(id, email, pw_hash), sessions(id, user_id, jti, expires_at); "
"refresh tokens stored as sessions with type='refresh'",
metadata={
"changed_files": ["migrations/001_users.sql", "migrations/002_sessions.sql"],
"decisions": ["bcrypt for hashing", "JWT for session tokens",
"7-day refresh, 15-min access"],
},
)
[/code]
kanban_show по умолчанию использует task_id из $HERMES_KANBAN_TASK, поэтому работнику не нужно знать свой собственный id. kanban_complete записывает сводку + метаданные в текущую строку task_runs, закрывает этот запуск и переводит задачу в done — всё одним атомарным переходом через kanban_db.
Когда SCHEMA переходит в done, механизм зависимостей автоматически переводит API в ready. Когда работник API подхватывает задачу, он вызывает kanban_show() и видит сводку и метаданные SCHEMA, прикреплённые к родительской передаче — таким образом он знает решения по схеме без необходимости перечитывать длинный документ с проектированием.
Нажмите на выполненную задачу схемы на доске, и боковая панель покажет всё:
Разработчик-одиночка — боковая панель выполненной задачи схемы
Раздел Run History внизу — ключевое дополнение. Одна попытка: результат completed, работник @backend-dev, длительность, временная метка и полная сводка передачи. Блоб метаданных (changed_files, decisions) также сохраняется в запуске и предоставляется любому downstream-работнику, который читает этого родителя.
Вы можете просмотреть те же данные из терминала в любое время — эти команды предназначены для вас, чтобы заглянуть на доску, а не для работника:
[code]
hermes kanban show $SCHEMA
hermes kanban runs $SCHEMA
# # OUTCOME PROFILE ELAPSED STARTED
# 1 completed backend-dev 0s 2026-04-27 19:34
# → users(id, email, pw_hash), sessions(id, user_id, jti, expires_at); refresh tokens ...
[/code]
История 2 — Ферма работников¶
У вас есть три работника (переводчик, расшифровщик, копирайтер) и куча независимых задач. Вы хотите, чтобы все три работали параллельно и демонстрировали видимый прогресс. Это самый простой сценарий использования kanban, и именно для него была оптимизирована первоначальная разработка. Создайте работу: [code] for lang in Spanish French German; do hermes kanban create "Translate homepage to $lang" \ --assignee translator --tenant content-ops done for i in 1 2 3 4 5; do hermes kanban create "Transcribe Q3 customer call #$i" \ --assignee transcriber --tenant content-ops done for sku in 1001 1002 1003 1004; do hermes kanban create "Generate product description: SKU-$sku" \ --assignee copywriter --tenant content-ops done
[/code] Запустите шлюз и отойдите — он содержит встроенный диспетчер, который подхватывает задачи всех трёх специализированных профилей в той же kanban.db: [code] hermes gateway start
[/code]
Теперь отфильтруйте доску по content-ops (или просто найдите «Transcribe»), и вы получите следующее:
Вид фермы, отфильтрованный по задачам расшифровки
Две расшифровки выполнены, одна выполняется, две готовы и ждут следующего такта диспетчера. Колонка In Progress сгруппирована по профилю (режим «Lanes by profile» по умолчанию), поэтому вы видите активную задачу каждого работника без просмотра смешанного списка. Диспетчер переведёт следующую готовую задачу в состояние выполнения, как только текущая будет завершена. С тремя демонами, работающими над тремя пулами исполнителей параллельно, вся очередь контента опустошается без дальнейшего вмешательства человека.
Всё, что было сказано в Истории 1 о структурированной передаче, по-прежнему применимо здесь. Работник-переводчик, завершающий вызов, вызывает kanban_complete(summary="translated 4 pages, style matched existing marketing voice", metadata={"duration_seconds": 720, "tokens_used": 2100}) — полезно для аналитики и для любых downstream-задач, зависящих от этой.
История 3 — Ролевой конвейер с повторными попытками¶
Это тот случай, когда Kanban действительно оправдывает себя по сравнению с плоским списком дел. Менеджер проекта пишет спецификацию. Инженер реализует её. Ревьюер отклоняет первую попытку. Инженер пробует снова с изменениями. Ревьюер одобряет.
Вид панели мониторинга, отфильтрованный по auth-project:
Вид конвейера для многоролевой функциональности
Цепочка из трёх этапов видна одновременно: Spec: password reset flow (DONE, pm), Implement password reset flow (DONE, backend-dev), Review password reset PR (READY, reviewer). У каждого есть родитель, выделенный зелёным внизу, и потомки в качестве зависимостей.
Самая интересная — задача реализации, потому что она была заблокирована и выполнена повторно. Вот полная хореография трёх агентов, показанная как вызовы инструментов, которые генерирует модель каждого работника:
[code]
# --- Работник PM порождается для $SPEC и пишет критерии приёмки ---
# worker tool calls
kanban_show()
kanban_complete(
summary="spec approved; POST /forgot-password sends email, "
"GET /reset/:token renders form, POST /reset applies new password",
metadata={"acceptance": [
"expired token returns 410",
"reused last-3 password returns 400 with message",
"successful reset invalidates all active sessions",
]},
)
# → $SPEC выполнена; $IMPL автоматически продвигается из todo в ready
# --- Работник-инженер порождается для $IMPL (первая попытка) ---
# worker tool calls
kanban_show() # читает сводку $SPEC + метаданные приёмки в worker_context
# (инженер пишет код, запускает тесты, открывает PR)
# Приходит отзыв ревьюера — инженер решает, что замечания обоснованны, и блокирует
kanban_block(
reason="Review: password strength check missing, reset link isn't "
"single-use (can be replayed within 30min)",
)
# → $IMPL переходит в blocked; запуск 1 закрывается с результатом 'blocked'
[/code] Теперь вы (человек или отдельный профиль ревьюера) читаете причину блокировки, решаете, что направление исправления понятно, и разблокируете с помощью кнопки «Unblock» на панели мониторинга — или из CLI / slash-команды: [code] hermes kanban unblock $IMPL # или из чата: /kanban unblock $IMPL
[/code]
Диспетчер переводит $IMPL обратно в ready и при следующем такте повторно порождает работника backend-dev. Это второй запуск — новый запуск той же задачи:
[code]
# --- Работник-инженер порождается для $IMPL (вторая попытка) ---
# worker tool calls
kanban_show()
# → worker_context теперь включает причину блокировки из запуска 1, поэтому этот работник
# знает, какие две вещи нужно исправить, вместо перечитывания всей спецификации
# (инженер добавляет проверку zxcvbn, делает токены сброса одноразовыми, перезапускает тесты)
kanban_complete(
summary="added zxcvbn strength check, reset tokens are now single-use "
"(stored + deleted on success)",
metadata={
"changed_files": [
"auth/reset.py",
"auth/tests/test_reset.py",
"migrations/003_single_use_reset_tokens.sql",
],
"tests_run": 11,
"review_iteration": 2,
},
)
[/code]
Нажмите на задачу реализации. Боковая панель показывает две попытки:
Задача реализации с двумя запусками — заблокирован, затем выполнен
* Запуск 1 — blocked от @backend-dev. Отзыв ревьюера находится прямо под результатом: «password strength check missing, reset link isn't single-use (can be replayed within 30min)».
* Запуск 2 — completed от @backend-dev. Новая сводка, новые метаданные.
Каждый запуск — это строка в task_runs с собственным результатом, сводкой и метаданными. История повторных попыток — это не концептуальное дополнение, надстроенное поверх «последнего состояния» задачи — это основное представление. Когда повторно запускаемый работник открывает задачу, build_worker_context показывает ему предыдущие попытки, поэтому работник второй попытки видит, почему первая попытка была заблокирована, и устраняет именно эти замечания, вместо того чтобы запускаться с нуля.
Следующим подхватывает ревьюер. Когда он открывает Review password reset PR, он видит:
Вид боковой панели ревьюера для конвейера
Ссылка на родителя — это выполненная реализация. Когда работник ревьюера порождается для Review password reset PR и вызывает kanban_show(), возвращаемый worker_context включает сводку + метаданные последнего выполненного запуска родителя — таким образом ревьюер читает «added zxcvbn strength check, reset tokens are now single-use» и имеет список изменённых файлов под рукой, прежде чем смотреть diff.
История 4 — Автоматический выключатель и восстановление после сбоя¶
Реальные работники дают сбои. Отсутствующие учётные данные, убийства из-за нехватки памяти, временные сетевые ошибки. У диспетчера есть две линии защиты: автоматический выключатель, который автоматически блокирует задачу после N последовательных неудач, чтобы доска не «молотила» вечно, и обнаружение сбоев, которое возвращает задачу, чей PID работника исчез до истечения TTL.
Автоматический выключатель — постоянно выглядящий сбой¶
Задача развёртывания, которая не может породить своего работника, потому что AWS_ACCESS_KEY_ID не установлен в окружении профиля:
[code]
hermes kanban create "Deploy to staging (missing creds)" \
--assignee deploy-bot --tenant ops
[/code]
Диспетчер пытается породить работника. Порождение не удаётся (RuntimeError: AWS_ACCESS_KEY_ID not set). Диспетчер освобождает захват, увеличивает счётчик неудач и пытается снова при следующем такте. После трёх последовательных неудач (значение failure_limit по умолчанию) выключатель срабатывает: задача переходит в blocked с результатом gave_up. Никаких повторных попыток до тех пор, пока человек не разблокирует её.
Нажмите на заблокированную задачу:
Автоматический выключатель — 2 spawn_failed + 1 gave_up
Три запуска, все с одинаковой ошибкой в поле error. Первые два — spawn_failed (с возможностью повторной попытки), третий — gave_up (терминальный). Журнал событий выше показывает полную последовательность: created → claimed → spawn_failed → claimed → spawn_failed → claimed → gave_up.
В терминале:
[code]
hermes kanban runs t_ef5d
# # OUTCOME PROFILE ELAPSED STARTED
# 1 spawn_failed deploy-bot 0s 2026-04-27 19:34
# ! AWS_ACCESS_KEY_ID not set in deploy-bot env
# 2 spawn_failed deploy-bot 0s 2026-04-27 19:34
# ! AWS_ACCESS_KEY_ID not set in deploy-bot env
# 3 gave_up deploy-bot 0s 2026-04-27 19:34
# ! AWS_ACCESS_KEY_ID not set in deploy-bot env
[/code]
Если подключены Telegram / Discord / Slack, уведомление шлюза отправляется при событии gave_up, чтобы вы узнали о проблеме без необходимости проверять доску.
Восстановление после сбоя — работник умирает в полёте¶
Иногда порождение удаётся, но процесс работника умирает позже — segfault, OOM, systemctl stop. Диспетчер опрашивает kill(pid, 0) и обнаруживает мёртвый pid; захват освобождается, задача возвращается в ready, и при следующем такте она передаётся новому работнику.
Пример в тестовых данных — миграция, которая исчерпала память:
[code]
# Работник захватывает, начинает сканирование 2.4M строк, OOM убивает его на ~2.3M
# Диспетчер обнаруживает мёртвый pid, освобождает захват, увеличивает счётчик попыток
# Повторная попытка с стратегией разбиения на части успешна
[/code]
Боковая панель показывает полную историю из двух попыток:
Сбой и восстановление — 1 crashed + 1 completed
Запуск 1 — crashed, с ошибкой OOM kill at row 2.3M (process 99999 gone). Запуск 2 — completed, с "strategy": "chunked with LIMIT + WHERE id > last_id" в его метаданных. Повторно запускаемый работник увидел сбой запуска 1 в своём контексте и выбрал более безопасную стратегию; метаданные делают очевидным для будущего наблюдателя (или автора посмертного анализа), что изменилось.
Структурированная передача — почему summary и metadata важны¶
В каждой истории выше работники вызывали kanban_complete(summary=..., metadata=...) в конце. Это не украшение — это основной канал передачи между этапами рабочего процесса.
Когда работник задачи B порождается и вызывает kanban_show(), worker_context, который он получает, включает:
* Предыдущие попытки B (предыдущие запуски: результат, сводка, ошибка, метаданные), чтобы повторно запускаемый работник не повторял неудачный путь.
* Результаты родительских задач — для каждого родителя сводку и метаданные последнего выполненного запуска — чтобы downstream-работники видели, почему и как была выполнена вышестоящая работа.
Это заменяет танец «покопаться в комментариях и результате работы», который преследует плоские kanban-системы. Менеджер проекта пишет критерии приёмки в метаданных спецификации, и работник инженера видит их структурно в родительской передаче. Инженер записывает, какие тесты он запустил и сколько прошло, и работник ревьюера имеет этот список под рукой, прежде чем открыть diff.
Защита от массового закрытия существует, потому что эти данные привязаны к запуску. hermes kanban complete a b c --summary X (вы, из CLI) отклоняется — копирование одной и той же сводки для трёх задач почти всегда неправильно. Массовое закрытие без флагов передачи всё ещё работает для обычного случая «Я закончил кучу административных задач». Интерфейс инструментов вообще не предоставляет массового варианта; kanban_complete всегда работает с одной задачей за раз по той же причине.
Просмотр текущей выполняемой задачи¶
Для полноты — вот боковая панель задачи, которая ещё выполняется (реализация API из Истории 1, захваченная backend-dev, но ещё не завершённая):
Захваченная, выполняемая задача
Статус — Running. Активный запуск отображается в разделе Run History с результатом active и без ended_at. Если этот работник умрёт или истечёт время, диспетчер закроет этот запуск с соответствующим результатом и откроет новый при следующем захвате — строка попытки никогда не исчезает.
Следующие шаги¶
- Обзор Kanban — полная модель данных, словарь событий и справочник по CLI.
hermes kanban --help— каждая подкоманда, каждый флаг.hermes kanban watch --kinds completed,gave_up,timed_out— просмотр событий в реальном времени в терминале по всей доске.-
hermes kanban notify-subscribe <task> --platform telegram --chat-id <id>— получать уведомление шлюза, когда конкретная задача завершится. - Доска вкратце
- История 1 — Разработчик-одиночка, выпускающий функциональность
- История 2 — Ферма работников
- История 3 — Ролевой конвейер с повторными попытками
- История 4 — Автоматический выключатель и восстановление после сбоя
- Структурированная передача — почему
summaryиmetadataважны - Просмотр текущей выполняемой задачи
- Следующие шаги