AI-агент для разбора входящей почты: сортировка, черновики ответов, утренняя сводка
Типичная жалоба, с которой к нам приходит офис-менеджер или секретарь директора: «в почте 100-150 писем в день, и я половину времени трачу не на ответы, а на то, чтобы понять, что вообще срочное». Правила Gmail и папка «Важное» тут не спасают — они работают на статистике открытий и ответов конкретного пользователя, а не на бизнес-логике компании. Мы строим для клиентов другой контур: агент на Claude, который читает почту через API, расставляет приоритеты по реальным правилам компании, готовит черновики типовых ответов и присылает к началу дня короткую сводку — что горит, что подождёт, кто уже неделю ждёт ответа. Это наша методология: архитектура доступа, классификация, экономика токенов и грабли, на которые мы уже наступили.
Почему встроенных фильтров почты недостаточно
Встроенная приоритизация Gmail (маркеры важности, вкладка «Важное») и похожие механизмы других почтовых клиентов обучены на поведении конкретного пользователя — что он открывает, на что отвечает быстро, что архивирует не читая. Это статистика кликов, а не знание о компании. Такой алгоритм не в курсе, что письмо от арендодателя офиса всегда приоритетное независимо от темы, что рассылка от одного конкретного маркетингового агентства — всегда мусор, а обращение с адреса на домене крупного клиента требует ответа в течение часа, даже если тема письма звучит нейтрально.
У секретаря или офис-менеджера в почте одновременно смешаны: письма от контрагентов и партнёров, автоматические уведомления 1С/CRM/банк-клиента, обращения соискателей, письма с документами на подпись, курьерские уведомления, спам и просто информационные рассылки. Правило «одна нейросеть на весь поток» тоже работает плохо без контекста — модели нужен список VIP-отправителей, глоссарий типовых категорий обращений и понимание, что для этой конкретной компании считается срочным. Поэтому наш агент — не обёртка над готовым ИИ-фильтром почтового провайдера, а отдельный сервис с собственной бизнес-логикой поверх LLM, который получает доступ к почтовому ящику через API и работает по правилам, которые мы формализуем вместе с клиентом на старте.
Дальше — как это устроено технически: откуда агент берёт письма, как классифицирует и приоритизирует, как готовит черновики и что попадает в утреннюю сводку.
Доступ к почте: Gmail API push или IMAP
Первое архитектурное решение — как агент узнаёт о новом письме. Здесь два принципиально разных пути в зависимости от того, где живёт почта клиента.
| Параметр | Gmail API (push через Pub/Sub) | IMAP (Exchange, корпоративная почта) |
|---|---|---|
| Механизм уведомления | users.watch регистрирует подписку, Gmail публикует событие с historyId в топик Google Cloud Pub/Sub, оттуда — вебхук в наш сервис | Команда IDLE держит TCP-соединение открытым, сервер сам присылает уведомление о новом письме в папке |
| Задержка | Секунды | Секунды, если соединение живо; при обрыве — до следующего переподключения |
| Срок жизни подписки | watch истекает через 7 дней — обязателен ежедневный cron на переподписку, иначе уведомления молча прекращаются | Сервер обычно закрывает IDLE-сессию по тайм-ауту около 29 минут (стандартная практика реализаций IMAP) — клиент обязан переоткрыть IDLE |
| Восстановление после простоя | users.history.list с сохранённым startHistoryId; если агент был недоступен дольше 7 дней, старый historyId возвращает 404 — нужен полный ресинк через messages.list с фильтром по дате | Обычный SEARCH/FETCH по UID с момента последнего обработанного письма |
| Права доступа | OAuth-скоупы gmail.readonly + gmail.modify (метки, архивирование) + gmail.compose (черновики) — не выдаём gmail.send, агент не должен уметь отправлять внешнюю почту сам | Отдельный почтовый аккаунт с ограниченными правами (только чтение + перемещение в папки), пароль приложения или OAuth2 для Exchange |
Для клиентов на Google Workspace мы почти всегда берём push-модель через Pub/Sub — она даёт нормальную задержку без постоянного опроса. Для клиентов на своей почте (Exchange, corporate IMAP, включая держателей ящиков на mail.ru для бизнеса) агент работает через MCP-сервер почты с инструментами вроде list_emails_metadata, get_emails_content, move_emails, archive_emails, mark_emails_as_read, create_draft — это тот же принцип: минимально необходимый набор операций, ничего лишнего типа удаления писем без подтверждения. Важное архитектурное правило, которое мы соблюдаем всегда: агент получает доступ только к тому ящику, для которого его настраивали (общий ящик секретаря или отдельный рабочий адрес), а не ко всей корпоративной почте — читать личную переписку сотрудников агенту незачем и нельзя.
Классификация и приоритизация: две ступени вместо одной
Прогонять каждое письмо целиком через тяжёлую модель — дорого и избыточно: большая часть входящего потока определяется по метаданным без обращения к телу письма. Поэтому классификация у нас двухступенчатая.
Ступень 0 — жёсткие правила без LLM. Домен отправителя из списка известного спама/рассылок, письма с адресов из внутреннего чёрного списка, автоматические уведомления с фиксированной темой (например, «Ваш заказ доставлен») — отсекаются до всякого обращения к модели, чистыми правилами по отправителю и заголовкам. Это экономит и токены, и время: по нашей практике на этом шаге отсеивается заметная часть суточного потока ещё до классификатора.
Ступень 1 — классификатор на дешёвой модели. Всё, что прошло правила, уходит в Claude Haiku 4.5 с обязательным вызовом инструмента — модель не отвечает свободным текстом, а обязана вернуть строго типизированный объект:
{
"model": "claude-haiku-4-5",
"max_tokens": 250,
"tools": [{
"name": "triage_email",
"input_schema": {
"type": "object",
"properties": {
"priority": {"type": "string", "enum": ["P0_critical", "P1_needs_reply", "P2_fyi", "P3_noise"]},
"category": {"type": "string", "enum": ["client", "partner", "vendor", "hr", "internal", "finance", "legal_docs", "newsletter", "other"]},
"requires_reply": {"type": "boolean"},
"deadline_hint": {"type": "string", "description": "дата или null, если явного дедлайна в тексте нет"},
"one_line_summary": {"type": "string"},
"suggested_label": {"type": "string"}
},
"required": ["priority", "category", "requires_reply", "one_line_summary"]
}
}],
"tool_choice": {"type": "tool", "name": "triage_email"}
}На вход классификатору мы даём не всё письмо целиком, а метаданные плюс первые несколько абзацев тела (снятые через get_emails_content) — этого достаточно в подавляющем большинстве случаев, а полный текст с вложениями подгружается только если модель явно не может определить категорию или запрашивается для генерации черновика ответа на следующем шаге.
Итоговый приоритет — не только вывод модели, а пересечение с бизнес-правилами: если отправитель есть в списке VIP-контактов (ключевые клиенты, учредители, арендодатель, бухгалтерия банка), приоритет не может быть ниже P1 независимо от того, что решила модель по тексту. Модель отвечает за нюансы содержания, список VIP и жёсткие правила — за то, что нельзя пропустить ни при каких обстоятельствах.
100+ писем в день съедают половину рабочего времени секретаря?
Мы настраиваем такого агента под конкретный почтовый ящик клиента — с его списком VIP-контактов, типовыми обращениями и правилами приоритезации, а не как универсальный шаблон поверх встроенных фильтров почты. Расскажите, сколько писем в день и какой у вас почтовый сервер — прикинем объём работ и с чего начать внедрение.
Маршрутизация: метки, папки, эскалация
После классификации агент выполняет действие, соответствующее приоритету, а не просто ставит метку и останавливается.
| Приоритет | Действие агента | Что видит человек |
|---|---|---|
| P0 — критично | Метка «Срочно» + мгновенное уведомление в мессенджер ответственному сотруднику с однострочной выжимкой и ссылкой на письмо | Алерт в Telegram/рабочий чат в течение секунд после получения письма |
| P1 — нужен ответ | Метка «Требует ответа», письмо ставится в очередь на генерацию черновика | Черновик ответа появляется в папке «Черновики» почтового ящика, ничего не отправляется автоматически |
| P2 — для сведения | Метка по категории (клиент/HR/финансы), письмо остаётся во «Входящих», но без пометки срочности | Попадает в утреннюю сводку одной строкой, отдельного уведомления нет |
| P3 — шум | Архивирование или перенос в папку «Автоматически отфильтровано» | Не показывается вообще; раз в неделю можно посмотреть папку и проверить, не улетело ли туда что-то важное |
Отдельно решаем проблему дублей: у Pub/Sub гарантия доставки «at least once», то есть одно и то же событие может прийти агенту дважды. Прежде чем ставить метку, отправлять алерт или создавать черновик, агент проверяет заголовок Message-ID в собственном журнале обработанных писем — если оно уже обработано, повторная доставка события просто игнорируется. Без этой проверки на практике получаются задвоенные алерты в мессенджер по одному и тому же письму, и после второго-третьего случая доверие к системе у секретаря падает.
Черновики ответов: контекст решает больше, чем модель
Для писем с приоритетом P1 агент готовит черновик ответа, но никогда не отправляет его сам — это осознанное ограничение, а не техническое. Внешняя переписка от лица компании — репутационная зона: черновик всегда ждёт человека в папке «Черновики», и отправляет его секретарь или ответственный сотрудник после беглой проверки. Автоматическая отправка без участия человека у нас разрешена только для чисто внутренних технических подтверждений (например, автоответ «письмо получено, в работе» на внутренний тикет), никогда — для внешней стороны.
Качество черновика определяется не столько моделью (для этой задачи достаточно Claude Sonnet 5 — здесь важнее не скорость, а точность тона и содержания), сколько контекстом, который мы ей даём:
- История переписки с этим отправителем. Последние несколько писем из того же треда через
get_emails_content— модель видит, как компания уже отвечала этому контрагенту, и не начинает разговор «с нуля». - Шаблоны типовых обращений. Для повторяющихся вопросов (запрос реквизитов, счёт на оплату, перенос встречи, статус заявки) в системном промпте лежит набор заготовок с плейсхолдерами — модель адаптирует шаблон под конкретную ситуацию, а не сочиняет с нуля каждый раз, что заметно снижает риск случайной отсебятины в важных деталях типа сумм и дат.
- Тон и подпись компании. Стиль обращения («вы», формальный деловой тон, стандартная подпись с должностью и телефоном) задаётся один раз в системном промпте и не меняется от письма к письму.
Для действительно сложных ящиков, где база знаний компании велика (типовые ответы по десяткам продуктов или услуг), простого поиска по отправителю и ключевым словам недостаточно — тогда мы добавляем векторный поиск по базе шаблонов и внутренних regulations (embeddings через Voyage AI, которую Anthropic рекомендует как основного провайдера эмбеддингов для таких задач), но для типичного ящика секретаря на 100-150 писем в день с несколькими сотнями постоянных контрагентов хватает обычного поиска по истории треда и справочнику VIP/шаблонов без отдельной векторной базы — это лишняя инфраструктура там, где задача решается проще.
Технически черновик создаётся вызовом drafts.create Gmail API (тело письма в формате RFC 2822, закодированное в base64url, с указанием threadId, чтобы ответ остался в исходном треде, а не улетел отдельным письмом) либо соответствующим инструментом MCP-сервера почты, если ящик не на Google Workspace.
Утренняя сводка: что должно быть на экране в 8:30
Отдельная генерация — не по каждому письму, а раз в день, до начала рабочего дня. Задача сводки — дать секретарю и руководителю единую картину без необходимости открывать почту и листать всё подряд.
| Блок сводки | Содержание |
|---|---|
| Горит сейчас | Все P0 за последние 24 часа с однострочной сутью и статусом (отвечено/не отвечено) |
| Ждут вашего ответа | P1 с черновиками, уже подготовленными агентом — достаточно проверить и отправить |
| Копится долго | Письма любого приоритета, которые висят без ответа дольше установленного порога (SLA по возрасту письма) — то, что рискует превратиться в неловкую ситуацию с контрагентом |
| Для сведения | Список P2 одной строкой на письмо, без черновиков и без действий |
| Отфильтровано | Количество писем, ушедших в P3 за сутки — чтобы человек видел объём, но не тратил на него время |
Сводка формируется по расписанию (мы обычно ставим её на время незадолго до начала рабочего дня клиента, конкретный час — часть настройки под график компании) и уходит в Telegram-бот или письмом на отдельный адрес — не смешивается с общим потоком входящих. Генерация текста сводки — это уже задача не классификации, а связного изложения, поэтому здесь мы снова используем Claude Sonnet 5: у модели есть на входе весь список писем с их приоритетами и однострочными выжимками от классификатора, а задача — собрать это в читаемый связный текст, а не выдать сухой список.
Системный промпт для сводки (правила приоритезации, список VIP-контактов, глоссарий категорий, стиль изложения) — величина постоянная от запуска к запуску в течение дня, поэтому мы кладём его в кэшируемый блок промпта. Anthropic документирует, что попадание в кэш стоит около 10% от цены обычного входного токена, то есть при многократных обращениях с одним и тем же системным контекстом (а классификатор внутри дня вызывается на каждое новое письмо с одним и тем же набором правил) стоимость повторных вызовов падает в разы по сравнению с тем, как если бы весь этот блок передавался заново в каждом запросе.
Экономика: какая модель на какую задачу и как считать токены
Мы намеренно не используем одну модель на всё — задачи внутри пайплайна разные по сложности, и переплата за избыточную мощность там, где хватает дешёвой модели, не имеет смысла.
| Задача | Модель | Почему |
|---|---|---|
| Классификация и приоритизация письма | Claude Haiku 4.5 | Строго типизированный короткий ответ через tool use, объём входа небольшой (метаданные + начало текста), важна цена и скорость на большом потоке |
| Генерация черновика ответа | Claude Sonnet 5 | Нужен корректный деловой тон, работа с контекстом истории переписки, минимизация риска фактических ошибок в реквизитах и датах |
| Утренняя сводка | Claude Sonnet 5 | Связное изложение по множеству входных объектов, а не разбор одного письма |
| Мгновенный алерт по P0 | Claude Haiku 4.5 | Нужна короткая формулировка «что случилось и почему срочно» для мессенджера, без развёрнутого анализа |
Два механизма снижения стоимости, которые мы применяем в связке. Во-первых, накопившуюся за ночь почту (письма, которые пришли не в рабочие часы и не требуют классификации в реальном времени) мы прогоняем через Message Batches API — Anthropic документирует скидку 50% от обычной цены токенов для асинхронной пакетной обработки. Во-вторых, входящий поток в течение рабочего дня, где счёт идёт на секунды до эскалации P0, обрабатывается синхронными вызовами, но с прогретым кэшем системного промпта. При совместном использовании batch-обработки и кэширования суммарная экономия на объёмных, не срочных участках пайплайна (прежде всего — ночная классификация backlog) складывается из обеих скидок, поскольку они документированы как совместимые друг с другом.
По нашей практике на потоке порядка 100-150 писем в день основная масса токенов уходит именно на классификацию (короткие вызовы, но их много), а не на черновики ответов — реального «нужен развёрнутый ответ» из полутора сотен писем в день обычно набирается на порядок меньше, поэтому именно классификатор в первую очередь стоит переводить на batch-обработку там, где это позволяет требование к скорости.
Грабли, на которые мы уже наступили
- Watch тихо перестаёт работать. Подписка Gmail API
users.watchистекает через 7 дней без предупреждения в почту — если cron на переподписку упал и никто не заметил, агент просто молча перестаёт получать уведомления, а не падает с явной ошибкой. Обязателен отдельный мониторинг самого факта продления подписки, а не только работоспособности сервиса. - Пропуск окна ресинка. Если агент был недоступен дольше 7 дней (отпуск инфраструктуры, миграция сервера), сохранённый
historyIdдляhistory.listстановится невалидным и API отвечает 404 — нужен запасной путь полного ресинка черезmessages.listс фильтром по дате, иначе часть писем просто теряется из вида агента. - Алерт-усталость от P0. На старте порог P0 у нас был слишком широким — любое письмо от домена клиента с восклицательным знаком в теме уходило в мгновенный алерт. Через неделю сотрудники начали игнорировать уведомления в принципе. Пришлось ужесточить правило: P0 присваивается только при совпадении двух независимых сигналов (VIP-отправитель И явный маркер срочности в тексте), а не любого из них по отдельности.
- Дублирующиеся события Pub/Sub. Гарантия доставки «at least once» означает, что одно письмо иногда триггерит обработку дважды — без проверки по
Message-IDперед действием агент дважды ставит метку, дважды создаёт черновик или дважды шлёт алерт в чат. - Вложения — не автоматическое исполнение. Агент скачивает вложения (через
download_attachment) только для чтения содержимого в контекст черновика или сводки — никогда не открывает и не исполняет файлы. Защита от вредоносных вложений остаётся за существующим почтовым шлюзом и антивирусом, агент эту функцию не подменяет и не должен. - Контекст только последнего письма недостаточен. Если анализировать только последнее сообщение в треде без предыдущей переписки, модель иногда неверно оценивает срочность длинной цепочки — переслано письмо с историей согласований, где суть в третьем сообщении сверху, а не в последнем «плюс один».
Как мы внедряем это по шагам
- Аудит реального потока (около недели). Смотрим фактическую почту клиента без автоматизации: сколько писем в день, какие категории повторяются, кто в списке VIP-отправителей, какие типовые ответы дублируются вручную из письма в письмо.
- Подключение с минимальными правами. OAuth-скоупы или MCP-доступ только к нужному ящику, без права самостоятельной отправки внешней почты на старте.
- Классификатор в «теневом» режиме. Агент размечает письма приоритетами, но не выполняет никаких действий — метки и решения сверяются вручную с тем, как реально поступил бы секретарь, правила и VIP-список калибруются по расхождениям.
- Включаем автодействия для низких приоритетов. Сначала автоматизируем самое безопасное — архивирование P3 и разметку P2, здесь цена ошибки минимальна.
- Черновики для P1. Включаем генерацию черновиков ответов, но отправка остаётся ручной; параллельно копится статистика, насколько черновики приходится править.
- Утренняя сводка. Включаем дайджест последним из «мирных» этапов — к этому моменту приоритеты уже откалиброваны и в сводке не будет шума.
- Эскалация P0 — в последнюю очередь. Самый чувствительный к порогам этап, включаем только когда правила VIP и маркеров срочности проверены на реальных данных за несколько недель, чтобы не словить алерт-усталость с первого дня.
- Регулярная калибровка. Раз в одну-две недели просматриваем письма, где классификация разошлась с фактическим поведением человека, и правим правила и системный промпт — список VIP-контактов и типовых категорий у живой компании не статичен.
Частые вопросы
- Агент может читать всю почту компании, включая личную переписку сотрудников?
- Нет. Доступ настраивается только к тому ящику, для которого агента разворачивают — обычно это общий ящик секретаря или отдельный рабочий адрес офис-менеджера. Права выдаются по принципу минимальной достаточности (чтение, разметка, черновики), и агент не подключается к личным почтовым ящикам сотрудников без отдельного согласования для каждого из них.
- Агент отправляет письма от лица компании самостоятельно?
- Нет, для внешней переписки — никогда. Агент готовит черновик ответа и кладёт его в папку «Черновики», отправляет человек после проверки. Автоматическая отправка без участия человека допускается только для сугубо внутренних технических подтверждений, никогда — для внешней стороны.
- Что если агент неправильно определит приоритет письма?
- На старте система работает в теневом режиме — расставляет приоритеты, но не выполняет действий, что позволяет сверить разметку с реальным поведением секретаря и откалибровать правила и список VIP-контактов до включения автоматических действий. После запуска расхождения разбираются на регулярной еженедельной калибровке.
- Нужно ли переходить на Gmail или менять почтовый сервер?
- Нет. Для Google Workspace используется push-модель через Gmail API и Pub/Sub с минимальной задержкой. Для любого другого сервера — корпоративного Exchange, почты на своём домене — агент работает через IMAP и MCP-сервер почты; разница только в задержке уведомления, а не в наборе возможностей.
- Сколько времени занимает внедрение такого агента?
- По нашей практике — порядка месяца от аудита реального потока писем до включения всех этапов, включая теневой режим для калибровки приоритетов и постепенное включение автоматических действий от самых безопасных (архивирование мусора) к самым чувствительным (мгновенная эскалация критичных писем). Срок зависит от того, насколько формализованы правила приоритезации у конкретной компании на старте.