Привет, Хабр! Меня зовут Максим, и я хочу рассказать историю о том, как простая боль при работе с ИИ-ассистентами превратилась в open-source проект, который, надеюсь, пригодится и вам.
Предыстория: когда всё началось
Последний год я активно использую локальные ИИ-агенты для работы над проектами. Не просто «напиши функцию», а полноценная декомпозиция задач: разбиваю большой проект на модули, модули на задачи, задачи на подзадачи. Через час работы у меня красивая иерархия из 50+ пунктов.
И вот тут начинается веселье.
Боль №1: «Добавь подпункт к 3.2.1»
Пишу в чат:
— Добавь подпункт к 3.2.1
А ИИ добавляет к 3.2. Или к 3.1. Или вообще создаёт новый раздел 4. Потому что контекст переполнен, и модель уже не помнит точную структуру.
Боль №2: «Перепиши раздел 4»
Прошу переписать один раздел, а ИИ заодно «улучшает» разделы 3 и 5. Которые я уже согласовал с заказчиком. Которые были идеальны.
Боль №3: «Верни как было»
— Верни структуру как было 20 сообщений назад
ИИ начинает галлюцинировать «как было», потому что не помнит. И приходилось вручную откатывать изменения, перечитывая историю чата и восстанавливая структуру по памяти.
Боль №4: Хрупкие ссылки
Переместил пункт 2.3 в раздел 5. Теперь он 5.4. А все ссылки «см. пункт 2.3» в других местах — битые. И ИИ про них не знает.
Первые попытки решения
Сначала я просто копировал структуру в отдельный .txt файл. После каждого изменения — копировал заново. Это работало... примерно неделю.
Потом я начал делать версии: plan_v1.txt, plan_v2.txt, plan_v3_final.txt, plan_v3_final_FINAL.txt. Знакомо, да?
Потом я попробовал Notion, Obsidian, даже Excel. Но проблема оставалась: ИИ не знает, что можно менять, а что нельзя трогать.
Момент озарения
Однажды я работал над большим проектом с автономным агентом. Агент должен был выполнять задачи по плану. И я понял, что мне нужно:
Стабильные идентификаторы — чтобы ссылка на задачу не ломалась при перемещении
Защита от изменений — чтобы утверждённые разделы нельзя было случайно изменить
История изменений — чтобы можно было откатиться
Простой интерфейс — чтобы и я, и ИИ могли работать с этим
Так родился HBT — Hierarchical Block Text.
Что такое HBT
HBT — это CLI-инструмент для управления иерархическими задачами. Один Python-файл, никаких зависимостей, работает везде где есть Python 3.8+.
Ключевые идеи:
UUID вместо позиционных номеров
Каждый узел получает уникальный 12-символьный ID:
└── a1b2c3d4 ⚪ Разработка API ✍️ ├── b2c3d4e5 ⚪ Аутентификация ✍️ └── c3d4e5f6 ⚪ База данных ✍️
Переместил «Аутентификацию» в другой раздел? ID остался b2c3d4e5. Все ссылки работают.
Статус locked/editable
Утвердили структуру раздела? Блокируем:
hbt status --id b2c3d4e5 --mode locked
Теперь этот узел нельзя изменить или удалить. Даже случайно. Даже если очень хочется.
└── b2c3d4e5 ⚪ Аутентификация 🔒 # Заблокировано!
Алиасы для удобства
Вместо b2c3d4e5 можно использовать человекочитаемое имя:
hbt alias --id b2c3d4e5 --name auth
Теперь можно писать @auth вместо ID:
hbt view --id @auth hbt add --to @auth --text "JWT токены"
Автоматические снапшоты
Каждое изменение сохраняется. Накосячили? Откат в одну команду:
hbt rollback --list # Посмотреть доступные точки hbt rollback --restore auto_20240218_100000.json # Восстановить
Как это выглядит на практике
Создаём структуру проекта
# Корневая задача hbt add --text "Мой крутой проект" --alias project --locked # Основные разделы hbt add --to @project --text "Backend" --alias api hbt add --to @project --text "Frontend" --alias fe hbt add --to @project --text "DevOps" --alias devops # Детализация hbt add --to @api --text "REST API" hbt add --to @api --text "База данных" hbt add --to @api --text "Авторизация" --alias auth
Смотрим что получилось
hbt view
└── a1b2c3d4 @project ⚪ Мой крутой проект 🔒 ├── b2c3d4e5 @api ⚪ Backend ✍️ │ ├── c3d4e5f6 ⚪ REST API ✍️ │ ├── d4e5f6a7 ⚪ База данных ✍️ │ └── e5f6a7b8 @auth ⚪ Авторизация ✍️ ├── f6a7b8c9 @fe ⚪ Frontend ✍️ └── a7b8c9d0 @devops ⚪ DevOps ✍️
Быстро наполняем раздел
hbt rewrite --id @auth "JWT токены" "OAuth Google" "Refresh tokens" "Rate limiting"
Одной командой создали 4 подпункта.
Блокируем утверждённое
hbt status --id @api --mode locked --recursive
Теперь весь Backend заблокирован. Никто (включая вас в 3 часа ночи) не сможет случайно его сломать.
Отслеживаем прогресс
hbt set-progress --id @auth --state doing # Начали работу hbt set-progress --id @auth --state done # Закончили
└── e5f6a7b8 @auth 🟢 Авторизация 🔒 # Зелёный = done
Находим следующую задачу
hbt next
🎯 Следующая задача: c3d4e5f6 — REST API [todo]
Идеально для автономных агентов: получил задачу → выполнил → отметил done → получил следующую.
Интеграция с ИИ-инструментами
Экспорт контекста для ИИ
Экспортируем структуру и передаём агенту:
hbt export context.txt cat context.txt
Теперь агент видит актуальную структуру и может ссылаться на узлы по ID или alias.
С Aider
# В сессии Aider /run hbt view --raw /run hbt next
С автономными агентами
Агент выполняет простой цикл:
1. hbt next → получить задачу 2. выполнить задачу 3. hbt set-progress → отметить done 4. goto 1
Что под капотом
Один файл
hbt.py— никаких зависимостей, только стандартная б��блиотека PythonJSON-хранилище
tasks.json— человекочитаемый формат, можно редактировать рукамиАтомарные операции — запись через временный файл, данные не потеряются при сбое
62 теста — всё покрыто, можно доверять
Какие боли закрывает HBT
Проблема | Решение |
|---|---|
ИИ путает вложенность | UUID-адресация — ID не меняется при перемещении |
Случайные изменения утверждённого | Статус |
Нет истории | Автоматические снапшоты каждого изменения |
Битые ссылки | Алиасы |
Потеря контекста | Экспорт актуальной структуры для нового чата |
Агент теряет фокус | Команда |
Почему я решил поделиться
Инструмент решает мою конкретную боль. Но я уверен, что не один такой. Если вы:
Работаете с ИИ над сложными проектами
Устали от того, что структура «плывёт»
Хотите защитить утверждённые разделы от случайных изменений
Используете автономных агентов и нужен чёткий план
...то HBT может вам пригодиться.
Проект полностью open-source под лицензией CC BY 4.0. Используйте, форкайте, улучшайте.
Ссылки
Документация: в README.md репозитория
Буду рад обратной связи в комментариях. Если есть идеи по улучшению — welcome в Issues на GitHub.
Спасибо за внимание! 🚀
