Разбор
ИИ-агент квалифицирует лиды в amoCRM: горячие, тёплые, холодные — автоматически за 30 секунд
Менеджеры тратят одинаковое время на горячих и холодных лидов — и теряют горячих, пока возятся с холодными. Webhook amoCRM + Python + Claude оценивает каждый лид по BANT за 30 секунд и обновляет карточку до того, как менеджер откроет CRM.
Компания MIT провела исследование: если не позвонить лиду в течение первого часа после заявки — шансы квалифицировать его падают в 7 раз. Через 24 часа — в 60 раз. При этом большинство отделов продаж обрабатывают заявки в порядке очереди — горячий лид с бюджетом 5 млн ждёт того же времени, что и студент, который «просто интересуется».
Почему менеджеры теряют горячих лидов
Картина в большинстве B2B-отделов продаж выглядит одинаково: все входящие заявки падают в одну воронку и обрабатываются по очереди. Менеджер открывает CRM утром и видит 12 лидов. Он начинает с первого. Первый — холодный: студент сравнивает цены для курсовой. Второй — тёплый: компания изучает рынок, решение не скоро. Третий — горячий: директор хочет подписать договор до конца месяца и уже разговаривал с вашим конкурентом.
К третьему менеджер добирается через час.
За этот час директор мог позвонить конкурентам. Или просто потерять интерес — горячие лиды быстро остывают именно потому, что у них есть срочность.
Проблема не в менеджерах — они работают так, как им позволяет инструмент. Инструмент не умеет расставлять приоритеты автоматически.
Есть бюджет, ЛПР на связи, чёткая потребность, нужно быстро
~15%Интерес есть, но бюджет не утверждён или решение не скоро
~45%Любопытство, нет бюджета, не тот человек или не та потребность
~40%Типичное распределение в B2B: 15% горячих, 45% тёплых, 40% холодных. При этом горячие дают 70–80% выручки. Но обрабатываются — в произвольном порядке.
Как работает автоквалификация
Схема простая: новый лид попадает в amoCRM → CRM отправляет webhook на ваш сервер → Python принимает запрос → Claude получает данные лида и оценивает по BANT → Python обновляет карточку через amoCRM API: теги, примечание, статус.
Всё происходит до того, как менеджер открыл CRM. Он видит карточку уже с тегом «горячий» и кратким объяснением почему. Менеджеру не нужно ничего изучать — нужно просто позвонить.
BANT в промпте: как объяснить Claude критерии
BANT — четыре критерия квалификации лида: Budget (бюджет), Authority (полномочия принимать решение), Need (потребность), Timeline (временные рамки). Чем больше галочек — тем горячее лид.
| Критерий | Что проверяем | Сигналы в данных лида |
|---|---|---|
| Budget | Есть деньги на покупку | Упомянул бюджет, UTM указывает на платный запрос, должность — директор/руководитель |
| Authority | ЛПР или влияет на решение | Должность в форме, домен корпоративной почты, написал от имени компании |
| Need | Есть конкретная проблема | Описал задачу в тексте, использовал профессиональные термины, пришёл по целевому запросу |
| Timeline | Нужно в ближайшее время | Написал «срочно», «до конца месяца», «уже ищем», пришёл с горячего запроса |
Claude получает данные лида в структурированном виде и промпт с чёткими инструкциями. Промпт — это не «оцени лида», а точные критерии с примерами:
BANT_PROMPT = """Ты помощник по квалификации лидов.
Проанализируй данные лида и оцени по критериям BANT.
КРИТЕРИИ ОЦЕНКИ:
Budget (Бюджет):
- Высокий: упомянул бюджет, должность директор/владелец/руководитель, B2B-сегмент
- Средний: корпоративная почта, пришёл с коммерческого запроса
- Низкий: частное лицо, нет упоминания бюджета, учебный/информационный запрос
Authority (Полномочия):
- Высокий: должность ЛПР в форме, пишет от имени компании, принимает решение
- Средний: не указал должность, но корпоративная почта
- Низкий: явно не ЛПР, «согласовываю с руководством», студент
Need (Потребность):
- Высокий: описал конкретную задачу с деталями, использует профессиональные термины
- Средний: общий интерес без конкретики
- Низкий: «просто интересуюсь», нет описания задачи
Timeline (Срочность):
- Высокий: «срочно», «до конца месяца», «уже выбираем», «переходим от конкурента»
- Средний: «планируем», «рассматриваем»
- Низкий: «когда-нибудь», «на будущее», нет указания срока
ДАННЫЕ ЛИДА:
{lead_data}
Верни JSON строго в таком формате:
{{
"status": "горячий" | "тёплый" | "холодный",
"score": {{
"budget": "высокий" | "средний" | "низкий",
"authority": "высокий" | "средний" | "низкий",
"need": "высокий" | "средний" | "низкий",
"timeline": "высокий" | "средний" | "низкий"
}},
"reasoning": "2-3 предложения почему такой статус",
"next_action": "конкретное действие менеджера"
}}
Правило: если данных мало — ставь "тёплый", не "холодный".
Лучше перепроверить тёплого, чем потерять горячего."""Конкретный код: FastAPI webhook + Claude + amoCRM API
amoCRM отправляет webhook в формате application/x-www-form-urlencoded — не JSON. FastAPI читает тело через await request.form().
import json
import httpx
import anthropic
from fastapi import FastAPI, Request
app = FastAPI()
# Настройки
AMOCRM_DOMAIN = "yourcompany.amocrm.ru"
AMOCRM_TOKEN = "YOUR_ACCESS_TOKEN" # OAuth 2.0 токен amoCRM
CLAUDE_API_KEY = "YOUR_CLAUDE_KEY"
AMO_HEADERS = {
"Authorization": f"Bearer {AMOCRM_TOKEN}",
"Content-Type": "application/json",
}
BANT_PROMPT = """Ты помощник по квалификации лидов.
Проанализируй данные лида и оцени по критериям BANT.
[... полный промпт из раздела выше ...]
Верни JSON строго в описанном формате."""
def parse_amo_webhook(form_data: dict) -> dict:
"""amoCRM шлёт bracket-нотацию: leads[add][0][id] = 12345"""
lead = {}
for key, value in form_data.items():
# Берём первый добавленный лид
if key.startswith("leads[add][0]["):
field = key.replace("leads[add][0][", "").rstrip("]")
lead[field] = value
return lead
async def get_lead_details(lead_id: str) -> dict:
"""Получаем полные данные лида через amoCRM API v4."""
async with httpx.AsyncClient() as client:
# Лид с кастомными полями и контактами
r = await client.get(
f"https://{AMOCRM_DOMAIN}/api/v4/leads/{lead_id}",
headers=AMO_HEADERS,
params={"with": "contacts,custom_fields_values"},
)
r.raise_for_status()
return r.json()
async def qualify_with_claude(lead_details: dict) -> dict:
"""Отправляем данные в Claude, получаем BANT-оценку."""
# Собираем данные для анализа
custom_fields = {
cf["field_name"]: cf.get("values", [{}])[0].get("value", "")
for cf in lead_details.get("custom_fields_values") or []
}
lead_data = {
"name": lead_details.get("name", ""),
"pipeline": lead_details.get("_embedded", {}).get("pipeline", {}).get("name", ""),
"source": custom_fields.get("Источник", ""),
"utm_source": custom_fields.get("UTM Source", ""),
"utm_medium": custom_fields.get("UTM Medium", ""),
"message": custom_fields.get("Сообщение", ""),
"company": custom_fields.get("Компания", ""),
"position": custom_fields.get("Должность", ""),
}
client = anthropic.Anthropic(api_key=CLAUDE_API_KEY)
message = client.messages.create(
model="claude-sonnet-4-6",
max_tokens=512,
messages=[{
"role": "user",
"content": BANT_PROMPT.replace("{lead_data}", json.dumps(lead_data, ensure_ascii=False, indent=2))
}]
)
# Claude возвращает JSON — парсим
response_text = message.content[0].text
# Ищем JSON в ответе
start = response_text.find("{")
end = response_text.rfind("}") + 1
return json.loads(response_text[start:end])
async def update_lead_in_amo(lead_id: str, qualification: dict):
"""Обновляем карточку лида: теги + примечание."""
status = qualification["status"]
reasoning = qualification.get("reasoning", "")
next_action = qualification.get("next_action", "")
async with httpx.AsyncClient() as client:
# 1. Добавляем тег к лиду через PATCH /api/v4/leads/{id}
tag_data = {
"_embedded": {
"tags": [{"name": f"квалификация:{status}"}]
}
}
await client.patch(
f"https://{AMOCRM_DOMAIN}/api/v4/leads/{lead_id}",
headers=AMO_HEADERS,
json=tag_data,
)
# 2. Добавляем примечание с объяснением
note_text = (
f"🤖 Автоквалификация: {status.upper()}
"
f"BANT: B={qualification['score']['budget']} | "
f"A={qualification['score']['authority']} | "
f"N={qualification['score']['need']} | "
f"T={qualification['score']['timeline']}
"
f"Вывод: {reasoning}
"
f"Следующий шаг: {next_action}"
)
note_data = {
"note_type": "common",
"params": {"text": note_text},
}
await client.post(
f"https://{AMOCRM_DOMAIN}/api/v4/leads/{lead_id}/notes",
headers=AMO_HEADERS,
json=[note_data],
)
@app.post("/webhook/amo-lead")
async def handle_new_lead(request: Request):
"""Принимаем webhook от amoCRM о новом лиде."""
form_data = dict(await request.form())
lead_basic = parse_amo_webhook(form_data)
lead_id = lead_basic.get("id")
if not lead_id:
return {"status": "skipped", "reason": "no lead id"}
# Полные данные, оценка, обновление карточки
lead_details = await get_lead_details(lead_id)
qualification = await qualify_with_claude(lead_details)
await update_lead_in_amo(lead_id, qualification)
return {"status": "ok", "lead_id": lead_id, "qualification": qualification["status"]}
# Запуск: uvicorn qualify_leads:app --host 0.0.0.0 --port 8000Несколько моментов по коду:
amoCRM хранит кастомные поля по-разному в зависимости от типа — для текстовых values[0].value, для множественных список объектов. Стоит добавить проверки на None перед обращением к полям.
OAuth-токен amoCRM живёт 24 часа. Для продакшена нужно реализовать refresh через refresh_token — сохранить пару токенов в переменных окружения и обновлять автоматически при получении 401.
Хостинг: Railway.app или Render.com запускают FastAPI-приложение бесплатно. Нужен публичный HTTPS-эндпоинт — именно туда настраивается webhook в amoCRM.
Есть вопрос по теме?
Разберу вашу посадочную страницу и укажу где теряются клиенты
Кейс: digital-агентство, 80 лидов в месяц
Digital-агентство из Москвы, специализация — контекстная реклама и SEO для B2B. 80 входящих лидов в месяц из разных источников: сайт, Яндекс.Директ, сарафан, партнёры.
До внедрения: два менеджера по продажам тратили суммарно 4 часа в день на первичную обработку лидов. Звонили всем подряд, пытаясь понять кто готов к сделке, а кто «просто посмотреть». Конверсия в договор — 8%.
Проблема стала очевидной после анализа: самые тёплые лиды часто ждали звонка дольше всего — они попадали в очередь после менеджеров, уже занятых холодными.
После внедрения автоквалификации: каждый лид получает оценку за 30 секунд. Горячие — первыми в список. Менеджеры видят не просто очередь, а приоритизированную очередь с объяснением.
Конверсия выросла с 8% до 13%. Не за счёт новых лидов — за счёт того, что горячие лиды перестали ждать в очереди.
Проверь свой отдел продаж
Диагностика: теряете ли вы горячих лидов?
4 вопроса — узнайте потенциал автоквалификации для вашего отдела
Как запустить: пошагово
В amoCRM: Настройки → Интеграции → Создать интеграцию. Указать redirect URI (можно localhost для тестирования). Пройти OAuth и сохранить access_token + refresh_token. Токен живёт 24 часа, refresh — 3 месяца.
amocrm.ru → Настройки → Интеграции → + ДобавитьНужен публичный HTTPS-эндпоинт. Самый быстрый вариант — Railway.app: подключить GitHub-репозиторий, добавить переменные окружения AMOCRM_TOKEN и CLAUDE_API_KEY. Деплой занимает 3–5 минут.
pip install fastapi uvicorn anthropic httpx python-multipartНастройки → Интеграции → Webhooks → Добавить. URL: ваш эндпоинт + /webhook/amo-lead. Событие: «Добавление лида». Убедиться что amoCRM шлёт POST и получает 200 OK в ответ.
POST https://yourapp.railway.app/webhook/amo-leadЧем больше данных о лиде — тем точнее оценка. Добавить поля «Должность», «Компания», «Сообщение» и передавать UTM-метки через скрытые поля формы. Агент сделает больше с полными данными.
Настройки → Поля → Лиды → + Добавить полеПосле запуска сравнивать оценку агента с оценкой менеджера по первым лидам. Если агент систематически ошибается по какому-то критерию — скорректировать промпт. Обычно 2–3 итерации дают приемлемую точность.
uvicorn qualify_leads:app —reload (тест локально)Что нельзя автоматизировать
Честно про ограничения. Агент хорош для первичной сортировки по косвенным признакам — но есть решения, которые он не принимает.
Финальное решение о сделке — всегда за человеком. Агент может ошибиться: написать «холодный» про лида, который просто коротко заполнил форму. Или «горячий» про конкурента, который мониторит ваши цены. Это инструмент первого фильтра, не замена опытного менеджера.
Переговоры и работа с возражениями — агент не может позвонить и выяснить настоящую причину обращения. Он работает только с тем, что написано.
Нюансы отрасли — Claude не знает что в вашей нише «директор по закупкам» может значить больше, чем «генеральный директор». Это знает ваш менеджер. Промпт можно и нужно дополнять бизнес-контекстом: «в нашей сфере горячий признак — упоминание тендера или конкурсной документации».
Долгосрочное развитие лида — если лид сегодня холодный, это не значит «навсегда холодный». Агент не ведёт историю и не напоминает вернуться к лиду через три месяца. Это отдельная задача для CRM-автоматизации.
Агентство из кейса потратило на настройку три дня — включая итерации с промптом. Первый месяц отдел продаж сравнивал оценки агента со своими вручную. На втором месяце перестали — агент ошибался реже, чем они успевали проверить. Время на квалификацию упало с 4 часов до 20 минут в день. Горячие лиды теперь получают звонок в среднем через 8 минут после заявки.
Есть вопрос по теме?
Разберу вашу посадочную страницу и укажу где теряются клиенты
Похожие кейсы
- WhatsApp-ассистент для продаж
- Коммерческое предложение за 10 минут
- Транскрибация звонков и разбор в CRM
- FAQ-бот для сайта без галлюцинаций
Источники
AI-агенты · Персональная карта
4 часа потратил — не работает?
Покажу где ты пошёл не туда и как сделать правильно за 2 недели
Получить разбор бесплатно →AI-агенты · 10 мест
Ты работаешь до полуночи — AI-агент будет работать вместо тебя
Покажу какой агент закроет твою главную операционную боль
Узнать свой маршрут →Есть вопрос по теме?
Разберу вашу посадочную страницу и укажу где теряются клиенты
Источники
Читайте также
Часто задаваемые вопросы
- Как ИИ-агент определяет, горячий лид или холодный?
- Агент анализирует все доступные данные о лиде через Claude: источник трафика, UTM-метки, первое сообщение и ответы на форму. Затем оценивает по четырём критериям BANT — Budget (бюджет), Authority (полномочия), Need (потребность), Timeline (срочность). На основе этой оценки присваивает статус горячий/тёплый/холодный и записывает объяснение в примечание карточки.
- Сколько стоит автоквалификация одного лида через Claude API?
- Один вызов Claude Sonnet для анализа лида стоит примерно 0.3–0.8 рублей в зависимости от объёма данных. При потоке 80 лидов в месяц — около 24–64 рублей на API. Для сравнения: час работы менеджера по квалификации стоит 300–700 рублей.
- Работает ли решение с Битрикс24?
- Архитектура аналогичная: Битрикс24 умеет отправлять webhook на события добавления лида. Отличие в формате данных и API для обратного обновления карточки. Основная логика — Python + Claude — остаётся без изменений, меняется только парсинг входящего webhook и вызовы REST API Битрикс24.
- Что делает агент, если данных о лиде мало?
- Claude получает инструкцию на этот случай: при недостатке данных ставить статус тёплый (не холодный) и явно указывать в примечании, каких данных не хватает. Это страховка от ложно-негативной квалификации — лучше перепроверить тёплого, чем потерять горячего из-за неполной формы.
- Нужно ли программирование для запуска агента?
- Базовый Python на уровне 'запустить скрипт и поменять переменные'. Нужно уметь установить pip-зависимости, зарегистрировать webhook в amoCRM и развернуть FastAPI-приложение на сервере или в облаке. Весь код — в статье. Хостинг — Railway, Render или любой VPS с Python.
- Может ли агент ошибиться в квалификации?
- Да. Claude делает вывод на основе косвенных признаков — текста сообщения, UTM, источника. Он не умеет читать мысли и не знает контекста вашего бизнеса лучше вас. Поэтому финальное решение о переходе сделки в следующий этап всегда остаётся за менеджером. Агент экономит время первичной сортировки, но не заменяет суждение человека.
Канал «Лёха Маркетолог»
Практика без воды: кейсы, инсайты, разборы. 1–2 поста в неделю.
Пока без комментариев. Будьте первым.