Internal prototype · v0.1

Credit Report Assistant — документация

AI-агент для автоматической подготовки первичного черновика кредитных заключений по корпоративному клиенту: Limit Application и Risk Opinion для Кредитного комитета. Рекомендованный контрольный чек-лист используется как методическое руководство — агент сверяет по нему полноту заключения, но не заполняет его.

Обзор

Аналитик загружает пакет due-diligence документов по клиенту (общая информация, финансы, налоги, лицензии, госзакупки, оценка рисков). Агент распознаёт содержимое, извлекает структурированные показатели и заполняет соответствующие поля DOCX-шаблонов. Каждое значение сопровождается ссылкой на первоисточник (файл + страница).

Агент не подменяет аналитика. Он готовит первичный черновик; окончательное суждение, проверка и подпись остаются за человеком.

Проблема

Цели

МетрикаЦель
Время подготовки черновика пакета< 5 минут
Доля полей, заполненных автоматически≥ 80%
Корректность заполненных значений≥ 95%
Пропуск рисковых флагов (false negative)< 2%

Шаблон: Limit Application

Заявка на кредитный лимит. Основные секции:

Шаблон: Risk Opinion (Appendix)

Заключение для Кредитного комитета. Содержит:

Чек-лист как методическое руководство

рекомендованный_чек.docx — это не шаблон на заполнение, а методический документ: какие пункты обязательно должны быть раскрыты в заключении для Кредитного комитета. Агент использует его на этапе проверки:

Если по какому-то пункту чек-листа данных в Risk Opinion нет — агент не выдумывает ответ, а добавляет в отчёт пометку TODO: требуется описание (см. чек-лист, п. N).

Пайплайн: приём документов

Набор документов клиента (PDF, DOCX, XLSX, сканы, произвольное количество) загружается на /files. Агент определяет тип каждого файла по имени и содержимому (общая информация, финансы, налоги, лицензии, госзакупки, риски, прочие) и маршрутизирует в профильный экстрактор.

Пайплайн: извлечение данных

Пайплайн: заполнение шаблона

Шаблон DOCX размечен плейсхолдерами вида {{client.name}}, {{finance.ebitda}}. Агент подставляет значения, сохраняя форматирование. Незаполненные поля остаются плейсхолдерами с префиксом TODO: и пометкой «требуется ручная проверка».

{{client.tin}}           → 308255174
{{finance.ebitda.uzs}}   → 184 562 300 000
{{risk.tax_overdue}}     → нет (по состоянию на 14.04.2026)
{{rating.internal}}      → TODO: отсутствует в DD-пакете

Пайплайн: проверка аналитиком

Готовый DOCX открывается аналитиком; каждое заполненное поле имеет комментарий со ссылкой на источник (имя файла, номер страницы, выдержка). Правки аналитика сохраняются и используются для улучшения маппинга.

Маппинг полей

Маппинг описан в mappings/<template>.yaml. Формат:

- field: client.tin
  source: document_type=общая_информация
  extractor: regex
  pattern: "ИНН\\s+(\\d{9,12})"

- field: finance.ebitda.uzs
  source: document_type=финансы, section=отчёт_о_прибылях
  extractor: table_cell
  locator: {row: "EBITDA", col: "Отчётный период"}
  unit: UZS

Как добавить новый шаблон

  1. Разметить DOCX плейсхолдерами {{...}}.
  2. Создать mappings/<template>.yaml с описанием полей и источников.
  3. Прогнать на 3–5 эталонных клиентах, зафиксировать целевые значения.
  4. Включить шаблон во фронт после прохождения smoke-теста.

API

Минимальный набор эндпоинтов:

МетодПутьНазначение
POST/api/accessЗагрузка документа клиента (base64)
POST/api/jobsЗапуск заполнения шаблона по пакету документов
GET/api/jobs/{id}Статус и ссылка на готовый DOCX
GET/filesСписок загруженных файлов

Сервисы и изоляция

На одном домене работают два независимых сервиса. Они разделены по URL, портам, базам данных, каталогам хранения и Linux-пользователям. Компрометация одного не должна давать доступ к данным другого.

СервисURLПортДанныеПользователь
filedrop — общий файловый drop/files, /api/*127.0.0.1:8000/var/lib/filedrop/filedrop
cra — Credit Report Assistant/app/*127.0.0.1:8001/var/lib/cra/cra

Единственная общая точка — nginx на портах 443/80, который терминирует TLS и маршрутизирует запросы по URL-префиксам. Сам nginx файлами сервисов не владеет.

Системные пользователи

Каждый сервис запускается от отдельного непривилегированного Linux-пользователя. Это базовая изоляция процесса: даже если в коде сервиса найдётся уязвимость (path traversal, command injection), атакующий получит права только этого пользователя — он не сможет читать или менять данные соседнего сервиса.

Пользователи создаются системным аккаунтом (useradd --system --no-create-home --shell /usr/sbin/nologin): у них нет домашней папки, нет пароля, нет возможности залогиниться по SSH. Это обычный приём для служебных пользователей.

Hardening systemd

Поверх разделения пользователей оба unit-файла используют sandbox-опции systemd. Это ограничивает возможности процесса даже внутри прав своего пользователя.

ОпцияЧто даёт
User=, Group=Запуск от выделенного непривилегированного аккаунта.
NoNewPrivileges=yesПроцесс и его дети не могут получить новые привилегии (setuid-бинарники обезврежены).
ProtectSystem=strict/, /usr, /boot, /etc монтируются только для чтения.
ProtectHome=yesДомашние каталоги пользователей недоступны сервису.
PrivateTmp=yesСобственный /tmp и /var/tmp; другие процессы и сервисы их не видят.
ReadWritePaths=Явный белый список каталогов, куда сервис может писать (только свой data-dir).
CapabilityBoundingSet=Пустой набор Linux-capabilities: сервис не может биндить привилегированные порты, менять владельца файлов и т.п.
RestrictAddressFamilies=AF_INET AF_INET6 AF_UNIXРазрешены только обычные сети и unix-сокеты; никакого AF_NETLINK/AF_PACKET.

Проверить применённые опции можно командой systemd-analyze security cra — она выводит оценку и список предупреждений.

Безопасность

Ограничения

FAQ

Заменит ли агент аналитика? Нет. Он снимает рутину заполнения форм; суждение и ответственность остаются за аналитиком.

Что с аудитом? Каждое поле имеет ссылку на источник и автора последней правки. Журнал выгружается в стандартном формате.

Как быть с полями, которых нет в DD-пакете? Агент помечает их TODO: и не заполняет «из головы» — это принципиальная позиция.