# Сценарии: тратить модель на неоднозначность, а не на готовые координаты

Статус: предложение, не реализовано. Инвазивность: **Низкая → средняя**. Основа: `webrtc-komaroff@772de4a`, 16.09.2026.

В текущем Ruby-node сценарии уже нет LLM-запроса для построения координат и сочинения финального ответа об аэропортах. Новая реплика без активного workflow всё ещё проходит через `routing_decision`, затем через `tool_params`. В обоих случаях модель читает близкий контекст.

![Два модельных шага и целевой путь](</experiments/voice-ai/archive/c/DOCS/architecture-2026-09-16/diagrams/p02-llm.svg>)

Router должен определить намерение, а extractor — недостающие аргументы. Их можно объединить в один структурированный результат, если схема разрешает только известные сценарии и параметры проходят обычную валидацию.

## Предлагаемая правка

Начать с двух путей. Явное действие UI передаёт типизированную команду с валидированными аргументами и не требует классификатора. Свободный текст получает один ответ вида `intent + args + missing_fields`. Неоднозначная реплика приводит к уточнению или существующему fallback. Координаты берутся из tool result; текстовое «уверен на 0.9» от LLM не является основанием вызвать инструмент.

Для коротких однозначных команд допустим детерминированный fast path. Его нельзя превращать в растущий набор регулярных выражений, который незаметно подменяет язык пользователя. Нужны ограниченная грамматика, corpus и явный переход к общей модели при несовпадении.

Следующим шагом можно пропускать `get_current_position`, когда поиск явно задан другим городом и маршрут от текущего места не нужен. Это меняет граф зависимостей: ошибка геолокации больше не блокирует такой запрос. Если нужно построить маршрут, исходная точка остаётся обязательной.

## Что измерять

Новый аэропортный turn сейчас имеет **2 LLM calls + 2 tool calls**, а запрос маршрута — **2 + 3**. При уже заданном active workflow в тестах остаётся один LLM call. Цель объединённого разбора — **1 LLM call** для того же нового текстового turn; для явной команды UI — **0**. Это числа логических calls: внутренние retries провайдера нужно считать отдельно.

Сравнить p50/p95 до первого ответа, input/output tokens, LLM calls/успешный turn, долю уточнений, неверный intent и неправомерный `BUILD_ROUTE`. Экономию считать как разницу токенов и inference time на одинаковом корпусе, а не как заранее выбранный процент.

## Как не потерять поведение

Собрать размеченный набор: «ближайший», список в радиусе, другой город, отрицание маршрута, опечатки, ссылка на предыдущий аэропорт, edit и follow-up. Сохранить существующие сценарии из MR !15. Приёмка: все детерминированные regression cases проходят; число ненужных route-вызовов в них равно нулю; на отложенном корпусе качество не хуже согласованного baseline.

В shadow-проверке сравнивать планы без повторного исполнения tools. Включать новый planner по типу сценария, оставив возможность вернуть прежние два шага.

## Когда оставить текущую схему

Если отдельная маршрутизация заметно повышает точность на реальных неоднозначных репликах, её цена может быть оправдана. Решение зависит от corpus и latency budget, а не от запрета «лишнего» вызова как такового.

## Основания

[Engine и router](<https://git.giscloud.ru/voice-chat/webrtc-komaroff/-/blob/772de4a714ae6c5abea91946e85a1953ee919ec3/src_langgraph_rb_node/lib/src_langgraph_rb_node/runtime/router.rb>), [nodes аэропортов](<https://git.giscloud.ru/voice-chat/webrtc-komaroff/-/blob/772de4a714ae6c5abea91946e85a1953ee919ec3/src_langgraph_rb_node/lib/src_langgraph_rb_node/scenarios/find_nearest_airport/nodes.rb>), [точные ожидания calls в tests](<https://git.giscloud.ru/voice-chat/webrtc-komaroff/-/blob/772de4a714ae6c5abea91946e85a1953ee919ec3/src_langgraph_rb_node/spec/scenarios/find_nearest_airport_spec.rb>). [LangGraph: workflows and agents](<https://docs.langchain.com/oss/python/langgraph/workflows-agents>) отделяет фиксированный workflow от динамического решения модели. Объединение planner — наше предложение по этому коду; документация не гарантирует его качество.

[Все предложения](</experiments/voice-ai/archive/c/DOCS/architecture-2026-09-16/improvements/README.md>) · [Фактическая архитектура](</experiments/voice-ai/archive/c/DOCS/architecture-2026-09-16/README.md>)
