MedStore Query Interface: прототип доступа к медицинскому хранилищу

Прототип интерфейса запросов к медицинскому хранилищу: когорты, роли и аудит, деперсонализация данных пациентов и поиск по выпискам через локальный RAG без выхода данных за контур клиники.

MedStore Query Interface: прототип доступа к медицинскому хранилищу
INGELLO / BUSINESS2838
Связаться с нами
MedStore: когортный запрос по диагнозу и назначению, таблица псевдонимизированных пациентов
Когортный запрос: выборка по диагнозу I26.9 и назначению гепарина, вместо имён только псевдонимы MS-id

MedStore, прототип интерфейса запросов к медицинскому хранилищу данных. Он сделан намеренно раньше самого хранилища: сначала договориться, как люди будут доставать данные, и только потом строить инфраструктуру.

Почему так

Медицинские хранилища чаще всего проваливаются не на инженерии, а на использовании: данные собраны, витрины построены, а врач или аналитик не может получить нужную выборку без разработчика. Прототип интерфейса стоит несопоставимо дешевле, чем переделка готового хранилища под реальные сценарии.

Что показывает прототип

  • конструктор запросов и выборок без написания SQL;
  • формирование когорт пациентов по набору критериев;
  • предпросмотр результата до запуска тяжёлого запроса;
  • ролевую логику доступа к чувствительным полям.
MedStore: конструктор когорты с критериями по диагнозу, препаратам и лабораторному показателю
Конструктор когорты: диагноз, препараты, лабораторный порог и логика AND, OR, NOT
MedStore: сводка по пациенту с AI-резюме, рисками и хронологией событий
Сводка по одному псевдониму: AI-резюме, риски, вопросы врачу и хронология из разных источников

Проблема номер один: агрегация данных из разных источников

В клинике данные о пациенте никогда не лежат в одном месте. Структурированные поля и шаблоны осмотров живут в МИС. Выписки, протоколы операций и эпикризы хранятся как HTML или бинарные документы. Лаборатория отдаёт PDF. Пациент приносит сканы из других клиник. За десять лет это десятки миллионов документов и несколько тысяч новых каждый день.

Собрать это в одно хранилище значит решить несколько задач, которые обычно недооценивают:

  • Сопоставление пациента. Один человек записан в разных системах с опечатками в фамилии, старым телефоном, без отчества. Сопоставление (MPI, master patient index) делается по детерминированным и вероятностным правилам и обязательно до деперсонализации, внутри доверенной зоны: после неё сравнивать уже нечего.
  • Единые справочники. Диагнозы приводятся к МКБ-10, анализы к LOINC, препараты к ATC, единицы измерения к одной системе. Без этого запрос «UACR от 200 мг/г» молча пропустит половину пациентов, у которых показатель записан в мг/ммоль.
  • Версии шаблонов и документов. Шаблоны осмотров меняются годами, документы исправляются задним числом. Хранилище должно помнить версию и не считать исправление новым случаем.
  • Текст из PDF и сканов. OCR и разметка разделов документа («анамнез», «заключение», «рекомендации») нужны до поиска, иначе совпадение в анамнезе будет выглядеть как диагноз.
  • Происхождение каждого факта. Любая строка выборки ссылается на документ-источник. Врач не поверит когорте, которую нельзя проверить глазами.

Анонимизация и деперсонализация

Ключевой принцип архитектуры: хранилище, по которому ищут, вообще не содержит персональных данных. Имя пациента не нужно ни для когорты, ни для статистики, ни для семантического поиска. Оно нужно только лечащему врачу в конкретный момент, и этот момент должен быть отдельным, контролируемым действием.

Термины часто путают, поэтому коротко. Анонимизация необратима: из данных нельзя восстановить человека никаким способом. Псевдонимизация обратима при наличии ключа: вместо ФИО стоит псевдоним, а таблица соответствия хранится отдельно. С точки зрения GDPR и украинского закона о защите персональных данных псевдонимизированные данные остаются персональными, поэтому ключ охраняется как самый ценный актив системы. Деперсонализация здесь общий термин для всего конвейера.

Прямые идентификаторы

ФИО, телефон, адрес, e-mail, номер карты, РНОКПП, номера документов удаляются из структурированных полей и заменяются псевдонимом вида MS-452184. Ключ соответствия живёт в отдельном сервисе с отдельными учётными записями и не реплицируется в хранилище. Ориентир по перечню полей: 18 идентификаторов метода Safe Harbor из HIPAA, дополненные украинскими реалиями.

Свободный текст

Самое опасное место. Врач пишет в выписке «со слов жены, Марии Петровны» или «направлен из больницы в Мукачево», и никакое удаление полей это не поймает. Текст проходит через NER-модель, словари (имена сотрудников, названия населённых пунктов) и регулярные выражения для телефонов и номеров документов. Найденное заменяется типизированными метками вроде [ИМЯ] или [НАСЕЛЁННЫЙ_ПУНКТ]. Качество очистки измеряется на размеченной выборке, и остаточный риск учитывается в правах доступа к полному тексту.

Косвенные идентификаторы и k-анонимность

Даже без имени человека можно узнать по сочетанию признаков: возраст, пол, район и редкий диагноз. Поэтому возраст обобщается до групп, даты сдвигаются на постоянное для каждого пациента смещение (интервалы между событиями сохраняются, календарные даты нет), редкие значения укрупняются. Выгрузки проверяются на k-анонимность: каждое сочетание косвенных признаков должно встречаться минимум у k пациентов. В агрегатах маленькие ячейки (например, меньше пяти человек) скрываются.

Уровни доступа и аудит

  • Аналитик видит агрегаты и псевдонимизированные выборки, может выгружать их в утверждённых форматах.
  • Врач-исследователь работает с когортами и документами, но выгрузка ему закрыта по политике.
  • Reverse lookup, то есть переход от псевдонима к карте пациента в МИС, доступен только ролям с правом идентификации, с указанием причины.
  • Журнал аудита фиксирует, кто, когда, какой запрос выполнил, сколько записей получил и какие документы открыл. Журнал только дописывается, правок в нём нет.
MedStore: журнал аудита с заблокированной выгрузкой для роли врача-исследователя
Аудит в прототипе: попытка выгрузки под ролью врача-исследователя заблокирована политикой и попала в журнал

Поиск по неструктурированным данным через локальный RAG

Самые ценные медицинские факты записаны не в полях, а в тексте: «узел 10 мм в S6 правого лёгкого», «стент в проксимальном сегменте», «толщина ткани 0.42 см». Полнотекстовый поиск находит слова, но не смысл: он не знает, что «новообразование» и «узел» могут означать одно и то же. Для таких вопросов нужен семантический поиск и языковая модель, которая соберёт ответ из найденных фрагментов. Это и есть RAG, retrieval-augmented generation.

Очевидное решение, отправить выписки в облачную LLM, для медицинских данных не подходит. Текст покидает периметр клиники, попадает в логи чужого провайдера, и никакой договор не вернёт его обратно. Поэтому весь RAG-контур работает локально.

Как устроен конвейер

  1. Индексируется только уже деперсонализированный текст. Документы режутся на фрагменты по разделам, у каждого фрагмента есть document_id, тип документа, дата и псевдоним пациента. Имён в индексе нет изначально, а не «фильтруются потом».
  2. Эмбеддинги считает локальная модель на собственном GPU-сервере клиники. Подходят открытые многоязычные модели, которые понимают украинский и медицинскую лексику. Эмбеддинги тоже считаются чувствительными: по ним можно частично восстановить исходный текст, поэтому индекс не выходит за периметр.
  3. Векторный индекс (например, pgvector, Qdrant или OpenSearch) хранит фрагменты с метаданными. Поиск гибридный: векторная близость плюс полнотекстовые совпадения, чтобы не терять точные числа и коды. Фильтры по ролям применяются на этапе выборки, до того как фрагменты увидит модель.
  4. Локальная LLM с открытыми весами работает на своём сервере инференса без выхода в интернет. Она отвечает только по найденным фрагментам и ссылается на документы-источники. Если в найденном нет ответа, модель так и говорит.

Контроль утечек в ответах

  • Сетевая политика запрещает исходящие соединения из RAG-контура, это проверяется технически, а не на честном слове.
  • Ответ модели проходит через тот же детектор персональных данных, что и документы. Если в ответе всплыло имя или номер, ответ блокируется и событие уходит в аудит.
  • Текст документов считается данными, а не инструкциями: защита от prompt injection, спрятанной в тексте выписки.
  • Каждый RAG-запрос журналируется: кто спросил, что спросил, какие фрагменты были подняты и что ушло пользователю.
  • Промпты и ответы не отправляются во внешние сервисы телеметрии и не используются для обучения чужих моделей.
MedStore: семантический поиск по КТ-заключениям с найденными фрагментами и уверенностью
Семантический поиск в прототипе: КТ ОГК с узлами от 10 мм, найденный фрагмент текста, локализация и уверенность

Архитектура целевой системы

Схема ниже показывает путь данных от источников до экрана пользователя. Всё, что внутри пунктирной рамки, работает в контуре клиники. Деперсонализация стоит до хранилища, поэтому ни витрины, ни полнотекстовый индекс, ни RAG никогда не видят прямых идентификаторов. Обратно к личности пациента ведёт единственная дверь, reverse lookup, и она под аудитом.

MedStore: архитектура целевой системы с источниками, интеграцией, деперсонализацией, хранилищем, локальным RAG и интерфейсом запросов

Что уже есть в прототипе, а что относится к целевой системе

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

Реализовано в прототипе:

  • вход под тремя демо-ролями: медицинский аналитик, врач-исследователь, администратор доступа;
  • четыре типа запросов: когорта, сводка по пациенту, семантический поиск по тексту документов, агрегированная аналитика с группировкой по возрастным группам для Power BI;
  • псевдонимы пациентов MS-id и отдельный идентификатор для reverse lookup вместо имён в выдаче;
  • таблица результатов с фильтрами и страницами, найденные фрагменты текста с подсветкой и уверенностью, ссылки на документы-источники, график;
  • запрет выгрузки для роли врача-исследователя с записью события в журнал аудита;
  • распознавание запросов без медицинских критериев: система просит уточнить и не запускает поиск;
  • нормализация похожих формулировок в один запрос, чтобы одинаковые вопросы давали одинаковый ответ;
  • контракт будущего API: в ответе описан план выполнения, например гибридный поиск по текстовому индексу и эмбеддингам.

Спроектировано для целевой системы: коннекторы к МИС и архивам, OCR, нормализация справочников и MPI, сервис псевдонимизации с отдельным ключом, NER-очистка текста, проверка k-анонимности выгрузок, локальные эмбеддинги, векторный индекс, локальная LLM с фильтром ответов, серверный неизменяемый журнал аудита. Необязательный AI-режим прототипа генерирует демо-ответы только по синтетическим данным; в целевой системе этот шаг выполняет исключительно локальная модель.

Важное ограничение

Это прототип согласования UX. Он не подключён к реальным медицинским данным и не содержит персональной информации пациентов: на нём проверяют логику работы, а не лечат.

Следующий шаг

После согласования интерфейса определяется модель данных, слой доступа, аудит обращений к чувствительным полям и правила деперсонализации выгрузок. Затем пилот на ограниченном срезе данных: один источник, одна группа документов, замер качества очистки текста и точности семантического поиска на размеченной выборке.

Схема данных

Из чего состоит база проекта и как связаны сущности.

MED STORE: Схема данных

Контур системы

Из каких частей собран проект.

MED STORE: Контур системы

Схема интерфейса

Как устроен рабочий экран.

MED STORE: Схема интерфейса

Где посмотреть

Публичной ссылки у проекта нет: прототип развёрнут на закрытом адресе с авторизацией и наружу не выкладывается. Показываем его на демонстрации, по записи.

Технологический стек и подходы

SaaS архитектура Микросервисы Облачные вычисления Масштабируемость ПО API интеграции DevOps процессы High-load системы Кибербезопасность решений

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

01Почему интерфейс делается раньше хранилища?

Потому что дешевле переделать прототип, чем перестраивать готовое хранилище под сценарии, которые всплыли уже после запуска.

02Есть ли в прототипе реальные данные?

Нет. Прототип работает без подключения к медицинским данным и не содержит персональной информации пациентов.

03Что дальше после согласования?

Модель данных, слой доступа с ролями, аудит обращений к чувствительным полям и правила деперсонализации выгрузок.