390 источников и языковая модель внутри контура: система мониторинга литературы для фармаконадзора
-
Вид услуги:
-
Технологии:
C#, ASP.NET Core, PostgreSQL, Entity Framework Core, Hangfire, локальные LLM
Год:
2023
О проекте
Держатель регистрационного удостоверения обязан регулярно просматривать научную литературу: не появилось ли где-то сообщение о нежелательной реакции на его препарат. Обычно это делают руками — сотрудники читают журналы и выписывают находки. Мы построили систему, которая обходит триста девяносто источников сама, достаёт полные тексты статей и передаёт их языковой модели, работающей внутри контура заказчика. Человек получает не список ссылок, а размеченные находки с обоснованием.
Отрасль: фармаконадзор
Задача: автоматизировать мониторинг литературы и открытых источников на предмет сообщений о нежелательных реакциях
Старт: декабрь 2023
Сегодня: система в промышленной эксплуатации и активно развивается
Роль Nabla Lab: проектирование, разработка, развитие
Хостинг: на стороне заказчика, включая языковую модель
Обязанность, которую сложно выполнить вручную
Безопасность лекарства не заканчивается регистрацией. Дальше начинается фармаконадзор: непрерывное наблюдение за тем, что происходит с препаратом в реальной жизни. Часть этой работы — мониторинг литературы и открытых источников.
Формально задача звучит просто: регулярно просматривать публикации и находить сообщения о нежелательных реакциях, случаях применения при беременности, передозировках, отсутствии терапевтического эффекта. Практически это означает, что кто-то должен раз в период открыть десятки медицинских журналов, найти статьи, где упоминается нужное действующее вещество, прочитать их и решить, есть ли там сообщение о безопасности.
Один препарат — уже заметная работа. Двадцать препаратов и сотня источников — работа, которую не выполнить полностью. Что-то будет пропущено, и пропущено незаметно: отсутствие находки выглядит одинаково и когда её действительно нет, и когда до источника не дошли руки.
Заказчик решил закрыть эту задачу системой.
Триста девяносто источников
Система собирает данные из трёхсот девяноста источников. Это не абстрактный «мониторинг интернета», а конкретный список: медицинские и фармацевтические журналы России и стран СНГ, вестники университетов и научных центров, международные базы публикаций, сайты регуляторов, отраслевые новостные издания, ветеринарные журналы.
Каждый источник — отдельный модуль сбора. Их приходится писать по одному, потому что двух одинаковых сайтов не бывает: у каждого своя структура страниц, своя разбивка на страницы, свои особенности поиска, своя манера отдавать даты в трёх разных форматах.
Там, где у источника есть официальный программный интерфейс, мы работаем через него, а не через разбор страниц. Так подключены крупные международные базы публикаций и часть агрегаторов: это надёжнее, честнее по отношению к источнику и не ломается при смене вёрстки.
Инженерия сбора данных
Собрать данные с одного сайта — задача на несколько часов. Собирать их ежедневно с четырёх сотен сайтов и не разваливаться — задача другого порядка.
Устойчивость к изменениям. Сайты меняют разметку без предупреждения. Ошибка сбора по одному источнику не должна ронять весь цикл: сбой локализуется, попадает в реестр технических ошибок и не мешает остальным.
Вежливость к источнику. Для части сайтов мы сделали кэширование, чтобы не создавать им лишнюю нагрузку. Это не техническая необходимость, а нормальное поведение: за источниками стоят живые организации, в том числе государственные.
Дедупликация. Одна и та же публикация приходит из нескольких источников и агрегаторов. Система сводит их к одной записи, иначе сотрудник читает одно и то же по четыре раза.
Извлечение полного текста. Найти ссылку мало — нужен текст статьи. Для этого работает отдельная подсистема с набором провайдеров и запасным механизмом на случай, когда основной не справился.
Параллельность и контроль ресурсов. Обход четырёхсот источников идёт параллельно, с ограничением одновременных запросов, профилированием по памяти и процессору и журналом времени выполнения.
Что система отбрасывает сама
Отдельная работа — научить систему не приносить лишнее.
Самый показательный пример: публикации о доклинических исследованиях. Статья, где нежелательная реакция описана у крыс или в пробирке, формально содержит все нужные слова, но сообщением о безопасности лекарства для человека не является. Мы добавили исключение таких работ на этапе сбора.
Похожая история с поиском: система умеет искать по словосочетаниям, а не по отдельным словам, иначе выдача забивается статьями, где нужные термины стоят в разных абзацах и не связаны между собой.
Языковая модель, которая не выходит наружу
Найденные статьи проходят анализ языковой моделью. Она читает текст и размечает его по категориям, важным для фармаконадзора: сообщение о нежелательной реакции, особая ситуация применения, отсутствие терапевтического эффекта. Отдельно обрабатываются ветеринарные препараты — там свои правила.
Ответ модели структурирован: по каждой категории она возвращает не только вердикт, но и уверенность в нём и обоснование — фрагмент, на котором вывод построен. Сотрудник видит, почему система так решила, и может с ней не согласиться.
Ключевое решение — модель работает внутри контура заказчика. Не облачный сервис, а локально развёрнутая открытая модель на его собственном оборудовании. Для фармаконадзора это принципиально: тексты публикаций и результаты анализа не уходят третьей стороне, и на вопрос «где обрабатываются ваши данные» есть простой ответ.
Работа с моделью выстроена как инженерная задача, а не как эксперимент: детерминированный режим генерации, ограничение одновременных запросов, отдельный разбор ответа с проверкой формата, журнал времени ожидания и времени ответа по каждому запросу.
Дисциплина вместо демонстрации
Про языковые модели сейчас пишут все. Разница между демонстрацией и работающей системой — в том, что происходит после первого удачного запуска.
Мы завели для этой части проекта режим, привычный скорее для исследований, чем для веб-разработки.
Порог выпуска. У кандидата на обновление есть заранее заданные требования: минимальная точность, минимальная полнота, стопроцентная корректность формата ответа и отсутствие критических провалов на состязательных примерах. Не прошёл — не выкатываем, каким бы хорошим он ни выглядел на глаз.
Запертая проверочная выборка. Часть размеченных данных отложена и не открывается до тех пор, пока кандидат не прошёл порог на рабочей выборке. Это защита от самообмана: если подглядывать в финальный тест при подборе, он перестаёт что-либо проверять.
Состязательные тесты. Отдельный набор пограничных случаев, включая попытки увести модель инструкцией, спрятанной в тексте статьи.
Готовность не выкатывать. В последней проверке кандидат улучшил точность, не потеряв полноту, — и всё равно не был принят, потому что не прошёл порог целиком. Запертая выборка осталась закрытой.
Отдельный результат той же проверки оказался важнее самих метрик: разбор ошибок показал, что часть эталонной разметки сомнительна — в статьях, отмеченных как «ничего не найдено», встречались прямые указания на проблемы безопасности. Дальнейшая подгонка промптов в такой ситуации только маскирует проблему, поэтому мы остановились и предложили сначала переразметить данные вслепую.
Система настроена так, чтобы скорее принести лишнее, чем пропустить нужное. В фармаконадзоре цена пропущенного сообщения несопоставима с ценой лишней минуты работы специалиста, и модель здесь помощник, а не последняя инстанция: решение всегда за человеком.
Что видит сотрудник
Работа ведётся по проектам. В проекте задаётся перечень препаратов в паре «торговое наименование — действующее вещество», набор источников и список ключевых слов, по которым идёт поиск.
По каждому проекту система показывает статистику за период и за всё время: сколько сообщений обработано, сколько найдено нежелательных реакций, сколько особых ситуаций. Ниже — отчёты по проведённым мониторингам с периодом скрининга, датой и статусом.
Внутри отчёта — таблица находок: препарат, действующее вещество, производитель, источник и ссылка на публикацию, дата обнаружения, тип сообщения по методологии, краткое резюме, контакты, комментарий сотрудника. Данные можно поправить руками, дополнить и выгрузить в Excel.
Справочники ключевых слов и источников ведутся отдельно и переиспользуются между проектами.
Прослеживаемость
Каждое действие пользователя фиксируется в журнале операций: кто, когда, что изменил. Для фармаконадзора это не пожелание — деятельность проверяют, и на вопрос, откуда взялась или куда делась запись, должен быть ответ.
Самостоятельная регистрация в системе закрыта: учётные записи заводит только администратор.
Как устроено внутри
Дальше — техническая сторона.
Серверная часть на .NET, данные в PostgreSQL. Решение разделено на одиннадцать проектов с чёткими границами: веб-часть, модели, слой данных, миграции, сервисы, аудит, конфигураторы, планировщик фоновых задач, почтовый сервис, общая часть сборщиков данных и отдельный инструментарий для оценки моделей.
Сбор, извлечение полных текстов и анализ работают как фоновые конвейеры: с реестром задач, с координацией параллельного выполнения через аренду задач, с отслеживанием состояния и статистикой запросов. Это позволяет запускать тяжёлые долгие процессы, не блокируя интерфейс и не теряя прогресс при перезапуске.
Прослеживаемость реализована на нашей собственной библиотеке аудита — той же, что работает в других наших системах для регулируемых сфер. Мы не пишем этот механизм заново под каждый проект.
С ноября 2023 года структура данных обновлялась шестьдесят четыре раза, последний раз — в конце июля 2026 года.
Не первая система для этого заказчика
С этим заказчиком мы работаем с 2022 года. Первой была единая цифровая платформа для системы фармаконадзора — наша первая большая работа. Эта система появилась позже и закрыла отдельную задачу: поиск информации там, где её раньше искали вручную.
Заказчик, который возвращается четвёртый год подряд, говорит о качестве работы больше, чем любое описание функций.
Почему это важно для вас
Этот проект — про две вещи, которые редко встречаются в одном месте.
Первая — инженерия сбора данных в промышленном масштабе. Не «напишем парсер», а четыре сотни источников, которые надо обходить регулярно, годами, с восстановлением после сбоев и без превращения работы в постоянное тушение пожаров.
Вторая — работа с языковыми моделями по-взрослому. С измеримыми порогами, запертыми проверочными выборками, состязательными тестами и готовностью не выкатывать то, что не прошло проверку. Мы умеем разворачивать модель внутри контура заказчика, когда данные нельзя отдавать наружу, — а в медицине, фарме и финансах это чаще правило, чем исключение.
Расскажите о своей задаче — обсудим, как её решить.
Давайте создавать вместе!
Свяжитесь с нами и мы проконсультируем по вопросам реализации IT-решений и найдем лучший подход к разработке
Контакты
Офис: г. Казань, ул. Островского, 57Б, оф. 110
Почта: info@nabla-lab.ru
Телефон: +7 (965) 595-62-78