Каждые несколько часов парсер обходит публичную ленту Habr Career по AI-запросам, дедуплицирует находки и прогоняет каждую новую вакансию через free-LLM в JSON-mode: категория, грейд, стек, оценка зарплаты. Результат — фильтруемая лента ниже плюс еженедельный markdown-дайджест. Адаптер hh.ru есть в коде, но в v1 выключен: с 2026 года их API требует OAuth-токен.
Фильтры
Как это работает
Простая идея. Представьте, что у вас в подписках открыто 10 досок с вакансиями, и каждое утро вы их пробегаете глазами в поисках AI-вакансий. Парсер делает то же самое, только без вас: ходит по публичной RSS Habr Career каждые несколько часов, складывает свежие вакансии в собственную базу, не дублируя одну и ту же ссылку, и просит free-LLM расставить ярлыки — «это AI-инженер middle, стек python+rag+langchain, зарплата выше среднего». Готовая лента — внизу, с фильтрами.
- Источник сейчас один: публичная RSS Habr Career
career.habr.com/vacancies/rss. Адаптер для официального API api.hh.ru написан и лежит в коде, но в v1 выключен — с 2026 года их API на чтение тоже требует OAuth-регистрацию приложения. Telegram-каналы и geekjob — в roadmap. - Каждая найденная вакансия сохраняется в Postgres (одна таблица
parser_vacancies). Дедупликация — по уникальномуsource_url: одна вакансия не классифицируется дважды. - Раз в N часов (по умолчанию 4) runner просыпается, фетчит все запросы со всех адаптеров с вежливой паузой 600ms между запросами, потом берёт до 25 неклассифицированных вакансий и шлёт каждую free-LLM через OpenRouter с
response_format: json_object. Невалидный JSON помечается ошибкой и пробуется ещё раз на следующем тике. - Cost guard: дневной бюджет 200 LLM-вызовов (UTC-сутки). Если он исчерпан — новые вакансии лежат непомеченные до следующих суток. Счётчик виден в шапке.
- Полные тексты вакансий не сохраняются — только заголовок, работодатель, зарплата, ссылка и AI-сводка. Хотите подробности — ссылка ведёт на оригинал.
Стек и ограничения
- Хранилище: Postgres рядом с RAG/flow/assistant. Тот же отход от изначального плана (SQLite), что и в Flow: ради двух таблиц не хочется заводить native-модуль на VPS.
- Расписание: in-process
setIntervalв том же Node-процессе, что обслуживает остальные агенты. Без systemd-timer-а — единый деплой, единые логи, единый рестарт. - Источники в v1: career.habr.com RSS (активный) и hh.ru API (выключен — 403 без OAuth). Если адаптер упал — остальные продолжают работать; ошибка пишется в
parser_runs.errors, видна оператору. Чтобы вернуть hh.ru — зарегистрировать приложение наdev.hh.ru/admin, добавить access_token в адаптер и вернуть «hh» вparser-queries.json. - Классификатор: free-LLM из OpenRouter в JSON-mode + fallback-модель при сбое. Категории, грейды, salary-band — фиксированные ENUM-ы, всё, что вне списка, нормализуется до значений-дефолтов.
- Что НЕ делает в v1: не парсит полный текст вакансий, не пишет работодателю, не сохраняет резюме посетителя, не интегрируется с Telegram-каналами через скрейпинг
t.me/s/. Это всё — отдельные кейсы.