BlazeStudio/HH-Auto-Response
BlazeStudio/HH-Auto-Response has 66 GitHub stars and 1 forks. GitHot measured 0 stars in 24 hours, +3 in 7 days, and +17 in 15 days. Last checked 2026-11-15 07:38 UTC. Last push 2026-11-05.
Measured star growth
- in 24h
- 0
- in 7 days
- +3
- in 15 days
- +17
- in 1 month
- Collecting history
Net star changes over overlapping periods, not daily totals. Missing measurements are left blank. Stars measure attention, not software quality.
About
Автоотклики на hh.ru: письмо под каждую вакансию, ответы на анкеты и анализ резюме нейросетью, отказы и приглашения из чатов, подъём резюме и статистика. Приложение для Windows, macOS, Linux и Docker — работает прямо на вашем компьютере
AIREADME.md
OriginalHH-Auto-Response
Автоотклики на hh.ru: письмо под вакансию, ответы на анкеты, разбор чатов с отказами и анализ резюме под рынок

Я устал вручную откликаться на сотню вакансий в день, поэтому написал эту программу. Она открывает выдачу hh.ru («подходящие к резюме» или обычный поиск), идёт по ней страница за страницей и откликается на всё, что прошло ваши фильтры. Письмо берётся из кнопки hh «Сгенерировать», пишется нейросетью под конкретную вакансию, берётся из вашего шаблона или не прикладывается вовсе.
Если работодатель прикрепил анкету, её заполняет нейросеть по вашему резюме. В чатах программа читает отказы и отвечает «Роботу-рекрутеру», а живых людей, приглашения и всё, что касается документов и денег, оставляет вам.
А чтобы откликов было с чем отправлять, есть анализ резюме: программа сравнивает его с открытыми вакансиями и подсказывает, какие навыки перенести из опыта в «Ключевые навыки», что изучить в первую очередь, хватает ли опыта и какие платят зарплаты.
Есть приложение с окном (Windows, macOS, Linux), консольные скрипты и Docker-образ для сервера.
Содержание
- Что умеет
- Скриншоты
- Установка, первый запуск и обновление
- Как проходит отклик
- Поиск и фильтры, отбор по данным hh
- Сопроводительное письмо
- Нейросеть: анкеты и чаты
- Статистика и анализ резюме
- Расписание, поднятие резюме, приглашения и компании мечты
- Браузер и мини-окно
- Отчёт, логи, уведомления
- Docker на сервере
- Сборка приложения
- Что где лежит
- hh.ru и Россия
- Почему это легально
- Ограничения
- Лицензия и участие
Что умеет
- Откликается по ссылке «подходящие к резюме» или по нескольким поисковым запросам за раз и проходит все страницы выдачи. Между вакансиями делает паузы, как человек.
- Запускается сам по расписанию (например, по будням в 10:00 и 15:00) и не заваливает одну компанию откликами: можно ограничить число откликов в компанию за N дней.
- Поднимает резюме в поиске каждые 4 часа — бесплатно, как кнопка «Поднять в поиске» на hh.
- Не тратит отклики впустую: пропускает вакансии, о которых предупреждает hh, «вечные» и переполненные вакансии, просьбы писать в Telegram, тесты и чужой уровень (Junior, когда вы Senior).
- Сразу сообщает о приглашении и первым откликается на свежие вакансии «компаний мечты».
- Анализирует резюме: сравнивает его с открытыми вакансиями hh и говорит, какие навыки перенести из опыта в «Ключевые навыки», что изучить в первую очередь, хватает ли опыта, какие зарплаты и какие вакансии подходят лучше всего. Резюме — PDF с hh, Word или текст; всё считается на вашем компьютере.
- Показывает воронку: сколько приглашений и отказов дал каждый запрос и вид письма, — и какие навыки чаще всего просят в вашей выдаче, но их нет в резюме.
- Разбирается со всем, что hh показывает после «Откликнуться»: окно с письмом, быстрый отклик с «Приложить письмо», «Отклик уже просмотрен», предупреждение о другом регионе (на удалёнку соглашается, на переезд нет).
- Письмо: кнопкой hh (нужна подписка), нейросетью без подписки, вашим шаблоном или без письма.
- Анкеты работодателя заполняет нейросеть. Технологии отмечает строго по резюме, зарплату и сроки выхода берёт из ваших настроек. Если опыта нет, честно так и пишет или подаёт смежный опыт, но ничего не выдумывает.
- Все фильтры поиска hh (график, часы, доход, специализации, отрасли, сортировка, период и другие) плюс свои: «только со словами», «только эти компании», исключения по названию вакансии и компании.
- ИИ-фильтр: перед откликом нейросеть читает карточку и сверяет её с вашим описанием своими словами («ищу удалёнку на Python, без продаж и 1С») — отсеивает то, что словами не поймать.
- В чатах читает отказы и проходит анкеты «Робота-рекрутера» — или только читает отказы, не трогая остальное.
- Ведёт Excel-отчёт: кто откликнулся, где были вопросы, что пропущено и почему.
- Показывает статистику: отклики, пропуски по причинам, отказы в чатах по дням, неделям и месяцам, графики настраиваются. Хранит только числа, без названий вакансий и компаний.
- Браузер не мешает: работает спрятанным, а в приложении видно, что он делает. Мини-окно в углу экрана показывает ход работы, пока вы заняты другим.
- По итогам может прислать уведомление на компьютер или в Telegram, если вы это разрешите.
- Пароль не вводит и капчу не обходит. Все данные хранятся только у вас.
Скриншоты
![]() Анализ резюме: оценка против открытых вакансий и что сделать — по пользе, от навыков из опыта до «Обо мне» |
![]() Навыки рынка: спрос, насколько больше платят, есть ли в резюме и сколько вакансий откроет каждый |
![]() Чаты: отказы прочитаны, на анкету робота ответила нейросеть, живой HR оставлен вам |
![]() Проверка ИИ: пишете за работодателя и смотрите, что ответит модель. В hh ничего не уходит |
![]() Настройки по вкладкам: все фильтры hh, можно заполнить одной ссылкой с сайта |
![]() Журналы: логи прошлых запусков, копирование и удаление |
![]() Статистика: отклики, пропуски по причинам, отказы и ответы ИИ по дням, неделям и месяцам; графики настраиваются, выше них — воронка откликов и навыки из вашей выдачи |
![]() Мини-окно в углу экрана: ход работы и превью браузера, пока вы заняты другим; «—» убирает его на панель задач |
На скриншотах демо-данные: резюме и компании вымышленные. Светлая или тёмная тема — как у вас на GitHub.
Установка
Windows
Нужны Windows 10 или 11 и Google Chrome или Microsoft Edge (Edge в Windows есть всегда). Python не нужен.
- Скачайте
HH-Auto-Response-<версия>-windows.zipсо страницы релизов (или соберите сами, см. ниже). - Распакуйте в любую свою папку, например в «Документы», и запустите
HH-Auto-Response.exe. Папка_internalдолжна лежать рядом с ним. ВProgram Filesлучше не класть: туда без прав администратора не запишешь, и обновление не сможет поставиться само.
Приложение не подписано платным сертификатом, поэтому при первом запуске Windows может показать «Windows защитил ваш компьютер». Нажмите «Подробнее», затем «Выполнить в любом случае». Антивирусы иногда ругаются на программы, собранные PyInstaller. Это ложное срабатывание.
macOS
Нужны macOS 11 или новее и Google Chrome. Распакуйте HH-Auto-Response-macos-arm64.zip (на Mac с Intel — -x86_64) и перенесите
HH-Auto-Response.app в «Программы». При первом запуске нажмите на приложение правой кнопкой и выберите
«Открыть»: оно не подписано, и обычный двойной клик macOS заблокирует.
Linux
Нужен Google Chrome (google-chrome-stable). Для уведомлений нужен notify-send (пакет libnotify-bin).
tar -xzf HH-Auto-Response-linux-x86_64.tar.gz
./HH-Auto-Response/HH-Auto-Response
Из исходников
Нужны Python 3.11+ и Chrome или Edge. Если их нет, подойдёт встроенный Chromium: python -m playwright install chromium и channel = "" в config.toml.
pip install -r requirements.txt
python scripts/gui.py
Из исходников приложение и консольные скрипты используют одну папку hh-data/ внутри проекта: там
config.toml, логи и вход в hh. Если вы запускали версию до 1.0.4, где всё это лежало прямо в корне проекта,
файлы сами переедут в hh-data/ при первом запуске.
При обновлении программы config.toml не перезаписывается: новые параметры дописываются в свои разделы
с пояснениями, ваши значения, комментарии и порядок строк остаются, а прежний файл сохраняется рядом как
config.toml.bak. Незнакомые программе параметры (от другой версии или с опечаткой) тоже не мешают:
программа их пропускает и пишет об этом в журнале.
Где хранятся данные
| Система | Папка |
|---|---|
| Windows | %LOCALAPPDATA%\HH-Auto-Response |
| macOS | ~/Library/Application Support/HH-Auto-Response |
| Linux | ~/.local/share/HH-Auto-Response |
| Из исходников | hh-data/ в папке проекта |
| Docker | volume /data, на сервере это та же hh-data/ в папке проекта |
Там лежат config.toml, логи, таблица откликов, память между запусками и профиль браузера со входом в hh.
Своё место можно задать переменной HH_AUTO_HOME. Обновление эту папку не трогает: настройки и вход
остаются.
Первый запуск
- В «Настройках» укажите, где искать вакансии: вставьте ссылку (hh.ru → «Мои резюме» → «N подходящих вакансий» → адрес из браузера) или переключитесь на «По запросу» и впишите запрос.
- Если подписки hh нет, выберите в «Сопроводительном письме» режим «Генерировать нейросетью», «Готовый текст» или «Без письма».
- Нажмите «Пробный прогон». Откроется браузер. Войдите в hh.ru сами, программа это увидит и покажет, на что откликнулась бы, ничего не отправляя. Дальше браузер работает спрятанным за краем экрана — что он делает, видно в превью в меню слева, «Показать» выводит его на экран (подробнее — ниже, в «Браузер и мини-окно»).
- Если всё устраивает, нажмите «Начать» вверху страницы «Отклики».
В консоли то же самое: python scripts/responses.py --dry-run, потом python scripts/responses.py --limit 1
для одного настоящего отклика, потом просто python scripts/responses.py. Чаты — python scripts/chats.py
(--dry-run только покажет, что было бы сделано).
Все параметры scripts/responses.py
| Параметр | Что делает |
|---|---|
--dry-run |
пройти выдачу и показать вакансии, не откликаясь |
--limit N |
не больше N откликов за запуск |
--start-page N |
начать с N-й страницы выдачи |
--url ССЫЛКА |
другая ссылка поиска вместо search_url |
--query "ЗАПРОС" |
поиск по запросу, например --query "python разработчик" |
--resume ССЫЛКА |
ссылка на резюме вместо resume_url |
--retry-skipped |
ещё раз попробовать вакансии, пропущенные раньше |
--login |
только войти в hh и сохранить сессию (удобно на сервере) |
-v |
подробный лог и в консоли |
Остановить можно в любой момент через Ctrl+C, итоги всё равно выведутся.
Обновление
Приложение само узнаёт о новых версиях. При запуске (и дальше раз в 12 часов) оно заглядывает в релизы на GitHub, и если там есть версия новее, в меню слева появляется зелёная кнопка «⬇ Обновить до …». По нажатию приложение покажет, что нового, скачает архив под вашу систему, сверит контрольную сумму, перезапустится уже новой версией и напишет «Обновлено до …». Настройки, логи, история откликов и вход в hh остаются как были.
Установщик для этого не нужен: обновление кладёт новые файлы на место старых (HH-Auto-Response.exe
и _internal, на Mac — HH-Auto-Response.app). Старые файлы сначала откладываются в сторону. Если
заменить не получилось, всё возвращается как было и запускается прежняя версия. Журнал обновления пишется
в logs/update.log в папке данных.
- Отключить проверку или проверить вручную: «Настройки» → «Данные приложения».
- Если в папку программы нельзя писать (например, она лежит в
Program Files), приложение предложит открыть страницу релиза и скачать архив вручную. Его достаточно распаковать поверх старой папки. - Из исходников:
git pullиpip install -r requirements.txt. В Docker:git pull, затемdocker compose buildиdocker compose up -dв папкеdocker/.
Как проходит отклик
Перед стартом программа проверяет, что hh.ru открывается, и показывает страну вашего IP. Логин и пароль она не знает: в первый раз вы входите сами, и сессия сохраняется в профиле браузера. Дальше она сверяет, что резюме из ссылки действительно ваше, и идёт по выдаче.
С каждой вакансией происходит одно из следующего:
- вакансия не прошла фильтры и пропускается без клика;
- открылось окно с письмом: программа вставляет письмо и нажимает «Откликнуться»;
- отклик ушёл сразу: программа жмёт «Приложить письмо» и отправляет письмо отдельно. Если hh пишет «Отклик уже просмотрен работодателем», окно просто закрывается;
- hh предупреждает, что вакансия в другом регионе. Если работа удалённая, программа соглашается.
Если в карточке нет «Можно удалённо» или есть «переезд» и «релокация», отказывается (
[relocation]); - открылась анкета работодателя. С нейросетью программа заполняет её целиком. Без нейросети отвечает, только если вопрос один и он про зарплату. В остальных случаях вакансия попадает на лист «Вопросы» со ссылкой на форму, и ответить можно вручную;
- вакансия открылась в отдельном окне или резюме скрыто: пропуск.
После каждой страницы в журнале написано, почему программа идёт дальше или почему остановилась. Если фильтры отсеяли почти всю страницу, она об этом предупредит.
Поиск и фильтры
Искать можно двумя способами. По ссылке ([search] mode = "resume" и search_url) обычно берут
«подходящие к резюме». По запросу (mode = "query" и query) это обычный поиск hh, как в строке поиска
на сайте. Для запроса можно выбрать регион.
Запросов может быть несколько, по одному на строку: «python разработчик», «backend python», «django». За
запуск программа пройдёт выдачу каждого по очереди. Лимит откликов на запуск общий, фильтры hh одни на все,
а вакансия, найденная по двум запросам, обрабатывается один раз. В консоли: --query python --query django.
Чтобы не отправлять крупной компании десяток откликов на похожие вакансии, задайте «Откликов в одну
компанию, не больше» ([limits] per_company, например 2) и период (per_company_days, по умолчанию
30 дней). «ООО "Ромашка"» и «Ромашка» считаются одной компанией.
Фильтры hh
Это те же фильтры, что на сайте hh. Программа подставляет их в ссылку поиска, и выдачу отбирает сам hh. Если фильтр не задан, программа его не трогает, а на hh это значит «выбрано всё».
Проще всего настроить фильтры прямо на hh.ru, скопировать адрес страницы и в приложении нажать «Настройки» → «Фильтры hh» → «Заполнить из ссылки hh». Все поля заполнятся сами. Если это была ссылка «подходящие к резюме», программа заодно поставит её ссылкой поиска, уже без фильтров: они теперь в полях.
| Фильтр | Настройка [hh_filters] |
|---|---|
| Сортировка: по соответствию, по дате, по убыванию или возрастанию зарплаты, по удалённости | order_by |
| Период: за всё время, неделю, три дня, сутки | search_period (0, 7, 3, 1) |
| График работы: 5/2, 2/2, свободный, по выходным… | work_schedule_by_days |
| Рабочие часы в день | working_hours |
| Опыт работы | experience |
| Формат работы: удалённо, гибрид, на месте, разъездной | work_format |
| Уровень дохода от ₽ и за что он указан (месяц, смена, час…) | salary, salary_mode |
| Частота выплат | salary_frequency |
| Тип занятости, оформление по ГПХ или совместительству | employment_form, accept_temporary |
| Специализации (выбор по названию из 194) | professional_role |
Компании (номера из ссылки hh.ru/employer/…) |
employer_id |
| Отрасль компании и подотрасли | industry |
| Слова-исключения | excluded_text |
| Образование | education |
| Другие параметры: без агентств, трудовой договор, указан доход, меньше 10 откликов… | label |
| Особенности здоровья | inclusiveness_types |
| Где искать слова запроса: в названии, в компании, в описании | search_field |
Все допустимые значения расписаны в комментариях config.example.toml. В журнале перед стартом видно,
какие фильтры ушли на hh: «фильтры hh: сортировка: по дате; период: за неделю; опыт: …».
Заданный фильтр заменяет то, что уже было в ссылке поиска, а незаданный оставляет как есть. Если ссылка досталась с фильтрами, а вы хотите управлять ими из настроек, возьмите ссылку без параметров или нажмите «Заполнить из ссылки». Поэтому же в браузере без фильтров вы увидите больше вакансий, чем найдёт программа.
Фильтры программы
Их проверяет сама программа по карточке вакансии, до клика. Подходящие под исключение вакансии пропускаются и попадают на лист «Пропущенные» с причиной.
| Фильтр | Настройка [filters] |
Как работает |
|---|---|---|
| Только со словами | include_words |
отклик, только если в названии (или в описании, include_in_snippet) есть хоть одно слово |
| Только эти компании | include_company_words |
отклик, только если в названии компании есть хоть одно слово; пусто — любые компании |
| Исключить по названию | exclude_title_words |
например, «преподаватель», «куратор» |
| Исключить компании | exclude_company_words |
«сбер» отсечёт Сбер, СберТех и Сбербанк |
Регистр не важен, ищется часть слова: «яндекс» подойдёт и для «Яндекс», и для «Яндекс Крауд».
Отбор по данным hh
Вместе со страницей выдачи hh отдаёт данные о каждой вакансии: проверен ли работодатель и есть ли
о нём предупреждения, рейтинг по отзывам, сколько откликов, когда вакансию создали, есть ли вопросы при
отклике. Программа читает их с уже открытой страницы, без лишних переходов, и пропускает вакансии,
на которые отклик, скорее всего, уйдёт впустую. «Настройки» → «Отбор», раздел [quality]:
| Правило | Настройка | По умолчанию |
|---|---|---|
| hh предупреждает (вводит в заблуждение, передаёт персональные данные), работодатель не подтверждён или на проверке | skip_suspicious |
включено |
| просят писать в Telegram, WhatsApp, ссылки t.me и wa.me (вакансии про Telegram-ботов не трогаются) | skip_messengers |
включено |
| на работодателя часто жалуются или у него нарушения правил hh | skip_complaints |
выключено: бывает и у крупных |
| «вечная» вакансия: создана давно и месяцами переопубликуется | max_age_days |
90 дней |
| на вакансию уже слишком много откликов | max_responses |
не проверяется (0) |
| рейтинг работодателя по отзывам ниже (при 5+ отзывах) | min_rating |
не проверяется (0) |
Там же — уровень вакансии ([filters] levels): Стажёр, Junior, Middle, Senior, Lead. Пропускается вакансия,
в названии которой явно указан другой уровень; без уровня в названии отклик будет. Опыт в годах —
фильтр hh «Опыт работы». А в «Откликах» → «Вопросы работодателя» можно пропускать тесты (анкеты
с вариантами ответа, [questions] skip_tests) или любые вопросы при отклике (skip_all) — такие вакансии
видно ещё в выдаче, без клика.
Если hh перестанет отдавать эти данные, отбор по ним просто не срабатывает — отклики идут как раньше. В итогах запуска и на «Статистике» такие пропуски — «Отсеяны: работодатель и вакансия».
Индекса вежливости работодателя (доли разобранных откликов) в выдаче нет: он только на странице самой вакансии, а открывать каждую — вдвое дольше и вдвое больше запросов к hh. Поэтому «мёртвые» вакансии отсеиваются по возрасту, числу откликов и предупреждениям hh.
Сопроводительное письмо
| Режим | Что делает | Подписка hh |
|---|---|---|
generate, «кнопкой hh» |
нажимает «Сгенерировать». Если кнопки нет или генерация не удалась, письмо пишет нейросеть (когда она включена), иначе берётся fallback_text |
нужна |
ai, «нейросетью» |
читает описание вакансии и пишет письмо под неё по вашему резюме | не нужна |
template, «готовый текст» |
вставляет ваш template_text, {vacancy} и {company} подставляются |
не нужна |
none, «без письма» |
откликается без письма; где письмо обязательно, пропускает | не нужна |
Письмо нейросетью получается на 3–5 предложений: чем зацепила вакансия и какие пункты из резюме подходят
под требования. Если модель припишет вам технологию из вакансии, которой в резюме нет, программа попросит
её переписать письмо, а если не поможет, вырежет такие предложения. Длину задаёт [letter] ai_max_chars.
Проверить без отклика можно кнопкой «Тест письма» на странице «Проверка ИИ» или командой
python scripts/ai_test.py --letter.
Нейросеть: анкеты и чаты
Нейросеть получает ваше резюме (программа загружает его с hh сама и вырезает телефон и почту), ваш контекст из настроек (зарплата, формат, когда готовы выйти) и вопрос. Отвечает от первого лица, коротко и своими словами.
Важные вещи программа не доверяет модели и считает сама:
- технологии в списке «отметьте, с чем работали» отмечаются только те, что есть в резюме;
- зарплату и сроки выхода берёт из контекста («Уровень дохода от 150» превращается в «Ожидаю от 150 000 ₽» или в нужную вилку). Если в контексте этого нет, пишет «Готов обсудить»;
- грейд считает по стажу: до года Junior, 1–3 года Junior+, 3–6 лет Middle, больше Senior;
- уровень языка, о котором в резюме ничего нет, ставит самый скромный.
Если прямого опыта нет, нейросеть не бросает анкету. Она либо подаёт смежный опыт («с Airflow напрямую не работал, но строил ETL на Celery»), либо честно пишет, что опыта не было. Если модель всё же «вспомнила» технологию, которой нет в резюме, программа переспросит её. Отказывается программа только от тестовых заданий, кода, ссылок на GitHub, документов, контактов и оплаты. Такие вакансии уходят на лист «Вопросы». Если модель на какой-то вопрос ответила пусто, программа переспросит её, а потом поставит честный осторожный ответ вместо того, чтобы бросать анкету. Вопросы-ловушки для нейросетей («этот пункт отмечают только нейросети») программа распознаёт сама и не отмечает.
В чатах программа включает фильтр «Только непрочитанные» и открывает отказы, чтобы hh отметил их
прочитанными. Если ИИ включён, она читает всю новую переписку и отвечает на каждый вопрос: «Роботу-рекрутеру»,
«ИИ-помощнику» и живому рекрутеру. Не отвечает она только на приглашения на встречу, собеседование или
звонок (время лучше согласовать самому) и на всё, что касается документов, контактов и денег. Такие чаты
остаются в списке «ждут вашего ответа». Если под сообщением есть кнопки ответа («Да» / «Нет», «Интересно»),
программа нажимает подходящую. Каждый ответ проверяется: вопрос должен быть из новых сообщений, ответ —
по сути, а срок выхода и зарплата — только из вашего контекста. Не получилось — чат остаётся вам.
Если робот присылает следующий вопрос позже, чем программа его ждала, она вернётся в этот чат в том же запуске.
Если хотите отвечать только ботам, включите «Отвечать только
ботам hh» в настройках ([ai] only_robot = true). Перед первым боевым запуском нажмите «Только показать»: программа покажет,
что ответила бы.
На странице «Чаты» можно выбрать, что делать: «Отказы и ответы ИИ» или «Только прочитать отказы»
([chats] mode = "rejections"). Во втором случае программа открывает только непрочитанные отказы, чтобы hh
отметил их прочитанными, а все остальные чаты не трогает — даже с включёнными ИИ-ответами: они остаются
непрочитанными и видны списком «ждут вашего ответа». Выбор сохраняется сразу; его же берут запуск чатов
по расписанию и Docker. В консоли — python scripts/chats.py --only-rejections.
ИИ-фильтр вакансий
Словесные фильтры не отличают «Python-разработчика» от «Python-разработчика в команду сопровождения 1С». ИИ-фильтр смотрит на смысл: перед каждым откликом нейросеть читает название, компанию и описание из карточки (плюс отметку hh «можно удалённо») и сверяет их с вашим описанием того, что вы ищете и чего не хотите. Не подходит — отклика не будет. Сомневается — откликается: лучше лишний отклик, чем потерянная вакансия.
Включается в «Настройки» → «Нейросеть» → «ИИ-фильтр вакансий» (в config.toml — раздел [ai_filter]).
Там же кнопка «Проверить фильтр на примере вакансии». Работает на той же нейросети, что и ответы в чатах;
с qwen3:8b на видеокарте это около полсекунды на вакансию. На наборе типичных карточек фильтр верно
решил 9 из 9, в том числе «Python в сопровождение 1С» и «только офис».
- Отсеянные вакансии запоминаются: в следующих запусках нейросеть о них не спрашивают. Поменяли описание или выключили фильтр — они пересматриваются сами.
- Что и почему отсеяно, видно в Excel на листе «Пропущенные» — по нему удобно уточнять описание.
- Если нейросеть не ответила, вакансия обрабатывается как обычно (
skip_on_error = true— пропускается). - Сам по себе фильтр не включает письма и анкеты нейросетью: они работают, только если вы включили их отдельно.
Фильтр предложен в pull request #2.
Какую нейросеть взять
| Нейросеть | Стоимость | Что нужно |
|---|---|---|
| OpenRouter | есть бесплатные модели, в том числе DeepSeek (:free) |
ключ: openrouter.ai → Keys |
| DeepSeek API | платно, но копейки за анкету | ключ: platform.deepseek.com → API keys |
| Ollama | бесплатно, на вашем компьютере, без интернета | ollama.com и ollama pull qwen3:8b |
| Другой сервис | по-разному | адрес API, модель и ключ |
Для Ollama я советую qwen3:8b. Она весит 5,2 ГБ, во время работы занимает около 7,5 ГБ видеопамяти
и отвечает примерно за 3 секунды на RTX 3080. На 12 типичных ситуациях из чатов она ответила верно 11 раз,
а со страховками программы все 12. Для сравнения: mistral 9 из 12, qwen2.5:7b 8 из 12, llama3 6 из 12.
Если Ollama не запущена, программа запустит её сама, а при выходе выгрузит модель из памяти.
Ollama на другом компьютере. Видеокарта не обязана быть там, где работает программа. Модель можно
поставить на домашний ПК или сервер с видеокартой, а программа будет ходить к ней по сети: через
SSH-туннель или по домашней сети/VPN. В настройках достаточно указать «Адрес API», например
http://192.168.1.50:11434. Пошаговый гайд с командами для Linux, Windows, macOS и Docker —
docs/ollama.md.
Включается всё в «Настройках» → «ИИ-ответы в чатах». Там же есть кнопка «Проверить подключение к ИИ».
В консоли это секция [ai] в config.toml. Ключ можно не хранить в файле, а задать переменной HH_AI_API_KEY.
Посмотреть, как модель отвечает, не трогая hh, можно на странице «Проверка ИИ» или командой
python scripts/ai_test.py (--demo, --form, --letter, --show-prompt). Видно ровно то, что уходит модели.
Статистика
Вкладка «Статистика» в приложении: сколько отправлено, с письмом, отказов в чатах и отказов на 100 откликов за 7, 30, 90 дней, год или всё время, и графики по дням, неделям или месяцам. Наведите на столбец — увидите числа за этот день.
Графики настраиваются: «Настроить» → показатели (отклики, письма, пропуски по видам причин, ошибки, отказы и ответы ИИ в чатах, запуски, минуты работы), вид (столбцы, линии, итоги) и название. «+ График» добавляет ещё один, «Убрать» — убирает. Набор графиков запоминается.
Над графиками — две карточки (выключаются в «Настройки» → «Прочее» → «Статистика»):
- Воронка (
[stats] funnel): что стало с откликами за период — сколько приглашений, отказов и без ответа, по каждому запросу, виду письма (кнопка hh, нейросеть, шаблон) и совпадению по навыкам. Видно, что работает, а что нет. Статусы берутся из чатов hh, когда программа их читает («Чаты» или фоновая проверка); раз в сутки просматриваются и прочитанные чаты (data/negotiations.json). - Навыки из вашей выдачи (
[stats] skill_tips): ключевые навыки, которые чаще всего просят в вакансиях вашего поиска, и есть ли они в резюме, плюс средний процент «подходит по навыкам» от hh. Навык, который у вас есть, но не указан, стоит добавить в «Ключевые навыки» резюме на hh. Текст резюме обновляется раз в 3 дня при откликах (data/skills.json— только навыки и числа).
Хранятся только числа по дням, без названий вакансий, компаний и текстов: data/stats.json, около 200 байт
на день. Дни старше года удаляются сами ([stats] keep_days, 0 — хранить всё), «Очистить статистику…»
удаляет всё сразу; таблица Excel и журналы при этом остаются. Не нужна статистика — «Настройки» → «Прочее»
→ «Не вести статистику» ([stats] disabled = true). При первом открытии вкладка соберёт статистику из уже
накопленной истории откликов.
Анализ резюме

Вкладка «Анализ резюме»: загрузите резюме — «Файл…» (PDF с hh: «Скачать» → PDF, Word или TXT), «С hh» (программа откроет страницу резюме) или «Вставить текст». Телефон и почта убираются сразу, резюме никуда не отправляется. Если резюме не загружено, берётся текст с hh, который программа сохраняет при откликах.
С чем сравнивается: вакансии, которые программа видела в выдаче за 30 дней. Они копятся при обычных
откликах ([stats] skill_tips) и при «Проверить рынок» — общем поиске hh по должности из резюме
(«Senior Python-разработчик (Backend)» → «Python разработчик») или по своему запросу. Поиск — без фильтров
и подбора «подходящие к резюме», только регион из настроек: так видна вся профессия, а не только то, что hh
уже подобрал под вас. Смотрится вся выдача: больше 2000 вакансий hh по одному поиску не показывает, поэтому
такой поиск делится по опыту и формату работы, а одна вакансия считается один раз («Python» на 5000 вакансий —
минут 4–5). Программа ни на что не откликается, а после проверки сравнивает резюме с её вакансиями. Из выдачи берётся то, что hh и так отдаёт со страницей:
название, ключевые навыки, требования, зарплата, опыт, формат; без компаний, в data/market.json, 45 дней
и не больше 15 000 вакансий. «Сравнивать с» — со всеми или с одной выдачей.
Как считается — без нейросети, по числам:
- Навыки вакансии — её ключевые навыки и навыки из словаря, упомянутые в названии и требованиях. Написания сводятся к одному навыку: «Postgres» — это PostgreSQL, «Английский — C1» — «Английский язык». Навыки резюме — «Ключевые навыки» и языки, отдельно — упомянутые только в тексте опыта, и всё, что из них следует (Django Rest Framework → Django → Python, PostgreSQL → SQL).
- Совпадение с вакансией — доля её профессиональных навыков («гибкие» не в счёт), которые есть в резюме. Подходит — от 60%.
- Ваш рынок — вакансии той же профессии (в названии есть слово из вашей должности), где у вас есть хотя бы 30% навыков. Спрос на навыки, зарплаты и советы считаются по нему: «Риск-аналитик» с Python и SQL — другая работа. Одна вакансия в нескольких городах считается один раз.
- Что изучить — по очереди: навык, который сильнее всего приближает к вакансиям, к которым вы уже близки, потом следующий с учётом выбранного; рядом — сколько вакансий с ним станут подходящими.
- Оценка 0–100: навыки 45 (сколько востребованных есть, с весом по спросу), опыт 20, название 15 (есть ли слова вашей должности в названиях подходящих вам вакансий), оформление 20 («Ключевые навыки», «Обо мне», цифры результата в опыте, описание последнего места, свежесть резюме, английский).
На вкладке: оценка, «Что сделать» по пользе, навыки рынка (спрос, насколько больше платят, есть ли в резюме, сколько вакансий откроет), что изучить, какие ваши навыки актуальны, а какие почти не просят, вилка зарплат и требуемый опыт, подходящие вакансии (в вашем городе, там, куда готовы переехать, или удалённо — щелчок открывает вакансию) и проверка оформления. «Разбор нейросетью» — по желанию: нейросеть из «Настроек» получает резюме и посчитанную сводку и предлагает конкретные формулировки. Любой текст отчёта можно выделить и скопировать, а «Копировать отчёт» кладёт в буфер обмена весь отчёт — например, чтобы обсудить его в чате.
В консоли и на сервере то же самое — python scripts/analyze_resume.py резюме.pdf; с --scan программа
сначала проверит рынок по должности из резюме, с --scan "запрос" — по своему запросу.
Расписание
В приложении: «Настройки» → «Расписание» → «Запускать отклики по расписанию». Укажите время (10:00, 15:30)
и дни недели. По желанию после откликов программа сама прочитает отказы в чатах. В меню слева видно, когда
следующий запуск: «Автозапуск сегодня в 15:30». Лимит берётся из «Откликов за запуск».
Расписание работает, пока приложение открыто (можно свернуть) и компьютер не спит. Если в назначенное время уже идёт работа, запуск будет сразу после неё. Время, которое прошло до включения или изменения расписания, не догоняется. Запуск, отложенный из-за другой работы, догоняется в течение трёх часов.
Для консольных скриптов расписание задаёт система. На Windows подойдёт Планировщик заданий: действие
«Запустить программу» python с аргументом scripts\responses.py и рабочей папкой проекта. На Linux
и macOS — cron. В Docker отклики и так идут по кругу (INTERVAL_HOURS).
Поднятие резюме
hh бесплатно поднимает резюме в поиске раз в 4 часа — кнопкой «Поднять в поиске» на странице «Мои резюме».
Свежее резюме работодатели видят выше. Программа может делать это сама: «Настройки» → «Расписание» →
«Поднимать резюме в поиске каждые 4 часа» ([raising] enabled).
Она отправляет hh тот же запрос, что и эта кнопка, с той же страницы — в вашем браузере и под вашим входом. Логин и пароль не нужны и нигде не хранятся. Пока приложение открыто (можно свернуть), браузер раз в 4 часа на несколько секунд открывается в фоне. Если в это время идут отклики или чаты, резюме поднимается в их начале. В меню слева видно, когда следующий подъём, в настройках — когда был прошлый, там же «Поднять сейчас».
- Какие резюме: из ссылки поиска (
resume=) или «Ссылки на резюме», а если её нет — все. Все сразу —all_resumes = true. - Раньше срока hh не трогается: когда поднималось и когда снова можно, программа помнит
(
data/raising.json). Если вы подняли резюме вручную и hh ответил «ещё рано», время берётся из карточки. - Если входа в hh нет, фоновый подъём окно входа не показывает: пишет об этом в меню слева и пробует снова через полчаса. Войдите при следующих откликах или чатах.
- Консоль и сервер:
python scripts/raise_resume.pyчерез Планировщик заданий Windows или cron, хоть каждый час — браузер откроется, только когда пора.--force— поднять сейчас. Отклики и чаты в консоли тоже поднимают резюме в начале, если включено и пора.
Фоновая проверка: приглашения и компании мечты
Пока приложение открыто (можно свернуть), оно может раз в N минут ([watch] every_minutes, не чаще раза
в 15 минут) на минуту открывать браузер в фоне. «Настройки» → «Расписание»:
- Приглашения (
[watch] invitations): смотрит непрочитанные чаты, не открывая их. Пришло приглашение — в меню слева строка «★ Приглашение: …» (щелчок откроет чаты hh в вашем браузере) и уведомление на компьютер или в Telegram, если уведомления включены ([notify] invitations). О каждом приглашении — один раз и только о непрочитанном. О приглашениях сообщают и обычные «Чаты». - Компании мечты (
[dream]): ссылки на страницы компаний (https://hh.ru/employer/2180). Их свежие вакансии — ваш поиск, только эта компания, за 3 дня, новые сверху — проверяются при каждой фоновой проверке, и отклик уходит сразу, раньше остальных откликнувшихся. Фильтры, письмо и анкеты — как у обычных откликов, не большеmax_per_checkоткликов за раз.
В обоих разделах есть «Проверить сейчас» и подпись, когда была прошлая проверка. Если входа в hh нет, фоновая проверка окно входа не показывает — пишет об этом в меню и пробует снова через полчаса. Подъём резюме идёт в той же фоновой проверке.
Консоль и сервер: python scripts/watch.py по расписанию (Планировщик заданий или cron), например каждые
15–30 минут: браузер открывается, только когда что-то пора. В Docker цикл делает это сам каждые 15 минут
(docker compose run --rm hh watch — разово).
Браузер и мини-окно
Спрятанный браузер (Windows). Браузер работает за краем экрана и не мешает, а в меню слева — превью:
кадр страницы раз в полторы секунды. «Показать» выводит окно на экран, «Спрятать» убирает обратно; щелчок
по значку браузера на панели задач тоже его показывает. Когда нужен человек — вход в hh или капча — окно
появляется само и после прячется. Страница за краем экрана работает так же, как на экране: проверено,
что она остаётся «видимой» для самой себя и подгружает карточки. Хотите обычное окно, как раньше:
«Настройки» → «Прочее» → «Браузер и сеть» → «Прятать окно браузера» ([browser] hide_window = false).
Мини-окно. Кнопка «В уголок» на «Откликах» и «Чатах» (или Ctrl+M) прячет окно программы, а в правом нижнем углу экрана остаётся маленькое окно поверх остальных: превью браузера, состояние, «Отправлено N из M», пропуски, ошибки, текущая вакансия, прогресс и кнопки «Начать / Остановить», «Браузер», «Развернуть». Его можно перетащить — место запомнится. Кнопка «—» сворачивает его на панель задач, щелчок по кнопке «HH-Auto-Response» там возвращает мини-окно. Если свернуть окно программы во время работы, мини-окно появится само (это выключается в «Настройки» → «Прочее» → «Данные приложения»).
Закрыли браузер — запуск сразу заканчивается с записью «окно браузера закрыто», ничего не «висит».
Отчёт, логи, уведомления
Excel. Все результаты собираются в logs/responses.xlsx. Там есть «Сводка» (сегодня из примерно 200,
последний запуск, всего, по дням), «Откликнулся» (с ответами на анкеты), «Вопросы» (со ссылкой на форму
отклика), «Пропущенные» с причиной, «Не откликнулся» (ошибки и лимит, эти вакансии программа попробует
снова) и «Ответы в чатах». Таблица собирается из data/responses.jsonl. Если она открыта в Excel,
программа обновит её, когда вы её закроете.
Логи. Каждый запуск пишет подробный лог в logs/ (run_*.log, chats_*.log), в нём есть полные
тексты писем. Журнал в окне можно копировать: выделите нужное или нажмите «Копировать», также работают
Ctrl+C и правая кнопка мыши. В «Журналах» можно удалить один лог, все логи или снимки страниц. Рядом
показано, сколько места они занимают.
Сбои окна. Если окно программы падает или не запускается, причина с полной трассировкой
записывается в logs/crash.log. Если такое повторяется — пришлите этот файл.
Снимки страниц. При ошибке программа сохраняет скриншот и HTML страницы в logs/snapshots. По ним
видно, что поменялось на hh. Один снимок весит 1–3 МБ, поэтому снимки старше 14 дней удаляются сами
([logs] keep_days, 0 — хранить всё). Если они не нужны совсем, отключите их: «Настройки» → «Логи и место
на диске» или [logs] snapshots = false.
Уведомления. После первого запуска приложение спросит, показывать ли уведомление по итогам. Без вашего
согласия ничего не приходит. На Windows уведомление приходит от HH-Auto-Response с иконкой
приложения: для этого программа регистрирует своё имя в разделе реестра текущего пользователя. Можно включить и Telegram: создайте бота у @BotFather, впишите токен и свой
chat id в «Настройки» → «Уведомления по итогам» (или в [notify]) и нажмите «Отправить тестовое уведомление».
На сервере это самый удобный способ узнать, что программа отработала.
Docker на сервере
Программу можно оставить работать на сервере, и она будет откликаться сама, например раз в 6 часов. Сервер должен быть в России: hh.ru работает только оттуда. Браузер в контейнере запускается на виртуальном экране. Чтобы один раз войти в hh, вы смотрите на этот экран по VNC через SSH-туннель. Наружу VNC не открывается.
1. Скопируйте проект на сервер и соберите образ. Нужны Docker и Docker Compose.
git clone https://github.com/BlazeStudio/hh-auto-response.git
Все команды docker compose дальше выполняются в папке docker/:
cd hh-auto-response/docker && docker compose build
2. Войдите в hh. На сервере запустите контейнер в режиме входа:
docker compose run --rm --service-ports hh login
На своём компьютере откройте туннель и оставьте это окно открытым:
ssh -L 5900:127.0.0.1:5900 user@ваш-сервер
Подключитесь любым VNC-клиентом (TigerVNC, RealVNC, на Mac подойдёт встроенный open vnc://localhost:5900)
к localhost:5900. Вы увидите браузер со страницей входа hh. Войдите как обычно: телефон или почта, затем код.
Контейнер сам поймёт, что вход выполнен, сохранит сессию и завершится.
3. Настройте. При первом запуске в hh-data/config.toml (в корне проекта) появится конфиг. Впишите ссылку поиска
(search_url) или запрос, а при желании нейросеть и Telegram-уведомления. Проверьте всё пробным прогоном:
docker compose run --rm hh responses --dry-run
4. Запустите. Дальше контейнер работает сам: отклики, потом чаты, потом пауза на INTERVAL_HOURS часов
(по умолчанию 6) и всё сначала. В паузе каждые 15 минут идёт фоновая проверка: подъём резюме,
приглашения и компании мечты — что включено и чему подошло время. После перезагрузки сервера контейнер
поднимется сам.
docker compose up -d
docker compose logs -f
Полезное:
- разовые запуски:
docker compose run --rm hh responses --limit 5,docker compose run --rm hh chatsиdocker compose run --rm hh raise --force(поднять резюме сейчас); - если вместо цикла удобнее cron на сервере, поставьте
restart: "no"и вызывайтеdocker compose run --rm hh responsesпо расписанию; - переменные
INTERVAL_HOURS,RUN_CHATS,VNC_PASSWORD,HH_AI_API_KEY,HH_TELEGRAM_TOKENзадаются вdocker/docker-compose.yml; - если hh разлогинил вас, повторите шаг 2. Логи, Excel и профиль браузера лежат в
hh-data/; - Ollama на том же сервере доступна из контейнера по адресу
http://host.docker.internal:11434/v1(на Linux добавьте в сервисextra_hosts: ["host.docker.internal:host-gateway"]).
Сборка приложения
Готовые архивы для всех систем лежат в релизах. Собрать самому:
PyInstaller собирает только под ту систему, на которой запущен: exe на Windows, .app на Mac, Linux-версию
на Linux. С Windows Linux-версию можно собрать в Docker. Сборщик сам создаёт окружение .venv-build, ставит
библиотеки и упаковывает архив. Всё для сборки лежит в папке packaging/.
| Что собрать | Где | Команда | Результат в dist/ |
|---|---|---|---|
| Windows | Windows | двойной клик по packaging\build.bat |
HH-Auto-Response-windows.zip |
| macOS | Mac | ./packaging/build-macos.sh |
HH-Auto-Response.app, HH-Auto-Response-macos-arm64.zip (или -x86_64 на Intel) |
| Linux | Linux | ./packaging/build.sh |
HH-Auto-Response-linux-x86_64.tar.gz |
| Linux | Windows или Mac с Docker | ./packaging/build-linux.sh |
HH-Auto-Response-linux-x86_64.tar.gz |
Перед сборкой на Windows закройте приложение, иначе открытый exe нельзя будет перезаписать.
На macOS нужен Python с Tk: brew install [email protected] [email protected]. На Linux нужны системные пакеты
python3 python3-venv python3-tk binutils. Портативные сборки Python (uv, conda, pyenv) часто идут с Tk
без Xft, и тогда в окне не будет кириллицы. Сборщик это проверяет и подскажет, что делать.
./packaging/build-linux.sh берёт Debian с правильным Tk, так что там всё в порядке.
Иконки лежат готовыми в packaging/ (icon.ico, icon.png, icon.icns), поэтому на всех системах
они одинаковые. Перерисовать: python packaging/make_icon.py.
Проверить готовую сборку можно командой HH-Auto-Response --self-test: она запускает браузеры и пишет
результат в logs/self_test.txt.
Версия приложения записана в одном месте, hh_auto/__init__.py. Её показывает окно, по ней сборка
называет архивы, с ней сравнивается версия релиза при проверке обновлений.
Что где лежит
| Папка | Что внутри |
|---|---|
hh_auto/ |
вся программа: поиск и отклики, чаты, нейросеть, окно, отчёт, обновление |
scripts/ |
точки входа: gui.py (окно), responses.py (отклики), chats.py (чаты), watch.py (фоновая проверка), raise_resume.py (поднять резюме), analyze_resume.py (анализ резюме), ai_test.py (песочница ИИ) |
packaging/ |
сборка приложения: build.bat, build.sh, build-macos.sh, build-linux.sh, настройки PyInstaller, иконки |
docker/ |
Dockerfile, entrypoint.sh и docker-compose.yml для сервера |
docs/ |
гайд по Ollama на другом компьютере, что нового в версии, скриншоты (светлые и dark/), баннер для GitHub (social-preview.png, тёмный — social-preview-dark.png) |
hh-data/ |
ваши данные при запуске из исходников и в Docker (в git не попадает) |
config.example.toml |
все настройки с пояснениями |
Сама программа, hh_auto/, разложена по папкам:
hh_auto/
├── app.py сценарии целиком: браузер → проверка доступа → вход → работа → итоги
├── core/ настройки, пути к данным, журнал, остановка, память о вакансиях, уведомления, обновление
├── web/ браузер и его окно, вход в hh, селекторы страниц hh
├── hh/ работа на hh.ru: выдача и фильтры, отклик, главный цикл, чаты, резюме, фоновая проверка
├── ai/ нейросеть (письма, анкеты, ответы в чатах, фильтр вакансий) и песочница «Проверка ИИ»
├── analysis/ анализ резюме: чтение файла, словарь навыков, вакансии рынка, оценка и советы
├── reports/ итоги откликов, таблица Excel, статистика по дням
└── ui/ окно программы, мини-окно, окна-сообщения, тема, свои виджеты
hh.ru и Россия
hh.ru работает только из России. Если вы за границей или сидите через VPN, добавьте hh.ru в исключения
VPN или укажите российский прокси: [geo] proxy = "http://user:pass@host:port". Перед стартом программа
показывает страну IP. При require_ru_ip = true она откажется запускаться с нероссийского IP.
Почему это легально
Коротко: программа делает то же, что вы сделали бы руками в своём браузере, только быстрее.
- Это ваш аккаунт и ваши действия. Вы сами входите в hh.ru, а программа нажимает те же кнопки, которые hh показывает вам. Отклик на вакансию — обычная функция сайта.
- Нет неправомерного доступа (ст. 272 УК РФ). Программа ничего не взламывает, не подбирает пароли и не заходит в чужие аккаунты.
- Это не вредоносная программа (ст. 273 УК РФ). Она не уничтожает, не блокирует и не копирует чужую информацию, а отправляет ваши отклики с вашим резюме.
- Защита не обходится. Капчу решаете вы. Чужие аккаунты, подмена личности и «накрутка» не используются.
- Персональные данные только ваши и хранятся у вас. Обработка данных физическим лицом для личных нужд под 152-ФЗ не подпадает (ч. 2 ст. 1). Нейросеть получает резюме без телефона и почты, а с Ollama данные вообще не покидают компьютер.
- Нагрузка как у человека: паузы между действиями и остановка на лимите hh, около 200 откликов в сутки. Резюме поднимается не чаще, чем это бесплатно разрешает сам hh, — раз в 4 часа, а фоновая проверка чатов и компаний мечты — не чаще раза в 15 минут.
Но «законно» и «разрешено правилами сайта» — не одно и то же. Пользовательское соглашение hh.ru может ограничивать автоматизацию. Нарушение правил сайта не преступление, а вопрос договора между вами и hh: в худшем случае аккаунт ограничат или заблокируют. Прочитайте соглашение и решите сами. Не ставьте слишком маленькие паузы и откликайтесь только на то, что вам правда подходит.
Это не юридическая консультация. За использование программы и соблюдение правил hh.ru отвечает пользователь.
Ограничения
- У hh лимит около 200 откликов в сутки. Когда hh сообщает о лимите, программа останавливается.
- Капчу программа не решает. После 10–15 откликов подряд hh может попросить её прямо вместо отклика. Тогда программа останавливается, выводит окно браузера вперёд и пишет «Нужна капча» (и присылает уведомление, если вы их разрешили). Решите капчу в окне браузера, и программа повторит ту же вакансию. Ждёт она до 30 минут. Если капча появляется часто, увеличьте паузы между вакансиями.
- После 5 ошибок подряд программа останавливается: скорее всего, hh поменял вёрстку или слетела сессия.
- Вакансии, которые открываются в отдельном окне, пропускаются.
- Если в окне отклика выбрано не то резюме, вакансия пропускается (
skip_on_resume_mismatch). - Сборки не подписаны, поэтому Windows и macOS при первом запуске предупреждают.
- Сборки для macOS и Linux собираются тем же сборщиком, но в бою я гонял в основном Windows.
Лицензия и участие
Проект распространяется под PolyForm Noncommercial License 1.0.0. Пользоваться программой, изучать и менять код, делиться им можно бесплатно в личных и других некоммерческих целях. Продавать программу или её части, встраивать в платные сервисы и использовать в коммерческих целях можно только с письменного разрешения автора.
Доработки приветствуются: сделайте форк и пришлите pull request. Как это устроено и на каких условиях принимается вклад, написано в CONTRIBUTING.md.






