惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

罗磊的独立博客
Google DeepMind News
Google DeepMind News
MyScale Blog
MyScale Blog
A
About on SuperTechFans
Martin Fowler
Martin Fowler
M
MIT News - Artificial intelligence
Recent Announcements
Recent Announcements
D
DataBreaches.Net
B
Blog
博客园 - 【当耐特】
爱范儿
爱范儿
有赞技术团队
有赞技术团队
P
Proofpoint News Feed
WordPress大学
WordPress大学
小众软件
小众软件
Apple Machine Learning Research
Apple Machine Learning Research
I
InfoQ
Engineering at Meta
Engineering at Meta
Cyber Security Advisories - MS-ISAC
Cyber Security Advisories - MS-ISAC
Last Week in AI
Last Week in AI
Microsoft Azure Blog
Microsoft Azure Blog
雷峰网
雷峰网
量子位
G
Google Developers Blog

Все публикации подряд на Хабре

Ловим музу за клавиатуру: как айтишнику стать автором Что умеет Midjourney в 2026? Мой немного грустный разбор этого шикарного инструмента Никто не любит писать тесты, но ИИ может исправить это IPv8 выглядит как мечта. Поэтому почти наверняка не взлетит Производители вернули в продажу материнки с DDR3. Что происходит? Управление агентом с телефона через Telegram теперь в KodaCode От координации к лидерству: как меняется роль руководителя разработки Я сделала родителям бизнес вместо пенсии: зарабатываем 70 тысяч, мама не даёт продать В три раза быстрее приемка товара и оптимизация трудозатрат на 73%: как «РСТ-Инвент» помог Gulliver Group ИИ-шечный мир победил? О влиянии искусственного интеллекта на игропром Кремль снижает давление на Телеграмм пока Европа строит интернет по паспорту Как CEO, CTO и CIO за 8 часов собрали ИИ-директора, который умеет держать позицию под давлением Как (не) потерять домен за выходные Вместо 8 разных VPS: как я организовал практику студентам на одном сервере Почему твой Open Source проект не замечают? R&D: искусство управления неопределенностью в разработке AI-дефляция: вакансий для разработчиков больше, а рост зарплат — худший за 15 лет Мы отдали управление роботами OpenClaw. Что из этого вышло Галактический ID: система идентификации для всех форм разумной жизни Шесть основ бизнес-анализа: начинаем с вопроса «Кто в игре?» Код-ревью, в котором дело не в коде Данные переехали. Команда — нет Системной подход к сдаче OSWE в 2025 Почему комната управления реактором покрашена в цвет морской пены 4 YAML-файла вместо PySpark: как аналитикам строить пайплайны без разработчиков LLM-агент для поиска свободных доменов: автоматизируем подбор Когда, зачем и как правильно начинать новую сессию в Claude Code? Как я заставил нейросеть писать макросы для FreeCAD Анатомия ИИ‑агента для подбора персонала. От тысячи резюме к топ‑10 за минуты Опыт разработчика как экономика внимания
Подключили B2B email-платформу к голосовым ассистентам че...
art-online-s · 2026-05-22 · via Все публикации подряд на Хабре

Время на прочтение6 мин

Охват и читатели307

Обзор

TL;DR. Live Direct Marketing (LDM) — B2B email-платформа с собственным MCP-сервером. Веб-интерфейс и MCP экспонируют один и тот же /api/* через HybridAuthGuard, поэтому при подключении к голосовому ассистенту через MCP агент получает ровно ту же поверхность, что и пользователь дашборда. Без дублирования контроллеров, без отдельного agent API.

Опробовали в полевых условиях на VODEXPO 2026: голосовая команда → рассылка по сегменту базы → пофайловая верификация доставки в инбокс. Ниже — архитектура, фрагменты кода, и где это всё реально ломается.

Контекст

LDM — мульти-тенантная платформа для B2B коммуникации: CRM (companies/contacts/leads), сегменты, креативы, рассылки, диалоги вход/выход, suppression/stop-lists, антиспам-маркинг, deliverability-чекер. Стек: NestJS + Prisma + PostgreSQL + BullMQ + Redis, фронт на React + Turborepo. Tenant-изоляция через отдельную БД на пользователя.

Главная особенность — пофайловая верификация попадания исходящих писем в инбокс через сеть seed-mailboxes.

Архитектурное решение: UI = MCP

Когда стало понятно, что MCP станет дефолт-стандартом для агентного доступа к SaaS, стандартный выбор был: писать отдельный agent-API mirror поверх существующего веб-API, или сделать единую поверхность. Выбрали второе.

Все эндпоинты живут под /api/*. Перед ними HybridAuthGuard, который умеет резолвить либо сессионный cookie (UI), либо Bearer-ключ формата ldm_pk_* (MCP/voice/external agent). Дальше — один контроллер, один scope-чек, одна бизнес-логика.

typescript

// упрощённо
@Injectable()
export class HybridAuthGuard implements CanActivate {
  async canActivate(ctx: ExecutionContext): Promise<boolean> {
    const req = ctx.switchToHttp().getRequest();

    // 1. Bearer (agent / MCP / voice skill)
    const m = req.headers.authorization?.match(/^Bearer (ldm_pk_\w+)$/);
    if (m) {
      const key = await this.apiKeys.verifyHash(m[1]);
      if (!key) throw new UnauthorizedException();
      req.user = key.user;
      req.scopes = key.scopes; // gated по grant
      return this.checkScopeFor(req);
    }

    // 2. Session cookie (web UI)
    const session = await this.sessions.fromCookie(req);
    if (!session) throw new UnauthorizedException();
    req.user = session.user;
    req.scopes = ['*']; // UI = full scope
    return true;
  }
}

Каждая capability описана в /.well-known/agent-card.json (A2A discovery) со своим scope-ом: email:send, crm:read, dialogs:write, mailing:write, и так далее. Bearer-ключ выпускается с явным набором scope-ов — голосовому навыку можно выдать ограниченный ключ, который умеет читать диалоги и слать письма из конкретного аккаунта, но не имеет доступа к exports, billing, suppression management.

MCP-сервер

Опубликован как npm-пакет ldm-crm-mcp. Под капотом тонкая обёртка над /api/*: берёт LDM_API_KEY из env, проксирует MCP-tool вызовы в HTTP. ~30 инструментов на частые операции, ~120 эндпоинтов всего доступно через generic invocation.

Конфиг Claude Desktop / Cursor:

json

{
  "mcpServers": {
    "ldm-crm": {
      "command": "npx",
      "args": ["-y", "ldm-crm-mcp"],
      "env": { "LDM_API_KEY": "ldm_pk_..." }
    }
  }
}

Подключение к Яндекс Алисе

Схема навыка:

  1. Голос → STT (Яндекс) → текст

  2. Текст → backend навыка → выбор MCP-инструмента + параметры

  3. MCP tool call → /api/* LDM → ответ

  4. Ответ → формулировка реплики → TTS Алисы

В роли «мозга» в backend навыка — Claude через API. Он интерпретирует свободную речь и выбирает нужный tool из MCP-списка. Это избавляет от необходимости писать grammar в навыке для каждой команды.

Аутентификация: account linking через Yandex OAuth → пользователь получает в LDM привязку к Yandex ID, навык получает Bearer-ключ с ограниченным scope (dialogs:read, dialogs:write, mailing:write, contacts:read).

Деструктивные действия (запуск рассылки, отправка письма, апдейт сделки) требуют голосового подтверждения — навык проговаривает summary и ждёт «да». Чтение и брифинг — без.

Полевой кейс: VODEXPO 2026

22 мая 2026. Москва, последний день водохозяйственной выставки. Клиент работает на стенде. Подходит ландшафтный дизайнер, просит каталог решений по водоёмам.

Клиент не за компьютером:

> Алиса, разошли каталог решений по водоёмам по всем подписавшимся 
  ландшафтным дизайнерам.

> Найдено: 247 контактов в сегменте "ландшафтные дизайнеры — подписка".
  Шаблон: "Каталог решений по водоёмам v3, май 2026". 
  Подтвердить отправку?

> Да.

> Отправляю.

Что происходит под капотом (Claude-агент в backend навыка решает выполнить такую последовательность):

bash

# 1. Резолв сегмента
GET /api/contacts?tagId=landscape-designers&subscribed=1&pageSize=500
→ 247 contacts

# 2. Резолв креатива
GET /api/creatives?search=каталог+водоёмы&latest=1
→ creativeId

# 3. Создание mailing task
POST /api/tasks
{
  "methodId": 2,
  "creativeId": "cmoue9...",
  "contactListId": "<ad-hoc>",
  "accountId": "<account>"
}
→ taskId, status: DRAFT

# 4. Self-approve (scope: mailing:write)
POST /api/mailing/$TASK_ID/approve
{ "note": "Voice-approved, designer at VODEXPO booth" }

# 5. Старт
POST /api/tasks/$TASK_ID/start
→ status: ACTIVE

20 секунд — рассылка ушла. Дальше начинается то, ради чего, собственно, всё и затевалось.

Per-message inbox verification

Стандартная схема у cold/B2B email-платформ: warm-up + inbox rotation + pre-flight inbox placement test (отправили 20 писем на seed-mailboxes до запуска, посчитали процент в инбоксе). Это статистическая оценка по сэмплу до факта.

У LDM схема другая: каждое реальное исходящее письмо после отправки верифицируется через сеть seed-mailboxes. На каждого провайдера развёрнуто 10–30 seed-ящиков (для Gmail и Outlook — около 100 каждый). Грубо схема такая: при отправке SMTP → реальный получатель параллельно создаётся test twin на seed-ящик соответствующего провайдера с теми же заголовками, body, аккаунтом-отправителем. Через IMAP опрашиваются папки INBOX vs SPAM/JUNK/Quarantine, результат пишется в поле placement диалога.

Это не идеальный proxy — seed-ящик ≠ конкретный реальный получатель, провайдер может фильтровать индивидуально по recipient-сигналам. Но это сильно лучше pre-flight теста по трём причинам:

  1. Проверка идёт по каждому реальному отправлению, а не по выборке.

  2. Учитывается актуальное состояние репутации в момент отправки (а не за день до запуска кампании).

  3. Падение в спам у конкретного провайдера ловится в реальном времени — и срабатывает автоматический pause, если процент spam за окно превышает порог.

Endpoint, который опрашивает навык после рассылки:

bash

GET /api/dialogs/stats?taskId=$TASK_ID
{
  "total": 247,
  "placement": {
    "inbox": 231,
    "spam": 4,
    "unchecked": 12
  },
  "byProvider": {
    "gmail":   { "inbox": 142, "spam": 1 },
    "yandex":  { "inbox": 47,  "spam": 0 },
    "outlook": { "inbox": 18,  "spam": 3 },
    ...
  }
}

Алиса возвращает голосом: «Отправлено 247. В инбоксе 231, в спаме 4, ещё 12 проверяются. Outlook просел — 3 в спаме из 21».

Биллинг — за 231 inbox-доставленных. 4 спам и 16 заблокированных не тарифицируются.

Где голос работает плохо

Без маркетингового лоска. Голос покрывает 20–30% операций оператора, не больше. Остальные 70% неудобны или невозможны.

Работает хорошо:

  • Утренний брифинг по входящим диалогам.

  • Запуск заранее настроенной рассылки по известному сегменту.

  • Ответ на конкретное входящее письмо (короткий).

  • Проверка статуса доставки конкретного письма или кампании.

  • Ad-hoc вопросы по статистике.

Не работает:

  • Сложные многопараметрические фильтры (вроде «компании Москва + 50–500 сотрудников + e-commerce + без активности 30 дней + tag X»). Это удобнее в UI.

  • HTML-вёрстка/правка креативов.

  • Дизайн многошаговых пайплайнов (best-time-sending, последовательности follow-up, A/B-ветвления).

  • Распознавание латинских доменов / имён компаний. Алиса систематически слышит Apple как «Эппл», Acme как «Акме». Лечится фонетической нормализацией на бэке через словарь из CRM, но точность ~70–85%, не 100%.

Хрупкие места:

  • Refresh OAuth-токенов Yandex ID. Особенно если пользователь меняет пароль — навык теряет привязку, требуется переавторизация.

  • Подтверждения в шумной среде. На стенде, в машине с открытыми окнами «да» распознаётся через раз.

  • Латентность. Цепочка STT → Claude (intent + tool selection) → MCP → /api/* → ответ → формулировка → TTS — суммарно 4–8 секунд на типовой команде. Для email-операций приемлемо, для conversational UX чувствуется.

Tradeoffs архитектуры

MCP — это транспорт. Полезность зависит от того, что через него экспонируется. У многих CRM-платформ (HubSpot, Salesforce DX) MCP read-only или ограничен подмножеством объектов. У LDM через MCP доступна полная UI-поверхность, включая запуск рассылок и self-approve — это полезно для агентов, но требует разумной модели scope-ов и подтверждений на стороне клиента (навыка / агента).

Архитектурное решение «UI = MCP» имеет цену. Любое расширение API автоматически становится агент-callable. Это требует дисциплины — нельзя положить в /api/* что-то, что должно быть UI-only по соображениям UX или безопасности. На практике это решается scope-ами и доп. middleware для отдельных handler-ов, но это нагрузка на дизайн.

Голос как UI — узкая ниша. Это не «новый интерфейс взамен дашборда». Это дополнение для конкретных сценариев — мобильности, занятых рук, быстрого брифинга. Прибавляет ценности на 10–15% операций, не больше.

Что дальше

  • MCP-сервер v2 с явной JSON Schema для каждого tool (сейчас многие возвращают свободный JSON, агенту приходится самостоятельно парсить).

  • Подключение к ChatGPT MCP Apps directory.

  • Voice-friendly dialogs/stats — плоский ответ, короче, без вложенных объектов, чтобы TTS не глотал секунды на проговаривании.

  • Поддержка Apple Intelligence через MCP App Extensions, как только Apple откроет это для third-party (по обещаниям — Q3 2026).

Доки публичные: developers.live-direct-marketing.online. Вопросы по архитектуре / реализации — в комментариях или в почту.