Менеджер слушает запись звонка и вручную заполняет карточку. Это 2026 год, бросьте
Каждый звонок от клиента - это золото. И каждый менеджер после часа переговоров тратит еще 15 минут, чтобы занести Budget, Authority, Need, Timeline в CRM. Ошибки, пропущенные детали, усталость. Цифры теряются, лиды "протухают".
Исправить это можно за один вечер. Соберите пайплайн, который сам слушает записи, понимает суть и структурирует данные в Bitrix24. Ядро - две российские технологии: YandexGPT 3.0 для анализа и МТС Exolve для расшифровки аудио. Все скрепим Python и Flask.
На 19 марта 2026 года YandexGPT 3.0 - самая свежая версия модели. Она поддерживает JSON-форматирование в ответах, что критично для автоматической обработки. МТС Exolve также обновил API транскрибации - теперь есть потоковый режим для длинных записей.
Что понадобится для сборки
- Аккаунт в Yandex Cloud (нужен для YandexGPT API).
- Доступ к МТС Exolve (сервис транскрибации).
- Bitrix24 с включенным REST API (любой тариф).
- Python 3.10+ на сервере (или даже на старой машинке в офисе).
- Базовое понимание, как работают HTTP-запросы.
Архитектура: три кита и один дирижер
Не делайте монолитный скрипт. Разбейте логику на модули, которые общаются через очереди или просто вызовы функций. Так легче тестировать и менять части.
| Модуль | Задача | Технология |
|---|---|---|
| Входная точка | Принимает вебхук о новом аудиофайле | Flask (легче всего) |
| Транскрибатор | Конвертирует запись звонка в текст | МТС Exolve API |
| Анализатор | Извлекает BANT-параметры из текста | YandexGPT 3.0 |
| Интегратор | Обновляет карточку лида в Bitrix24 | Bitrix24 REST API |
Если вы уже работали с OpenClaw и Битрикс24, то принцип слоеной архитектуры вам знаком. Здесь - та же философия.
1 Готовим ключи и среду
Сначала получите все API-ключи. Для YandexGPT понадобится идентификатор каталога и IAM-токен. В Exolve - просто API-ключ из личного кабинета. В Bitrix24 - вебхук для приложения (с правами на crm).
# Установите зависимости. Я предпочитаю venv.
python -m venv venv
source venv/bin/activate # или venv\\Scripts\\activate на Windows
pip install flask requests python-dotenv
Создайте файл .env и положите в него секреты. Никогда не хардкодьте их в скрипт.
# .env.example
YANDEX_FOLDER_ID=your_folder_id
YANDEX_IAM_TOKEN=your_iam_token
EXOLVE_API_KEY=your_exolve_key
BITRIX24_WEBHOOK=https://your_domain.bitrix24.ru/rest/1/your_webhook/
IAM-токен Yandex Cloud живет недолго. В продакшене нужно автоматически обновлять его через сервисный аккаунт. Для теста хватит ручного получения через CLI.
2 Пишем Flask-вебхук, который будет слушать
Этот эндпоинт будет принимать POST-запрос от вашей телефонии или из Bitrix24 (если запись звонка уже загружена).
from flask import Flask, request, jsonify
import os
from dotenv import load_dotenv
import logging
load_dotenv()
app = Flask(__name__)
logging.basicConfig(level=logging.INFO)
@app.route('/webhook/new_call', methods=['POST'])
def handle_new_call():
"""
Эндпоинт для приема данных о новом звонке.
Ожидает JSON с полями: call_id, record_url, lead_id.
"""
data = request.json
if not data:
return jsonify({'error': 'No JSON data'}), 400
call_id = data.get('call_id')
record_url = data.get('record_url')
lead_id = data.get('lead_id')
if not all([call_id, record_url, lead_id]):
return jsonify({'error': 'Missing fields'}), 400
# Запускаем асинхронную обработку (в реальности - в очередь)
# Для простоты сделаем синхронно
try:
transcript = transcribe_with_exolve(record_url)
bant_data = analyze_with_yagpt(transcript)
update_bitrix24_lead(lead_id, bant_data)
return jsonify({'status': 'success', 'call_id': call_id}), 200
except Exception as e:
logging.error(f"Pipeline failed: {e}")
return jsonify({'error': str(e)}), 500
if __name__ == '__main__':
app.run(host='0.0.0.0', port=5000, debug=True)
Сервер поднят. Теперь нужна логика для трех основных функций.
3 Заставляем МТС Exolve превратить аудио в текст
Exolve дает простой REST API. Отправляем ссылку на аудиофайл, получаем текст. Проверьте, что ваш файл доступен по публичной ссылке или используйте загрузку через multipart/form-data.
import requests
def transcribe_with_exolve(audio_url: str) -> str:
"""
Отправляет аудио на транскрибацию в МТС Exolve.
Возвращает распознанный текст.
"""
api_key = os.getenv('EXOLVE_API_KEY')
if not api_key:
raise ValueError('EXOLVE_API_KEY not set')
# Актуальный на 2026 год endpoint
url = "https://api.exolve.ru/v2/speech/recognize"
headers = {
'Authorization': f'Bearer {api_key}',
'Content-Type': 'application/json'
}
payload = {
'url': audio_url,
'language': 'ru-RU', # или 'en-US'
'profanity_filter': True,
'format': 'plain' # 'plain' или 'srt'
}
response = requests.post(url, json=payload, headers=headers)
response.raise_for_status()
result = response.json()
# Структура ответа может меняться, проверьте документацию
return result.get('text', '')
4 Дампим текст в YandexGPT и просим вытащить BANT
Вот здесь нужна точная настройка промпта. YandexGPT 3.0 умеет возвращать JSON. Мы заставим ее структурировать ответ по полям: Budget, Authority, Need, Timeline.
def analyze_with_yagpt(text: str) -> dict:
"""
Анализирует текст разговора и извлекает BANT-параметры.
"""
folder_id = os.getenv('YANDEX_FOLDER_ID')
iam_token = os.getenv('YANDEX_IAM_TOKEN')
if not folder_id or not iam_token:
raise ValueError('Yandex Cloud credentials not set')
url = "https://llm.api.cloud.yandex.net/llm/v1alpha/completion"
headers = {
'Authorization': f'Bearer {iam_token}',
'Content-Type': 'application/json'
}
# Критически важный промпт. Он должен быть стабильным.
prompt = f"""
Текст разговора менеджера с клиентом:
{text}
Проанализируй разговор и извлеки следующую информацию в формате JSON:
1. budget - бюджет клиента (цифра, если упоминается, или текстовая оценка).
2. authority - имеет ли клиент право принимать решение (true/false).
3. need - четко сформулированная потребность клиента.
4. timeline - сроки, когда клиенту нужно решение.
Если какая-то информация не найдена, укажи null.
Верни ТОЛЬКО JSON-объект без пояснений.
"""
payload = {
'model': 'general', # YandexGPT 3.0 доступна как 'general'
'generationOptions': {
'maxTokens': 1000,
'temperature': 0.1 # Низкая температура для предсказуемости
},
'messages': [
{'role': 'user', 'content': prompt}
],
'instructionText': 'Ты - аналитик продаж. Извлекай факты.'
}
response = requests.post(url, json=payload, headers=headers)
response.raise_for_status()
result = response.json()
# Ответ модели - строка, содержащая JSON
import json
result_text = result['result']['alternatives'][0]['message']['content']
try:
return json.loads(result_text.strip())
except json.JSONDecodeError:
# Фолбэк, если модель накосячила
logging.warning(f"YandexGPT returned invalid JSON: {result_text}")
return {'budget': None, 'authority': None, 'need': None, 'timeline': None}
Температуру ставим низкую, чтобы ответы были консервативными. Если ваши менеджеры говорят на специфичном жаргоне, добавьте в промпт примеры из реальных диалогов.
5 Толкаем структурированные данные обратно в Bitrix24
Теперь обновим карточку лида. В Bitrix24 REST API есть метод crm.lead.update. Мы мапим поля BANT на пользовательские поля CRM. Предположим, вы уже создали их в интерфейсе.
def update_bitrix24_lead(lead_id: int, bant_data: dict):
"""
Обновляет лид в Bitrix24, заполняя пользовательские поля BANT.
"""
webhook = os.getenv('BITRIX24_WEBHOOK')
if not webhook:
raise ValueError('BITRIX24_WEBHOOK not set')
# Маппинг полей. Названия полей должны совпадать с вашими в Bitrix24.
fields = {
'UF_CRM_BUDGET': bant_data.get('budget'),
'UF_CRM_AUTHORITY': 'Да' if bant_data.get('authority') else 'Нет',
'UF_CRM_NEED': bant_data.get('need'),
'UF_CRM_TIMELINE': bant_data.get('timeline'),
'COMMENTS': f"Автоматический анализ звонка выполнен. BANT извлечен." # Можно добавить текст разговора
}
# Удаляем None значения, чтобы Bitrix24 не ругался
fields = {k: v for k, v in fields.items() if v is not None}
params = {
'id': lead_id,
'fields': fields
}
response = requests.post(f"{webhook}crm.lead.update", json=params)
response.raise_for_status()
result = response.json()
if 'error' in result:
raise Exception(f"Bitrix24 error: {result['error_description']}")
return result
Все. Пайплайн готов. Но это только каркас.
Где вы споткнетесь: подводные камни 2026 года
- Обновление IAM-токена. В коде выше он статичный. В реальности нужно обновлять его каждые 12 часов. Используйте сервисный аккаунт с ролью
ai.languageModels.userи библиотекуyandex-cloudдля автоматизации. - Ограничения Bitrix24. Не штурмуйте API чаще 2 запросов в секунду. Добавьте задержки
time.sleep(0.5)между вызовами. Иначе получите 429 ошибку. - Качество транскрибации. Exolve может ошибаться в цифрах. Всегда проверяйте критичные данные (бюджет, сроки) вручную первые пару недель. Добавьте флаг "требует проверки" в карточку лида, если модель неуверена.
- Конфиденциальность. Аудиозаписи уходят во внешний API. Убедитесь, что это допускает ваша политика безопасности. МТС и Yandex имеют сертификаты, но риск всегда есть.
Для масштабирования вынесите задачи в очередь, например, Redis RQ или Celery. Flask-приложение будет только принимать вебхуки и ставить задачи в очередь. Это уберет таймауты.
Если вы хотите пойти дальше и создать целую систему ИИ-агентов для CRM, изучите наш гайд про ИИ-агентов для бизнеса. Там разобраны кейсы автоответов и прогнозирования.
Что дальше? Пару идей на вечер
Пайплайн работает. Данные летят в CRM. Но это только начало.
- Добавьте второй вебхук, который будет срабатывать при изменении лида и запускать сравнение моделей для оценки тональности разговора.
- Подключите Telegram-бота, который будет присылать менеджеру сводку по только что обработанному звонку. Как в кейсе с Woyax и Dynamics.
- Настройте автоматическое распределение лидов на основе полученного BANT. Если бюджет выше порога - сразу директору. См. гайд по распределению в Bitrix24.
Самое главное - запустите сначала в тестовом режиме на 10-20 звонках. Посмотрите, как модель ошибается. Подкорректируйте промпт. И только потом давайте доступ всем менеджерам.
Автоматизация не должна быть идеальной с первого дня. Она должна экономить время уже сейчас. Даже если 70% полей заполняются верно - это уже победа.