Создание агента для оценки кандидатов на роль в области ИИ на Python с использованием FastAPI и Pydantic
Превращайте сырые потенциальные клиенты в квалифицированных: структурированный извлечение с помощью LLM, проверка с использованием Pydantic, оценка на основе правил, хранение в PostgreSQL, очереди и этап ручного рассмотрения.
Источники: I Built an AI Lead Filtering Agent in Python — From Raw Leads to Qualified Customers
У большинства компаний нет проблем с нехваткой потенциальных клиентов. Их сложность заключается в их отборе. Сотни запросов могут поступать через формы на сайте, рассылки по электронной почте и инструменты маркетинга, и кому-то всё равно приходится открывать каждый из них, читать сообщение, понимать, чего хочет клиент, проверять бюджет и решать, заслуживает ли он внимания. По мере увеличения объёма такая ручная обработка становится дорогостоящей.
Практический вопрос заключается в том, может ли ИИ-агент принимать поступающие запросы, понимать их цель, проверять их согласно бизнес-правилам и направлять подходящие в отдел продаж. Это возможно, но не путём простого ввода каждого запроса в большую языковую модель и доверия к её ответу. Надёжная система требует структурированного вывода, чётких правил, верификации, хранения данных и правильного рабочего процесса. В следующих разделах показано, как создать такую систему на Python.
Что делает система
Процесс прост: поступает потенциальный клиент, система интерпретирует его запрос, оценивает его, сохраняет результат и запускает следующий шаг.
Вот сообщение от потенциального клиента:
«Нашей команде продаж нужен CRM на заказ, примерно на 30 пользователей, с доставкой в течение двух месяцев. Сколько это примерно будет стоить?»
Человек сразу выделит несколько ключевых моментов:
- существует четкая бизнес-потребность
- проект представляет собой индивидуальное программное решение
- в команде примерно 30 пользователей
- есть сроки доставки
- важен вопрос стоимости
Агент должен выделить те же факты и помочь отделу продаж решить, что делать дальше. Он не должен предполагать, что каждое подробное сообщение является хорошим потенциальным клиентом. Необходимо оценивать информацию с учетом реальных критериев отбора компании.
Архитектура
Планируемый рабочий процесс показан ниже:
┌──────────────────┐
│ Incoming Lead │
│ Website / Email │
└────────┬─────────┘
│
▼
┌──────────────────┐
│ Lead Ingestion │
│ Validate & Store │
└────────┬─────────┘
│
▼
┌──────────────────┐
│ AI Extraction │
│ Intent, Need, │
│ Budget, Timeline │
└────────┬─────────┘
│
▼
┌──────────────────┐
│ Business Rules │
│ Qualification │
└────────┬─────────┘
│
▼
┌──────────────────┐
│ Lead Scoring │
│ Qualified / │
│ Review / Reject │
└────────┬─────────┘
│
▼
┌──────────────────┐
│ PostgreSQL │
│ Store Result │
└────────┬─────────┘
│
▼
┌──────────────────┐
│ Automation │
│ CRM / Email / │
│ Sales Notification│
└──────────────────┘
Существует один ключевой принцип дизайна, который имеет первостепенное значение: необходимо разделять процесс понимания информации ИИ и принятие бизнес-решений. Большая языковая модель извлекает информацию из заявки, в то время как ваш собственный код определяет, как эта информация влияет на оценку подходящести клиента. Благодаря такому разделению систему легче тестировать, отлаживать и изменять.
Шаг 1: Определите критерии подходящести клиента
Бизнес-правила должны предшествовать коду. Рассмотрим пример агентства по разработке программного обеспечения. Оно может считать заявку подходящей, когда:
- у клиента действительно есть потребность в программном обеспечении
- эта потребность соответствует услугам, которые предлагает агентство
- в сообщении содержится достаточно информации для понимания проекта
- бюджет или намерение совершить покупку соответствуют требованиям агентства
- сообщение не является спамом или явно не относится к теме
Эти правила носят иллюстративный характер, и реальный бизнес должен устанавливать собственные пороговые значения. Заполненная запись может выглядеть так: тип услуги — разработка индивидуальных CRM-систем, бюджет — 5 00 000 рупий, срок выполнения — два месяца, количество пользователей в компании — 30, уровень значимости задачи — высокий, решение — одобрено.
Искусственный интеллект должен извлекать данные, а бизнес-правила должны принимать окончательное решение.
Шаг 2: Создание проекта на Python
Python подходит для этой задачи благодаря своей экосистеме API, интеграции с большими языками моделирования, обработке данных и автоматизации. Структура проекта выглядит следующим образом:
ai-lead-agent/
│
├── app/
│ ├── main.py
│ ├── config.py
│ │
│ ├── agents/
│ │ └── lead_agent.py
│ │
│ ├── schemas/
│ │ └── lead.py
│ │
│ ├── services/
│ │ ├── lead_service.py
│ │ └── scoring_service.py
│ │
│ └── db/
│ └── database.py
│
├── tests/
│ └── test_scoring.py
│
├── requirements.txt
└── .env
Установите необходимые пакеты:
pip install openai pydantic fastapi uvicorn python-dotenv
Используемые компоненты:
- FastAPI — для бэкенд-API
- Pydantic — для структурированной валидации
- API OpenAI — для примера работы с большими языковыми моделями
- PostgreSQL — в качестве производственной базы данных
- обычный Python — для оценки потенциальных клиентов
Провайдера больших языковых моделей можно позже заменить на другой.
Шаг 3: Определение структурированной схемы потенциальных клиентов
Распространенной ошибкой в приложениях на основе ИИ является использование свободного текста в качестве окончательного результата. Такой ответ трудно обрабатывать надежно:
This looks like a good lead.
The customer wants a CRM and seems interested.
Цель — получить предсказуемый JSON. Создайте файл app/schemas/lead.py и начните с импортов:
from typing import Optional, Literal
from pydantic import BaseModel, Field
Затем определите модели, начиная с поступающего потенциального клиента, и продолжите с анализом, который должна вернуть модель:
class LeadInput(BaseModel):
name: str
email: str
company: Optional[str] = None
message: str
class LeadAnalysis(BaseModel):
summary: str service_type: Optional[str] = None intent: Literal[
"high",
"medium",
"low",
"unknown"
] budget: Optional[float] = None currency: Optional[str] = None timeline: Optional[str] = None is_spam: bool = False missing_information: list[str] = Field(
default_factory=list
) qualification_notes: str recommended_action: Literal[
"contact_sales",
"request_more_information",
"reject",
"manual_review"
]
Теперь ответ ИИ имеет определенную структуру. Если модель возвращает недопустимое значение, приложение может отклонить его или обработать, вместо того чтобы молча сохранять неверные данные.
Шаг 4: Создание функции анализа потенциальных клиентов
Далее идет файл app/agents/lead_agent.py. Модель должна интерпретировать слова потенциального клиента и не должна выдумывать того, чего нет. Начнем с импортов:
import json
import os
Далее идет сама функция анализа. Она передает входные данные в модель, запрашивает результат, соответствующий схеме, и проверяет полученный ответ:
from openai import OpenAIfrom app.schemas.lead import (
LeadInput,
LeadAnalysis
)
client = OpenAI(
api_key=os.getenv("OPENAI_API_KEY")
)
SYSTEM_PROMPT = """
You are a lead analysis assistant for a software
development agency.Your task is to analyze incoming customer leads.Extract:
- Customer requirement
- Service type
- Buying intent
- Budget if explicitly mentioned
- Timeline if explicitly mentioned
- Spam indicators
- Missing informationRules:
1. Never invent a budget.
2. Never invent a timeline.
3. If information is missing, return null.
4. Return valid structured JSON.
5. Do not make a final business decision based
only on assumptions.
"""
def analyze_lead(lead: LeadInput) -> LeadAnalysis: user_prompt = f"""
Analyze this incoming lead: Name: {lead.name}
Email: {lead.email}
Company: {lead.company}
Message: {lead.message}
""" response = client.chat.completions.create(
model="gpt-4o-mini",
temperature=0,
response_format={
"type": "json_object"
},
messages=[
{
"role": "system",
"content": SYSTEM_PROMPT
},
{
"role": "user",
"content": user_prompt
}
]
) result = json.loads(
response.choices[0].message.content
) return LeadAnalysis.model_validate(result)
Почему температура равна нулю
Для извлечения информации важна последовательность, а не креативный стиль изложения. Низкая температура снижает разброс между ответами, но не гарантирует их корректности. Поэтому всё равно требуется проверка схемы и соблюдение бизнес-правил.
Названия моделей и функции API также меняются со временем. При внедрении решения в производственную среду выбирайте модель и метод структурированного вывода, которые в настоящее время поддерживаются вашим поставщиком.
Шаг 5: Добавление правил квалификации
Эту часть нельзя полностью передавать ИИ. Предположим, что примерные критерии агентства следующие:
- проект относится к разработке программного обеспечения
- если указан бюджет, он должен составлять не менее ₹2,00,000
- сообщение не является спамом
- имеется достаточно информации для понимания требований
Создайте файл app/services/scoring_service.py, начав с импорта:
from app.schemas.lead import LeadAnalysis
Затем функция оценки, начинающаяся с нуля, собирает причины каждой корректировки и возвращает нуль для спама немедленно:
def score_lead(analysis: LeadAnalysis) -> dict: score = 0
reasons = [] if analysis.is_spam:
return {
"score": 0,
"status": "rejected",
"reasons": ["Spam detected"]
} if analysis.service_type:
score += 25
reasons.append(
"Service requirement identified"
) if analysis.intent == "high":
score += 30
reasons.append(
"High buying intent"
) elif analysis.intent == "medium":
score += 15
reasons.append(
"Medium buying intent"
) if analysis.budget is not None:
if analysis.budget >= 200000:
score += 25
reasons.append(
"Budget meets example threshold"
)
else:
reasons.append(
"Budget below example threshold"
) if analysis.timeline:
score += 10
reasons.append(
"Timeline provided"
) if analysis.missing_information:
score -= 10
reasons.append(
"Some information is missing"
) score = max(0, min(score, 100)) if score >= 70:
status = "qualified" elif score >= 40:
status = "review" else:
status = "unqualified" return {
"score": score,
"status": status,
"reasons": reasons
}
Это простая, иллюстративная схема оценки. На самом деле агентство может учитывать и другие факторы:
- размер проекта
- отрасль
- местоположение
- наличие услуги
- степень срочности у клиента
- предыдущее взаимодействие
- доверие к указанному бюджету
- дублирующиеся заявки
Протестируйте функцию оценки на реальных примерах, прежде чем позволять ей автоматически отклонять заявки.
Шаг 6: Подключение агента к FastAPI
Создайте файл app/main.py и импортируйте FastAPI:
from fastapi import FastAPI
Остальная часть файла связывает схему, функцию анализа и сервис оценки через один конечный пункт:
from app.schemas.lead import LeadInput
from app.agents.lead_agent import analyze_lead
from app.services.scoring_service import score_lead
app = FastAPI(
title="AI Lead Filtering Agent"
)
@app.get("/health")
def health_check():
return {
"status": "ok"
}
@app.post("/analyze-lead")
def analyze_incoming_lead(
lead: LeadInput
): analysis = analyze_lead(lead) score = score_lead(analysis) return {
"lead": lead,
"analysis": analysis,
"qualification": score
}
Запустите сервер:
uvicorn app.main:app --reload
Затем откройте интерактивную документацию API:
http://127.0.0.1:8000/docs
Оттуда вы можете отправить запрос и просмотреть структурированный ответ.
Шаг 7: Попробуйте реалистичный запрос
Отправьте пример запроса вот такого:
{
"name": "Rahul Sharma",
"email": "rahul@example.com",
"company": "Example Technologies",
"message": "We need a custom CRM for around 30 users. Our budget is approximately 500000 INR and we want to launch within 2 months."
}
Вероятный результат извлечения выглядит следующим образом:
{
"summary": "Customer needs a custom CRM.",
"service_type": "CRM development",
"intent": "high",
"budget": 500000,
"currency": "INR",
"timeline": "2 months",
"is_spam": false,
"missing_information": [],
"qualification_notes": "Clear requirement, budget, and timeline.",
"recommended_action": "contact_sales"
}
Служба оценки затем анализирует извлеченные данные, причем результат представляет собой что-то вроде:
{
"score": 90,
"status": "qualified",
"reasons": [
"Service requirement identified",
"High buying intent",
"Budget meets example threshold",
"Timeline provided"
]
}
Имейте в виду, что этот результат представляет собой пример того, чего можно ожидать, а не показатель, полученный при реальном запуске API.
Шаг 8: Хранение потенциальных клиентов в PostgreSQL
Для реального бизнес-использования недостаточно хранить результаты только в памяти, поэтому требуется их сохранение. Простая таблица выглядит примерно так:
CREATE TABLE leads (
id BIGSERIAL PRIMARY KEY,
Оставшиеся колонки содержат детали лидера и анализ:
name VARCHAR(150) NOT NULL, email VARCHAR(255) NOT NULL, company VARCHAR(255), message TEXT NOT NULL, service_type VARCHAR(255), intent VARCHAR(20), budget NUMERIC(14, 2), currency VARCHAR(10), timeline VARCHAR(100), is_spam BOOLEAN DEFAULT FALSE, ai_score INTEGER, qualification_status VARCHAR(30), analysis JSONB, created_at TIMESTAMPTZ DEFAULT NOW()
);
Столбец analysis сохраняет исходный структурированный результат работы ИИ, что полезно при отладке причин определённой классификации потенциального клиента.
Для производственного использования также необходимо учесть:
- уникальный идентификатор для каждого потенциального клиента
- способ выявления дубликатов
- индексы, охватывающие статус и время создания
- шифрование и строгий контроль доступа, поскольку данные потенциальных клиентов являются конфиденциальными
- миграции схемы
- журнал аудита
Шаг 9: Добавление автоматизации
На этом этапе агент превращается в нечто большее, чем простой API. Представьте следующий поток действий:
New Lead
│
▼
Save in PostgreSQL
│
▼
Analyze with AI
│
▼
Calculate Qualification
│
├── Qualified ────────► Notify Sales
│
├── Review ───────────► Human Review Queue
│
└── Unqualified ─────► Store for Reporting
Когда поступает квалифицированный потенциальный клиент, система может:
- хранить его в базе данных
- уведомлять команду продаж
- создавать запись в CRM
- назначать представителя по продажам
- планировать последующий контакт
- обновлять статус потенциального клиента
Слой автоматизации может быть представлен инструментом n8n, фоновым процессом или системой на основе очередей. В реальных условиях неразумно делать так, чтобы весь процесс зависел от одного синхронного HTTP-запроса. Более надежный подход предусматривает использование очереди в качестве посредника:
Lead API
│
▼
Message Queue
│
▼
Background Worker
│
▼
AI Analysis
│
▼
Database
│
▼
Automation
Затем потенциальные клиенты обрабатываются асинхронно, и невыполненные задачи можно попытаться выполнить заново.
Шаг 10: Добавление проверки человеком
Это, возможно, самый важный этап. Искусственный интеллект может неправильно интерпретировать информацию о потенциальном клиенте. Рассмотрим следующее сообщение:
«В настоящее время мы сравниваем варианты CRM и у нас ещё нет утверждённого бюджета, хотя нам бы хотелось знать примерные цены».
Модель может отнести уровень интереса клиента к среднему или высокому, тогда как компания предпочла бы направить такого клиента к специалисту, а не автоматически считать его подходящим. Именно поэтому существует три статуса:
- Подходящий: клиент соответствует установленным критериям и направляется в отдел продаж.
- На проверку: у клиента есть полезная информация, но решение должен принять человек.
- Не подходящий: клиент не соответствует установленным критериям.
Проверка человеком особенно полезна в следующих случаях:
- если бюджет не указан
- потребность нечеткая
- модель, по-видимому, не уверена в собственном результате
- детали сообщения противоречат друг другу
- отправитель работает в отрасли, которую компания не обслуживает
Хорошая система ИИ не скрывает неопределенности. Она делает ее видимой.
Что делает это агентом
Простой вызов LLM — это просто ввод, модель, вывод:
Input → LLM → Output
Рабочий процесс агента выполняет гораздо больше функций. Он понимает поступающее задание, извлекает соответствующую информацию, применяет инструменты или бизнес-правила, определяет следующий шаг, сохраняет состояние, запускает действие, а также повторяет попытку или передаёт задачу на более высокий уровень при возникновении проблем. Для фильтра лидов полный путь выглядит следующим образом:
Incoming Lead
│
▼
AI Analysis
│
▼
Business Rules
│
▼
Qualification Decision
│
▼
Action / Human Review
Искусственный интеллект — это лишь один из компонентов. Бэкенд-приложение делает весь процесс надежным, и это имеет большое значение.
Улучшения перед запуском в производство
Первая версия достаточна для ознакомления с рабочим процессом, но ее не следует выпускать в таком виде.
Обработка в фоновом режиме. Запускайте анализ потенциальных клиентов через очередь задач, такую как Celery с Redis, RQ, облачную очередь или систему задач на основе базы данных. Это помогает при повторных попытках и при большом объеме данных.
Обнаружение дубликатов. Один потенциальный клиент может поступить дважды: один раз с веб-сайта, а другой раз из рассылки по электронной почте. Сопоставляйте по электронной почте, названию компании и другим идентификаторам.
Версионирование промптов. Храните версии промптов рядом с каждым результатом работы ИИ. Когда изменяются критерии отбора, вы сможете определить, какой промпт и правила привели к предыдущему результату.
Наблюдаемость. Отслеживайте задержки работы ИИ, ошибки API, использование токенов, стоимость каждого потенциального клиента, распределение результатов оценки квалификации и частоту, с которой люди переопределяют решения агента.
Набор данных для оценки. Собирайте реальные потенциальные клиенты с метками, проверенными людьми, и тестируйте систему на их основе. Это гораздо надежнее, чем оценивать агента по одному хорошему примеру.
Безопасность. Полностью исключайте ключи API из кода фронтенда, проверяйте каждый входящий запрос, защищайте персональные данные и ограничивайте доступ к информации о потенциальных клиентах.
Уроки архитектуры
Создание ИИ-агента — это не просто вызов большой языковой модели. Настоящая инженерная работа связана с самой моделью: четкой бизнес-задачей, структурированными данными, надежной верификацией, детерминистичными правилами, сохранением информации, автоматизацией, проверкой человеком и мониторингом. Без этого получается чат-бот, который кажется умным, но не решает бизнес-задачу.
Фильтр потенциальных клиентов должен не просто давать ответ, а создавать полезный и отслеживаемый рабочий процесс. Модель понимает неструктурированные сообщения клиентов, Python запускает процесс, бизнес-правила определяют критерии отбора, PostgreSQL хранит информацию, а автоматизация связывает результат с отделом продаж. Вместе они превращают демо-версию ИИ в рабочее приложение.
Естественным следующим шагом является подключение API к источнику потенциальных клиентов в реальном времени, добавление фоновых задач и создание панели управления для сотрудников отдела продаж, чтобы они могли анализировать, какие из потенциальных клиентов подходят. Цель не в том, чтобы заменить все решения отдела продаж искусственным интеллектом, а в том, чтобы уменьшить количество повторяющейся работы, чтобы сотрудники могли сосредоточиться на тех потенциальных клиентах, которые действительно этого заслуживают.