/ Дневник курса / Урок 2

Управление мышлением агента: глубина рассуждения, бюджеты и роутинг

Глубина «мышления» модели имеет обратную точку: после порога качество падает, а счёт растёт. Как мерить, ограничивать и роутить — в проде, не на бумаге.

  • ИИ-агенты
  • глубина рассуждения
  • контроль затрат
  • роутинг
  • наблюдаемость

В 2026 году глубина reasoning (рассуждение) больше не задаётся фразой «думай шаг за шагом» в промпте — она управляется параметром API и тратит токены отдельно от ответа. Управлять ею стало проще, но кривая «больше думаешь — лучше отвечаешь» работает не везде: после определённой точки лишний reasoning начинает ломать качество.

1. Reasoning effort: три рычага и четыре режима

Reasoning effort (усилие рассуждения) — управляемая глубина мышления модели. Ключевой вопрос не «умнее ли модель», а «какое усилие нужно для этой конкретной задачи». Мышление — ресурс, им нужно управлять явно, не по умолчанию.

Полезная градация по глубине; порядок цены растёт примерно на десятичный множитель с каждой ступенью:

  • Reflexive — прямой ответ без рассуждения («Как тебя зовут?»).
  • Standard — промпт + один вызов, без extended thinking (расширенное обдумывание).
  • Deliberate — Chain-of-Thought (цепочка рассуждений) до 5 шагов: анализ, сравнение, выбор.
  • Exhaustive — много итераций с reflection (рефлексия) и self-correction (самокоррекция): сложный код, многошаговый reasoning.

Эмпирика проста: высокое усилие оправдано только на меньшей части задач — оценочно один из пяти. На остальных глубокий reasoning жжёт бюджет и latency без прироста точности.

Три независимых рычага усилия:

  1. Модель — Tier 1 (mini/haiku) против Tier 3 (Opus/GPT-5); разница цены порядка 15–20×.
  2. Глубина reasoning — параметр API: reasoning_effort у OpenAI, budget_tokens или effort у Anthropic, thinkingLevel / thinkingBudget у Gemini, Dual Mode у DeepSeek.
  3. Число шаговmax_iterations в петле плюс early stopping (ранняя остановка) при достижении цели.

В 2026 году парадигма окончательно сместилась от «текстовых инструкций в промпте» к управлению через параметры API. Внутренняя трассировка размышлений происходит автоматически; фраза «думай шаг за шагом» в пользовательском запросе теперь только зря расходует контекст, дублируя встроенную делиберацию.

Текущая раскладка API на флагманах:

Provider API-параметр Уровни Default
OpenAI reasoning_effort none / low / medium / high none (GPT-5.1)
Anthropic budget_tokens, effort low / medium / high / xhigh / max off (Opus 4.7, требует явной активации)
Google thinkingLevel, thinkingBudget токены бюджета, уровни задержки встроенное (рекоменд. =0 для чата)
DeepSeek Streamed Trace, Dual Mode Non-Think / High / Max thinking on

Минимальный пример активации extended thinking у Anthropic:

import anthropic

client = anthropic.Anthropic()
response = client.messages.create(
    model="claude-opus-4-7",
    max_tokens=8192,
    thinking={"type": "enabled", "budget_tokens": 4096},
    messages=[{"role": "user", "content": "..."}],
)

budget_tokens ограничивает скрытый reasoning-трейс отдельно от итогового ответа. Поднимать не «потому что можно», а под конкретный профиль задачи.

2. Кривая overthinking: три региона

Зависимость точности от объёма test-time compute (вычислений на этапе вывода) — не монотонная. На кривой три характерных региона.

accuracy
   ▲
   │       ╭─────╮
   │      ╱       ╲       ◄── inversion: точность падает
   │     ╱         ╲          (overthinking, доменно-специфично)
   │    ╱           ╲
   │   ╱
   │  ╱ ◄── token-burning: точность ровно,
   │ ╱     цена и latency растут
   │╱
   │ ◄── high-yield: +5–10% качества окупают токены
   │
   └─────────────────────────────────────►  thinking budget
  1. High-yield — сложный код (уровень SWE-bench), аудит многопоточного, оптимизация SQL, доказательство теорем, ветвящиеся планы с жёсткими ограничениями. Здесь effort: high или максимальный budget_tokens окупают деньги.
  2. Token-burning — извлечение JSON-сущностей, классификация интента, заполнение шаблонов, саммаризация. Глубокое мышление генерирует сотни пустых рассуждений; точность та же, счёт выше.
  3. Inversion — режим, описанный в «When More Thinking Hurts» (см. обзор эффекта): при чрезмерном бюджете модель начинает сомневаться в очевидном, ломает синтаксически верные конструкции, уходит в избыточное усложнение. На зафиксированных тестах точность падала с 49.6% до 48.1%, стоимость росла на 56%, latency — критически.

Self-reflection не бесплатное добро. У слабых моделей самокоррекция нередко усугубляет ошибку — модель запутывается в собственных правках. Включать осознанно, как и любой глубокий режим.

3. Пятислойная защита: бюджет — это не экономия, это стабильность

Runaway agent (зацикленный агент) бывает не только от атаки. Гораздо чаще — от обычного бага: изменился формат API → retry-петля → 200× токенов за 40 минут. CPU/RAM при этом в норме, поэтому стандартный Prometheus такого не ловит.

Цифры порядка масштаба, чтобы калибровать тревогу:

  • Развёртывание Claude Code в Uber: 95% инженеров подхватили инструмент, индивидуальные счета $500–2000 в месяц на разработчика. Годовой бюджет на AI-ассистентов исчерпан за 4 месяца.
  • В малом сегменте — case из LangChain-комьюнити: отсутствие max_iterations в цикле ресерча → бесконечные проходы валидации → более $150 за решение одной задачи через o1-preview.
  • В корпоративе — несколько тысяч долларов за выходные из-за рекурсивной обработки ошибок в фоновом воркере.

Защита строится из пяти независимых слоёв. Нужны все одновременно: каждый ловит то, что пропустил предыдущий.

запрос
  │
  ▼
┌─────────────┐  agentic-сессия живёт 5–20 минут;
│ 1. Timeout  │  NGINX/ALB/Ingress режут на 30–300 сек.
└─────┬───────┘  Лечение: async queue, background worker,
      │          hard-limit времени у планировщика.
      ▼
┌─────────────┐  max_iterations = 10–15 в ReAct;
│ 2. Anti-loop│  max 3 попытки исправить одну ошибку;
└─────┬───────┘  стоп-условие "No Progress" наряду с лимитами.
      │
      ▼
┌──────────────────┐  Шлюз (Portkey, LiteLLM, MLflow Gateway)
│ 3. Cost Circuit  │  считает $ в реальном времени.
│    Breaker       │  Пороги: $50 warning / $100 halt,
└─────┬────────────┘  per-task ≈ $5.
      │
      ▼
┌─────────────┐  Никаких алиасов gpt-4o или claude-3-5-sonnet —
│ 4. Model    │  только фиксированные версии (gpt-4o-2024-05-13).
│    Pinning  │  Тихое обновление модели у провайдера
└─────┬───────┘  ломает парсеры → бесконечный цикл валидации.
      │
      ▼
┌─────────────┐  OpenTelemetry-атрибуты:
│ 5. Audit Log│  gen_ai.usage.input_tokens,
└─────────────┘  gen_ai.usage.output_tokens, session_id.

Бюджетные уровни как стартовые: задача ~$0.50 / сессия ~$2 / день ~$10. Дальше калибровать по своему профилю нагрузки.

Один нюанс из практики LangGraph: даже защитные слои сами протекают. В Issue #7554 у RetryPolicy jitter добавлялся после ограничителя max_interval — фактическое ожидание уходило выше декларированного лимита. Мораль: даже backoff-логика (отступы между повторами) — это код, который надо тестировать как код.

4. AI-метрики: что мерить вместо RPS

Классический мониторинг — stateless: RPS, latency, ошибки HTTP. Распределённую транзакцию агента из десятков гетерогенных вызовов к разным моделям он не видит. Нужен другой набор показателей, собираемый шлюзом.

  • tokens_per_task — суммарные токены на одну прикладную задачу, включая скрытые токены reasoning.
  • cost_per_completion — итоговая стоимость сессии: (I × P_in + O × P_out) / 1_000_000.
  • loop_iterations — число итераций цикла. Рост при неизменной точности = деградация планирования.
  • retry_overhead_tokens — токены, сожжённые на повторные вызовы при ошибках парсинга и валидации. Прокси к качеству системного промпта и стабильности парсеров.

Алерт — при от baseline по любой из метрик, не по абсолюту.

Технически собирать это удобнее всего на шлюзе (Portkey, LiteLLM, MLflow Gateway), а не внутри самого агента. Шлюз видит все вызовы — включая ретраи и fallback-переключения — и аннотирует их одним session_id. Атрибуты OpenTelemetry gen_ai.usage.input_tokens / gen_ai.usage.output_tokens плюс session_id дают сквозную трассировку одной агентской задачи поверх десятков гетерогенных LLM-вызовов. Бонус: вынос retry-логики на уровень шлюза изолирует сетевые сбои от внутренней логики агента — иначе сбой одного терминального узла порождает каскадный retry-шторм у всех вышестоящих оркестраторов с взрывным ростом retry_overhead_tokens.

При достижении критических лимитов система должна делать early stopping, а не hard error (жёсткое падение). Контролируемая остановка персистит текущую сессию: оператор вмешивается, правит промпт, продолжает с последнего валидного шага. Жёсткое падение уничтожает прогресс и провоцирует ту же retry-петлю снаружи.

5. Каскадный роутинг и budget-aware эскалация

Типичная ошибка экономики — одна (самая мощная) модель на всё: «который час?» и «напиши алгоритм» стоят одинаково дорого. Роутер оценивает сложность запроса и выбирает модель. На правильно настроенном каскаде значительная часть трафика уходит на дешёвую модель, а качество держится близко к флагману — конкретные цифры см. ниже по TRACER.

запрос
  │
  ▼
┌────────────────────┐   hit → ответ из кэша, cost = 0
│ 1. Семантический   │   miss ↓
│    кэш  (<5 мс)    │
└────────────────────┘
  │
  ▼
┌────────────────────┐   simple → cheap-модель сразу
│ 2. Классификатор   │              (Haiku 4.5, GPT-4o-mini)
│    интента ~0.5B,  │   complex → дорогая модель reasoning
│    vLLM (<5 мс)    │   ambiguous ↓
└────────────────────┘
  │
  ▼
┌────────────────────┐   confidence ≥ порога (≈ 0.85) → отдать
│ 3. Cheap-модель +  │   confidence <  порога → escalation
│    confidence      │
│    score           │
└────────────────────┘

Порог confidence (старт ≈ 0.85) калибруется на 100–200 реальных запросах. Confidence получают через structured output: {answer, confidence, reason}. «На глаз» порог не ставят — оценка с LLM-judge или ручная разметка.

Калибровка через ручную разметку — затратна. Альтернатива — обучить суррогатный классификатор на traces работы флагмана: tracer-based routing. Активация через parity gate: суррогат пускают в прод только когда его согласие с моделью-учителем на тесте выше порога α. На опубликованных результатах — до 85% рутинного трафика уходит на дешёвые локальные модели при сохранении 95% качества и общем снижении затрат на 70% (разбор LLM-routing).

Роутер бывает двух разных типов, и в проде они сосуществуют. Первый — экономический каскад по confidence (про деньги): cheap → escalate при низкой уверенности. Второй — Intent / Task Router: классификация типа запроса («объясни термин» / «дай план» / «сделай отчёт» / «найди в документах») → выбор сценария, шаблона и источника контекста, а не модели. Плюс этот же роутер работает как guardrail (защитный фильтр): отсекает вредные запросы и prompt injection (инъекция в промпт) до «мозга». Это две разные оси, и в продакшен-системе они обычно сосуществуют.

И наконец Budget-Aware Agentic Routing (BAAR) — маршрутизация под бюджет как последовательная задача принятия решений, где ошибки на ранних шагах лавинообразно накапливаются. На практике это значит:

  • остаток бюджета <30% — шлюз форсит cheap-модель и перестраивает план декомпозиции в сторону минимизации шагов;
  • остаток <10% — пропускаются только simple-запросы, остальное — controlled stop.

6. Architect/Editor split: архитектура экономии

Самая надёжная экономия — не «уменьшить effort», а разнести роли по моделям разного класса.

┌──────────────────┐   short JSON   ┌──────────────────┐
│ Architect        │  ─── plan ───▶ │ Editor           │
│ дорогая «умная»  │                │ дешёвая быстрая  │
│ (Opus, GPT-5.1)  │                │ (Haiku, mini)    │
│                  │                │                  │
│ ► один раз       │                │ ► каждый шаг,    │
│ ► разворачивает  │                │   свежее окно    │
│   план в JSON    │                │ ► читает прогресс│
│ ► passes: false  │                │ ► пишет passes:  │
│   для подзадач   │                │   true в Git     │
└──────────────────┘                └──────────────────┘

В исследованиях Anthropic это два профиля:

  • Initializer Agent (агент-инициализатор) запускается один раз: разворачивает окружение, создаёт claude-progress.txt, init.sh, формирует JSON-файл требований, где каждой атомарной подзадаче проставлен флаг "passes": false. JSON, а не markdown — потому что модели работают со схемами точнее и реже случайно перезаписывают смежные ветки.
  • Coding Agent (агент-исполнитель) запускается на каждом шаге в свежем контекстном окне: читает прогресс, выбирает подзадачу с false, выполняет, тестирует, переключает в true, коммитит в Git.

Экономия — 50–80% бюджета, причём качество часто выше: «редактор» не отвлекается на архитектуру.

7. Контекст как переменная стоимости

Каждый шаг агента передаёт в модель всю накопленную историю сессии. Стоимость растёт квадратично относительно числа итераций. Поэтому борьба с контекстом — это борьба с бюджетом.

Три стратегии динамического урезания, расположенные по риску потери информации:

Стратегия Механика Применять когда Риск
Compaction (саммаризация) Саммаризация транскрипта, рестарт сессии с summary Длинные аналитические сессии, обсуждения архитектуры Потеря информации по дизайну: важная деталь может потеряться
Tool-Result Clearing (очистка результатов инструментов) Хирургическое удаление содержимого tool_result, запись tool_use остаётся Частое чтение больших файлов, тяжёлые API Практически безопасна — модель просто вызовет инструмент повторно
Structured Notes (внешние заметки) Запись фактов во внешние файлы (claude-progress.txt) вне контекста Сверхдлинные сессии, распределённые по времени Нужен бэкенд, инструменты чтения/записи

Tool-Result Clearing — средний путь между compaction (агрессивная потеря) и context reset (полный сброс). В заметках про context engineering этот рычаг часто пропускают.

Архитектурное правило, которое стоит запомнить: программная обвязка кодирует предположения о недостатках текущей модели, которые быстро устаревают по мере обновления моделей. Пример: Claude Sonnet 4.5 страдал «контекстной тревожностью» — при приближении к лимиту окна модель преждевременно завершала задачи и декларировала успех без тестов. Под это в harness (программная обвязка) добавили жёсткую логику context reset. С переходом на Opus 4.5/4.6 поведение исчезло на уровне весов, а логика сбросов осталась — как технический долг.

Под масштабирование долгоживущих агентов в 2026 закрепилась трёхслойная архитектура Managed Agents:

  • Brain — stateless LLM. Не хранит истории; восстанавливает контекст через wake(sessionId) из внешней БД, выбирает срез событий через getEvents(start, end). Это и есть «стабильная утилизация prompt-кэша».
  • Hands — одноразовые песочницы (Docker, Python-интерпретатор) с минимальным интерфейсом execute(name, input) → string. Сбой контейнера = обычная ошибка инструмента, оркестратор не падает.
  • Session — персистентный append-only лог событий вне контекстного окна.

Метрики эффекта на проде: −60% p50 TTFT, более −90% p95 latency за счёт ленивой инициализации песочниц. Паттерн уже воспроизведён в enterprise — те же три слоя ложатся на стек Azure AI Foundry (Foundry Agent Service → brain, Container Apps Dynamic Sessions → hands, Cosmos DB → session log).

FAQ

Когда повышать reasoning effort, а когда держать минимальным?

Высокое усилие окупается примерно на одной задаче из пяти — там, где есть верифицируемая глубина: сложный код, аудит многопоточного, оптимизация SQL, доказательства, ветвящиеся планы с жёсткими ограничениями. На извлечении сущностей, классификации, шаблонах и саммаризации глубокий reasoning жжёт токены и latency без прироста точности, а в режиме inversion даже снижает его.

Что такое overthinking и как его поймать?

Overthinking — участок кривой, где рост test-time compute не помогает или вредит: модель сомневается в очевидном и переусложняет. Ловится по метрикам — tokens_per_task и loop_iterations растут при неизменной точности. Лечение: снижать budget_tokens/effort под профиль задачи и не включать self-reflection у слабых моделей, где она чаще усугубляет ошибку, чем исправляет.

Как защититься от runaway-агента?

Пятью независимыми слоями одновременно: timeout (async queue вместо синхронного запроса), anti-loop (max_iterations 10–15 плюс стоп «No Progress»), cost circuit breaker на шлюзе ($50 warning / $100 halt), model pinning (фиксированные версии вместо алиасов) и audit log (OpenTelemetry gen_ai.usage.* + session_id). Каждый слой ловит то, что пропустил предыдущий.

Какие метрики мерить у агента вместо RPS?

Классический stateless-мониторинг (RPS, latency, HTTP-ошибки) не видит распределённую транзакцию агента. Собирайте на шлюзе: tokens_per_task (с учётом скрытого reasoning), cost_per_completion, loop_iterations и retry_overhead_tokens. Алертьте при от baseline по любой из них, а не по абсолютному порогу.

Сколько закладывать в бюджет на задачу, сессию и день?

Стартовые порядки величины: задача ~$0.50, сессия ~$2, день ~$10; на уровне cost circuit breaker — $50 warning / $100 halt, per-task ≈ $5. Это калибровочные ориентиры, а не универсальные значения — подстраивайте под свой профиль нагрузки и набор моделей.

Источники

Числовые ориентиры из текста (15–20× разница цены между tiers, 49.6%→48.1% при росте стоимости на 56%, бюджеты $0.5/$2/$10, −60% p50 / −90% p95) — это порядки величины и значения из конкретных кейсов; на вашем профиле нагрузки они будут другими.