Industry-standard pattern для LLM-агентов: LLM описывается набором тулов с typed-схемой; на каждом шаге LLM emit’ит дискретные tool invocations (один или N parallel) в structured-формате; runtime парсит, исполняет handler, возвращает результат в conversation messages; LLM решает следующий шаг. Композиция и фильтрация — в LLM-контексте.
Используется во всех агентах BloodGPT. 5 production-агентов через mastra, плюс Никитин FHIR-агент в Realai-plus/fhir-services (feature/medagentbench-agent) на Gemini SDK напрямую. Альтернатива (emerging idea, у нас не применяется) — code execution с typed bindings, см. code-mode-pattern.
Терминология (провайдер-специфика)
Один и тот же pattern в разных вендорских API:
| Провайдер | Термин | Wire-формат |
|---|---|---|
| OpenAI | tool calling (раньше function calling) | tool_calls field в response, JSON-структура |
| Anthropic | tool use | tool_use content blocks, JSON-структура |
| Gemini | function calling | functionCalls[] в response, JSON-структура |
| MCP (Model Context Protocol) | tool calls | стандартизированный protocol поверх любого LLM |
Семантически идентичны: structured tool invocation с typed args, parallel execution support, result в conversation history. Frameworks (Mastra, LangChain, Vercel AI SDK, OpenAI Assistants) скрывают различия за единым API.
Использование в BloodGPT
Mastra-агенты (5 production)
Все через createTool({ inputSchema: z.object({...}), execute: async (...) => ... }). См. mastra раздел “Использование в BloodGPT” с таблицей агентов и pattern’ов. Ключевые паттерны:
loincMappingAgent— 3-step decomposed workflow (agent-vs-workflow); каждый step — agent с узкими туламиpatientSummaryAgent— agent для retrieval, 4-фазный agentic loop с FHIR fetcher tools + явныйfinishSummaryexit tool (patient-summary)healthChatAgent+surveyAgent— multi-turn agents с 5 shared FHIR write tools (recordSymptom/recordMedication/recordAllergy/recordProcedure/recordFamilyHistory); те же tools используются в TextToFHIR (V2). См. fhir-meta-tagging, llm-numeric-codes-policy, clinical-record-reconciliation.
Никитин FHIR-агент
ReAct-loop через Gemini SDK напрямую (не Mastra). 5 тулов: fhir_search, fhir_read, get_patient_resources, execute_python_code, submit_answer. Использует parallel tool calls Gemini — за одну итерацию может быть несколько вызовов одновременно. Реальные циклы — 2-5 итераций (MAX_ITERATIONS = 20 — safety cap). Контекст исследования — code-execution-sandbox и code-mode-pattern.
Parallel tool calls
Frontier-модели (Gemini, Claude 4.x, GPT-5.x) поддерживают parallel tool calls — LLM в одной response может emit’ить несколько tool invocations одновременно. Runtime исполняет параллельно (через Promise.all если handlers независимы), результаты собираются и подаются обратно одной партией.
В наших агентах — основное место где этот выигрыш материализуется — Никитин ReAct-loop (Gemini parallel calls в одной итерации) и V2 param analysis (Promise.all для personalizer+generator, mastra раздел “Promise.all parallelism”). В Mastra-агентах для structured-LLM workflow (LOINC) parallelism меньше — последовательная цепочка по дизайну.
Mastra-specific gotchas
Подробно в mastra раздел “Gotchas / debugging patterns”. Кратко:
- Zod
inputSchemaстрипает unknown fields вcreateTool— runtime валидация удаляет поля не описанные в схеме; tool execute получает обрезанный input. - Tool format mismatch между Studio API (
step.toolCalls[i].toolName) иagent.generate()(step.toolCalls[i].payload.toolName) — парсеры результатов нужно дублировать. - Field order в Zod schema влияет на LLM output — порядок полей в input/output влияет на iteration count и quality. При портировании из Python — повторять порядок точно.
- snake_case ↔ camelCase boundary — LLM output по schema (snake_case parity с Python) → boundary-converter → TS-consumer (camelCase). Утилита shared, иначе silent field-mismatch.
Связанные концепты
- code-mode-pattern — emerging idea как альтернатива tool calling (LLM emit’ит код вместо дискретных invocations); composition внутри code execution, не в LLM context. У нас не применяется.
- mastra — primary framework для tool calling в BloodGPT; entity-страница со специфичными gotcha
- agent-vs-workflow — ортогональная axis (single agent loop vs decomposed pipeline); обе парадигмы используют tool calling
- fhir-meta-tagging — паттерн tagging для FHIR write tools (health-chat / survey / TextToFHIR)
- llm-numeric-codes-policy — LLM-агенты возвращают English term, не SNOMED код
- clinical-record-reconciliation — dedup / reconciliation existing FHIR resources на write
Связано
- mastra, patient-summary, loinc-harmonization-pipeline, medical-context-survey — агенты, использующие tool calling
- code-execution-sandbox — runtime для тулов которые исполняют LLM-сгенерённый код (Никитин
execute_python_code); специфический подкласс tool calling
Источники
Сноски
-
OpenAI tool calling docs, accessed 2026-05-17, https://platform.openai.com/docs/guides/function-calling. ↩
-
Anthropic tool use docs, accessed 2026-05-17, https://docs.anthropic.com/en/docs/agents-and-tools/tool-use. ↩
-
Gemini function calling docs, accessed 2026-05-17, https://ai.google.dev/gemini-api/docs/function-calling. ↩
-
MCP specification (Model Context Protocol), accessed 2026-05-17, https://modelcontextprotocol.io. ↩
-
Anthropic “Building Effective Agents” — workflow vs agent (оба паттерна на tool calling), accessed 2026-05-17, https://www.anthropic.com/research/building-effective-agents. ↩