惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

爱范儿
爱范儿
Security Latest
Security Latest
NISL@THU
NISL@THU
OSCHINA 社区最新新闻
OSCHINA 社区最新新闻
C
Cybersecurity and Infrastructure Security Agency CISA
Cloudbric
Cloudbric
T
Threat Research - Cisco Blogs
大猫的无限游戏
大猫的无限游戏
C
CXSECURITY Database RSS Feed - CXSecurity.com
阮一峰的网络日志
阮一峰的网络日志
freeCodeCamp Programming Tutorials: Python, JavaScript, Git & More
雷峰网
雷峰网
C
Cisco Blogs
V
Vulnerabilities – Threatpost
S
Security Archives - TechRepublic
V
Visual Studio Blog
让小产品的独立变现更简单 - ezindie.com
让小产品的独立变现更简单 - ezindie.com
cs.AI updates on arXiv.org
cs.AI updates on arXiv.org
J
Java Code Geeks
D
Darknet – Hacking Tools, Hacker News & Cyber Security
Know Your Adversary
Know Your Adversary
博客园 - 叶小钗
腾讯CDC
钛媒体:引领未来商业与生活新知
钛媒体:引领未来商业与生活新知
P
Privacy International News Feed
P
Palo Alto Networks Blog
博客园_首页
V
V2EX
WordPress大学
WordPress大学
Schneier on Security
Schneier on Security
月光博客
月光博客
博客园 - 司徒正美
Google DeepMind News
Google DeepMind News
TaoSecurity Blog
TaoSecurity Blog
博客园 - 聂微东
酷 壳 – CoolShell
酷 壳 – CoolShell
人人都是产品经理
人人都是产品经理
奇客Solidot–传递最新科技情报
奇客Solidot–传递最新科技情报
博客园 - 【当耐特】
The Cloudflare Blog
罗磊的独立博客
美团技术团队
N
News | PayPal Newsroom
K
KPMG report finds enterprise disconnect between AI and its ROI | CIO
Last Week in AI
Last Week in AI
K
Kaspersky official blog
Google Online Security Blog
Google Online Security Blog
S
SegmentFault 最新的问题
Application and Cybersecurity Blog
Application and Cybersecurity Blog
T
Tailwind CSS Blog

Все публикации подряд на Хабре

Ловим музу за клавиатуру: как айтишнику стать автором Что умеет Midjourney в 2026? Мой немного грустный разбор этого шикарного инструмента Никто не любит писать тесты, но ИИ может исправить это IPv8 выглядит как мечта. Поэтому почти наверняка не взлетит Производители вернули в продажу материнки с DDR3. Что происходит? Управление агентом с телефона через Telegram теперь в KodaCode От координации к лидерству: как меняется роль руководителя разработки Я сделала родителям бизнес вместо пенсии: зарабатываем 70 тысяч, мама не даёт продать В три раза быстрее приемка товара и оптимизация трудозатрат на 73%: как «РСТ-Инвент» помог Gulliver Group ИИ-шечный мир победил? О влиянии искусственного интеллекта на игропром Кремль снижает давление на Телеграмм пока Европа строит интернет по паспорту Как CEO, CTO и CIO за 8 часов собрали ИИ-директора, который умеет держать позицию под давлением Как (не) потерять домен за выходные Вместо 8 разных VPS: как я организовал практику студентам на одном сервере Почему твой Open Source проект не замечают? R&D: искусство управления неопределенностью в разработке AI-дефляция: вакансий для разработчиков больше, а рост зарплат — худший за 15 лет Мы отдали управление роботами OpenClaw. Что из этого вышло Галактический ID: система идентификации для всех форм разумной жизни Кто решает судьбу вашего проекта? Разбираем заинтересованные стороны. BABOK #1 Код-ревью, в котором дело не в коде Данные переехали. Команда — нет Системной подход к сдаче OSWE в 2025 Почему комната управления реактором покрашена в цвет морской пены 4 YAML-файла вместо PySpark: как аналитикам строить пайплайны без разработчиков LLM-агент для поиска свободных доменов: автоматизируем подбор Когда, зачем и как правильно начинать новую сессию в Claude Code? Как я заставил нейросеть писать макросы для FreeCAD Анатомия ИИ‑агента для подбора персонала. От тысячи резюме к топ‑10 за минуты Опыт разработчика как экономика внимания Автономность как точка невозврата: кто будет субъектом в цифровом будущем Обучение ИИ в «диких» условиях: как рутинные действия превращаются в датасеты Как измерить LLM для задач кибербеза: обзор открытых бенчмарков Где хранить код? Сравнение GitHub, GitLab и Bitbucket Математика объясняет, почему нормальное распределение встречается повсюду Почему ваш FinOps не работает: 12 тезисов от практиков Как подписать проектную документацию УКЭП с использованием бесплатных лицензий Pilot Адаптивное администрирование Sigla Vision Я грузил уран в бочки, а потом 20 лет строил ИТ в атомной отрасли Чем позвонить с Эвереста? История и обзор спутниковой связи. Часть 2 Как языковая модель помогает контролировать качество инструктажей по охране труда в металлургии Как не передать на desktop свой IP в РКН Анатомия SAP Privileges: как устроено управление правами в macOS MoneyDev: Сказка про три главных слова Обновлённый токенизатор видео K-VAE 2.0 от Сбера Как сделать диспетчеризацию дома на 1284 квартиры почти бесплатно Как мы разогнали железную дорогу Мы дали агентам рутину. Теперь надо решить — что делать с освободившимся временем Токсичный контент, промпт-хакинг и защита ИИ — всё о Guardrails для LLM Умный город начинается с точного взгляда: как «Фалькон Тех» меняет пространство к лучшему Навайбкодил приложение для анализа графов Почему Дюну так интересно читать? Упрощаем работу с рутиной или как стать Гендальфом Белым Деконструкция Go: CPU, RAM и что там происходит. Go Assembler база. Часть 1.1 Какие профессии исчезнут из-за ИИ, а какие появятся? И что с этим делать Как мы построили IT-отдел, где хочется расти: архитектурные встречи, прозрачные метрики и книжные подарки Rufler: Делаем из Claude Code автономный рой через один YAML-конфиг Sing-box и белый список приложений Как построить надёжный обмен сообщениями в микросервисах: лучшие практики для enterprise OpenAI строит MLM-пирамиду, а McKinsey и Accenture помогают ей в этом Дом, который не построил Фишер (Часть 2) «Сверхзвуковой математик» против «Вдумчивого логиста»: битва алгоритмов 3D-упаковки Мультимодальные модели – грубый и дорогой инструмент Разговоры ничего не стоят. Код тоже Проверки физических лиц: с кого начнет ФНС Топ-10 бесплатных нейросетей для создания видео в 2026 году Первые слои кода: как наши решения сегодня определяют архитектуру ИИ на десятилетия Разработка нового статического анализатора: PVS-Studio JavaScript Поиск уязвимостей ПО: базовый минимум или роскошный максимум Почему оценка персонала не работает как инструмент управления Как мы разработали ИИ-ассистента и сократили рутину продуктовой команды на 50% Как я ушел из найма, нажарил косточек и продал на маркетплейсах на 168 млн в год Когда 1С:ERP уже внедрена, а нормального производственного плана всё ещё нет Как я сделал Claude мультимодальным, подключив к нему Qwen Omni Как приглашение на вакансию мечты превращается в атаку Infrastructure as Code: философия и лучшие практики IaC Тестируем Yandex Code Assistant на задаче, в которой нужно хранить секреты nxs-universal-chart v3.0: новое поколение универсального Helm-чарта Callback Injection: Техника, которая отправила Microsoft Defender в глухой нокаут «Все идеи на стол»: митап как способ вывести проект из тупика Сегодня я узнал нечто новое о GPU благодаря багу в своей игре Как заставить LLM ̶ ̶г̶а̶л̶л̶ю̶ ̶ эволюционировать Карта событий как фундамент аналитики: практический кейс для E-commerce Что выбрать для AI: x86, ARM или RISC-V? Дайджест железа за март Роль соматических мутаций в развитии аутоиммунных заболеваний: путь к избирательной терапии Mythos от Anthropic — тревожный сигнал для всех, а не только для банков Guardrails для LLM на Java: как приручить промпт‑инъекции и токсичные ответы Green-VLA: как мы собрали VLA-модель для реального антропоморфного робота и не потеряли обобщение Финансовая гонка вооружений: почему умные люди добровольно в ней участвуют Эра ИИ-агентов наступила: выбираем лучшего цифрового сотрудника # Практический опыт внедрения WinCC Redundancy на производственном предприятии Сделал MVP за 3 дня, а потом неделю прикручивал оплату. Оно того стоило? Физика против Маска: почему Starship V3 может оказаться ещё одной катастрофой Нефть Венесуэлы: крупнейшие запасы в мире, но не крупнейшая нефтяная держава JPA 4. Переосмысление Hibernate Почему зеркальная фотокамера Nikon D5 десятилетней давности идеально подошла для миссии «Артемида-2» Проект «Уровень-Спутник» или как мы сделали платформу для гидрологов «Замедлиться, чтобы ускориться»: почему ИИ повышает цену ошибок в требованиях и архитектуре Как с нуля поднять трафик IT-компании на 1657% при бюджете 55 тыс. и выжить Pixel-perfect Downsampling — идеальная отрисовка 50 миллионов точек без потерь
Интероперабельность медданных: почему один биомаркер — это не один код
Никита Заверач · 2026-06-14 · via Все публикации подряд на Хабре

Интероперабельность медданных: почему один биомаркер — это не один код

Средний

6 мин

1.1K

Эта статья — про то, как я проектировал референсную архитектуру для приведения лабораторных данных к LOINC (Logical Observation Identifiers Names and Codes — международный справочник кодов лабораторных и клинических показателей) и UCUM (Unified Code for Units of Measure — стандарт машиночитаемого кодирования единиц измерения), и что понял по дороге.

Сразу оговорюсь: это архитектура на бумаге — ADR, схемы и разобранные примеры в репозитории, а не развёрнутый в проде сервис. Боевой нагрузкой пока не проверена.

Все решают одну проблему заново

В каждой лаборатории один и тот же биомаркер пишут по-своему. Вот реальная цепочка названий для одного-единственного фермента — аспартатаминотрансферазы:

АсАТ · AST · АСТ · аспартатаминотрансфераза · аспартат-аминотрансфераза · глутамат-оксалоацетат-трансаминаза · SGOT · СГОТ

Всё это — один и тот же аналит (то, что измеряют в пробе, — конкретное вещество или показатель). Пока данные живут внутри одной системы, это не проблема: справочник знает свои синонимы. Проблема появляется на границе — когда данные нужно обменять между лабораториями, свести в регистр, отдать в аналитику. Тогда выясняется, что «свой справочник» каждого не стыкуется ни с чьим другим.

Естественная реакция инженера — построить граф синонимов и схлопнуть весь этот список в один код. Я сам так думал. И это работает ровно наполовину.

Почему «список синонимов → один код» — это ловушка

LOINC-код — это не «название анализа». Это полностью специфицированная комбинация шести осей:

Ось

Что задаёт

Пример

Component

Что измеряем (аналит)

Glucose, AST

Property

В чём измеряем (размерность)

масс-конц. mg/dL или молярная mmol/L

Time

Момент или интервал

разовая проба или суточная моча

System

Биоматериал

сыворотка, плазма, моча

Scale

Тип шкалы

количественная, порядковая, номинальная

Method

Техника измерения

с P-5’-P / без P-5’-P

И вот ключевой момент: список синонимов выше схлопывается только по одной оси — Component (что за аналит). Но тот же AST в сыворотке и в плазме — это разные коды (ось System). С пиридоксальфосфатом и без — разные коды (ось Method). Количественный и качественный результат — разные коды (ось Scale).

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

LOINC отвечает на «что», UCUM — на «сколько»

Здесь меня долго сбивала одна неточность: казалось, что раз есть LOINC, то единица измерения уже зашита в код, и UCUM избыточен. Это не так.

LOINC задаёт размерность (через ось Property): «это масс-концентрация» или «это молярная концентрация». Но он не говорит, отчиталась ли лаборатория в mg/dL, g/L или mcg/mL — а это всё одна размерность, но разные числа. Реальная единица приходит вместе с данными, не из кода.

LOINC

UCUM

Отвечает на

Что измерено

Сколько и в каких единицах

Нормализует

Понятие измерения

Единицу внутри размерности

Объект

Аналит + обстоятельства

Величина значения

Они ортогональны, и нужны оба. Даже внутри одного LOINC-кода единицы могут различаться: лаборатория А шлёт глюкозу в mg/dL, лаборатория Б — ту же самую в g/L. Понятие совпало, числа — нет. Усреднишь по коду без приведения единиц — получишь мусор. Вот тут и работает UCUM: приводит mg/dL → g/L детерминированно, потому что это одна размерность и коэффициент не зависит от вещества.

А вот mg/dL → mmol/L (масса → молярность) — это смена размерности, и она требует молярной массы конкретного вещества. UCUM этого не делает и делать не должен — он ничего не знает про вещества. Это та же самая стена, что ось Property в LOINC, просто с другой стороны: масс-код и молярный код — это разные коды, и переход между ними — отдельная задача с учётом вещества.

Зачем такая дотошность: RWE и OMOP

В этот момент возникает законный вопрос: не избыточное ли это усложнение? Ответ зависит от того, зачем вы нормализуете данные.

Если цель — просто зарегистрировать факт («тест на глюкозу назначался»), посчитать частоты или обменяться понятием, то хватит и одной LOINC-нормализации. UCUM здесь ничего не добавляет. То же для качественных результатов («положительно / отрицательно») — там числовой единицы нет вовсе.

Но если цель — аналитика на уровне значений, то есть считать по самим значениям (динамика, сравнение с референсными интервалами, когорты для RWE, фичи для ML), то картина другая. Real-world evidence (RWE — доказательства из данных реальной клинической практики, а не из клинических испытаний) живёт на объединении данных из десятков источников, и здесь критичны две вещи:

  • Сопоставимость — глюкоза из лаборатории А и из лаборатории Б должны быть одной и той же сущностью, иначе их нельзя складывать. LOINC даёт стабильный ключ.

  • Защита от ложной агрегации — нельзя тихо смешать сывороточную глюкозу с мочевой или активность AST «с P-5’-P» и «без». Оси не дают этому случиться молча.

И это не абстракция. OMOP CDM (Common Data Model — стандартная модель данных для наблюдательных исследований), на которой стоит весь инструментарий OHDSI (Observational Health Data Sciences and Informatics — международное сообщество и набор инструментов с открытым исходным кодом поверх OMOP), спроектирована буквально под эту пару. В таблице MEASUREMENT:

  • measurement_concept_id ← LOINC (что измерено, со всеми осями),

  • unit_concept_id + value_as_number ← UCUM (единица + число),

  • value_as_concept_id ← качественный результат (ось Scale у LOINC).

То есть OMOP-таблица — это почти один-в-один LOINC (оси) + UCUM (единица). Это не совпадение: модель строилась вокруг этих стандартов. А значит, слой нормализации сырое имя + контекст → LOINC + канон UCUM — это, по сути, ETL-дверь (extract-transform-load — извлечение, преобразование и загрузка данных) в OMOP. Без него таблица MEASUREMENT заполняется мусором.

Поток данных: сырое имя + значение + контекст → резолвер → LOINC-код и канон UCUM → таблица OMOP MEASUREMENT → RWE-аналитика

Поток данных: сырое имя + значение + контекст → резолвер → LOINC-код и канон UCUM → таблица OMOP MEASUREMENT → RWE-аналитика

Как это внедрить, не переписывая всё

Самый частый страх при слове «стандартизация»: «значит, надо снести наш справочник и собрать всё заново». Нет. Это классический паттерн strangler fig («удушающий плющ») — новый слой обрастает старую систему по краям, ничего не ломая.

Ключевой сдвиг: LOINC/UCUM не заменяет ваш внутренний справочник. Он садится слоем выше как канонический интерлингва (промежуточный язык-посредник, через который сопоставляются разные системы). Ваш справочник остаётся локальным словарём, а LOINC — тем, с чем он сопоставляется для обмена наружу. Те самые кропотливо собранные синонимы не выбрасываются — они становятся входным слоем, который питает нормализацию. Граф синонимов ALT — это не конкурент резолверу, это его поставщик.

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

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

Здесь возникает резонное возражение: зачем весь этот аппарат осей, версий и правил, если современная языковая модель и так «поймёт», что АлАТ — это ALT? Ответ — не «модель плохая», а «у неё в этой архитектуре точное и узкое место, и это не место того, кто выдаёт итоговый код».

Где модель незаменима — это распознавание имени аналита: схлопнуть «АсАТ / AST / SGOT / глутамат-оксалоацетат-трансаминаза» в одну сущность. Здесь доменная модель — или биомедицинские эмбеддинги (числовые векторы, кодирующие смысл: близкие по смыслу названия близки и в пространстве) класса BioLORD / SapBERT — бьёт любой рукописный словарь синонимов. То есть модель нормализует имя (ось Component) и поднимает кандидатов-кодов с оценкой. Остальные оси, от которых и зависит конкретный код (System, Method, Scale, Property), приходят отдельно и явно из контекста и применяются детерминированными правилами приоритета — а не угадываются. Поэтому важные обстоятельства не теряются: модель за них просто не отвечает. И итоговый код она тоже не выдаёт — его выбирает детерминированный слой: правила приоритета, проверка кода по снимку справочника, аудит.

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

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

  • Нет воспроизводимости и учёта версий из коробки. Модель не объяснит, почему выбран именно этот код, и не знает, что он устарел и заменён в текущей версии. Это держат слой аудита и слой версионирования — на них и стоят воспроизводимость и разбор.

А какая именно модель стоит в резолвере — деталь реализации: архитектура держит его как заменяемый слой и от конкретной модели не зависит.

Честно про путь

И последнее, личное.

Я спроектировал эту архитектуру раньше, чем разобрался в LOINC и UCUM до уровня шести осей. Сначала появились решения и компромиссы, и только потом, докапываясь до деталей стандарта, я заметил, что многие из них совпали с тем, как устроены сами стандарты. Выглядит как «надо было сначала изучить, потом делать» — но, кажется, порядок был правильный.

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

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

Ссылки

Репозиторий: https://github.com/alarent/loinc-ucum-reference-architecture

Разбор решений (ADR): каталог docs/adr/ в репозитории