Разработка AI-агента для HR (скрининг резюме, ответы кандидатам)
AI-агент для HR автоматизирует массовые задачи: первичный скрининг резюме по критериям вакансии, ранжирование кандидатов, автоматические ответы, назначение интервью, сбор обратной связи. Это снижает нагрузку рекрутеров и сокращает time-to-hire при сохранении качества отбора.
Компоненты HR-агента
from pydantic import BaseModel
from typing import Optional, Literal
from openai import OpenAI
import json
client = OpenAI()
class CandidateScreeningResult(BaseModel):
candidate_id: str
overall_score: int # 0-100
hard_skills_match: int # % соответствия hard skills
experience_match: int # % соответствия опыту
red_flags: list[str] # Стоп-факторы
green_flags: list[str] # Сильные стороны
recommendation: Literal["strong_yes", "yes", "maybe", "no"]
next_step: str
personalized_rejection_reason: Optional[str]
def screen_resume(
resume_text: str,
job_description: str,
required_skills: list[str],
nice_to_have: list[str],
) -> CandidateScreeningResult:
"""Скрининг резюме относительно требований вакансии"""
response = client.beta.chat.completions.parse(
model="gpt-4o",
messages=[{
"role": "system",
"content": """Ты — опытный рекрутер. Объективно оцени соответствие кандидата вакансии.
НЕ делай допущений — если опыт не указан явно, считай его отсутствующим.
Будь честен в оценке стоп-факторов."""
}, {
"role": "user",
"content": f"""Вакансия:
{job_description}
Обязательные навыки: {required_skills}
Желательные навыки: {nice_to_have}
Резюме кандидата:
{resume_text}"""
}],
response_format=CandidateScreeningResult,
temperature=0,
)
return response.choices[0].message.parsed
Автоматические ответы кандидатам
def generate_candidate_response(
candidate_name: str,
decision: str,
position: str,
feedback: str = None,
) -> str:
"""Персонализированный ответ кандидату"""
templates = {
"invite_interview": f"""Уважаемый(ая) {candidate_name},
Благодарим за интерес к позиции {position}. Ваш опыт показался нам интересным, и мы хотели бы пригласить вас на интервью.
Доступные слоты: [CALENDAR_LINK]
Интервью займёт около 45 минут. Формат — видеозвонок.
С уважением, команда рекрутинга""",
"rejection": None, # Генерируем персонализированно
}
if decision == "rejection" and feedback:
response = client.chat.completions.create(
model="gpt-4o-mini",
messages=[{
"role": "system",
"content": "Напиши вежливый отказ кандидату. Тон: уважительный, без клише типа 'вы нам не подходите'. Укажи конкретную причину (без унизительных формулировок)."
}, {
"role": "user",
"content": f"Кандидат: {candidate_name}, Позиция: {position}, Причина: {feedback}"
}],
)
return response.choices[0].message.content
return templates.get(decision, "")
Пайплайн массового скрининга
import asyncio
from typing import List
async def batch_screen_resumes(
resumes: List[dict],
job_description: str,
required_skills: List[str],
concurrency: int = 10,
) -> List[dict]:
"""Параллельный скрининг нескольких резюме"""
semaphore = asyncio.Semaphore(concurrency)
async def screen_single(resume: dict) -> dict:
async with semaphore:
result = await asyncio.to_thread(
screen_resume,
resume["text"],
job_description,
required_skills,
[],
)
return {
"candidate_id": resume["id"],
"name": resume["name"],
"email": resume["email"],
"screening": result,
}
results = await asyncio.gather(*[screen_single(r) for r in resumes])
# Сортируем по score
return sorted(results, key=lambda x: -x["screening"].overall_score)
Практический кейс: массовый найм колл-центра
Задача: найм 80 операторов колл-центра за 3 месяца. Входящий поток — 600+ резюме в неделю. Рекрутер один.
Критерии скрининга: опыт работы с клиентами (обязательно), грамотная письменная речь (обязательно), знание CRM (желательно), готовность к ночным сменам (обязательно).
Пайплайн агента:
- Парсинг входящих резюме с hh.ru/Авито (API)
- Скрининг через LLM (50 резюме за 8 минут vs 4 часа вручную)
- Топ-30% → приглашение на телефонный скрининг
- Отказы → персонализированный ответ автоматически
- После скрининга → назначение личного интервью (Calendly интеграция)
Результаты:
- Время скрининга 100 резюме: 4.5ч (вручную) → 18мин (агент)
- Concordance rate (агент vs рекрутер): 89% (проверено на 200 совместно оцененных)
- Доля ложных отказов (qualified rejected): 4.1%
- Time-to-hire: 42 дня → 28 дней
- Рекрутер фокус: переключился на интервью и onboarding
Юридическое ограничение: финальное решение о найме — за человеком. Агент делает рекомендацию, рекрутер подтверждает.
Anti-bias фильтрация
ANTI_BIAS_PROMPT_ADDENDUM = """ВАЖНО: При оценке:
- НЕ учитывай имя, пол, возраст (если указан), национальность
- Оценивай только профессиональные компетенции и опыт
- Не делай допущений на основе личных данных
- Применяй одинаковые критерии ко всем кандидатам"""
Сроки
- HR-агент скрининга: 2–3 недели
- Интеграция с hh.ru/job board API: 1–2 недели
- Автоматические ответы + calendar: 1 неделя
- Calibration с рекрутером: 1–2 недели
- Итого: 5–8 недель







