Я автоматизировал поиск работы, сделал 553 отклика за три недели и сходил на собеседования
В сентябре я начал искать работу, роль COO или CTO, или DevRel и тд. И сделал то, что делаю со всеми своими задачами: отдал рутину агентам.
За три недели мои агенты нашли 10 687 вакансий в 2 204 компаниях и довели 553 отклика до кнопки «отправить». Из них мне были назначены 3 собеседования, которые я прошел.
Если честно, я в шоке как устроен найм в 2026 году: с обеих сторон стола сидят роботы
Как выглядит найм.
Раньше я представлял поиск работы так: нашёл вакансию, отправил резюме, получил ответ. Теперь между мной и живым человеком на той стороне — три слоя автоматики.
Первый слой это системы приема откликов, ATS. Почти все отклики ушли в две системы: Greenhouse и Ashby — это 96% всех отправленных откликов
Второй слой это защита этих систем от ботов: коды на почту, капчи, проверка, что форму заполнял человек.
Третий слой это вопросы в форме, на которые никак не ответить шаблоном. Именно на них держится большая часть отбора ещё до того, как резюме увидит рекрутер.
Я строил автоматизацию под первый слой, но, само собой, сложности во втором и третьем
Откуда берутся вакансии и где их искать самому
Никакого волшебства в поиске вакансий, конечно же, нет: почти все компании держат вакансии в какой-то из систем найма, и у каждой из них есть открытый адрес, который отдаёт список вакансий обычным текстом. Ни логина, ни ключа, ни браузера не нужно.
Вот эти адреса, подставьте вместо скобок имя компании:
Greenhouse https://boards-api.greenhouse.io/v1/boards/{company}/jobs
Ashby https://api.ashbyhq.com/posting-api/job-board/{company}
Lever https://api.lever.co/v0/postings/{company}?mode=json
Workable https://apply.workable.com/api/v1/widget/accounts/{company}
SmartRecruiters https://api.smartrecruiters.com/v1/companies/{company}/postings
Имя компании берётся из адреса её страницы с вакансиями. Сейчас в карте 397: Ashby 206, Greenhouse 139, Lever 42, Workable 9, SmartRecruiters 1. Список я собрал автоматически и каждую такую доску проверил живым запросом, про способ проверки — чуть ниже.
Второй класс источников — это агрегаторы. Они дают вакансии компаний, чьих досок я не знаю, и именно там — половина вакансий, которую ты по-другому быстро не найдешь:
Himalayas https://himalayas.app/jobs/api
Remotive https://remotive.com/api/remote-jobs
Jobicy https://jobicy.com/api/v2/remote-jobs
Arbeitnow https://www.arbeitnow.com/api/job-board-api
RemoteOK https://remoteok.com/api
Плюс два потока новостями: вакансии с Hacker News из ежемесячной ветки «Who is hiring» и русскоязычные Telegram-каналы с вакансиями.
Не получилось (пока) у меня настроить сбор информации с Reddit, он без регистрации приложения отвечает отказом, у ai-jobs.net публичного потока я не нашёл, и не получилось (опять же, надеюсь, пока) с CryptoJobsList Но все такие источники я записываю в отдельный список, чтобы к ним потом вернуться
Дальше всё, что пришло, проходит два простых фильтра без LLM. Первый по названию должности: каждое название получает оценку по словам, и если совпадений с моими ролями нет, вакансия не сохраняется. Второй по географии: позиции, где требуется присутствие в стране, куда я не поеду, я сразу вычеркивал.
Сколько чего пришло:
|
источник |
объявлений |
|---|---|
|
Greenhouse |
4 265 |
|
Ashby |
3 143 |
|
Himalayas |
1 193 |
|
Telegram-каналы |
877 |
|
Lever |
471 |
|
Arbeitnow |
386 |
|
Jobicy |
145 |
|
Hacker News |
129 |
|
Workable |
67 |
|
RemoteOK |
11 |
За три недели так набралось 10 687 объявлений от 2 204 компаний. Из них 7 946 это вакансии на настоящих платформах, страницах, куда можно подать отклик, а остальные 2 741 пришли с агрегаторов, из Telegram и с Hacker News, где формы обычно нет и её ещё надо отдельно найти на сайте компании.
Как я искал компании, в которых могли быть вакансии
У Greenhouse, Ashby и Lever есть открытые доски: список вакансий компании оттуда забирается обычным запросом, без браузера. Но чтобы такой запрос сделать, нужен адрес доски, а в нём помещено короткое имя компании.
У Lever это выглядит как api.lever.co/v0/postings/<имя>, у Greenhouse как boards-api.greenhouse.io/v1/boards/<имя>. Имя почти никогда не совпадает с названием компании: бывает без пробелов, бывает со старым названием до ребрендинга, бывает вообще внутреннее.
Сначала я делал наверное самое простое: брал название компании, делал из него несколько вариантов имени и пробовал каждый. Это работает, но есть ограничения, которые я сам не сразу увидел — я проверял только компании, которые были в моей голове, на слуху и тд.
Потом до меня дошло, что эти адреса лежат в открытом коде всего мира. Компания вставляет ссылку на свою доску на собственный сайт, кто-то пишет парсер вакансий и оставляет адрес в примере, кто-то делает себе такую же машинку и складывает список компаний в репозиторий.
То есть искать надо не по названиям компаний, а по самой строке адреса. Поиск по коду GitHub умеет это прямо из командной строки.
# запрос к поиску по коду → достаёт имя компании из найденного куска
QUERIES = [
("lever", '"api.lever.co/v0/postings"',
r"api.lever.co/v0/postings/([A-Za-z0-9._-]{2,40})"),
("greenhouse", '"boards-api.greenhouse.io/v1/boards"',
r"boards-api.greenhouse.io/v1/boards/([A-Za-z0-9._-]{2,40})"),
("ashby", '"api.ashbyhq.com/posting-api/job-board"',
r"api.ashbyhq.com/posting-api/job-board/([A-Za-z0-9._-]{2,40})"),
]
Дальше четыре шага:.
Первый: у поиска надо попросить сами куски кода, а не только имена файлов. Без фрагмента совпадения имя компании из ответа не получить, потому что оно — внутри строки, а не в названии файла.
Второй: выкинуть весь мусор. В примерах кода вместо настоящего имени стоит test, demo, acme, your_company, и таких совпадений находится много.
Третий: сверить с тем, что я уже знаю, и не проверять это заново.
Четвертый: сделать живой запрос к каждому. Ко мне в итоге попадают только те, кто ответил непустым списком вакансий, всё остальное уходит в отдельный список (список отбракованных)
Про третий шаг. Сначала я сверял то, что нашел, только со списком досок, которые и так мониторил, но этого недостаточно В один из моих таких прогонов из 189 найденных живых досок 121 оказалась теми, которые я неделю назад уже проверял, и они — пустые… Поэтому теперь у меня идет сверка с двумя списками: и с тем, что я мониторю, и с тем, что уже было отбраковано.
Сейчас в карте 397 живых досок и 196 отбракованных.
Сколько откликов я сделал в результате за это время
Первое, на чём я ошибся, это масштаб. В базе было 9 447 открытых вакансий в 2 133 компаниях, и я посчитал, что это и есть весь мой список
Но у крупных компаний одна доска это сотни позиций. У одной компании было 423 открытые вакансии, у другой 247. Подаваться в одну компанию сорок раз это спам, а не поиск работы.
Поэтому у меня стоит потолок: не больше двух откликов в одну компанию. После него реальная очередь сжалась с 9 447 до 2 707, то есть в 3,5 раза.
-- очередь откликов: не больше двух на компанию, лучшие по оценке
SELECT url, company, title, score
FROM (
SELECT *,
ROW_NUMBER() OVER (
PARTITION BY company
ORDER BY score DESC
) AS rank_in_company
FROM ats_jobs
WHERE status = 'new'
)
WHERE rank_in_company <= 2
ORDER BY tier = 'vip' DESC, score DESC;
Оценка вакансии считается без LLM: совпадение роли с одним из моих профилей, локация, уровень позиции. Модель я подключаю позже, когда нужно ответить на вопросы формы.
16 резюме вместо одного
Одним резюме на все вакансии не откликнешься. Роль в продукте, в работе с клиентами и в развитии экосистемы — это разные оттенки опыта, и рекрутер в каждом резюме ищет только то, что релевантно его компании
Я разделил вакансии на 16 типов и под каждый тип у меня есть отдельная версия резюме. Все версии собираются из одного моего файла с фактами биографии: я поправляю какую-то информацию в нем один раз, а дальше скрипт пересобирает все резюме и лендинг.
По каждому типу у меня отдельная сессия с агентом. Он описывает, как выглядит идеальный кандидат на такую роль, я сверяю это со своим опытом и дорабатываю резюме.
Как агент заполняет форму
Сама подача моих резюме устроена следующим образом: браузер под управлением скрипта открывает форму, заполняет поля и нажимает «отправить».
Обычные поля (имя, почта, ссылки, резюме) заполняются из профиля. Для вопросов у меня есть банк канонических ответов: право на работу, готовность к переезду, часовой пояс, откуда узнал о вакансии.
Всё, чего нет в банке, агент не придумывает, он отправляет вопросы мне, и я считаю это правильным. Пока. В дальнейшем автоматизирую и это
Где всё останавливается
Робот открыл 1 127 форм. 553 из них дошли до кнопки «отправить», 575 остановились на полпути (остальные вакансии из базы просто еще ждут своей очереди)
|
причина остановки |
форм |
|---|---|
|
вопрос без канонического ответа |
383 |
|
капча на отправке |
132 |
|
форма вернула ошибку |
29 |
|
нажал «отправить», подтверждения нет |
23 |
|
прочее (дубль, аккаунт, код из письма) |
8 |
⅔ таких стопов — это вопросы, которые требовали моего внимание. Часто такие:
-
годовая зарплата в конкретной валюте, числом, без диапазона;
-
тестовое задание, ссылку на которое надо вставить прямо в форму;
-
есть ли у вас или ваших близких родственников интерес в компании-конкуренте или связь с кем-то из её сотрудников;
-
даты окончания каждого места работы, отдельными полями.
Выводы я тут делаю о том, что формы — это те еще двери. В них надо уметь проходить.
Экран «Спасибо за отклик»
Еще один вывод был о том, что влияло на мою статистику
Первую неделю я считал отклик отправленным, если форма показывала «Спасибо, ваш отклик принят». Потом уже сверил это с подтверждением, которое высылается на почту. На самом деле, доказательство подачи — это письмо-подтверждение от ATS, а экран про “спасибо за отклик” показывается и в случаях, когда резюме не дошло
Я сейчас у каждого отклика ставлю отметку, чем он доказан:
|
чем доказан отклик |
откликов |
|---|---|
|
письмо-подтверждение от ATS |
188 |
|
только экран успеха формы |
144 |
|
пока ничем (старые записи, сверка идёт) |
221 |
Сверку у меня делает отдельный скрипт без обращений к LLM. Он идёт по отметкам в базе и ищет для каждой письмо в почте:
def verdict(job, emails):
"""Чем доказан отклик: письмом ATS, а не экраном формы."""
mine = [e for e in emails
if job.company.lower() in (e.subject + e.sender).lower()
and e.date >= job.applied_at]
if any(is_confirmation(e) for e in mine):
return "PROVEN" # письмо «Thank you for applying» пришло
if any(is_security_code(e) for e in mine):
return "STALLED" # система прислала код, форма его не получила
return "NO_PROOF" # подавать заново
Отдельно надо принимать в расчет мелочи. Например, название компании иногда стоит не в теме письма, а только в поле отправителя. А письма «новый вход в аккаунт» похожи на подтверждения, но ими, конечно, не являются.
Какие у меня результаты
За три недели картина такая:
|
что |
сколько |
доля от откликов |
|---|---|---|
|
откликов дошло до отправки |
553 |
100% |
|
отказов |
79 |
14% |
|
собеседований (компаний) |
3 |
0,5% |
|
пока без ответа |
470 |
85% |
Три собеседования из 553 откликов выглядят плохо, но тут важно обратить внимание на то, в каких компаниях эти собеседования
Все три собеседования дали вакансии так назовем «массового» уровня: компании среднего размера. В «VIP»-уровень, крупные лаборатории, я отправил 63 отклика и получил 10 отказов и пока ни одного собеседования.
И все эти три собеседования на вакансии инженера, который работает прямо у клиента (forward deployed engineer), и на работу с сообществом разработчиков (DevRel). По продуктовым ролям, куда отправилось больше всего откликов, собеседований пока ноль.
Для меня это полезный вывод. Автоматизация показала, в какую дверь рынок меня пускает, а в какую нет.
Во что превратился найм
Теперь я смотрю на найм конечно иначе, чем месяц назад.
Отклик стал почти бесплатным и массовым. Роботом его можно отправить за минуту, и именно поэтому компании защищаются: капчами, кодами на почту, вопросами, на которые нельзя ответить по шаблону
Отбор сдвинут с резюме в форму. Вопросы про зарплату, родственников и тестовое задание — это первый отсев, отбор еще до того, как на кандидата обратит внимание живой человек из компании
Экран «спасибо» не гарантирует получение резюме.
И главное: всё, что робот делает до кнопки «отправить», стало быстрым и дешёвым.
Сейчас я жду вторых этапов собеседований и продолжаю свой поиск работы.
Автор: Antondz

