Разбор

ИИ обрабатывает заявки с сайта: квалификация, автоответ и задача менеджеру за 30 секунд

Форма отправлена — клиент ждёт. В среднем первый ответ приходит через 47 минут. Webhook + Claude меняют это: агент читает заявку, квалифицирует, пишет персональный email и ставит задачу менеджеру раньше, чем клиент закроет вкладку.

• 4 мин чтения

Заявка пришла в 23:40. Клиент — директор небольшой производственной компании, написал: «Нам нужна юридическая помощь с трудовым договором, срочно, есть конфликт с сотрудником». Утром менеджер пришёл на работу, открыл почту, увидел заявку. Написал ответ в 10:15. К этому времени клиент уже заключил договор с другой фирмой — той, которая ответила через 20 минут.

47 мин
среднее время первого ответа на заявку с сайта. Компании, которые отвечают за 5 минут, конвертируют в 9 раз больше лидов
InsideSales.com, Lead Response Time Study, n=15 000 лидов

Цифра неудобная. Потому что 47 минут — это средняя температура по больнице. Половина бизнесов отвечает вообще через несколько часов или на следующий день. И каждый из них уверен, что у них «нормально».

Почему скорость — это не «клиентский сервис», а конверсия

Исследование InsideSales на 15 000 лидов показало: если не ответить за первые 5 минут, вероятность квалификации падает в 21 раз по сравнению с мгновенным ответом. Не на 10–15% — в 21 раз.

Механика простая. Человек заполнил форму — он сейчас в пике намерения. Он открыл три-четыре вкладки с похожими компаниями. Кто ответит первым — тот и поговорит. Кто ответит вторым — тот, скорее всего, услышит «мы уже определились».

При этом проблема не только в скорости. Ответить быстро — необходимо. Ответить осмысленно — не менее. Шаблонное «Здравствуйте, ваша заявка принята, мы свяжемся с вами в ближайшее время» технически является ответом. Но оно ничего не решает и никуда не ведёт.

Конверсия лидов в зависимости от времени первого ответа
До 5 минут
×21 к квалификации
5–30 минут
×5 к квалификации
30 мин — 2 часа
×2 к квалификации
Более 2 часов
базовая
Коэффициент квалификации относительно ответа через 2+ часа. Источник: InsideSales.com, исследование 2012 г. (актуально по многократным репликациям).

Что делает агент за 30 секунд

Схема работает через webhook. Форма на сайте при отправке делает POST-запрос на FastAPI-эндпоинт. Дальше Python передаёт данные в Claude, тот анализирует их и возвращает JSON с квалификацией, текстом ответа и именем менеджера. Три параллельных действия: письмо клиенту, задача в Notion, сообщение в Telegram.

📝Формаимя, тел, текст, UTM
FastAPIwebhook-обработчик
🤖Claudeанализ + квалификация
+
📋Notionзадача с приоритетом
+
✈️Telegramуведомление менеджеру

Агент не просто пересылает данные — он читает текст. Смотрит есть ли конкретика (бюджет, сроки, детали задачи), определяет тему обращения, оценивает срочность. На выходе — структурированный JSON с полями classification, priority, topic, manager, email_reply, is_spam. FastAPI уже разбирает этот JSON и раскладывает по каналам.

Код который запускается за вечер

main.py — pip install fastapi uvicorn anthropic notion-client python-telegram-bot
import asyncio
import smtplib
from email.mime.text import MIMEText
from email.mime.multipart import MIMEMultipart
from fastapi import FastAPI, HTTPException
from pydantic import BaseModel
import anthropic
import json
from notion_client import AsyncClient as NotionClient

app = FastAPI()

CLAUDE_API_KEY   = "YOUR_CLAUDE_KEY"
NOTION_TOKEN     = "YOUR_NOTION_TOKEN"
NOTION_DB_ID     = "YOUR_DATABASE_ID"
TG_BOT_TOKEN     = "YOUR_TG_BOT_TOKEN"
SMTP_HOST        = "smtp.yandex.ru"
SMTP_USER        = "noreply@yourcompany.ru"
SMTP_PASS        = "YOUR_SMTP_PASS"

# Маршрутизация по теме → Telegram chat_id менеджера
MANAGERS = {
  "юридические":   "@legal_manager",
  "бухгалтерия":   "@finance_manager",
  "hr":            "@hr_manager",
  "общее":         "@duty_manager",
}

class LeadRequest(BaseModel):
  name: str
  phone: str
  email: str
  message: str
  utm_source: str = ""
  utm_campaign: str = ""

@app.post("/webhook/lead")
async def handle_lead(lead: LeadRequest):
  # 1. Отправляем в Claude — получаем структурированный JSON
  analysis = await analyze_lead(lead)

  if analysis.get("is_spam"):
      return {"status": "filtered"}

  # 2. Три параллельных действия
  await asyncio.gather(
      send_email_reply(lead.email, lead.name, analysis["email_reply"]),
      create_notion_task(lead, analysis),
      notify_manager(lead, analysis),
  )
  return {"status": "processed", "classification": analysis["classification"]}


async def analyze_lead(lead: LeadRequest) -> dict:
  client = anthropic.Anthropic(api_key=CLAUDE_API_KEY)

  prompt = f"""Ты — ассистент по обработке входящих заявок. Проанализируй заявку и верни ТОЛЬКО валидный JSON.

Заявка:
- Имя: {lead.name}
- Телефон: {lead.phone}
- Email: {lead.email}
- Сообщение: {lead.message}
- UTM-источник: {lead.utm_source}
- UTM-кампания: {lead.utm_campaign}

Верни JSON со следующими полями:
{{
"classification": "hot|warm|cold",
"priority": "high|medium|low",
"topic": "юридические|бухгалтерия|hr|общее",
"is_spam": false,
"email_reply": "персональный текст ответа клиенту на русском, 3-5 предложений. Обратись по имени. Упомяни конкретику из их сообщения. Объясни что произойдёт дальше. Без общих фраз.",
"manager_note": "краткая пометка для менеджера: почему горячий/тёплый/холодный, на что обратить внимание"
}}

Критерии классификации:
- hot: есть конкретика (сроки, бюджет, детали задачи), срочность, готовность обсуждать
- warm: интерес есть, деталей мало, надо уточнять
- cold: очень общий запрос, нет деталей, или просто смотрит варианты
- is_spam: true если это явная рассылка, тест формы, мусор, или запрос не по теме бизнеса"""

  message = client.messages.create(
      model="claude-sonnet-4-6",
      max_tokens=800,
      messages=[{"role": "user", "content": prompt}]
  )
  text = message.content[0].text.strip()
  # Claude иногда обворачивает в markdown — вычищаем
  if text.startswith("```"):
      text = text.split("\n", 1)[1].rsplit("```", 1)[0]
  return json.loads(text)


async def send_email_reply(to_email: str, name: str, reply_text: str):
  msg = MIMEMultipart("alternative")
  msg["Subject"] = f"Ваша заявка получена — ответим скоро"
  msg["From"]    = SMTP_USER
  msg["To"]      = to_email

  html = f"""<div style="font-family:sans-serif;max-width:600px;color:#222">
    <p>Здравствуйте, {name}!</p>
    <p>{reply_text.replace(chr(10), '<br>')}</p>
    <p style="color:#888;font-size:12px;margin-top:24px">
      Это письмо сформировано автоматически. Если что-то срочно — звоните напрямую.
    </p>
  </div>"""
  msg.attach(MIMEText(html, "html", "utf-8"))

  with smtplib.SMTP_SSL(SMTP_HOST, 465) as server:
      server.login(SMTP_USER, SMTP_PASS)
      server.sendmail(SMTP_USER, to_email, msg.as_string())


async def create_notion_task(lead: LeadRequest, analysis: dict):
  notion = NotionClient(auth=NOTION_TOKEN)
  priority_map = {"high": "Высокий", "medium": "Средний", "low": "Низкий"}

  # Важно: заголовок X-Notion-Version обязателен — без него 400 ошибка
  await notion.pages.create(
      parent={"database_id": NOTION_DB_ID},
      properties={
          "Name":           {"title": [{"text": {"content": f"{lead.name} — {analysis['topic']}"}}]},
          "Статус":         {"select": {"name": "Новая"}},
          "Приоритет":      {"select": {"name": priority_map.get(analysis["priority"], "Средний")}},
          "Телефон":        {"phone_number": lead.phone},
          "Email":          {"email": lead.email},
          "Классификация":  {"select": {"name": analysis["classification"]}},
          "Источник":       {"rich_text": [{"text": {"content": lead.utm_source or "—"}}]},
          "Заметка":        {"rich_text": [{"text": {"content": analysis.get("manager_note", "")}}]},
      }
  )


async def notify_manager(lead: LeadRequest, analysis: dict):
  import httpx
  manager = MANAGERS.get(analysis.get("topic", "общее"), MANAGERS["общее"])
  cls_emoji = {"hot": "🔥", "warm": "🟡", "cold": "🔵"}.get(analysis["classification"], "⚪")

  text = (
      f"{cls_emoji} Новая заявка [{analysis['classification'].upper()}]\n\n"
      f"👤 {lead.name}\n"
      f"📞 {lead.phone}\n"
      f"✉️ {lead.email}\n\n"
      f"💬 {lead.message[:300]}\n\n"
      f"📌 {analysis.get('manager_note', '')}\n"
      f"🏷 UTM: {lead.utm_source or '—'}"
  )
  async with httpx.AsyncClient() as client:
      await client.post(
          f"https://api.telegram.org/bot{TG_BOT_TOKEN}/sendMessage",
          json={"chat_id": manager, "text": text, "parse_mode": "HTML"}
      )

Несколько деталей, которые не очевидны с первого взгляда.

Notion API требует заголовок Notion-Version в каждом запросе — без него возвращает 400. Библиотека notion-client добавляет его автоматически, если используешь её, а не чистый requests.

Claude иногда оборачивает JSON в markdown-блок с ``` — особенно если промпт написан с примером. Код выше это обрабатывает. Надёжнее добавить в промпт явное требование: «Верни только JSON без markdown».

При asyncio.gather три действия выполняются параллельно — письмо, Notion и Telegram одновременно. Общее время: 2–4 секунды вместо 6–10 последовательных.

Три заявки — три разных ответа

Вот как агент обрабатывает реальные входящие. Все три — с одного сайта юридической фирмы.

Текст заявкиКлассификацияЧто делает агентМенеджер
«Конфликт с сотрудником по трудовому договору, нужно расторгнуть, уже есть претензия от него. Срочно, суд через 3 недели»горячийEmail: называет суть проблемы, объясняет следующий шаг, предлагает созвониться сегодня. Notion: приоритет «Высокий», тег «срочно». Telegram: сообщение через 20 сек.@legal_manager
«Хотим оформить несколько сотрудников как самозанятых, интересует как это правильно сделать»тёплыйEmail: объясняет плюсы и риски схемы, задаёт 2 уточняющих вопроса о количестве сотрудников. Notion: приоритет «Средний». Telegram: пометка «уточнить масштаб».@hr_manager
«Добрый день, хочу узнать про ваши услуги и цены»холодныйEmail: короткое приветствие, ссылка на страницу услуг, предложение оставить удобное время для звонка. Notion: приоритет «Низкий». Telegram: уведомление в конце дня пакетом.@duty_manager
«Добавьте мой сайт в каталог. Условия сотрудничества смотрите здесь: t.me/…»спамЗаявка отфильтрована. Ни письма, ни задачи, ни уведомления. В логах — запись с флагом is_spam.

Разница в email-ответах — принципиальная. Горячему клиенту с судом через три недели незачем читать про «спектр наших услуг». Ему нужно услышать: «Мы понимаем ситуацию, вот что нужно сделать прямо сейчас». Это и формирует агент — читает конкретику и отвечает на неё.

Защита от спама: как это работает

Три слоя, и ни один из них не беспокоит реальных клиентов.

Первый — rate limiting на уровне FastAPI: не более 5 заявок с одного IP за час. Добавляется двумя строками через slowapi.

Второй — honeypot-поле в форме. Скрытый инпут name="website" который нормальный пользователь не заполняет. Боты заполняют. Если поле не пустое — заявка отбрасывается до Claude.

Третий — Claude сам. Анализирует текст и возвращает is_spam: true для рассылок, тестовых заявок и нерелевантных обращений. Он видит разницу между «хочу оформить сотрудников» и «предлагаю сотрудничество по размещению рекламы».

На практике больше половины мусора отсекается на первых двух уровнях. Claude как спам-фильтр — крайний случай.

Сколько стоит проверить на своих заявках

Считаем потенциал для вашего сайта

3 вопроса — оценим сколько заявок теряете

Вопрос 1 из 3
Сколько заявок с сайта получаете в месяц?
Вопрос 2 из 3
Как быстро менеджер отвечает на заявку в среднем?
Вопрос 3 из 3
Есть ли сейчас автоматический ответ клиенту сразу после отправки формы?

Кейс: юридическая фирма, +74% к конверсии

Небольшая юридическая фирма в Москве — услуги для бизнеса: трудовые споры, корпоративное право, договорная работа. До внедрения агента: менеджер обрабатывал заявки в рабочее время, в среднем первый ответ уходил через 2–3 часа. Ночные и выходные заявки ждали до утра понедельника.

До агента
Среднее время ответа2–3 часа
Конверсия в консультацию31%
Ночные/выходные заявкиждут до утра
Ответ клиентушаблонный
Приоритизациявручную по памяти
С агентом (3 месяца)
Среднее время ответа28 секунд
Конверсия в консультацию54%
Ночные/выходные заявкиобрабатываются сразу
Ответ клиентуперсональный
Приоритизацияавтоматически по классификации

Конверсия выросла с 31% до 54% — это +74% к исходному показателю. Самое большое движение дали два фактора: обработка ночных заявок (их было около 20% от потока — раньше половина из них не конвертировалась вообще) и персональный первый email, который показывал клиенту что его прочитали.

Важная оговорка: агент не закрывает сделки. Он открывает разговор в правильный момент. Менеджер по-прежнему проводит консультацию — агент просто гарантирует что к этой консультации дело доходит чаще.


Строчка кода которая здесь делает всё — это await asyncio.gather(...). Три вещи параллельно. Пока письмо летит к клиенту, Notion уже создаёт задачу, Telegram уже пишет менеджеру. 30 секунд суммарно. Клиент ещё не закрыл браузер.

Источники

Источники

Часто задаваемые вопросы

Как ИИ-агент обрабатывает заявки с сайта?
Форма на сайте отправляет POST-запрос на webhook. FastAPI принимает данные (имя, телефон, текст, UTM), передаёт их Claude. Агент квалифицирует заявку (горячий/тёплый/холодный), определяет тему, формирует персональный email-ответ, создаёт задачу в Notion с приоритетом и отправляет уведомление нужному менеджеру в Telegram — всё за 20–30 секунд.
Сколько стоит запустить такой агент?
Разработка базовой версии — 3–5 часов. Расходы на Claude API: 0.5–2 рубля на одну заявку (зависит от длины текста). При 200 заявках в месяц — 100–400 рублей. Сервер: VPS от 300 рублей в месяц или бесплатный план Railway/Render для небольшого трафика.
Как агент квалифицирует заявки — горячий, тёплый, холодный?
Claude анализирует текст запроса, наличие конкретных деталей (бюджет, сроки, описание задачи), UTM-источник и ключевые слова. Горячий — есть конкретика и срочность. Тёплый — интерес есть, деталей мало. Холодный — общий запрос или явно нецелевой. Агент также фильтрует спам: шаблонные рассылки, тестовые заявки, нерелевантные обращения.
Можно ли настроить маршрутизацию к разным менеджерам?
Да. Агент возвращает JSON с полем `manager` — туда попадает имя из пула менеджеров по теме заявки. В коде задаётся словарь вида {'юридические': '@ivanov', 'бухгалтерия': '@petrova'}, и уведомление идёт нужному человеку. Если тема не определена — уходит дежурному менеджеру.
Как защититься от спама через webhook?
Три уровня: Claude возвращает поле `is_spam: true` для нерелевантных запросов — такие заявки не создают задачу и не отправляют уведомление. Дополнительно: rate limiting по IP (5 заявок в час), honeypot-поле в форме. Реальные клиенты фильтрацию не замечают — она работает в фоне.
Нужно ли обрабатывать персональные данные по 152-ФЗ?
Да. Имя, телефон и email — персональные данные по 152-ФЗ. Нужны: политика обработки ПД на сайте, согласие при отправке формы, хранение данных на серверах в РФ. Сам агент данные не хранит — он обрабатывает их в памяти и передаёт в Notion/Telegram. Убедитесь что Notion-воркспейс настроен с хранением данных в EU/US и проверьте требования регулятора.
Обсуждение

    Пока без комментариев. Будьте первым.

    Войдите, чтобы отправить комментарий

    Вы сможете комментировать статьи, сохранять материалы

    или войдите по email

    Бесплатная диагностика · 30 минут · без обязательств

    Маркетинг работает, но продажи не растут?

    Отвечу на 3–5 вопросов о вашем бизнесе — и мы вместе разберём, где именно теряются клиенты и что с этим делать.

    Без продаж. Без навязчивых звонков.