Для structured-LLM задач (LOINC mapping и подобных). Применимость к другим задачам BloodGPT — добавляется по мере появления опыта.
Контекст
Structured-LLM задачу (например, маппинг lab-specific параметра в стандартный LOINC код) можно делать двумя способами:
- Workflow / decomposed — 2-3 узких LLM-вызова с детерминированным слоем между ними. Каждый вызов с узкой инструкцией под свой шаг.
- Agent loop — один LLM в цикле рассуждений с tool calling. Модель сама выбирает что делать на каждом шаге.
Anthropic в посте “Building Effective Agents” формализует это разделение: workflows — для предсказуемых задач, agents — для open-ended (https://www.anthropic.com/research/building-effective-agents). Наш выбор по конкретным задачам BloodGPT согласуется с этим разделением.
Рассматривали
A. Single agent (Mastra) — первая попытка TS-порта LOINC
Один LLM в цикле рассуждений с tool calling — генерация keywords, search-tool, оценка кандидатов, финальный выбор в одном loop. Initial accuracy 2/5 (40%) на gpt-4o-mini, 14/20 (70%) на gpt-5.2 после фиксов. Это была одна попытка которая показала что для этой задачи такой подход работает не очень хорошо. Не доказано что недостижимо вообще — но live-эксперименты показали что доведение до production-quality потребует значительной времени-инвестиции.
B. Decomposed 3-step workflow — production Python
KeywordGenerator → CsvSearcher (deterministic) → LoincSelector. Каждый LLM-step с узкой инструкцией (selection prompt ~392 строки, 6 примеров, mandatory reasoning steps). Production accuracy ~85% (18/20 в benchmark с decision cache).
Выбрали: decomposed для structured, agent для open-ended
Mastra-порт LOINC сделан как 3-step workflow по настоянию Ильдара («сначала повтори оригинал, потом улучшай»). Accuracy сразу выросла 2/5 → 4/5 → 14/20 → 16/20 после поэтапного восстановления production-параметров.
Ильдар: «надо как в оригинале сначала постараться»
Граница (что когда) — в разделе “Три варианта на нашей карте” ниже.
Почему decomposed выигрывает на structured-task
- Specialization. Узкая инструкция per-step упрощает требования к модели и увеличивает шансы на качественное выполнение. Не про “силу” модели в общем смысле — про сужение задачи. На selection-step нашего pipeline промпт детально описывает правила match по Method / System / Property; модель получает узкую задачу с примерами вместо открытого “найди мне код”.
- Detеrministic слой между LLM-шагами. Custom inverted index (TF-IDF) делает search детерминированным — убирает источник нестабильности. Single agent полагается на LLM-эвристики для search → добавляется недетерминированность.
chain_of_thoughtкак явное поле в schema KeywordGenerator — модель сначала рассуждает (“Что значит «реакция» в контексте мочи? → pH”), потом генерирует keywords. Это можно теоретически сделать и через несколько отдельных tools, но в decomposed варианте это получается естественно.- Cascade fallback явный и проще отлаживается. В decomposed pipeline cascade
Gemini → GPT-5.2настроен per-step независимо. В агенте — точку отказа в reasoning loop ловить сложнее.
Ильдар: «мне не нравится что он почти на уровне он должен быть на уровне или не хуже»
Три варианта на нашей карте
По результатам Mastra-портажа Mar-Apr 2026:
1. Decomposed pipeline
Structured задача с детерминированными компонентами (search, lookup, validation). Узкие prompt per-step, deterministic слой между LLM-шагами. Cascade fallback per-step. Конкретный пример: LOINC mapping (loinc-harmonization-pipeline, session 833ec924/82806132).
2. Agent для разговора
Open-ended многоступенчатый разговор с пациентом, ветвление по ответу. Multi-turn Mastra-agent с динамическим control-flow. Decomposed не подходит — поток вопросов нельзя задать заранее. Конкретный пример: medical-context-survey (SurveyAgent, session 7d777edb).
3. Agent для retrieval
Agentic loop с детерминированными tool calls (FHIR fetchers), но profile-driven динамический выбор какие tools вызывать. Decomposed planner был бы тоже agent (нужна reasoning-логика “diabetes detected → HbA1c”). Phases (1-basic / 2-conditional / 3-sweep / 4-exit) — компромисс: agent получает свободу рассуждений, но bounded структурой. Конкретный пример: PatientSummaryAgent (BG-1049, session 3d5c475c), 4-фазный agentic loop с FHIR fetchers + finishSummary exit tool.
Граница применимости
Когда decomposed:
- Структура задачи известна вперёд (LOINC: keyword → search → select).
- Есть детерминированные компоненты, которые лучше выводить из LLM-loop (TF-IDF search, lookup table).
- Промпт можно сузить и подгонять per-step.
Когда agent:
- Поток зависит от содержимого (разговор, profile-driven retrieval).
- Нужно рассуждение между tool calls.
- Заранее задать порядок шагов нельзя.
Открытые вопросы
- Single agent на LOINC — недостижимо в принципе или недостижимо за разумное время? Live-эксперименты ушли в decomposed; недоказано что качества не достичь, но потребуется значительная времени-инвестиция.
chain_of_thoughtкак поле schema vs multiple tools. Не очевидно какой вариант чище для других задач — для LOINC выбран embedded (поле в schema). Carry-over.- Mastra workflow pattern. Mastra поддерживает workflow native (не только agents); это значит граница “Mastra agent vs AI SDK direct” частично можем переформулировать в “Mastra workflow vs Mastra agent”. Возможно конвергируем когда пробуем Mastra workflow на новой задаче.
- Exit tool в agent loop. PatientSummaryAgent потребовал отдельный
finishSummarytool для завершения. В других фреймворках (Mastra native completion semantics, Python custom implementations) можно завершать без отдельного tool. Не очевидно какой подход правильный. - Применимость к другим LLM-задачам в BloodGPT. AI overview generation (Composition + CarePlan) сейчас через single LLM call. Если decomposition выигрывает и там — major refactor. Не проверено.
- Tool calling vs
generateObject. Production использует tool calling (select_loinc / no_matchбинарный), TS-порт —generateObject(Zod schema). Обе работают, могут давать разное LLM-reasoning. Не зафиксировано какой выбор для каких use case. - BG-1023 production-readiness. На момент Apr 2 2026 Mastra-port на 18/20. Какие конкретно ошибки в оставшихся 2 — порт-проблема (TS воспроизводит Python неточно) или fundamental issue? Carry-over: разобрать следующую сессию (
18b47185Apr 15-18 или позже).
Следствия
- Mastra agent vs AI SDK direct — отдельная axis в TS-стеке. Для one-shot prompts со structured output (без multi-tool reasoning)
ai-sdk/openaiнапрямую может быть proper choice. Mastra скрывает 4 слоя абстракции (см. mastra gotchas), что усложняет parity-debugging при портаже из Python. Session4791d030пробовала обе версии параллельно. - Pattern: Mastra для agentic loops, AI SDK direct для one-shot tasks. Mastra workflow — third option, ещё не пробовали под нашим use case.
Связано
- loinc — pattern 1 (decomposed): LOINC harmonization
- loinc-harmonization-pipeline — реализация pattern 1
- medical-context-survey — pattern 2 (agent для разговора): SurveyAgent
- patient-summary — pattern 3 (agent для retrieval): PatientSummaryAgent (BG-1049)
- mastra — execution engine для всех трёх patterns
- fhir-modeling-ai-content — другие structured-LLM задачи в BloodGPT, к которым decision потенциально применим
- health-report-vision — exploratory direction, где Mastra-агенты планировались как замена нескольких отдельных промптов; pattern decomposition применим обратно
- loinc-unification-direction — design philosophy сохраняется в TS-port
Источники
Сноски
-
Anthropic, “Building Effective Agents”, accessed 2026-05-17, https://www.anthropic.com/research/building-effective-agents. ↩
-
Сессия
ildar/833ec924, 2026-03-24 —:/vault/session-digests/833ec924_digest. ↩ -
Linear BG-1023, accessed 2026-05-17, https://linear.app/realai/issue/BG-1023 — TS-port:
bloodgpt-for-business-mastra-agentsworktree, веткаfeat/mastra-agents,. ↩