Отчёт отдела продаж по расписанию: ИИ-агент

7 минут чтения

Недельный отчёт отдела продаж может приходить сам, по расписанию. Если руководителю нужны цифры, хватит скрипта: он считает выручку, оплаты и зависшие сделки по выгрузке из CRM без расходов на нейросеть. Если нужен разбор с вопросами к планёрке, добавьте ИИ-агента: он разбирает первый отчёт и затем каждый изменившийся. Первый разбор Hermes оценил в $0,22. Если не уверены, начните со скрипта.

Мы собрали оба варианта в Hermes Agent на выгрузке вымышленной компании. Настройку под вашу CRM оцениваем в 6–11 часов работы исполнителя, или 930–1 705 разово.

Что выбрать

Что получаете
Цена и где подводит

Только цифры

Что получаете

отчёт в понедельник утром, как в примере ниже

Цена и где подводит

без расходов на нейросеть; старая или неполная выгрузка может дать неверный отчёт

Цифры и разбор

Что получаете

вопросы к планёрке по первому и каждому изменившемуся отчёту, включая правки задним числом

Цена и где подводит

первый разбор оценён в $0,22; пропускает правки вне отчёта

Разбор с памятью

Что получаете

сравнение с прошлой неделей: какие сделки висят дольше

Цена и где подводит

нейросеть вызывается каждый раз; цену недельного запуска не проверяли. Список прошлой недели храните скриптом

Что приходит в понедельник

Компания в примере вымышленная: монтаж отопления в частных домах, четыре менеджера, 58 сделок в выгрузке. Скрипт берёт прошлую неделю с понедельника по воскресенье и сравнивает её с позапрошлой. Вот вывод ручного запуска 22 октября:

Отчёт из задачи без нейросети, 22 октября 2026
Отчёт отдела продаж: 12–18 октября
(в скобках прошлая неделя, 5–11 октября)

Выручка: 85 600 BYN (37 900)
Оплачено сделок: 18 (6), средний чек 4 755 BYN
Новых сделок: 20 (22)
Отказов: 7 (3)

Воронка сделок, созданных за две недели (42):
  Квалификация     38  90%
  КП отправлено    27  64%
  Счёт выставлен   19  45%
  Оплачено         16  38%

Менеджеры за неделю: новых / оплачено / выручка BYN
  Ольга     5 / 9 / 49 600
  Марина    4 / 4 / 14 500
  Сергей    6 / 2 / 11 500
  Павел     5 / 3 / 10 000

Зависли: открыты и без движения больше 7 дней (5)
  #1003 Ольга, КП отправлено, 3 800 BYN, без движения с 21 сентября
  #1011 Сергей, Счёт выставлен, 2 400 BYN, без движения с 26 сентября
  #1007 Павел, КП отправлено, 11 200 BYN, без движения с 30 сентября
  #1030 Сергей, Новая, 11 200 BYN, без движения с 8 октября
  #1025 Павел, Новая, 8 400 BYN, без движения с 9 октября

Здесь выручка равна сумме полностью оплаченных сделок, дата закрытия считается датой оплаты. Частичных оплат и возвратов нет. В оплатах есть и сделки сентября. В воронку попадают сделки, созданные за две недели; скрипт считает, что этапы они проходят по порядку. Воронка и список зависших отражают текущую выгрузку. Состояние на конец недели скрипт не восстанавливает. Зависшая сделка открыта, а последняя правка была больше семи дней до конца отчётной недели.

Что пишет ИИ-агент

Каждое утро Hermes пересчитывает отчёт и сравнивает его с прошлым. Если ничего не изменилось, нейросеть не вызывается: у нас такая проверка заняла 1,6 секунды. В понедельник меняются даты в заголовке, поэтому разбор будет даже при прежних итогах. Мы изменили одну строку выгрузки, как будто менеджер задним числом отметил оплату сделки #1007, полученную 17 октября. При проверке после правки агент подготовил разбор за 25 секунд:

Разбор агента после правки выгрузки, как он пришёл
**Что изменилось.** Отчёт за уже прошедшую неделю 12–18 октября обновился. Выручка теперь 96 800 BYN вместо 85 600, оплат 19 вместо 18, средний чек 5 094 BYN. У Павла 4 оплаты на 21 200 BYN вместо 3 на 10 000. Сделка #1007 на 11 200 BYN выпала из зависших, их теперь 4.

**Вопросы на планёрку:**
1. Павел: оплачена ли #1007 и почему она появилась в отчёте за закрытую неделю. Ещё у него #1025 на 8 400 BYN стоит «Новой» с 9 октября.
2. Сергей: #1030 на 11 200 BYN «Новая» с 8 октября, по #1011 на 2 400 BYN счёт без движения с 26 сентября.
3. Отказов 7 против 3 неделей раньше. Чьи это сделки и почему отказали?
Три запуска проверки отчёта и разница, которую получил агент
На тех же цифрах нейросеть не вызывалась.

Вопрос про оплату в закрытой неделе агент нашёл сам. Из CRM в запрос попадают суммы, этапы, имена менеджеров и номера сделок, их обрабатывает Claude от Anthropic. Hermes также добавляет служебные инструкции и записи из памяти профиля, если они есть: перед рабочим запуском проверьте, что в ней хранится.

Где это работает: Hermes Agent

Hermes Agent от Nous Research можно бесплатно установить на компьютер или сервер компании. У программы открытый код. Исполнитель настраивает запуск скрипта и агента по расписанию. Для отчёта в Telegram он подключает бота. В нашем примере результат сохранялся в файл, отправку в Telegram мы не проверяли.

В 9:00 должны работать компьютер и Hermes, поэтому надёжнее сервер. Если Hermes был выключен, после включения он выполнит один пропущенный запуск. Подойдёт CRM, из которой сделки выгружаются в таблицу или забираются программным подключением, как у amoCRM и Битрикс24. Мы работаем в Hermes с 19 октября 2026 года, опыт короткий.

Сколько стоит

Сам Hermes бесплатный. Разборы шли по нашей подписке на Claude. В журнале Hermes указана расчётная стоимость: $0,22 за первый разбор на Claude Opus 5.5 и $0,06 за разбор после правки выгрузки через минуту. Отдельных списаний мы не измеряли. Если оценивать каждый разбор в $0,22, получится около $1 в месяц по понедельникам или $7 при ежедневном разборе. Подписка и компьютер сюда не входят, другая модель или объём отчёта изменят сумму.

Настройку под ключ мы посчитали без замера: автоматическая выгрузка сделок из CRM 2–4 часа, скрипт под ваши этапы и поля 3–5 часов, задачи, доставка и проверка первого запуска 1–2 часа. Всего 6–11 часов, по нашей ставке разработки 155 в час это 930–1 705 . Такие задачи мы делаем в автоматизации с ИИ.

Где подводит

  1. Старая или неполная выгрузка. Если за неделю в файле нет ни одной правки, наш скрипт останавливается с ошибкой вместо отчёта с нулями. Неполный файл эта проверка может пропустить: выгрузка без сделок сентября прошла её с выручкой 72 800 вместо 85 600, а свежий файл без правок с начала отчётной недели вызовет ложную тревогу. Полноту выгрузки проверяют отдельно.
  2. Разбор замечает только изменения текста отчёта. Правки CRM, которые туда не попали, нейросеть не вызовут.
  3. Память агента. В одном запуске модель записала в память вместо списка сделок пример из нашего задания и потеряла две сделки. Список прошлой недели надёжнее хранит скрипт, а примеров, похожих на ответ, в задании агенту лучше не давать.
  4. Доступы. Для автоматической выгрузки заведите пользователя CRM с правами только на просмотр. Выгружайте нужные колонки, без данных покупателей: у агента есть доступ к файлам. Опасные команды Hermes по умолчанию запрещает, но запрет снимается одной настройкой, поэтому права на запись в CRM агенту не дают.
  5. Причин агент не знает: почему клиент молчит после КП, выясняет руководитель. Как ловить тихие сбои таких задач, мы разбирали в статье про проверку автоматизации.

Когда агент не нужен

Если нужны только цифры, хватит скрипта и обычного планировщика операционной системы, без Hermes. Переложить данные из CRM в таблицу и отправить сообщение проще сценарием n8n. Если нужный отчёт уже есть в самой CRM и руководитель его открывает, строить ничего не нужно.

С чего начать

Решите, какие цифры руководитель смотрит каждую неделю, и начните с отчёта без нейросети. Первые недели сверяйте выручку и число оплат в отчёте с CRM. Разбор агентом добавляйте, когда ясно, какие вопросы повторяются. Разобрать цифры глубже поможет анализ продаж в Excel с ИИ.

Для исполнителя

Ниже скрипт на Python и команды для трёх режимов, проверенные на Hermes Agent 0.22.2 22 октября 2026 года ручными запусками. Сначала согласуйте с руководителем значения полей и проверьте расчёты на его выгрузке: одного переименования колонок недостаточно. Учебная выгрузка даёт отчёт из начала статьи.

Скрипт отчёта: в строке EXPORT укажите путь к своей выгрузке
#!/usr/bin/env python3
"""Недельный отчёт отдела продаж из выгрузки CRM.

Считает прошлую полную неделю (пн–вс) и сравнивает с позапрошлой.
В выводе нет времени запуска и «дней назад»: всю неделю на неизменённой
выгрузке он одинаков байт в байт, это нужно режиму монитора.
Сохраните скрипт как ~/.hermes/scripts/sales_report.py: задачи Hermes
берут скрипты только из этого каталога.
"""
# CSV: UTF-8, разделитель «;». Даты: YYYY-MM-DD; сумма_byn: целое число.
# Колонки: id, создана, менеджер, источник, этап, сумма_byn, изменена, закрыта, этап_отказа.
# В этом примере закрыта означает дату полной оплаты или отказа.
# У открытых сделок закрыта пустая; у отказов заполнен этап_отказа.
# Поле изменена содержит дату последней правки карточки. Истории переходов нет.
# Сопоставьте этапы CRM со STAGES, согласуйте частичные оплаты и возвраты.
# Учебная выгрузка из статьи:
# https://fomenko.by/api/media/fomenko/blog/otchet-otdela-prodazh-po-raspisaniyu/deals.csv
# Отчёт из статьи на ней: REPORT_DATE=2026-10-22 python3 sales_report.py
import csv
import os
from collections import Counter, defaultdict
from datetime import date, timedelta

EXPORT = "/путь/к/выгрузке/deals.csv"
STAGES = ["Новая", "Квалификация", "КП отправлено", "Счёт выставлен", "Оплачено"]
STUCK_DAYS = 7
MONTHS = ["января", "февраля", "марта", "апреля", "мая", "июня", "июля",
          "августа", "сентября", "октября", "ноября", "декабря"]


def d(s):
    return date.fromisoformat(s) if s else None


def money(x):
    return f"{x:,}".replace(",", " ")


def span(a, b):
    if a.month == b.month:
        return f"{a.day}–{b.day} {MONTHS[b.month - 1]}"
    return f"{a.day} {MONTHS[a.month - 1]}–{b.day} {MONTHS[b.month - 1]}"


with open(EXPORT, encoding="utf-8") as f:
    deals = list(csv.DictReader(f, delimiter=";"))

today = date.fromisoformat(os.environ.get("REPORT_DATE") or date.today().isoformat())
end = today - timedelta(days=today.weekday() + 1)  # прошлое воскресенье
start = end - timedelta(days=6)
prev_end, prev_start = start - timedelta(days=1), start - timedelta(days=7)

# Неделя без единой правки: возможно, выгрузка старая или неполная. Ошибка вместо
# отчёта с нулями; возраст выгрузки эта проверка не определяет.
latest = max(d(x["изменена"]) for x in deals)
if latest < start:
    raise SystemExit(f"Нет изменений с {start}: проверьте полноту выгрузки и работу отдела")


def week(a, b):
    won = [x for x in deals if x["этап"] == "Оплачено" and a <= d(x["закрыта"]) <= b]
    return dict(
        revenue=sum(int(x["сумма_byn"]) for x in won),
        won=len(won),
        new=sum(a <= d(x["создана"]) <= b for x in deals),
        lost=sum(x["этап"] == "Отказ" and a <= d(x["закрыта"]) <= b for x in deals),
    )


cur, prev = week(start, end), week(prev_start, prev_end)
avg = cur["revenue"] // cur["won"] if cur["won"] else 0

out = [f"Отчёт отдела продаж: {span(start, end)}",
       f"(в скобках прошлая неделя, {span(prev_start, prev_end)})", "",
       f"Выручка: {money(cur['revenue'])} BYN ({money(prev['revenue'])})",
       f"Оплачено сделок: {cur['won']} ({prev['won']}), средний чек {money(avg)} BYN",
       f"Новых сделок: {cur['new']} ({prev['new']})",
       f"Отказов: {cur['lost']} ({prev['lost']})", ""]

# Воронка: до какого этапа дошли сделки, созданные за две недели.
cohort = [x for x in deals if prev_start <= d(x["создана"]) <= end]
reached = Counter()
for x in cohort:
    stage = x["этап_отказа"] if x["этап"] == "Отказ" else x["этап"]
    for s in STAGES[1:STAGES.index(stage) + 1]:
        reached[s] += 1
out.append(f"Воронка сделок, созданных за две недели ({len(cohort)}):")
for s in STAGES[1:]:
    pct = round(100 * reached[s] / len(cohort)) if cohort else 0
    out.append(f"  {s:<15} {reached[s]:>3}  {pct}%")
out.append("")

by = defaultdict(lambda: [0, 0, 0])
for x in deals:
    m = by[x["менеджер"]]
    if start <= d(x["создана"]) <= end:
        m[0] += 1
    if x["этап"] == "Оплачено" and start <= d(x["закрыта"]) <= end:
        m[1] += 1
        m[2] += int(x["сумма_byn"])
out.append("Менеджеры за неделю: новых / оплачено / выручка BYN")
for name, (n, w, r) in sorted(by.items(), key=lambda kv: -kv[1][2]):
    out.append(f"  {name:<8} {n:>2} / {w} / {money(r)}")
out.append("")

limit = end - timedelta(days=STUCK_DAYS)
stuck = [x for x in deals if x["этап"] not in ("Оплачено", "Отказ") and d(x["изменена"]) < limit]
stuck.sort(key=lambda x: x["изменена"])
out.append(f"Зависли: открыты и без движения больше {STUCK_DAYS} дней ({len(stuck)})")
for x in stuck:
    ch = d(x["изменена"])
    out.append(f"  #{x['id']} {x['менеджер']}, {x['этап']}, {money(int(x['сумма_byn']))} BYN,"
               f" без движения с {ch.day} {MONTHS[ch.month - 1]}")

print("\n".join(out))
Только цифры: задача без нейросети, понедельник 9:00
hermes cron create '0 9 * * 1' --name otchet-prodazh \
  --script sales_report.py --no-agent \
  --deliver local
# local: результат в файл на этом компьютере;
# с подключённым Telegram-ботом вместо local пишут telegram
Цифры и разбор: монитор с заданием для агента
# каждое утро в 9:00; модель вызывается при первом отчёте и изменении вывода скрипта
hermes cron create '0 9 * * *' --name razbor-prodazh \
  --monitor-script sales_report.py \
  --deliver local \
  "Ты помогаешь руководителю отдела продаж. Ниже недельный отчёт, который посчитал скрипт по выгрузке CRM, и что в нём изменилось с прошлого запуска. Напиши руководителю разбор до 100 слов: что изменилось и какие 2-3 вопроса (конкретные сделки или менеджеры) поднять на планёрке. Числа бери только из отчёта, ничего не пересчитывай и не добавляй того, чего в отчёте нет. Команды не запускай и файлы не открывай: всё нужное уже в сообщении."
Разбор с памятью: агент с блокнотом задачи
hermes cron create '0 9 * * 1' --name zavisshie-sdelki \
  --script sales_report.py \
  --deliver local \
  "Ты помогаешь руководителю отдела продаж. Ниже недельный отчёт, который посчитал скрипт по выгрузке CRM. В блокноте задачи под ключом zavisshie записаны номера зависших сделок из прошлого отчёта. 1) Сравни их с зависшими в этом отчёте и напиши руководителю до 100 слов: какие сделки висят вторую неделю подряд (их назови первыми), какие ушли из списка, какие появились. Номера и суммы бери только из отчёта и блокнота. 2) Последним шагом перезапиши ключ zavisshie командой из раздела про блокнот: номера зависших из этого отчёта через пробел, в конце неделя в скобках. Других команд не запускай."

# записать в блокнот задачи итог прошлой недели
hermes cron notepad <id задачи> set zavisshie "1003 1011 1007 (5–11 октября)"

Частые вопросы

Да. Автоматизация формирования отчёта нейросети не требует: цифры и зависшие сделки считает скрипт.
Выручку, оплаченные сделки и средний чек, новые сделки и отказы, воронку, итоги менеджеров и зависшие сделки. Если есть план, добавьте процент выполнения.
На регулярной задаче да: [такой агент](/blog/chto-takoe-ii-agent) запускается сам и пишет разбор. Решений по сделкам и записи в CRM мы ему не даём.

Новые посты на почту

Без спама. Отписка в один клик в любом письме.