↩️ Назад

Категории

CRM СЭД для счетов: скелет ТЗ для Hermes-агента и сколько это стоит

22.10.2026 | из категории: Нейросети

Описание самописного CRM СЭД для счетов фактур и корпоративн
IT-блог · проектирование · AI-агенты

Разбираем готовую внутреннюю систему согласования входящих счетов и превращаем её в воспроизводимый шаблон задачи для AI-агента. Плюс — честный расчёт бюджета: генерация ТЗ, стоимость прогона и во что обходится рабочая CRM «под ключ».

Django 6 + PostgreSQL 17 4 роли · 13 статусов 1С OData + HTTP-сервис LLM-распознавание

01Идея: что именно строим

Есть класс внутренних систем, которые не ведут учёт, а наводят порядок в процессе. Конкретный пример — CRM СЭД для входящих счетов: счёт поставщика проходит маршрут от заявки менеджера до оплаты и закрытия в 1С, а система отвечает за согласование, сроки, историю и прозрачность «кто что сделал и когда».

Почему это хороший кандидат для агентной генерации:

Ключевая мысль. Ценность такой системы — не в коде, а в зафиксированной логике маршрута. Если ТЗ описывает переходы, права и проверки однозначно, генерация кода становится механической. Если нет — агент придумает свою логику, и её придётся переписывать.

02Скелет ТЗ для Hermes-агента

Ниже — структура промпта/ТЗ, которую можно отдавать агенту по частям. Каждый блок самодостаточен: агент генерирует один слой, получает проверку и идёт дальше. Дробить на этапы важно — так ошибка в модели данных не тянет за собой все шаблоны.

Блок 0. Контекст и рамки

# РОЛЬ АГЕНТА
Ты — senior Django-разработчик. Сгенерируй монолитное приложение
на Django 6 + PostgreSQL 17, серверные шаблоны, Bootstrap 5.

# ЖЁСТКИЕ РАМКИ
- Нет API-слоя и SPA. Всё рендерится на сервере.
- Часовой пояс Europe/Moscow, USE_TZ=True, интерфейс на русском.
- Все действия, меняющие статус, — только POST + CSRF.
- Все настройки интеграций — через .env, с безопасными дефолтами.
- Никаких секретов в коде и в git.

# РЕЗУЛЬТАТ ЭТАПА
Структура приложений: core, users, invoices, payments, notifications.
Заглушки settings.py, urls.py, manage.py. Без бизнес-логики.

Блок 1. Модель данных

# СУЩНОСТИ
User(role in {manager, head, bookkeeper, treasurer}, is_admin)
Counterparty(name, full_name, inn, kpp, guid_1c, is_active, raw_json)
Branch(name)
Invoice(
  number UNIQUE, date, counterparty FK PROTECT, branches M2M,
  amount DECIMAL(12,2) CHECK > 0, purpose, file,
  status in 13 значений, created_by FK,
  payment_order_number, payment_date, error_screenshot,
  raw_json, created_at, updated_at
)
InvoiceStatusHistory(invoice FK, from_status, to_status,
                     changed_by, changed_at, comment)
RecognitionTask(file, status, invoice FK, error, created_at)
CounterpartyRequest(status, inn, kpp, name, author, handler,
                    linked_counterparty, reject_reason)
Timer(invoice FK, kind, deadline, state, reminded_at)
Notification(user FK, text, is_read, invoice FK, created_at)

# ПРАВИЛА
- История статусов пишется АВТОМАТИЧЕСКИ при сохранении Invoice
  (сравнение старого и нового status в save()).
- Автор изменения берётся из thread-local, который заполняет middleware.
- Удаление контрагента запрещено при наличии счетов (PROTECT).
- Пропавшие из 1С контрагенты деактивируются, а не удаляются.

# ПРОВЕРКА ЭТАПА
pytest: модели создаются, история пишется, PROTECT срабатывает,
amount <= 0 отклоняется.

Блок 2. Статусная машина

# СТАТУСЫ (13)
draft, pending, approved, in_accounting, registered_in_1c,
pending_payment, payment_sent, payment_failed, needs_clarification,
paid, rejected, overdue, closed_in_1c

# ПЕРЕХОДЫ — ЕДИНСТВЕННЫЙ ИСТОЧНИК ПРАВДЫ
draft            --submit-->        pending        (manager, свой, номер+дата+сумма>0)
pending          --approve-->       approved       (head)
pending          --reject-->        rejected       (head, причина обязательна)
approved         --accept-->        in_accounting  (bookkeeper)
in_accounting    --enter_1c-->      registered_in_1c (bookkeeper, ТОЛЬКО при успехе 1С)
registered_in_1c --send_payment-->  pending_payment (bookkeeper)
pending_payment  --pay-->           paid           (treasurer, номер п/п + дата)
pending_payment  --send_bank-->     payment_sent   (treasurer)
pending_payment  --fail-->          payment_failed (treasurer, причина из 7)
payment_sent     --fail-->          payment_failed (treasurer)
payment_failed   --retry-->         pending_payment (treasurer)
payment_failed   --return-->        needs_clarification (treasurer)
paid             --close_1c-->      closed_in_1c   (bookkeeper)

# ЖЁСТКОЕ ТРЕБОВАНИЕ
Переход enter_1c выполняется только если 1С вернула success=true.
При ошибке связи статус НЕ меняется, пользователь видит текст ошибки.
«Внесён в 1С» = факт создания документа, а не нажатие кнопки.

# ПРОВЕРКА ЭТАПА
Сквозной тест: draft -> ... -> closed_in_1c на замоканной 1С.
Тест на отказ 1С: статус остаётся in_accounting.

Блок 3. Права и доступ

# ТРИ НЕЗАВИСИМЫХ СЛОЯ (намеренное дублирование)
1. Декоратор роли на каждом view.
2. Middleware: проверка префиксов URL по роли.
3. Проверка владения счётом для manager.

# ВИДИМОСТЬ СПИСКА
manager:    только свои счета
head:       pending, approved, paid, rejected, overdue
bookkeeper: все
treasurer:  pending_payment, payment_sent, paid, payment_failed

# ПОВЕДЕНИЕ ПРИ ЗАПРЕТЕ
Не 403, а мягкий редирект на собственный дашборд роли.
(Зафиксировать это явно — иначе агент поставит 403.)

# ПРОВЕРКА ЭТАПА
Тест на каждую роль x каждый защищённый URL.

Блок 4. Экраны

# СПИСОК ЭКРАНОВ (минимум)
login, register, 4 дашборда по ролям,
/invoices/ (список), карточка счёта, создание, редактирование,
оплата с реквизитами, «не проведён», бухгалтерская операция,
закрытие в 1С, загрузка на распознавание,
заявки на контрагента (3 экрана), 2 отчёта, уведомления, таймеры.

# КАРТОЧКА СЧЁТА — ГЛАВНЫЙ ЭКРАН
Данные + цветной статус + история лентой + блок кнопок,
который зависит от роли И статуса. Кнопки — формы POST,
не ссылки GET. Модальные окна: подтверждение, причина отказа,
комментарий, отправка копии на почту.

# ПРОВЕРКА ЭТАПА
Снимок карточки для каждой пары (роль, статус): какие кнопки видны.

Блок 5. Интеграции (заглушки + реальный код)

# 1С: ЧТЕНИЕ КОНТРАГЕНТОВ (OData)
GET {ONEC_BASE_URL}/{ONEC_COUNTERPARTY_RESOURCE}
Basic auth. Терпимый разбор полей: Ref_Key|GUID, ИНН|INN, КПП|KPP,
Наименование|Description, НаименованиеПолное.
Синхронизация: create / update by GUID / deactivate missing /
skip без GUID (ручные записи не трогать).

# 1С: СОЗДАНИЕ СЧЁТА (HTTP-сервис)
POST {ONEC_BASE_URL}/hs/invoice/create
JSON: number, date, counterparty_guid, amount (строка 2 знака),
      purpose, branches[].
Ответ: {success, guid, number_1c, error}.
Ошибка связи или не-200 => статус счёта не меняется.

# РАСПОЗНАВАНИЕ (внешний FastAPI-сервис)
POST {RECOGNITION_URL}/recognize, файл PDF/JPG/PNG/TIFF до 10 МБ.
Ответ: {success, fields{number,date,amount,counterparty_inn,
counterparty_name,purpose}, confidence{}, error}.
Создаётся ЧЕРНОВИК, не готовый счёт.
Поиск контрагента: ИНН -> точное имя -> подстрока -> служебный
«Не определён» (inactive, вне выпадающих списков).

# ПРОВЕРКА ЭТАПА
Тесты на заглушках: успех, отказ, таймаут, не-JSON.

Блок 6. Автоматика и сроки

# ПРОВЕРКИ (пороги в коде, не в настройках)
pending > 2 дней        -> письмо руководителям + timer
in_accounting > 1 день  -> бухгалтерам + timer
pending_payment > 3 дней-> казначеям + timer
timer истёк             -> напоминание адресату
напомнили + 24ч         -> эскалация руководителю
payment_sent + 24ч      -> auto-fail (требует timer при send_bank!)

# РАСПИСАНИЕ
Проверки — каждые 5 минут. Синхронизация контрагентов — 03:00.
На Windows django-crontab не работает => внешний планировщик.
Явно указать это в ТЗ, иначе агент «забудет» про Windows.

# ПРОВЕРКА ЭТАПА
Тест: таймер создаётся при send_bank и через сутки даёт payment_failed.

Блок 7. Приёмка

# ЧЕК-ЛИСТ (агент обязан приложить отчёт)
[ ] check --deploy без критических ошибок
[ ] нет неприменённых миграций
[ ] быстрые тесты (модели, права) — зелёные
[ ] полный прогон — без падений
[ ] сквозной маршрут на замоканных 1С и распознавании
[ ] отказ 1С не меняет статус
[ ] auto-fail через 24ч работает
[ ] все действия со статусом — POST + CSRF
[ ] .env.example без секретов, DEBUG=False в примере
[ ] регистрация закрыта флагом
Практика. Отдавайте агенту блоки 1–7 последовательно, с прогоном тестов между этапами. Один большой промпт «сделай всю CRM» даёт красивый каркас и сломанную статусную машину — её потом чинить дороже, чем писать заново.

03Какой моделью генерировать ТЗ и код

Задача делится на две разные по природе части, и для них подходят разные модели.

ЭтапЧто делаемТип моделиРекомендация
ТЗ и декомпозиция Из описания процесса собрать блоки 0–7, таблицу переходов, чек-лист Сильная reasoning-модель, длинный контекст Флагманская модель с «рассуждением» (reasoning-режим). Важна способность держать 40+ страниц описания и не терять инварианты.
Модель данных + миграции Django-модели, PROTECT, автоистория, thread-local Кодовая модель среднего размера, сильная в Python Модель уровня «сильный код-ассистент». Достаточно, если ТЗ уже зафиксировано.
View + шаблоны Много однотипных экранов, Bootstrap Быстрая дешёвая модель Младшая/средняя модель по образцу первых 2–3 экранов. Экономия 5–10x без потери качества.
Интеграции 1С и распознавание HTTP-клиенты, разбор ответов, обработка ошибок Reasoning-модель + кодовая Сначала reasoning для контракта обмена, потом кодовая для реализации. Ошибки здесь дорогие.
Тесты и сквозной сценарий pytest, моки 1С, e2e Reasoning-модель Та же флагманская: тесты — это спецификация, модель должна «понимать» инварианты.
Ревью и поиск дефектов Сверка кода с таблицей переходов Reasoning-модель, отдельный прогон Обязательно другая сессия/модель, чем писала код. Самопроверка слабее.

Общее правило: чем выше цена ошибки, тем «умнее» модель. Логика маршрута, права и интеграции — флагман. Шаблоны и CRUD-экраны — младшая модель по образцу. Смешивать нельзя: дешёвая модель на статусной машине даст красивый, но неверный код.

Про «Гермес». Если Hermes-агент умеет оркестрировать несколько моделей, заложите маршрутизацию: reasoning — на ТЗ, тесты и ревью; кодовая — на реализацию; дешёвая — на шаблоны. Это главный рычаг экономии, он даёт больше, чем выбор одной «лучшей» модели.

04Сколько стоит на выходе

Считаем в двух разрезах: стоимость генерации (токены, прогоны, правки) и стоимость рабочей системы (если бы её делали люди). Цифры — порядок величин для планирования, а не смета.

Генерация агентом

ТЗ + декомпозиция
$3–15
Один длинный контекст, 2–3 итерации уточнений
Код + тесты
$40–200
7 этапов, прогоны, правки после падений
Ревью и доводка
$15–80
Отдельная сессия, сверка с таблицей переходов
Итого генерация
$60–300
Без учёта времени человека на приёмку

Разброс определяется числом итераций: агент почти всегда ошибается в автоистории, правах и обработке отказа 1С. Каждая такая правка — отдельный прогон с контекстом.

Рабочая система «под ключ»

СтатьяОценкаКомментарий
Генерация агентом$60–300Токены и прогоны
Приёмка и правки человеком40–120 чРевью, ручные сценарии, доводка UX
Интеграция 1С20–60 ч + программист 1СПубликация HTTP-сервиса и OData — на стороне 1С
Развёртывание распознавания8–24 чСервис + ядро разбора + локальная модель
Инфраструктура и бэкапы4–16 чPostgreSQL, планировщик, архив media
Безопасность перед публикацией8–24 чPOST вместо GET, закрыть регистрацию, DEBUG off
Агент + приёмка
$2–6k
Если интеграции отложены, локальный контур
Полный контур
$6–18k
С 1С, распознаванием, безопасностью

Для сравнения: та же система, написанная людьми с нуля, — это ориентировочно 400–800 часов разработки плюс интеграционная часть. Агентная генерация снимает основную часть «механического» кода (модели, CRUD, шаблоны), но не снимает стоимость интеграций, приёмки и безопасности. Именно они формируют нижнюю границу бюджета.

Главный риск бюджета. Не токены, а приёмка. Если ТЗ не зафиксировало инварианты (POST вместо GET, отказ 1С не меняет статус, автоистория), человек будет искать эти дефекты вручную — и это самая дорогая часть проекта.

05Где агент обязательно ошибётся

По опыту разбора подобных систем — список повторяющихся мест. Заложите их в ТЗ явно и проверяйте тестами.

06Вывод

CRM СЭД для счетов — почти идеальный полигон для агентной генерации: конечная логика, шаблонный интерфейс, изолированные интеграции. Скелет ТЗ из семи блоков превращает «сделай CRM» в воспроизводимый процесс с проверяемыми этапами.

По деньгам: генерация — десятки-сотни долларов, рабочая система — единицы-десятки тысяч, и разница почти целиком уходит на интеграции, приёмку и безопасность. Модель выбирайте по цене ошибки: reasoning — на ТЗ, тесты и ревью; кодовая — на реализацию; дешёвая — на шаблоны. Если Hermes умеет маршрутизировать модели, это даст больше экономии, чем любой отдельно взятый флагман.

Материал подготовлен по описанию внутренней системы согласования входящих счетов (Django 6, PostgreSQL 17, 4 роли, 13 статусов). Оценки стоимости — ориентировочные, для планирования. Внутренние сведения о конкретной инсталляции в статью не включены.



Категории:

Категории

← Назад к списку