Предложение, обсуждается в chain 6bfe41d1, 2026-05-10).
Контекст
Лабораторные документы часто несут текст, привязанный к конкретному результату, а не ко всему отчёту: inline-ремарка (“slightly elevated, repeat advised”), сноска по маркеру (*, (1)), блок conditional-ranges (normal: <150, borderline: 150-200, high: >200), пояснение метода. Это не само значение, не врачебный вердикт — это аннотация к измерению.
Легаси-распознавание (recognize_gpt, Langfuse prompt) это поддерживает: per-parameter поле inline_interpretation (“any explanatory text, comments, or complex reference value structures located directly [рядом с параметром]”), per-parameter footnote_ids (number[]) → root-level массив footnotes[] ({id, symbol, text, scope}, scope ∈ parameter_interpretation | general_note), плюс секция “Footnote and Comment Processing” в промпте с правилами inline vs referenced.
Новый recognize_image_to_fhir (in-repo, recognize-image-to-fhir.schema.ts) это потерял: per-parameter поля — только param_name / original_value / value / unit / original_range / loinc_code / fhir_value / is_allergen / page / test_date. Комментарии/сноски могут попасть только в document-level narrative_blocks[] (content_type ∈ recommendation | other), не привязанные ни к какому параметру. Следствие: комментарий к конкретному результату либо теряется, либо всплывает несвязанным narrative-блоком — а иногда (как “Continue current lifestyle measures” в тесте teqzg42…) неудачно превращается в отдельный social-history Observation с valueString, что вдобавок ломает enrich-fhir-observations.
Связанное, но другое: лабовский H/L/↑/↓ флаг (не текст) — это original_status (RFC-013, proposed; см. recognition) → Observation.interpretation. Этот документ — про текст-комментарий, не про флаг.
Предложение
Вернуть в recognize-image-to-fhir схему/промпт:
- per-parameter
inline_interpretation: string | null— дословный inline-текст, привязанный к параметру; промпт классифицирует «комментарий vs блок conditional-ranges» как в легаси (если это conditional-ranges —original_rangeзануляется, текст идёт сюда); - per-parameter
footnote_ids: number[]; - root-level
footnotes: [{ id, symbol, text, scope }],scope ∈ parameter_interpretation | general_note.
Маппинг в FHIR (без новых extension — см. zero-extensions-fhir):
- свободный текст
inline_interpretation→Observation.note[]({ authorString: lab_name | authorReference: Organization лабы, time: test_date, text }); автор — лаба, отличается от AI-ноты (authorReference: Organization/bloodgpt, добавляетсяenrich-fhir-observations— он сохраняет существующиеnote[], конфликта нет); - блок conditional-ranges из
inline_interpretation→Observation.referenceRange[].text(v1 — дословно; structuredreferenceRange[]сtype/appliesTo— later, см. multi-tier-range-storage); - футноут со
scope=parameter_interpretation, референснутый параметром →Observation.note[]с символом-префиксом ("* <text>"); - футноут со
scope=general_note→DiagnosticReport.note[](это про весь отчёт, не про параметр).
Не делаем: парсинг “slightly elevated” → interpretation: H (распознавание — OCR, не врач; interpretation ставит шаг анализа, см. recognition и lab-status-vs-derived-interpretation); складывать комментарий в valueString / в дочерний Observation; новые custom extensions.
Следствия
- Часть случаев, когда recommendation-текст лаб-коммента всплывает несвязанным Observation’ом (типа “Continue current lifestyle measures”), снимается: текст привязывается к нужному результату как
note[], а не материализуется фейковымsocial-historyObservation. (Где должен жить чисто-рекомендательный текст без привязки к параметру —CarePlan/DiagnosticReport.note[]/ drop — см. lifestyle-vs-clinical-data, medical-as-instrument-not-recommendation, uploaded-document-types.) - Выбор «conditional-ranges →
referenceRange[].text» де-факто частично разрешает multi-tier-range-storage в сторону Variant B (FHIR-nativereferenceRange[]), хотя там это покаcontested. - Паритет нового image-pipeline с легаси
recognize_gptпо comment/footnote-данным — снимает один из cutover-блокеров (см. fact-based-recognition). narrative-to-fhir/save-fhir-*шаги получают новый маппинг (inline_interpretation/footnotes→Observation.note[]/referenceRange[].text/DiagnosticReport.note[]).
Observation.note[] — только lab-originated
Важное уточнение: Observation.note[] зарезервирован под аннотации из документа (этот inline_interpretation / footnotes, author = лаба). Сгенерированный нами контент туда НЕ идёт — в V2.5 пер-параметровый AI-разбор живёт в ClinicalImpression.extension[bloodgpt-parameter-analysis], на уровне пациента — в Composition/CarePlan. Раздельность «оригинальное vs сгенерированное» — чтобы можно было достать одно без другого (?_security:not=AIAST для trusted lab data; ?_tag=origin|user-uploaded); tagging mechanism — fhir-meta-tagging; lifecycle (immutability raw Observation, легаси enrich-fhir-observations кладёт AI parameterDetails в Observation.note[] с author=Organization/bloodgpt — артефакт тест-scoped эры, помечен на удаление) — fhir-resource-origin-and-lifecycle. То есть после этого decision’а в Observation.note[] живёт лаб-текст; наш текст — отдельно, в своих ресурсах.
Открытые вопросы
authorString: lab_namevs создавать/референситьOrganizationдля лабы (естьlab_nameизtest_info) — v1 строкой, потом, возможно, ресурс.- Дедуп: если тот же inline-текст подтверждён несколькими VLM-проходами / уже есть в
note[]— не дублировать (какenrich-fhir-observationsделаетnotes = [...(obs.note||[])]). - Нужно ли отдельное поле под conditional-ranges в схеме (
conditional_ranges?) вместо того чтобы они приезжали внутриinline_interpretationи классифицировались эвристикой в narrative→FHIR. - Перенос обновлённого
recognize_image_to_fhirпромпта/схемы в Langfuse (сейчас in-repo).
Связано
- recognition — pipeline; там же
original_status(RFC-013) — лабовский флаг (отличается от текст-комментария) - lab-status-vs-derived-interpretation — trust lab status; смежное (флаг, не текст)
- multi-tier-range-storage — conditional-ranges часть пересекается (contested → Variant B)
- zero-extensions-fhir — почему маппинг идёт в стандартные
note[]/referenceRange[], не в extension - fhir-resource-origin-and-lifecycle —
note[]lab-originated vs generated;enrich-fhir-observationsна удаление - fhir-meta-tagging —
meta.security:AIAST/meta.tag:source— как метим «это сгенерировано» - authorship-organization-not-device — кого ставить в
note[].author - ai-enrichment-separate-step — AI-ноты добавляются отдельным шагом; лаб-нота пишется раньше при распознавании
- fhir-observation, fhir-annotation, fhir-diagnostic-report
- lifestyle-vs-clinical-data, medical-as-instrument-not-recommendation — recommendation-фрагменты не должны быть Observation’ами
- fact-based-recognition — cutover legacy → image pipeline
Источники
Источники: 1.
Сноски
-
FHIR R4
Observation.note/Observation.referenceRange, accessed 2026-05-17, https://hl7.org/fhir/R4/observation.html. ↩