Что получится в результате
Соберем безопасную интеграцию ИИ-агента с CRM. Агент сможет принимать обращение из сайта, чата, формы или почты, извлекать контакт и потребность, проверять дубли, создавать лид, добавлять комментарий, ставить задачу менеджеру, готовить черновик изменения сделки и получать обратные события из CRM.
В первой версии агент не должен самостоятельно менять деньги, стадии, ответственного, договоренности и критичные поля сделки. Правильный MVP: read-only чтение, создание лида, комментарии, задачи и write-back только через правила или подтверждение человека.
В результате будет рабочий контур:
- CRM-подключение описано в `crm_connections`;
- доступы лежат в `crm_credentials`;
- сущности CRM сопоставлены в `crm_entity_map`;
- входящие обращения лежат в `inbound_requests`;
- нормализованные контакты лежат в `crm_contact_candidates`;
- проверка дублей пишется в `crm_dedupe_checks`;
- лиды создаются через `crm_lead_queue`;
- сделки обновляются через `crm_deal_update_queue`;
- задачи менеджерам создаются через `crm_task_queue`;
- комментарии пишутся через `crm_note_queue`;
- разрешения tools лежат в `crm_tool_policy`;
- подтверждения пишутся в `crm_approval_queue`;
- события из CRM принимаются в `crm_webhook_events`;
- результаты API-вызовов пишутся в `crm_api_log`;
- ошибки пишутся в `crm_error_log`;
- тесты лежат в `crm_integration_test_cases`;
- метрики качества пишутся в `crm_integration_metrics`.
Итоговый MVP должен уметь: создать лид из входящего обращения, найти существующий контакт, не создать дубль, добавить summary диалога, поставить задачу менеджеру и отправить спорное изменение на approval.
Что понадобится
Подготовьте:
- CRM: Bitrix24, amoCRM, HubSpot, Salesforce или своя CRM;
- тестовый портал или sandbox CRM;
- API key, OAuth-приложение или webhook CRM;
- backend, n8n, Make или другой orchestration layer;
- LLM API key;
- тестовый канал входящих обращений;
- список полей контакта;
- список полей лида;
- список стадий сделки;
- список менеджеров и команд;
- правила дедупликации;
- список разрешенных CRM-действий;
- список запрещенных CRM-действий;
- 20-50 тестовых обращений;
- человек, который проверит первые write-back действия.
Для инструкции берем универсальную схему. Названия методов CRM будут отличаться, но логика одинаковая: агент не ходит в CRM напрямую, а вызывает ограниченные backend tools.
Шаг 1. Выберите первый CRM-сценарий
Не подключайте всю CRM сразу. Выберите один сценарий.
Хороший первый сценарий:
- пользователь оставляет заявку на сайте;
- агент извлекает имя, телефон, email, компанию и потребность;
- backend проверяет дубли;
- backend создает лид;
- агент добавляет summary;
- backend ставит задачу менеджеру;
- менеджер получает уведомление.
Плохой первый сценарий:
- агент меняет стадии сделок;
- агент закрывает сделки;
- агент назначает скидки;
- агент удаляет контакты;
- агент массово пишет клиентам.
Проверка: первый сценарий можно пройти вручную за 5 минут и понять, какие поля CRM нужны.
Шаг 2. Опишите CRM-подключение
Создайте `crm_connections`.
Колонки:
id
connection_key
crm_type
base_url
auth_type
environment
is_active
created_at
updated_at
Пример:
{
"connection_key": "bitrix24_sales_test",
"crm_type": "bitrix24",
"base_url": "https://example.bitrix24.ru",
"auth_type": "incoming_webhook",
"environment": "staging",
"is_active": true
}
Проверка: production и staging CRM не используют один и тот же connection key.
Шаг 3. Спрячьте доступы в `crm_credentials`
Создайте `crm_credentials`.
Колонки:
id
connection_key
credential_type
secret_ref
scopes_json
expires_at
last_rotated_at
is_active
Правила:
- webhook URL, OAuth token и refresh token не показывать агенту;
- хранить секреты в `.env`, vault или secret manager;
- давать минимальные scopes;
- не использовать аккаунт администратора;
- rotation делать по расписанию;
- логировать только `secret_ref`, а не значение секрета.
Проверка: в prompt, logs и `crm_api_log` нет полного webhook URL или token.
Шаг 4. Создайте карту сущностей CRM
Создайте `crm_entity_map`.
Колонки:
id
connection_key
local_entity
crm_entity
crm_method_create
crm_method_update
crm_method_read
required_fields_json
readonly_fields_json
Сопоставьте:
- `contact` -> CRM contact;
- `lead` -> CRM lead;
- `deal` -> CRM deal;
- `company` -> CRM company;
- `task` -> CRM task;
- `note` -> CRM comment или timeline note;
- `activity` -> CRM activity.
Проверка: разработчик видит, какой tool работает с какой CRM-сущностью и методом.
Шаг 5. Зафиксируйте поля контакта
Создайте `crm_contact_fields`.
Колонки:
id
field_key
crm_field_code
field_type
is_required
is_unique_candidate
can_ai_write
can_ai_read
Минимальные поля:
- `name`;
- `phone`;
- `email`;
- `company_name`;
- `position`;
- `source`;
- `messenger`;
- `consent_status`;
- `language`;
- `timezone`.
Правила:
- AI может предлагать `name`, `company_name`, `position`;
- телефон и email проходят валидацию;
- согласие на коммуникацию не выдумывается;
- секретные поля AI не читает и не пишет.
Проверка: агент не создает контакт без email или телефона, если CRM требует один из этих каналов.
Шаг 6. Зафиксируйте поля лида
Создайте `crm_lead_fields`.
Колонки:
id
field_key
crm_field_code
field_type
is_required
default_value
can_ai_write
requires_approval
Минимальные поля лида:
- `title`;
- `contact_name`;
- `phone`;
- `email`;
- `source`;
- `utm_source`;
- `utm_campaign`;
- `need_summary`;
- `budget_range`;
- `urgency`;
- `assigned_team`;
- `comment`.
Запрещенные для AI поля на старте:
- `deal_amount`;
- `discount`;
- `contract_terms`;
- `final_stage`;
- `manager_commission`;
- `payment_status`.
Проверка: поле суммы сделки не заполняется моделью без правила или оператора.
Шаг 7. Создайте таблицу входящих обращений
`inbound_requests` хранит сырое событие до CRM.
Колонки:
id
request_id
channel
source
raw_payload_json
message_text
attachments_json
utm_json
received_at
status
Статусы:
- `received`;
- `normalized`;
- `dedupe_checked`;
- `queued_to_crm`;
- `crm_created`;
- `needs_human`;
- `failed`.
Проверка: повтор webhook с тем же `request_id` не создает вторую заявку.
Шаг 8. Нормализуйте входящие данные
Создайте `normalized_request`.
Колонки:
id
request_id
clean_text
detected_language
customer_name
phone_normalized
email_normalized
company_name
need_summary
source_channel
created_at
Правила нормализации:
- телефон привести к единому формату;
- email привести к lowercase;
- HTML убрать;
- UTM сохранить отдельно;
- вложения не отправлять в CRM без проверки;
- длинный диалог превратить в summary;
- исходный payload не терять.
Проверка: `+7 (999) 111-22-33` и `79991112233` становятся одним нормализованным телефоном.
Шаг 9. Настройте извлечение данных через structured output
Агент должен возвращать JSON, а не произвольный текст.
Prompt:
Ты извлекаешь данные для CRM.
Верни только JSON по схеме.
Не выдумывай телефон, email, бюджет и имя.
Если данных нет, верни null.
Если запрос связан с деньгами, договором или жалобой, поставь needs_human = true.
Схема:
{
"name": "string|null",
"phone": "string|null",
"email": "string|null",
"company": "string|null",
"need_summary": "string",
"intent": "sales_lead|support|partner|complaint|other",
"urgency": "low|normal|high",
"needs_human": true
}
Проверка: если клиент написал "позвоните мне", но не оставил номер, агент не придумывает телефон.
Шаг 10. Создайте кандидата контакта
`crm_contact_candidates` хранит извлеченные контакты до записи в CRM.
Колонки:
id
request_id
name
phone
email
company_name
confidence_score
validation_status
validation_errors_json
created_at
Валидация:
- email имеет корректный формат;
- phone проходит нормализацию;
- хотя бы один контактный канал заполнен;
- name не содержит мусор;
- company не равна сообщению целиком;
- confidence ниже 0.7 отправляет на ручную проверку.
Проверка: кандидат без телефона и email не уходит в CRM автоматически.
Шаг 11. Сделайте дедупликацию
Создайте `crm_dedupe_checks`.
Колонки:
id
request_id
phone_hash
email_hash
matched_contact_id
matched_lead_id
matched_deal_id
match_reason
action
created_at
Порядок проверки:
- поиск по email;
- поиск по телефону;
- поиск по внешнему customer id;
- поиск по open lead;
- поиск по open deal;
- если найден контакт и открытая сделка, добавить note;
- если найден контакт без сделки, создать лид или задачу;
- если ничего не найдено, создать новый лид.
Возможные действия:
- `create_new_lead`;
- `attach_to_existing_contact`;
- `add_note_to_open_deal`;
- `create_task_for_manager`;
- `needs_human_review`.
Проверка: два обращения с одним email не создают два новых контакта.
Шаг 12. Создайте очередь CRM-лидов
`crm_lead_queue` защищает CRM от хаотичных вызовов.
Колонки:
id
request_id
connection_key
lead_payload_json
status
attempts
last_error
crm_lead_id
created_at
updated_at
Статусы:
- `queued`;
- `validating`;
- `waiting_approval`;
- `sending`;
- `created`;
- `failed`;
- `skipped_duplicate`.
Проверка: если CRM API недоступна, заявка остается в очереди и повторяется, а не теряется.
Шаг 13. Создайте backend tool `create_crm_lead`
Агент вызывает не CRM API, а backend tool.
Вход:
{
"request_id": "req-001",
"name": "Иван",
"phone": "+79991112233",
"email": "ivan@example.com",
"company": "Ромашка",
"need_summary": "Интересуется внедрением ИИ-агента в поддержку",
"source": "site_chat"
}
Backend делает:
- проверку API key клиента;
- проверку схемы;
- нормализацию контактов;
- дедупликацию;
- проверку tool policy;
- запись в `crm_lead_queue`;
- вызов CRM API;
- запись результата в `crm_api_log`.
Проверка: агент не может передать произвольный CRM method вроде `crm.deal.delete`.
Шаг 14. Настройте `crm_tool_policy`
Создайте `crm_tool_policy`.
Колонки:
id
tool_name
enabled
can_read
can_write
requires_approval
allowed_fields_json
blocked_fields_json
max_calls_per_run
is_active
Правила для MVP:
- `find_contact` разрешен read-only;
- `find_open_deal` разрешен read-only;
- `create_lead` разрешен после dedupe;
- `add_note` разрешен;
- `create_task` разрешен;
- `update_deal_stage` требует approval;
- `update_deal_amount` запрещен;
- `delete_contact` запрещен;
- `merge_contacts` запрещен;
- `send_message_to_client` требует approval.
Проверка: попытка обновить сумму сделки блокируется до CRM API.
Шаг 15. Создайте очередь комментариев
`crm_note_queue` хранит заметки и summary.
Колонки:
id
request_id
crm_entity_type
crm_entity_id
note_text
visibility
status
created_at
sent_at
Типы заметок:
- `dialog_summary`;
- `customer_need`;
- `ai_recommendation`;
- `handoff_reason`;
- `source_context`;
- `operator_note`.
Правила:
- заметка не должна содержать API keys;
- заметка не должна содержать полный prompt;
- длинный диалог сокращается;
- клиентские персональные данные не дублируются без необходимости;
- заметка привязана к lead, deal или contact.
Проверка: менеджер видит короткое summary, а не сырой лог модели.
Шаг 16. Создайте очередь задач менеджеру
`crm_task_queue` нужна для next step.
Колонки:
id
request_id
crm_entity_type
crm_entity_id
task_title
task_description
assignee_id
deadline_at
priority
status
created_at
Правила постановки задачи:
- urgent заявка - deadline 15-30 минут;
- normal заявка - deadline 2-4 часа;
- без контакта - задача "уточнить контакт";
- жалоба - задача ответственному руководителю;
- сложный запрос - задача профильной команде.
Проверка: после создания лида менеджер получает конкретную задачу, а не просто новый объект в CRM.
Шаг 17. Подготовьте обновление сделки как черновик
Не меняйте сделку сразу. Создайте `crm_deal_update_queue`.
Колонки:
id
request_id
crm_deal_id
proposed_changes_json
reason
confidence_score
requires_approval
status
approved_by
sent_at
created_at
Разрешенные черновики:
- добавить next step;
- предложить stage;
- предложить priority;
- предложить source;
- предложить tags;
- предложить summary.
Запрещено без approval:
- менять сумму;
- закрывать сделку;
- ставить `won`;
- ставить `lost`;
- менять ответственного;
- менять договорные условия.
Проверка: агент готовит предложение, а CRM меняется только после подтверждения.
Шаг 18. Настройте approval
Создайте `crm_approval_queue`.
Колонки:
id
request_id
action_type
crm_entity_type
crm_entity_id
payload_json
reason
risk_level
status
approved_by
approved_at
rejected_reason
Через approval должны проходить:
- изменение стадии сделки;
- изменение суммы;
- смена ответственного;
- отправка сообщения клиенту;
- создание коммерческого предложения;
- изменение даты оплаты;
- массовое обновление CRM;
- merge контактов;
- любые действия с жалобой или возвратом.
Проверка: оператор видит действие, причину и diff до подтверждения.
Шаг 19. Настройте входящие события из CRM
CRM должна не только принимать записи, но и сообщать агенту о событиях.
Создайте `crm_webhook_events`.
Колонки:
id
connection_key
event_id
event_type
crm_entity_type
crm_entity_id
payload_json
received_at
processed_at
status
События:
- создан лид;
- создана сделка;
- изменена стадия;
- добавлен комментарий;
- назначен ответственный;
- закрыта задача;
- клиент ответил;
- сделка выиграна;
- сделка проиграна.
Проверка: повторное CRM-событие с тем же `event_id` не обрабатывается дважды.
Шаг 20. Обновляйте контекст агента из CRM
Создайте read-only tool `get_crm_context`.
Вход:
{
"email": "ivan@example.com",
"phone": "+79991112233"
}
Выход:
{
"contact_id": "123",
"open_deal_id": "456",
"deal_stage": "qualification",
"last_activity_summary": "Обсуждали внедрение агента поддержки",
"assigned_manager": "manager_7"
}
Правила:
- tool только читает;
- возвращает минимум полей;
- скрывает приватные заметки;
- не возвращает платежные секреты;
- логирует доступ.
Проверка: агент видит текущую стадию, но не получает лишние персональные данные.
Шаг 21. Разведите CRM, память и базу знаний
У каждой системы своя роль.
CRM хранит:
- контакты;
- компании;
- лиды;
- сделки;
- задачи;
- коммуникации;
- ответственных.
Память агента хранит:
- предпочтения пользователя;
- настройки сценария;
- короткие рабочие факты с TTL.
База знаний хранит:
- правила продаж;
- FAQ;
- описания продуктов;
- инструкции;
- скрипты;
- ограничения.
Проверка: агент не пишет правила продаж в CRM, а клиентские сделки в RAG-базу знаний.
Шаг 22. Настройте CRM API log
Создайте `crm_api_log`.
Колонки:
id
request_id
connection_key
tool_name
crm_method
crm_entity_type
crm_entity_id
request_payload_hash
response_status
response_body_json
duration_ms
created_at
Логируйте:
- каждый CRM API call;
- tool name;
- entity id;
- статус ответа;
- duration;
- ошибку;
- run id агента;
- approved_by, если было approval.
Не логируйте:
- CRM token;
- webhook secret;
- полный access token;
- пароли;
- лишние персональные данные.
Проверка: по `request_id` можно понять, что агент сделал в CRM.
Шаг 23. Обрабатывайте ошибки CRM API
Создайте `crm_error_log`.
Колонки:
id
request_id
tool_name
error_type
error_message
crm_status_code
retryable
created_at
Ошибки:
- `auth_failed`;
- `rate_limited`;
- `validation_error`;
- `duplicate_found`;
- `network_timeout`;
- `crm_unavailable`;
- `permission_denied`;
- `unknown_error`.
Поведение:
- auth error - отключить connection и alert;
- rate limit - retry позже;
- validation error - human review;
- duplicate - не создавать лид;
- timeout - retry;
- permission denied - alert администратору.
Проверка: ошибка CRM не приводит к повторному созданию дублей.
Шаг 24. Настройте rate limit
Создайте `crm_rate_limit_rules`.
Колонки:
id
connection_key
tool_name
limit_per_minute
limit_per_hour
action_on_limit
is_active
Стартовые правила:
- `find_contact` - 60 в минуту;
- `create_lead` - 20 в минуту;
- `add_note` - 40 в минуту;
- `create_task` - 30 в минуту;
- `update_deal` - 10 в минуту и approval;
- общий лимит connection - ниже лимита CRM-провайдера.
Проверка: серия заявок не выбивает CRM в ban или throttling.
Шаг 25. Настройте idempotency
Создайте `crm_idempotency_keys`.
Колонки:
id
idempotency_key
request_id
action_type
crm_entity_type
crm_entity_id
payload_hash
created_at
expires_at
Ключ:
source_channel + external_message_id + action_type
Правила:
- повтор webhook не создает новый лид;
- retry после timeout проверяет, не создалась ли запись;
- один request не ставит две одинаковые задачи;
- повторная заметка не дублируется;
- ключ живет 7-30 дней.
Проверка: один и тот же webhook можно отправить 3 раза, а в CRM появится одна запись.
Шаг 26. Подготовьте тестовые данные
Создайте `crm_integration_test_cases`.
Колонки:
id
case_key
input_payload_json
expected_action
expected_crm_entity
expected_status
expected_not_create_duplicate
is_critical
Минимальные тесты:
- новый лид с телефоном;
- новый лид с email;
- обращение без контакта;
- дубль по email;
- дубль по телефону;
- существующая открытая сделка;
- жалоба клиента;
- запрос на скидку;
- запрос без потребности;
- CRM API timeout;
- CRM API validation error;
- повтор webhook;
- forbidden update deal amount;
- create task for manager;
- add note to deal.
Проверка: critical tests проходят до включения production CRM.
Шаг 27. Прогоните тест создания лида
Отправьте payload:
{
"request_id": "test-lead-001",
"channel": "site_form",
"message_text": "Здравствуйте, хочу внедрить ИИ-агента в отдел продаж. Иван, ivan@example.com, +79991112233",
"utm": {
"source": "yandex",
"campaign": "ai-agent-crm"
}
}
Проверьте:
- `inbound_requests` получил событие;
- `normalized_request` содержит телефон и email;
- `crm_contact_candidates` прошел валидацию;
- `crm_dedupe_checks` не нашел дубль;
- `crm_lead_queue` создал задачу;
- CRM вернула `crm_lead_id`;
- `crm_note_queue` добавила summary;
- `crm_task_queue` поставила задачу менеджеру;
- `crm_api_log` содержит все вызовы;
- секреты не попали в логи.
Проверка результата: в CRM есть один лид, одна заметка и одна задача.
Шаг 28. Прогоните тест дубля
Отправьте тот же payload повторно.
Ожидаемый результат:
- `inbound_requests` фиксирует повтор;
- `crm_dedupe_checks` находит существующий email;
- новый контакт не создается;
- новый лид не создается;
- создается note или task, если это новое обращение;
- `crm_idempotency_keys` блокирует дубль action;
- статус становится `skipped_duplicate` или `attached_to_existing`.
Проверка: CRM не засоряется дублями после retry.
Шаг 29. Прогоните тест approval
Отправьте запрос:
Клиент просит скидку 30% и хочет, чтобы сделку закрыли сегодня.
Ожидаемое поведение:
- агент создает summary;
- агент не меняет сумму;
- агент не меняет стадию на won;
- агент создает `crm_approval_queue`;
- оператор видит proposed changes;
- CRM меняется только после approve;
- отказ записывается с причиной.
Проверка: скидка и стадия не меняются автоматически.
Шаг 30. Прогоните тест CRM webhook
Смоделируйте событие из CRM:
{
"event_id": "crm-event-001",
"event_type": "deal_stage_changed",
"entity_type": "deal",
"entity_id": "456",
"new_stage": "proposal_sent"
}
Проверьте:
- событие записано в `crm_webhook_events`;
- дубль `event_id` не обработан повторно;
- агент обновил внутренний контекст;
- если нужно, создана follow-up задача;
- CRM не получила обратный бесконечный webhook loop.
Проверка: событие из CRM не запускает бесконечную цепочку обновлений.
Шаг 31. Настройте метрики интеграции
Создайте `crm_integration_metrics`.
Колонки:
id
date
inbound_requests
leads_created
duplicates_skipped
notes_added
tasks_created
approval_required
crm_api_errors
avg_api_latency_ms
created_at
Смотрите каждый день:
- сколько лидов создал агент;
- сколько дублей остановлено;
- сколько ошибок CRM API;
- сколько действий ушло на approval;
- сколько write-действий отклонено;
- сколько заявок осталось в failed;
- сколько заявок без контакта;
- среднее время обработки.
Проверка: после первого дня видно, помогает интеграция или создает мусор.
Шаг 32. Включите ограниченный production
Первый запуск:
- один канал;
- один pipeline;
- только создание лидов;
- комментарии разрешены;
- задачи разрешены;
- изменение сделок только через approval;
- auto-send клиенту выключен;
- лимит CRM API включен;
- alert по ошибкам включен;
- ежедневный review включен.
Проверка: если что-то идет не так, можно выключить `crm_connections.is_active` или конкретный tool.
Шаг 33. Минимальный результат для запуска
MVP готов, если выполнены условия:
- CRM connection настроен;
- секреты не видны агенту;
- entity map заполнен;
- поля контакта описаны;
- поля лида описаны;
- входящие события сохраняются;
- structured output валидируется;
- кандидат контакта проходит проверку;
- дедупликация работает;
- лид создается через очередь;
- CRM API спрятан за backend tool;
- tool policy блокирует опасные действия;
- note создается;
- task создается;
- deal update идет через approval;
- CRM webhook принимается;
- API log заполнен;
- ошибки обрабатываются;
- idempotency работает;
- тесты критичных сценариев проходят.
Финальная проверка: отправьте новый лид, дубль, запрос на скидку, ошибку CRM API и CRM webhook. Если CRM получает одну чистую запись, дубли не создаются, опасные изменения идут на approval, а логи полные, интеграцию можно запускать ограниченно.
Что нельзя автоматизировать в первой версии
В первой версии не автоматизируйте:
- удаление контактов;
- merge контактов;
- изменение суммы сделки;
- изменение стадии на won или lost;
- смену ответственного без правила;
- массовое обновление CRM;
- отправку сообщений клиенту без approval;
- назначение скидок;
- изменение договорных условий;
- работу с платежными данными;
- создание счетов и актов;
- импорт всей истории CRM в prompt;
- запись сырых диалогов без summary;
- выполнение произвольных CRM methods;
- работу с production CRM без staging-тестов.
Сначала агент должен аккуратно создавать лиды, добавлять заметки и ставить задачи. Все, что влияет на деньги, юридические обязательства, стадию сделки и коммуникацию с клиентом, включайте только после тестов и approval.
Частые вопросы
Можно ли подключить агента напрямую к API CRM?
Лучше не надо. Безопаснее спрятать CRM API за backend tool, где есть валидация, дедупликация, права, rate limit, approval и audit log.
Что выбрать для первого запуска: Bitrix24, amoCRM или HubSpot?
Выбирайте ту CRM, где уже работают менеджеры. Технически важнее не бренд CRM, а наличие API, webhooks, sandbox, понятных сущностей и возможности ограничить права.
Нужно ли агенту менять сделки автоматически?
На первом этапе нет. Пусть агент создает черновик изменения и отправляет его на approval. Автоизменения стадий и сумм включайте только для очень узких правил.
Как не создавать дубли лидов?
Нужны нормализация телефона и email, поиск по существующим контактам, idempotency key для webhook и отдельный `crm_dedupe_checks` перед созданием записи.
Что делать, если CRM API временно недоступна?
Сохраняйте действие в очередь, делайте retry с лимитом, пишите ошибку в `crm_error_log` и показывайте оператору статус. Нельзя терять заявку или повторно создавать дубль при восстановлении API.