FHIR R4 ресурс — record of who, when, why и из какого исходного материала был создан или изменён другой ресурс. Provenance ссылается на target-ресурсы через target[]: Reference. Один Provenance может покрывать множественные ресурсы (например, все resources, созданные при разборе одного source-документа).
Использование в BloodGPT
Универсальный source attribution для multi-source FHIR-write
Pipeline пишет FHIR-ресурсы из нескольких источников:
- Health chat — пациент говорит в чате, AI агент пишет
Condition/MedicationStatement/Observationчерез 5 smart write tools - Survey — пациент проходит опросник, агент собирает ответы, потом bridge-step пишет в FHIR (V1.5)
- Document import (TextToFHIR) — загрузка медицинской выписки или PDF (V2)
Для всех трёх — один Provenance ресурс на каждое событие записи, ссылается на все resources из этого события через target[]. Чтобы получить Conditions с их audit-trail, делается обратный include:
GET Condition?patient={pid}&_revinclude=Provenance:target
Что происходит: FHIR-сервер возвращает запрошенные Conditions плюс все Provenance-ресурсы у которых target[] ссылается на эти Conditions. Это и есть _revinclude — “включи в ответ ресурсы которые ссылаются на меня”. Стандартный FHIR pattern для audit. Без _revinclude пришлось бы делать второй запрос Provenance?target=Condition/{id} per result.
Почему не альтернативы
В session 7ff79368 рассмотрены и отклонены:
evidence.detail— работает только дляCondition, не универсально дляMedication/AllergyIntolerance/Procedure/FamilyMemberHistory.containedDocumentReference — каждый ресурс хранит свой DocumentReference, дублирование. Не работает для batch-import одного документа во множество resources.extension— кастомное custom extension URL. Risk: GCP Healthcare API может не поддерживать_includeдля extensions (vendor verification требуется).- Provenance — стандартный FHIR pattern,
_revinclude=Provenance:targetподдерживается на GCP (verified в 7ff79368).
Ильдар: «блин. неуниверсально как-то. можно запутаться» — про
extension/containedварианты до выбора Provenance.
Ключевые поля
{
"resourceType": "Provenance",
"target": [
{ "reference": "Condition/abc-123" },
{ "reference": "MedicationStatement/def-456" }
],
"recorded": "2026-04-26T10:00:00Z",
"agent": [{
"type": { "coding": [{ "code": "author" }] },
"who": { "reference": "Organization/bloodgpt" }
}],
"entity": [{
"role": "source",
"what": { "reference": "DocumentReference/doc-789" }
}]
}target[]— ссылки на ресурсы, которые этот Provenance документируетrecorded— timestamp создания/записиagent.who— кто записал. Для AI-генераций — open design question (нужно унифицировать pattern):- V0.5 smart write tools (chat agent / survey-bridge): сейчас
agent.who: Organization/bloodgptнапрямую — single-level. - V2.5 multi-stage pipeline (Diagnostician → Retriever → Generator → Triage, plan BG-1323):
agent.who: Device/bloodgpt-pipeline-v{N}(singleton per version) +agent.onBehalfOf: Organization/bloodgpt. - Drift между ними — некрасиво. Лучше unify: либо всегда Device-per-tool (
Device/bloodgpt-chat-vN,Device/bloodgpt-survey-vN,Device/bloodgpt-pipeline-vN) с Organization какonBehalfOfвезде; либо всегда Organization напрямую и version черезagent.roleextension. - Не финализировано. Ильдар явно: «надо подумать, может лучше сделать однообразно».
- V0.5 smart write tools (chat agent / survey-bridge): сейчас
entity.role: source+entity.what— ссылка на исходный материал (DocumentReference для загруженного документа, или ничего если source — chat/survey)
Связь с DocumentReference
DocumentReference — FHIR-обёртка над внешним документом (PDF выписки, HL7-файл, скан анализов, URL guideline’а). Метаданные документа (mime-type, дата, source) + содержание (либо attachment, либо ссылка).
Для document import flow создаётся пара:
DocumentReference— метаданные исходного документаProvenance— ссылается на DocumentReference вentity.what+ перечисляет все созданные resources вtarget[]
Для chat/survey flow создаётся только Provenance с agent.who = Organization/bloodgpt без DocumentReference (нет исходного документа — патиент говорил/отвечал).
Status: exploratory. Сейчас входящие документы (загруженные PDF, HL7-файлы лабы) НЕ оформляются через DocumentReference — только парсятся в Observation/Patient ресурсы напрямую. Plan для citations в V2.5 plan-файле явно отвергает DocumentReference («citations это URLs»). Для incoming documents (загруженных пациентом/лабой) — open question, хотим внедрить, но не реализовано.
Multi-agent chain — для multi-stage pipelines
Для pipelines где output генерируется через несколько LLM-stages (Diagnostician → Retriever → Generator → Triage) — один Provenance per pipeline-run с agent[] массивом, где каждый element = stage. Это canonical FHIR pattern для audit chain (Provenance именно для этого создан).
{
"resourceType": "Provenance",
"target": [
{ "reference": "ClinicalImpression/ci-hemoglobin-test123" },
{ "reference": "ClinicalImpression/ci-glucose-test123" }
],
"recorded": "2026-04-24T10:03:42Z",
"agent": [
{
"type": { "coding": [{ "code": "composer" }] },
"who": { "reference": "Device/bloodgpt-pipeline-v2-5" },
"onBehalfOf": { "reference": "Organization/bloodgpt" },
"extension": [
{ "url": ".../stage", "valueCode": "diagnostician" },
{ "url": ".../promptName", "valueString": "diagnostic_plan" },
{ "url": ".../promptVersion", "valueString": "v2.1" },
{ "url": ".../model", "valueString": "gpt-5.2" },
{ "url": ".../langfuseTraceId", "valueString": "lf-abc123" }
]
},
{ /* retriever stage */ },
{ /* generator stage */ }
]
}Pipeline version singleton — Device/bloodgpt-pipeline-v{N}. Singleton resource per pipeline version (не per-test). Multiple versions могут coexist для backward-compat read. Это тонкая деталь — отличается от Device/bloodgpt-ai (который superseded из-за GCP Healthcare API limitations, см. authorship-organization-not-device):
- Старый
Device/bloodgpt-ai— пытались положить вauthor[x](отвергнут vendor) - Новый
Device/bloodgpt-pipeline-vN— кладётся вProvenance.agent.who(vendor поддерживает Provenance.agent fully)
Organization/bloodgpt остаётся как onBehalfOf (legal entity, см. fhir-organization).
CI получает короткий tag-extension pipeline-run-id для UI debug-режима. Детали — через Provenance lookup ?target=CI/....
Status: exploratory. Реализация в worktree (V2.5 BG-1323), не в production deploy.
Зачем 3 параллельных механизма (Provenance + meta.tag + meta.security)
Кратко (полная картина — в fhir-meta-tagging):
- Provenance — full audit chain. Один ресурс per write event, ссылается на все созданные resources, держит agents/timestamp/source documents. Это для глубокого вопроса “кто/когда/откуда/каким путём”.
meta.tag.code: "health-chat" | "survey" | "document-import"— быстрый filter “из какого источника”. Хранится прямо на ресурсе (e.g., Observation), доступен через?_tag=без extra_revincludeзапроса.meta.security: AIAST— отметка “AI-asserted”. Стандартный HL7 v3 код. Доступен через?_security=(или?_security:not=AIASTдля trusted-only).
Не дублирование — три разных оси для трёх разных вопросов:
| Вопрос | Механизм |
|---|---|
| Откуда пришли данные (chat / survey / документ)? | meta.tag |
| Это AI-сгенерировано? | meta.security |
| Кто конкретно написал, когда, через какой pipeline, из какого документа? | Provenance |
Историческая логика “почему три”: сначала добавлялся Provenance (универсальный, но требует _revinclude). meta.tag появился как оптимизация для частых fast-filter запросов. meta.security: AIAST пришёл из HL7 AI Transparency on FHIR IG (2026 ballot) — стандартное обозначение “это AI”, лучше custom тега.
Gotchas / ограничения
recordedобязателен. При import documents — указывать timestamp импорта, не дату документа (для последнего использоватьProvenance.occurredPeriod).target[]не пустой. Provenance без target — invalid resource, отвергается валидаторами._revinclude=Provenance:targetна GCP Healthcare API verified working (session 7ff79368). На других FHIR-серверах verify отдельно (google-healthcare-api [О2] vendor capability matrix).
Открытые вопросы
[О1] Unified agent.who pattern для всех write paths
V0.5 smart write tools используют agent.who: Organization/bloodgpt, V2.5 multi-stage pipeline — agent.who: Device/bloodgpt-pipeline-vN + onBehalfOf: Organization/bloodgpt. Нужно унифицировать. Варианты:
- Везде Device-per-tool (
Device/bloodgpt-chat-vN,Device/bloodgpt-survey-vN,Device/bloodgpt-pipeline-vN) с Organization какonBehalfOfeverywhere. - Везде Organization напрямую, version через
agent.roleextension.
Ильдар: «может лучше сделать однообразно»
[О2] DocumentReference для входящих документов
Полное обсуждение — отдельная page fhir-document-reference (status: exploratory). Кратко: incoming PDFs / HL7 / выписки сейчас парсятся прямо в Observations без обёртки в FHIR DocumentReference, оригинальный файл в GCS bucket с путём в BloodTest.gcsKey Postgres. Хочется внедрить FHIR DocumentReference для audit-trail и portability — pending design.
[О3] Provenance в save-fhir-resources (test-flow analysis pipeline)
Сейчас Composition + CarePlan создаются без Provenance. План на ~30-40 строк кода — описан в plan-файле V2.5, реализация отложена.
[О4] V2.5 multi-agent Provenance deploy
Worktree v2-param-analysis имеет builder, не deployed. Cutover plan в ~/vault/plans/v2-5-rich-output-to-fhir.md.
Связано
- fhir-meta-tagging — actual decision (Provenance + meta.tag + meta.security unified policy)
- fhir-organization — Organization/bloodgpt как
Provenance.agent.who - fhir-bundle — Provenance создаётся в transaction bundle вместе с target-ресурсами
- fhir-modeling-ai-content — closes [О5] (separate det/AI) и [О6] (audit marking)
- health-report-vision — Provenance enables multi-source events (chat / survey / document import)
Источники
Сноски
-
FHIR R4 Provenance, accessed 2026-05-17, https://hl7.org/fhir/R4/provenance.html. ↩
-
FHIR R4 DocumentReference, accessed 2026-05-17, https://hl7.org/fhir/R4/documentreference.html. ↩
-
Сессия
ildar/7ff79368, 2026-03-27 — `. ↩ -
Сессия
ildar/d9de9416, 2026-04-24 — `. ↩