Подход к AI-интерпретации одного лабораторного параметра одним LLM-вызовом с одним промптом-template, в который инжектится статический medical context. Один из двух подходов в pipeline’е BloodGPT — параллельно с biomarker-analysis-pipeline (см. staged-output-fhir-storage про сравнение).
Структура
build medical context (один раз на тест из FHIR)
│
↓
для каждого параметра (sequential):
template substitution (single_parameter_analysis из Langfuse)
+ biomarker name, value, unit, refRange
+ abnormal observations из того же теста
+ conditions / medications / allergies пациента
│
↓
analyzeTextWithStructuredOutput(prompt, schema)
└── один LLM call → JSON по Zod schema
│
↓
flat ParameterAnalysis row → Postgres
└── копия prose-текста → FHIR Observation.note[].text
{>>Storage layout ниже устарел после BG-1337 PR-5/PR-7 (примерно после 2026-05-07 даты этой страницы). Текущее состояние per packages/database/prisma/schema.prisma:326-329 + prisma-batch.ts:94: ParameterAnalysis / TestOverview / FollowUpRecommendations / PanelOverview / ParameterTrends — все 5 таблиц dropped. Per-param результат пишется в BloodTest.enrichmentDraft.parameters[] (Json column, transient во время прогона), post-completion source of truth — FHIR Composition + CarePlan. Запись в Observation.note[].text тоже надо verify — может быть тоже изменилась. Эту секцию + раздел Output ниже надо refresh’нуть.<<}
Один LLM round-trip per parameter, без агентского loop’а, без stages, без structured evidence.
Контекст-инжекшн
Medical context собирается детерминированно один раз до loop’а:
- patient demographics (age, sex)
- active conditions (
Condition) - active medications (
MedicationStatement/MedicationRequest) - allergies (
AllergyIntolerance) - abnormal observations (другие параметры из того же теста)
Всё это inline в prompt-template через переменные. LLM видит контекст в одном блоке, не выбирает что подгрузить.
Output
{>>см. CriticMarkup выше — секция Output устарела после BG-1337; ParameterAnalysis table dropped, parameterDetails теперь в BloodTest.enrichmentDraft.parameters[].parameterDetails. Структуру полей ниже надо сверить с current LocalParameterAnalysis в apps/analysis-worker/inngest/functions/analysis-steps/types.<<}
ParameterAnalysis flat row в Postgres:
interpretation— H / L / NisHealthy— booleanparameterDetails— text (AI explanation)triagePriorityrequiresDoctorPreparation— boolean
parameterDetails дублируется в Observation.note[].text для FHIR-чтения. Без structured evidence, без citations, без per-audience варианта. Один text-вывод на единую аудиторию.
Где живёт
| Артефакт | Расположение |
|---|---|
| TS реализация | packages/analysis-core/src/services/blood-parameter-analysis.service.ts (BloodParameterAnalysisService) |
| Langfuse prompt | single_parameter_analysis (production-managed) |
| Activation toggle | SKIP_LEGACY_ANALYSIS env var (true → пропускается) |
| Pre-TS implementation | legacy BloodGPT-dotnet repo |
Свойства
- Простой conceptual model — один промпт, понятный input/output
- Prompt iteration через Langfuse без code deploy — централизованное версионирование
- Одна точка качества — качество = качество промпта; A/B на промптах простой
- Низкий cost / latency — один LLM round-trip per param, ~5-15s
- Нет dynamic retrieval — context fixed на момент сбора
- Flat output structure — нет evidence items, citations, mechanism chain’ов
Известные ограничения
- Нельзя гранулярно дебажить вывод — если интерпретация плохая, неясно что починить: prompt? medical context build? schema? — всё в одном вызове
- Нет audience-split — output один; doctor / patient delineation возможна только через style hint в промпте, не через separate ресурс
- Нет structured evidence — quotes из guidelines невозможно прикрепить к конкретному выводу
- Static context может быть неполон — agentic retrieval недоступен; «чего не хватает в context’е» не выявляется
Связано
- staged-output-fhir-storage — где обсуждается переход на staged подход
- biomarker-analysis-pipeline — sibling-страница про staged подход (Reasoner + Writer + Personalizer)
- fhir-observation — куда single-prompt output попадает (
note[]) - fhir-clinical-impression — куда staged-analysis output попадает (для контраста)
- parameter-range-type-prompt — параллельный Langfuse-prompt в pipeline (range type detection, тоже single-prompt архитектура)