Moneymaker

Automation

Автоотклик на HH.ru: агент в Telegram с ручным approval

23 СЕН 2026 · 6 МИН ЧТЕНИЯ

hhtelegrampythonllmautomation

Мониторить свежие вакансии на HH вручную утомляет: одни и те же запросы, десятки карточек, половина мимо. Нужен помощник, который сам обойдёт выдачу, отсечёт явный мусор по заголовку и пришлёт в Telegram то, на что стоит взглянуть — а отклик отправит только после вашего решения. Платных сервисов «автоотклика на HH.ru» хватает — здесь тот же класс задачи, только код открытый и без подписки.

Я взял открытый hh-ai-agent и сделал форк hh-ai-agent-advance. Скрипт универсальный: подставляете свои запросы, резюме и стоп-слова — подойдёт разработчику, аналитику, маркетологу, SEO и любой другой специальности. Ниже — порядок работы, настройка и использование; в примерах — SEO-вакансии, потому что так настроен мой рабочий профиль.

Важное отличие от апстрима: в оригинале на каждую вакансию вызывается LLM («подходит / не подходит» + часто сразу письмо). На reasoning-моделях это быстро сжигает бюджет. В форке цикл поиска не ходит в модель. Письмо генерируется только по кнопке в Telegram, когда вакансия вам уже интересна.

→ github.com/google-dad/hh-ai-agent-advance

«Автоотклик» здесь = автоматический поиск и превью + отклик только после вашей кнопки. Массовой рассылки без участия человека нет — и это сознательно.

Порядок работы

  1. По списку search_queries агент ищет свежие вакансии на HH.
  2. Заголовок проходит локальный фильтр (стоп-слова, ваши исключения, маркеры роли).
  3. Браузер открывает карточку, читает описание и рейтинг компании.
  4. В Telegram приходит превью.
  5. Вы жмёте «Сгенерировать письмо» (LLM) → при необходимости правите текст → «Откликнуться» или «Пропустить».

На карточке без письма две кнопки: «Сгенерировать письмо» и «Пропустить». После генерации — текст письма и «Откликнуться» / «Изменить письмо» / «Пропустить».

Карточки вакансий в Telegram: кнопки «Сгенерировать письмо» и «Пропустить»

Рис. 1. Превью без письма. Внизу клавиатура: Пауза, Продолжить, Отклики, Ожидают.

Реальный отклик возможен только при трёх условиях сразу: режим approval, флаг ENABLE_REAL_APPLY=true и нажатие кнопки вашим Telegram ID.

Почему LLM не оценивает каждую вакансию

Допустим, за цикл нашлось ~40 вакансий по запросам, после фильтра заголовка осталось ~12 карточек, письмо вы запросили по 3.

Подход Вызовы LLM Итог по токенам
Оценка + письмо на каждую ~40 оценок и часто письма сразу дорого, особенно на reasoning-моделях
Этот форк 0 оценок в цикле + письма по кнопке токены только на выбранные отклики

Фильтр и просмотр глазами закрывают основной отсев. Модель нужна для текста письма, а не для сотен авто-вердиктов suitable.

Установка

Нужны: Python 3.11+, Telegram-бот и ваш User ID, браузер (CloakBrowser или Playwright), LLM — если будете генерировать письма (Ollama / Mistral / OpenAI-compatible вроде Together).

git clone https://github.com/google-dad/hh-ai-agent-advance.git
cd hh-ai-agent-advance
py -3.12 -m venv .venv
.\.venv\Scripts\activate
pip install -r requirements.txt
python setup_wizard.py
python main.py --check-config
python main.py --check-llm
python main.py

Wizard создаст локальные .env и profile.yaml (в Git их нет). Правки позже: python setup_wizard.py --edit или руками в YAML.

Режимы:

Режим Поведение
dry_run Поиск и карточки без кнопок отклика — начните с него
approval Можно генерировать письмо и откликаться после вашей кнопки

Telegram-бот

Бот — отдельный аккаунт в Telegram, через который скрипт шлёт карточки. Создаётся один раз, токен и ваш User ID попадают в .env.

  1. Откройте @BotFather и отправьте /newbot. Задайте отображаемое имя и username (должен заканчиваться на bot). В ответ придёт токен вида 123456789:AA....
  2. Узнайте свой числовой User ID: напишите что угодно @userinfobot. Это не username — бот отвечает числом.
  3. Привяжите бота к скрипту. python setup_wizard.py спрашивает токен и User ID и записывает их в локальный .env. Вручную — те же поля:
TG_BOT_TOKEN=123456:your_bot_token
TG_USER_ID=your_numeric_id
  1. Запустите python main.py и напишите своему боту /start. Карточки и кнопки отклика принимает только этот TG_USER_ID: чужой чат с ботом отклик не отправит.

Повторная правка токена или ID: python setup_wizard.py --edit. Файл .env в git не коммитьте.

Настройка profile.yaml

Специальность задаётся не «режимом SEO», а содержимым профиля: запросы поиска, резюме, стоп-слова, текст о себе для писем.

Обязательное

Поле За что
candidate.name Имя в промпте письма
candidate.desired_positions Целевые роли для письма (не строки поиска HH)
candidate.experience_summary Опыт — основной блок фактов для LLM
hh.resume_name Точное имя резюме в селекторе HH при отклике
hh.search_queries Запросы, по которым агент ищет вакансии

Поиск и отсев

Поле За что
hh.areas ID регионов HH (1 Москва, 2 СПб). [] — без геофильтра. Не писать «Москва» текстом
hh.experience_filters noExperience / between1And3 / between3And6 / moreThan6 или [] = любой опыт
candidate.work_format Если есть «удалённо» или remote — в поиск уходит schedule=remote
candidate.excluded_positions Доп. стоп-слова в заголовке (стажёр, junior, нерелевантные роли)
cover_letter.max_length Лимит символов письма (у HH поле до ~10 000)
cover_letter.language / style Язык и тон письма

Полный список полей — в README и в profile.example.yaml с комментариями.

Фильтр заголовка в коде (vacancy_filter.py) по умолчанию заточен под маркеры SEO-ролей и типовой «мусор» (SMM, таргет, продажи…). Для другой специальности:

  1. пропишите свои search_queries и excluded_positions в профиле;
  2. при необходимости поправьте списки ROLE_KEYWORDS / BLOCK_WORDS в vacancy_filter.py под ваши маркеры роли (иначе заголовки без этих маркеров уйдут в no-role).

Пример: SEO (мой профиль)

Фрагмент идей для profile.yaml (без персональных данных и секретов):

candidate:
  desired_positions:
    - "SEO-специалист"
    - "SEO Team Lead"
    - "Линкбилдер"
  work_format:
    - "удалённо"
  excluded_positions:
    - "Junior SEO"
    - "Стажёр"
    - "SMM-менеджер"
    - "Таргетолог"

hh:
  resume_name: "SEO-специалист"
  search_queries:
    - "SEO-специалист"
    - "SEO Team Lead"
    - "линкбилдер"
    - "техническое SEO"
    - "PBN"
  areas: []
  experience_filters: []

cover_letter:
  language: "ru"
  max_length: 8000
  style: "professional"

Для другой роли меняете запросы и стоп-слова, например: Python developer, аналитик данных, продуктовый менеджер — та же схема.

LLM для писем

На отбор в цикле поиска модель не влияет. Нужна для кнопки «Сгенерировать письмо», /keys и --check-llm.

  • Ollama — локально, без облачных ключей
  • Mistral / OpenAI-compatible (Together, Groq…) — пул ключей через /keys в Telegram

Пример Together в .env (значения — плейсхолдеры):

LLM_PROVIDER=openai_compatible
LLM_MODEL=openai/gpt-oss-120b
OPENAI_COMPATIBLE_BASE_URL=https://api.together.xyz/v1
OPENAI_COMPATIBLE_API_KEY=your_key
LLM_KEYS_MASTER_KEY=your_fernet_master_key
LLM_TIMEOUT_SECONDS=90
LLM_MAX_OUTPUT_TOKENS=4000

У reasoning-моделей часть токенов уходит во внутренние рассуждения — для писем держите LLM_MAX_OUTPUT_TOKENS с запасом (~3500–4000).

Использование день за днём

  1. Запускаете python main.py, в HH при необходимости логинитесь (BROWSER_HEADLESS=false).
  2. Ждёте карточки в Telegram (/status, /diagnostics — состояние цикла).
  3. Ненужное — «Пропустить». Интересное — «Сгенерировать письмо», читаете, правите, «Откликнуться».
  4. Пауза поиска: /pause / /resume. Очередь решений: /pending.

Если карточек нет: логи — отсев по заголовку, дубли в agent.db, пауза, circuit breaker. Перед «чистым» прогоном остановите агент и сделайте backup базы.

Команды: /start, /status, /pause, /resume, /pending, /stats, /diagnostics, /keys, /cancel.

Кому подойдёт — и когда нет

Подойдёт, если вы:

  • любой специальности и готовы один раз настроить запросы и фильтр под себя;
  • хотите автопоиск и превью в Telegram, а отклик — под контролем;
  • не хотите жечь LLM на оценку каждой строки выдачи;
  • ок с Python и браузерной автоматизацией.

Не подойдёт, если нужно:

  • полностью безголовая массовая рассылка откликов;
  • гарантия обхода детекта, CAPTCHA и ограничений HH;
  • замена чтению вакансии и письма перед отправкой.

Автоматизация HH.ru может нарушать правила сервиса. Риск для аккаунта — на вас. Используйте как ассистента с approval, не как пушку по рынку.

Ссылки

Токены Telegram, API-ключи и личный profile.yaml держите вне git. В статье секретов нет.

Связанное

Связанные Tools

HH AI Agent — Python-агент для HH.ru — поиск вакансий, превью в Telegram и отклик только после вашей кнопки.