Я разработал инструмент для автоматизации подбора специалистов. Основная его задача сократить время первичного отбора кандидатов за счет автоматического анализа резюме, GitHub-репозиториев и применения RAG(Retrieval-Augmented Generation) подхода.
Архитектура
Система построена из 5 модулей:
Backend: Python, FastApi (оркестрация пайпланов)
Frontend: TS, React
ChromaDB (хранение эмбеддингов и семантический поиск)
SQLite (хранение структурированных профилей для каждого резюме)
Mistral API (формирование эмбеддингов, анализ и переранжирование результатов)
Пайплайны
В инструменте используется всего 2 основных пайплайна: Indexing (Выполняется каждый раз для индексации новых резюме) и Search (Выполняется при каждом запросе о поиске кандидатов).

Процесс индексации резюме
Для индексации резюме система выполняет следующие этапы:
Извлекает текст из PDF
Разбивает его на чанки (текст делится на чанки по 500 символов с перекрытием 100 символов)
Генерация эмбеддингов (вызовом Mistral Embedding API получаем векторное представление каждого чанка)
Сохранение в ChromaDB (эмбеддинги и метаданные записываем в векторную базу данных)
Анализ GitHub репозиториев (если кандидат указывал ссылку на GitHub - система получает данные о репозиториях и примерах кода)
Формирование профиля (Mistral LLM формирует для каждого кандидата структурированный json профиль с основной информацией)
Многоэтапный поиск кандидатов
Главная фишка инструмента - двухэтапное ранжирование кандидатов.
1. Семантическая оценка
Преобразуем запрос пользователя в вектор, после чего в ChromaDB находим наиболее близкие фрагменты резюме по косинусному расстоянию.
best_chunk_distance - лучший чанк
avg_chunk_distance - среднее по файлу
Тем самым, получаем оценку семантической близости между запросом пользователя и резюме кандидата. Чем ниже значение, тем выше семантическое соответсвие.
2. Оценка LLM на основе контекста
Находим 10 лучших кандидатов на основе EmbeddingScore и получаем их профиля из SQLite, включая результаты анализа GitHub.
Одним вызовом LLM оценивает каждого кандидата от 1 до 10 с учетом:
Технического стека;
Релевантного опыта;
Проектов и достижений;
Качества кода на GitHub;
Архитектурных навыков.
И подставляем все в итоговую формулу:
Чем ниже финальный результат, тем выше соответствие кандидата с запросом. Таким образом, система объединяет семантический поиск с оценкой LLM на основе контекста.
Интеграция GitHub анализа
Такой же уникальной фичей является интеграция анализа кода кандидата через MCP (Machine Communication Protocol)
Во время анализа система:
Извлекает ссылки на GitHub из резюме;
Получает README и структуру проектов;
Анализирует примеры кода;
Оценивает качество архитектуры, используемые паттерны и уровень владения технологиями;
Добавляет результаты в поле github_analysis профиля.
Это позволяет нам сравнивать реальный код кандидата с заявленными навыками в резюме.
Q&A по базе кандидатов
Помимо поиска кандидатов инструмент также может отвечать на любые вопросы по базе с резюме.
Например:
«Сколько кандидатов на данный момент имеют высшее образование?» или «Приведи краткое описание всех кандидатов владющих тем или иным навыком»
В этом режиме мы извлекаем все профиля и анализируется одним вызовом LLM, который формирует формирует ответ.
Количество вызовом к API Mistral
1. При индексации:
~5-10 Вызовов эмбеддингов (зависит от длины резюме).
1 Вызов анализа GitHub (если найдена ссылка).
1 Вызов создания профиля.
Итого: ~7-12 вызовов на одно резюме.
2. При поиске:
1 Вызов валидации (проверка релевантности LLM).
1 Вызов эмбеддинга.
1 Вызов переранжирования (оценка llm на основе контекста).
3 Вызова объяснения (по одному на каждого топового кандидата).
Итого: 6 вызовов Mistral API на один запрос.
3. При Q&A режиме:
1 вызов LLM (все профили + вопрос = ответ).
Итого: 1 вызов Mistral API на один вопрос.
Лимиты Mistral
По дефолту в инструменте используется:
Mistral small ($0.15/1M input токенов и $0.6/1M output) для вопросов по базе и оценки по контексту.
Mistral embedding ($0.15/1M токенов) для всех эмбеддингов.
За все время разработки и тестировки инструмента я потратил:
Mistral small - Input tokens: 624.568 и Output tokens: 34.189.
Mistral embedding - Input tokens: 736.280
Это все с учетом того, что я на этапе тестировки по неосторожности закинул книгу около 150 страниц вместе со всеми резюме и где то раз 10 полностью ее проиндексировал)
Исходя из этого если мы будем хранить около 200 резюме то его 2-3 месячного стоимость интенсивного использования не будет превышать 30 центов.
Интерфейс
Для удобного пользования инструментом я создал простенькую страницу состоящую из двух чатов по бокам экрана: слева - ищем подходящих кандидатов, справа - задаем вопросы по базе с резюме.

Главный результат
Главным результатом стало объединение векторного поиска, RAG подхода и анализа кода с GitHub в едином полностью рабочем инструменте, который сможет сильно облегчить анализ большого количества резюме.
Репозиторий проекта: https://github.com/alexcfv/ai-recruiter-assistance