Створіть агента для оцінки кваліфікації лідерів у сфері ШІ на 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, інтеграціям з LLM, обробці даних та автоматизації. Структура проекту виглядає так:
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 для прикладу роботи з LLM
- PostgreSQL як база даних у продакшені
- звичайний Python для оцінки потенційних клієнтів
Постачальника LLM можна буде пізніше замінити на іншого.
Крок 3: Визначити структуровану схему потенційних клієнтів
Поширеною помилкою в AI-застосунках є використання вільного тексту як кінцевого результату. Таку відповідь важко надійно обробити:
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 у коді фронтенду, перевіряйте кожен надходження запиту, захищайте персональні дані та обмежуйте доступ до інформації про потенційних клієнтів.
Уроки архітектури
Створення AI-агента — це не лише виклик LLM. Справжня інженерія полягає у самій моделі: чітка бізнес-проблема, структуровані дані, надійна перевірка, детерміністичні правила, зберігання даних, автоматизація, людський огляд та моніторинг. Якщо пропустити це, результатом буде чат-бот, який здається розумним, але не вирішує бізнес-проблему.
Фільтр потенційних клієнтів не повинен лише формувати відповідь. Він має створювати корисний, простежуваний робочий процес. Модель розуміє неструктуровані повідомлення клієнтів, Python керує цим процесом, бізнес-правила визначають критерії відбору, PostgreSQL зберігає стан, а автоматизація пов’язує результат із командою з продажів. Разом вони перетворюють демо-версію AI на функціональний додаток.
Природним наступним кроком є підключення API до джерела потенційних клієнтів у реальному часі, додавання фонових завдань та створення панелі керування для продавців, щоб вони могли переглядати інформацію про кандидатів. Мета не в тому, щоб замінити кожне рішення щодо продажів на ШІ, а в тому, щоб скоротити повторювану роботу, щоб люди могли зосередитися на тих потенційних клієнтах, які цього варті.