Форма не передаёт заявки: диагностика с ИИ по журналам

Форма не передаёт заявки: диагностика с ИИ по журналам. Учебный пример с исходными данными, полным промптом и проверкой результата. Неизвестное сохраняем.

Диагностика с ИИ здесь означает не «пусть модель догадается, где сломалось», а разбор связанных наблюдений по одному идентификатору заявки. Когда форма заявки не работает, проверка начинается не с перебора причин, а с вопроса: до какого этапа путь заявки подтверждён журналом, а где обрывается. Ниже — учебный сквозной разбор пяти трасс и готовый промпт для такой работы. Это полный текстовый разбор, не работа в настоящем кабинете, и все данные вымышлены.

Учебный пример: пять трасс F1–F5 описывают разные сбои на пути от браузера до CRM и уведомления. Реальных заявок, реального прогона Tilda или CRM здесь нет. Ценность разбора — в дисциплине: каждое утверждение привязано к наблюдению, отсутствующее помечено как неизвестное, а не заменено догадкой.

Соберите одну цепочку

Сквозной путь заявки удобно разложить на восемь наблюдаемых этапов: идентификатор заявки и время, введённые данные без персональной информации, клиентская валидация, сетевой запрос и ответ, обработка на backend, очередь, запись в CRM и уведомление. Каждый этап даёт собственное свидетельство, и связывать их можно только по общему request_id или lead_id.

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

Тильда описывает похожую границу между симптомом и логом: если в форме не отображается ошибка, а заявки всё равно не приходят, нужно проверять логи сервиса приёма данных, раздел «Заявки» и «Журнал ошибок» (Ошибки в формах приема данных). Среди частых причин там названы неактивные приёмщики данных и дублирование данных при повторной отправке (Ошибки в формах приема данных). Это первичная справка по кодам, но она не заменяет сквозную трассу одной заявки.

Практический минимум по одной заявке: один идентификатор, время, статус валидации, HTTP-код запроса и ответа, статус backend и очереди, наличие и номер записи в CRM, статус уведомления. Персональные данные в разбор не переносят. Секреты, токены и полные адреса endpoint модели не передают.

Пять полных учебных входов

Ниже — все пять трасс и правило работы с ними. Наблюдатель, которого нет в данных, помечается как отсутствующий, а не как проваленный этап. Отправка, которая не выполнялась, помечается как not attempted, а не как ошибка.

{
  "type": "Вымышленные учебные трассы, не реальные заявки, не прогон Tilda/CRM",
  "policy": "Связывать наблюдения только по request_id/lead_id. HTTP и сообщение интерфейса не равны созданию лида. Отсутствующий этап — unknown, кроме явно not attempted. Не выполнять отправок, не менять конфигурацию, не повторять запросы автоматически.",
  "traces": [
    {
      "id": "F1",
      "input": "email без символа @",
      "browser": {
        "validation": "invalid_email",
        "network_request": null,
        "message": "Проверьте email"
      },
      "backend": null,
      "crm": null,
      "notification": null
    },
    {
      "id": "F2",
      "input": "учебный валидный контакт C2",
      "browser": {
        "request_id": "r2",
        "http": 202,
        "message": "Заявка принята в обработку"
      },
      "backend": {
        "request_id": "r2",
        "status": "queued",
        "crm_attempt": "timeout",
        "retry": "pending"
      },
      "crm": {
        "search": "not performed",
        "record_id": null
      },
      "notification": {
        "status": "not attempted"
      }
    },
    {
      "id": "F3",
      "input": "учебный валидный контакт C3",
      "browser": {
        "request_id": "r3",
        "http": 200,
        "response": {
          "ok": true,
          "lead_id": "L3"
        },
        "message": "Ошибка отправки",
        "render_rule": "Учебный баг: ветка ok=true ошибочно рисует текст ошибки"
      },
      "backend": {
        "request_id": "r3",
        "status": "crm_created",
        "lead_id": "L3"
      },
      "crm": {
        "record_id": "L3",
        "request_id": "r3",
        "status": "created"
      },
      "notification": {
        "status": "sent",
        "lead_id": "L3"
      }
    },
    {
      "id": "F4",
      "input": "учебный валидный контакт C4",
      "browser": {
        "request_id": "r4",
        "http": 200,
        "message": "Спасибо"
      },
      "backend": {
        "request_id": "r4",
        "status": "crm_created",
        "lead_id": "L4"
      },
      "crm": {
        "record_id": "L4",
        "request_id": "r4",
        "status": "created"
      },
      "notification": {
        "status": "failed",
        "error": "mail_transport_error",
        "lead_id": "L4"
      }
    },
    {
      "id": "F5",
      "input": "учебный валидный контакт C5",
      "browser": {
        "request_id": "r5",
        "http": 502,
        "message": "Не удалось подтвердить передачу"
      },
      "backend": {
        "request_id": "r5",
        "crm_http": 401,
        "crm_body": "Unauthorized",
        "retry": "none"
      },
      "crm": {
        "record_id": null,
        "request_id": "r5",
        "response": "401 Unauthorized"
      },
      "notification": {
        "status": "not attempted"
      }
    }
  ],
  "negative_controls": [
    {
      "id": "N1",
      "claim": "F2 потеряна: timeout доказывает, что записи в CRM нет."
    },
    {
      "id": "N2",
      "claim": "F3 не дошла в CRM, потому что интерфейс показывает ошибку."
    },
    {
      "id": "N3",
      "claim": "F4 не создала запись в CRM, потому что письмо-уведомление не отправилось."
    },
    {
      "id": "N4",
      "claim": "F5 доказывает, что токен CRM истёк."
    }
  ]
}

Как читать входы. F1 остановилась на клиентской проверке: POST не создавался, поэтому backend, CRM и уведомление отсутствуют как наблюдатели. F2 прошла браузер и попала в очередь, но попытка CRM завершилась timeout, повтор висит в pending, а поиск в CRM не выполнялся. F3 получила HTTP 200 с ok=true и lead_id L3, при этом интерфейс по учебному правилу рисует текст ошибки. F4 создала L4 и отправила уведомление, но транспорт почты вернул ошибку. F5 дошла до endpoint CRM и получила 401; создание записи не подтверждено, повтор не предпринимался, уведомление не отправлялось.

Законченный диагностический результат

Ниже — реестр по всем пяти трассам с классификацией, состоянием доставки в CRM, неизвестным и следующим конкретным шагом.

ID Последний подтверждённый этап Классификация Доставка в CRM Неизвестно Следующая проверка
F1 Клиентская проверка вернула invalid_email; POST не создан validation_block not attempted Настоящий почтовый ящик не проверялся Отдельный контролируемый тест с корректным разрешённым контактом; валидацию не отключать
F2 Backend поставил r2 в очередь, попытка CRM дала timeout pending_unknown unknown Timeout не доказывает отсутствие записи; итог retry не предоставлен Сверить очередь и CRM по r2, затем решать повтор с защитой от дублей
F3 CRM создала L3 с request_id r3, уведомление отправлено confirmation_ui_defect confirmed_created Другие браузеры и заявки не исследованы Исправить учебную ветку render_rule и перепроверить отображение без лишнего лида
F4 CRM создала L4 с r4, уведомление вернуло mail_transport_error notification_failure confirmed_created Конкретная причина сбоя почтового транспорта неизвестна Смотреть журнал уведомления по L4; лид в CRM не пересоздавать
F5 Запрос r5 дошёл до endpoint CRM, ответ 401 Unauthorized crm_auth_rejection not confirmed Истечение токена, неверный ключ и иные причины 401 не различены Сверить разрешённую конфигурацию и журнал авторизации; токены не публиковать

Итог по трассам: пять трасс, две подтверждённые записи в CRM (L3 и L4), ноль выполненных отправок и ноль изменений конфигурации. Это не итог реального аудита CRM, а результат разбора вымышленных входов.

Почему сообщение формы, цель и уведомление не доказывают CRM. Сообщение формы — это текст интерфейса, и в F3 он расходится с фактом записи. HTTP 200 подтверждает, что сервер ответил, но не гарантирует создание лида. Уведомление живёт отдельно от записи: в F4 письмо не ушло, а лид L4 существует. Timeout в F2 не является отрицательным доказательством: поиск в CRM не выполнялся, и запись могла появиться позже или уже быть.

Где заканчивается подтверждённая цепочка. По F1 подтверждение заканчивается на валидации. По F2 — на очереди и неудачной попытке CRM, дальше unknown. По F3 и F4 подтверждена запись в CRM, у F3 дополнительно уведомление. По F5 подтверждён только отказ endpoint с кодом 401; создание записи не подтверждено, уведомление not attempted.

Самодостаточный промпт и отрицательный контроль

Ниже — полный текст промпта. Он содержит все входы, правило связывания, требования к выводу и запрет на действия. Секреты и реальные персональные данные в такой запрос не попадают.

Для всех F1–F5 верни диагностический реестр: id, последний подтверждённый этап, classification, crm_delivery, unknown, next_check. Связывай стадии по request_id/lead_id. Различай валидацию, очередь, CRM, интерфейс подтверждения и уведомление. Timeout не доказывает отсутствие записи; HTTP 200 не гарантирует передачу; 401 не доказывает истечение токена. Подсчитай подтверждённые CRM записи. Проверь отрицательные утверждения из входов. Ничего не отправляй, не повторяй запросы, не раскрывай секреты.

Полные учебные входы:
{
  "type": "Вымышленные учебные трассы, не реальные заявки, не прогон Tilda/CRM",
  "policy": "Связывать наблюдения только по request_id/lead_id. HTTP и сообщение интерфейса не равны созданию лида. Отсутствующий этап — unknown, кроме явно not attempted. Не выполнять отправок, не менять конфигурацию, не повторять запросы автоматически.",
  "traces": [
    {
      "id": "F1",
      "input": "email без символа @",
      "browser": {
        "validation": "invalid_email",
        "network_request": null,
        "message": "Проверьте email"
      },
      "backend": null,
      "crm": null,
      "notification": null
    },
    {
      "id": "F2",
      "input": "учебный валидный контакт C2",
      "browser": {
        "request_id": "r2",
        "http": 202,
        "message": "Заявка принята в обработку"
      },
      "backend": {
        "request_id": "r2",
        "status": "queued",
        "crm_attempt": "timeout",
        "retry": "pending"
      },
      "crm": {
        "search": "not performed",
        "record_id": null
      },
      "notification": {
        "status": "not attempted"
      }
    },
    {
      "id": "F3",
      "input": "учебный валидный контакт C3",
      "browser": {
        "request_id": "r3",
        "http": 200,
        "response": {
          "ok": true,
          "lead_id": "L3"
        },
        "message": "Ошибка отправки",
        "render_rule": "Учебный баг: ветка ok=true ошибочно рисует текст ошибки"
      },
      "backend": {
        "request_id": "r3",
        "status": "crm_created",
        "lead_id": "L3"
      },
      "crm": {
        "record_id": "L3",
        "request_id": "r3",
        "status": "created"
      },
      "notification": {
        "status": "sent",
        "lead_id": "L3"
      }
    },
    {
      "id": "F4",
      "input": "учебный валидный контакт C4",
      "browser": {
        "request_id": "r4",
        "http": 200,
        "message": "Спасибо"
      },
      "backend": {
        "request_id": "r4",
        "status": "crm_created",
        "lead_id": "L4"
      },
      "crm": {
        "record_id": "L4",
        "request_id": "r4",
        "status": "created"
      },
      "notification": {
        "status": "failed",
        "error": "mail_transport_error",
        "lead_id": "L4"
      }
    },
    {
      "id": "F5",
      "input": "учебный валидный контакт C5",
      "browser": {
        "request_id": "r5",
        "http": 502,
        "message": "Не удалось подтвердить передачу"
      },
      "backend": {
        "request_id": "r5",
        "crm_http": 401,
        "crm_body": "Unauthorized",
        "retry": "none"
      },
      "crm": {
        "record_id": null,
        "request_id": "r5",
        "response": "401 Unauthorized"
      },
      "notification": {
        "status": "not attempted"
      }
    }
  ],
  "negative_controls": [
    {
      "id": "N1",
      "claim": "F2 потеряна: timeout доказывает, что записи в CRM нет."
    },
    {
      "id": "N2",
      "claim": "F3 не дошла в CRM, потому что интерфейс показывает ошибку."
    },
    {
      "id": "N3",
      "claim": "F4 не создала запись в CRM, потому что письмо-уведомление не отправилось."
    },
    {
      "id": "N4",
      "claim": "F5 доказывает, что токен CRM истёк."
    }
  ]
}
Верни все F1–F5 и N1–N4, ничего не отправляй.

Эталон результата приведён в таблице выше. Отрицательный контроль проверяет, что модель не выдаёт догадку за факт:

ID Утверждение на входе Вердикт Основание
N1 F2 потеряна: timeout доказывает, что записи в CRM нет REJECT Поиск в CRM не выполнялся, повтор в pending, итог unknown
N2 F3 не дошла в CRM, потому что интерфейс показывает ошибку REJECT Запись L3 создана, ошибка только в учебной ветке интерфейса
N3 F4 не создала запись в CRM, потому что письмо не ушло REJECT Запись L4 создана, failed относится к уведомлению
N4 F5 доказывает, что токен CRM истёк REJECT Код 401 не различает конкретные причины авторизации

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

Если агент разбирает реальные журналы по правилам, ручная вычитка каждой строки не нужна. Человек уточняет то, чего в журналах нет: бизнес-контекст заявки, допустимость повтора и решение по исключению. Ручная сверка остаётся на стороне владельца данных.

Перенос на собственную форму

Порядок для своего сайта такой. Сначала получить разрешение на тестовую заявку и подготовить безопасные данные без реальных персональных сведений. Затем собрать реальные журналы и выбрать наблюдения по одному идентификатору: браузер, backend, очередь, CRM, уведомление. Секреты в разбор не передавать.

До любой повторной отправки проверить pending и наличие записи в CRM, а также правила дедупликации. Тильда прямо предупреждает о дублировании данных при повторной отправке (Ошибки в формах приема данных). Поэтому повтор без проверки рискует создать второй лид.

Конфигурацию на основе догадки не менять. Если причина неизвестна, следующий шаг — собрать недостающее свидетельство: журнал очереди по идентификатору, журнал авторизации CRM, журнал транспорта уведомлений. Только подтверждённый факт даёт основание менять настройку.

Смежные задачи разобраны отдельно: проверка входящего запроса и адреса в разборе webhook в n8n и словарь событий с проверкой дублей в разборе событий аналитики.

Валерий Курземнек

Автор метода «Машиночитаемый маркетинг»

Что ещё почитать