«С уважением, Иван» в середине письма: как мы чистим email-треды перед LLM

Менеджер пересылает нам письмо: килобайт сорок с лишним текста, шесть вложенных цитат, четыре блока с подписями, три юридических дисклеймера про «информацию, предназначенную исключительно для адресата», два автоматических «Sent from my iPhone» и где-то в самой середине — две строчки настоящей просьбы клиента: «Подскажите, есть ли ВВГ 5х10 в наличии и когда отгрузка». Эти две строчки — и есть та задача, ради которой запускается ИИ-агент. Всё остальное — балласт, который мы платим в токенах GigaChat Pro и за который расплачиваемся качеством ответа.
Я веду этот проект с самого начала, и когда мы впервые сели считать, из чего состоит средний корпоративный email-тред, стало не по себе. Смысла в письме — на две строки, а «мяса» — на пять экранов. Модель это «мясо» не игнорирует: она его аккуратно читает, тратит окно контекста и периодически галлюцинирует поверх подписей («заказчик упомянул другую модель кабеля» — нет, дорогой, это была фамилия отправителя, Кабельщиков).
Так и появился отдельный кусок работы, без которого никакое создание ИИ-агента на корпоративной почте не заработает нормально: чистка входящих писем до того, как их увидит модель.
Что мы режем и зачем
Давайте по-честному определим, что вообще считается мусором в B2B-переписке.
Первое — подписи. От лаконичной «С уважением, Анна» до полотна на пол-экрана с логотипом в base64, телефонами трёх отделов, дисклеймером про конфиденциальность и ссылками на соцсети.
Второе — цитаты предыдущих писем. В русском Outlook они идут с разделителем «От: … Отправлено: … Кому: … Тема: …». В Gmail — с «On … wrote:». В корпоративном Exchange — со своей причудой. И часто цитат несколько уровней вложенности.
Третье — авто-сноски. «Отправлено с моего iPhone», «Защищено антивирусом Касперского», «Это сообщение проверено DLP».
Четвёртое — дисклеймеры юристов на десять строк, которые в каждом письме одинаковые.
Каждый из этих блоков в отдельности безобиден. Все вместе — это большая часть контекста и большая часть счёта.
Первая попытка: давайте просто regex
Поначалу казалось, что задача линейная. Подпись начинается с «С уважением» или «Best regards». Цитата — с «От: …». Авто-сноска — с «Sent from». Двадцать минут на регулярки, обедаем, идём тестировать.
Я честно был уверен, что за день закроем.
Первая же тестовая выборка живых писем показала: треть мы либо обрезали слишком агрессивно, срезая половину последнего абзаца клиента, либо оставляли подпись внутри, потому что она начиналась с «Спасибо, Иван» вместо канонического «С уважением». Ещё в паре случаев regex съел цену из прайс-листа, потому что «₽» шёл после длинного тире и был похож на разделитель.
Боль номер один: «С уважением» в русской переписке встречается не только в конце. «С уважением к вашему графику предлагаю…» — это середина абзаца, а не точка отсечения.
Боль номер два: цитата не всегда начинается с «От:». В пересылках через мобильный Outlook бывает просто пустая строка и текст в кавычках. В Gmail на iOS — иногда без «On … wrote» вообще, просто отступ.
Боль номер три, самая мерзкая: подпись бывает первой, а не последней. Когда менеджер пересылает письмо и сверху пишет свой комментарий, его подпись оказывается зажатой между блоками. Резать «всё после первой подписи» — обрежешь ровно то, что нужно клиенту.
Стало понятно: регулярка — это слой номер один, и одного слоя мало. Настрой ИИ-агента без честного препроцессинга — это дорогая иллюзия работы.
23 признака, где заканчивается тело письма
Мы собрали корпус из нескольких тысяч писем (заранее анонимизированных — про это писали отдельно) и разметили руками, где у каждого письма проходит граница «текст-балласт». Дальше — простой статистический анализ: какие сигналы предшествуют границе.
Получили список из 23 признаков. Несколько примеров:
- Строка из трёх и более символов
-,=,_подряд (классический разделитель подписи). - Строка длиной до 40 символов, оканчивающаяся именем собственным, а следующая строка — должность или название компании.
- Подряд две строки с телефоном в формате
+7 (XXX)или8 (XXX). - Слово «Тел.», «Моб.», «E-mail», «Сайт» в начале строки.
- Заголовок цитаты Outlook: четыре строки подряд начинаются с «От:», «Отправлено:», «Кому:», «Тема:».
- Строка состоит только из
>с отступами (текстовая цитата). - Юридический дисклеймер: ключевые слова «конфиденциальн», «адресат», «не является публичной офертой» в пределах одного абзаца.
Каждому признаку присвоили вес. Решение «здесь заканчивается тело» принимается, если сумма весов на участке превышает порог. Это уже не голая регулярка, а лёгкий скоринг — десяток экранов на pure Python без всякого ML. Никаких моделей, никаких эмбеддингов, никакого GPU — просто арифметика по признакам.
Точность после этого шага перестала быть проблемой на глаз: разметчики брали случайные письма, смотрели, где мы поставили границу, и обычно кивали. Оставшиеся спорные случаи мы разбирали отдельно.
Подпись посреди письма и другие русские особенности
Последние проценты качества всегда самые дорогие. Их забрали отдельные эвристики под пересланные треды.
Когда у нас пересылка вида «Fwd: Re: Re: запрос по ВВГ», режем не один раз, а итеративно. Парсим письмо как DAG из сегментов: «комментарий менеджера», «подпись менеджера», «цитата клиента 1», «подпись клиента 1», «цитата клиента 2». Для LLM собираем только сегменты типа «комментарий» и «цитата», подписи выкидываем все.
Отдельная история — корпоративные шаблоны. У крупных заказчиков подпись часто содержит блок «Информация ниже предназначена…», а внутри — ссылка с UTM-меткой, в которой попадается слово «договор». Если ищем ключевые слова наивно, модель решит, что в письме обсуждали договор, хотя его там и близко не было. Такие блоки режем до извлечения смысла, а не после.
И самое коварное: корпоративные ответы вида «Согласовано. С уважением, Иван». Когда вся полезная информация — это одно слово «Согласовано», и оно приклеено к подписи. Если резать жадно, мы выкинем смысл вместе с подписью. Поэтому правило: если над сигнатурным блоком меньше пяти слов содержательного текста, сохраняем последнее предложение перед границей.
Именно на таких мелочах и живёт настоящая разница между ИИ-агентами и автоматизацией «на тяп-ляп». Регулярка на «С уважением» пишется за вечер. Устойчивая обработка русской корпоративной почты пишется месяцами и вылезает через живые кейсы.
Кейс: оптовик со стеной входящих
Один из наших заказчиков — крупный дистрибьютор, у которого менеджеры целый день обрабатывают запросы на остатки и сроки. Поток входящих такой, что живьём за ним не угнаться: часть писем неизбежно висит по полдня, клиенты нервничают, менеджеры выгорают. Задача ИИ-агента — снимать типовой поток «есть ли на складе, когда отгрузка, дайте цену», а людям оставлять сложное и нестандартное.
Что было до чистки писем. Каждый вызов модели тащил с собой всю подпись, все цитаты, все дисклеймеры. Модель регулярно путала контекст: вытаскивала имя клиента не из тела письма, а из подписи менеджера, который переслал запрос. Иногда придумывала товар, потому что в юридическом дисклеймере мелькало слово «кабель». Счёт за токены рос быстрее, чем радовал результат.
Что стало после того, как в пайплайн встал EmailCleaner. Средний запрос к модели похудел в разы — визуально это «письмо на экран» вместо «письмо на пять экранов». Путаница с контекстом почти ушла — не до нуля, у модели остались свои источники галлюцинаций, но менеджеры перестали приносить скриншоты «а откуда она это взяла». Счёт за токены заметно просел. Бонусом — задержка ответа упала: модель просто читает в разы меньше текста, и это чувствуется.
Окупился пайплайн быстро. Две недели работы инженера отбились экономией на токенах за считаные недели, качество ответа менеджеры отметили независимо, без наших графиков.
Где это лежит в продакшене
В архитектуре всё скучно — и это хорошо. Перед каждым вызовом LLM письмо проходит через сервис EmailCleaner:
- Парсинг MIME, выделение plain-text части (HTML конвертируется через
html2textс нашими правилами). - Сегментация на блоки по двойным переводам строк.
- Классификация каждого блока: «тело», «подпись», «цитата», «дисклеймер», «авто-сноска».
- Сборка очищенного текста с сохранением структуры тред-цепочки.
- Логирование того, что выкинули, — для аудита и для дальнейшей настройки правил.
Хранение — отдельная таблица в PostgreSQL: исходник, очищенная версия, список вырезанных блоков с типами. Если что-то пошло не так, всегда можно поднять письмо, посмотреть, что мы сочли мусором, и понять, в каком сегменте промахнулись. Без этого лога любая правка правил превратилась бы в гадание.
Отдельно про инфраструктуру: сервис живёт рядом с очередью писем, не на пользовательском ПК. Мысль «поставим ИИ-агента на пк секретаря и пусть он там что-то жуёт» звучит соблазнительно, но плохо кончается — с корпоративной почтой и 152-ФЗ такие вещи должны крутиться на нашем контуре, с нормальным логированием и разграничением прав.
Что важно понять
LLM — не магия, которая «как-нибудь разберётся». Каждый лишний абзац в промпте — это деньги, задержка и риск галлюцинации. Чистка email до того, как письмо доберётся до модели, — один из самых дешёвых способов одновременно поднять качество и сократить счёт.
Скоринг по 23 признакам — не rocket science. Это несколько сотен строк Python и день работы дата-аналитика на разметку. Но именно из таких «скучных» слоёв и складывается взрослая связка ИИ-агентов и автоматизации — та, которая доживает до второго квартала эксплуатации, а не разваливается на первой же нестандартной подписи.
Вопрос, который стоит задать себе, глядя на собственный пайплайн: какая доля токенов в ваших промптах — это содержательный сигнал, а какая — балласт, за который вы платите каждый день?
Похожие статьи
- Как мы научили ИИ-агента на GigaChat Pro не путать живого клиента с ночным батчем
- Как мы настроили ИИ-агента для поиска в 1С: MCP-сервер вместо метаний между окнами
- Один вопрос — три темы: как мы научили ИИ-агента разбирать составные запросы
- Text2SQL для 340 таблиц: как мы собирали ИИ-агента для анализа корпоративных данных на GigaChat Pro




