<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:content="http://purl.org/rss/1.0/modules/content/">
<channel>
  <title>nikolskiy.dev — Blog</title>
  <link>https://nikolskiy.dev/posts/</link>
  <description>Записи Александра Никольского о разработке ИИ-агентов, LLM и RAG</description>
  <language>ru</language>
  <lastBuildDate>Thu, 28 May 2026 00:00:00 GMT</lastBuildDate>
  <item>
    <title>Управление мышлением агента: глубина рассуждения, бюджеты и роутинг</title>
    <link>https://nikolskiy.dev/posts/agent-thinking-budgets/</link>
    <guid isPermaLink="true">https://nikolskiy.dev/posts/agent-thinking-budgets/</guid>
    <pubDate>Thu, 28 May 2026 00:00:00 GMT</pubDate>
    <description>Глубина «мышления» модели имеет обратную точку: после порога качество падает, а счёт растёт. Как мерить, ограничивать и роутить — в проде, не на бумаге.</description>
    <content:encoded><![CDATA[<p>В 2026 году глубина reasoning (рассуждение) больше не задаётся фразой «думай шаг за шагом» в промпте — она управляется параметром API и тратит токены отдельно от ответа. Управлять ею стало проще, но кривая «больше думаешь — лучше отвечаешь» работает не везде: после определённой точки лишний reasoning начинает ломать качество.</p>
<h2>1. Reasoning effort: три рычага и четыре режима</h2>
<p>Reasoning effort (усилие рассуждения) — управляемая глубина мышления модели. Ключевой вопрос не «умнее ли модель», а <strong>«какое усилие нужно для этой конкретной задачи»</strong>. Мышление — ресурс, им нужно управлять явно, не по умолчанию.</p>
<p>Полезная градация по глубине; порядок цены растёт примерно на десятичный множитель с каждой ступенью:</p>
<ul>
<li><strong>Reflexive</strong> — прямой ответ без рассуждения («Как тебя зовут?»).</li>
<li><strong>Standard</strong> — промпт + один вызов, без extended thinking (расширенное обдумывание).</li>
<li><strong>Deliberate</strong> — Chain-of-Thought (цепочка рассуждений) до 5 шагов: анализ, сравнение, выбор.</li>
<li><strong>Exhaustive</strong> — много итераций с reflection (рефлексия) и self-correction (самокоррекция): сложный код, многошаговый reasoning.</li>
</ul>
<p>Эмпирика проста: <strong>высокое усилие оправдано только на меньшей части задач — оценочно один из пяти</strong>. На остальных глубокий reasoning жжёт бюджет и latency без прироста точности.</p>
<p>Три независимых рычага усилия:</p>
<ol>
<li><strong>Модель</strong> — Tier 1 (mini/haiku) против Tier 3 (Opus/GPT-5); разница цены порядка 15–20×.</li>
<li><strong>Глубина reasoning</strong> — параметр API: <code>reasoning_effort</code> у OpenAI, <code>budget_tokens</code> или <code>effort</code> у Anthropic, <code>thinkingLevel</code> / <code>thinkingBudget</code> у Gemini, Dual Mode у DeepSeek.</li>
<li><strong>Число шагов</strong> — <code>max_iterations</code> в петле плюс early stopping (ранняя остановка) при достижении цели.</li>
</ol>
<p>В 2026 году парадигма окончательно сместилась от «текстовых инструкций в промпте» к управлению через параметры API. Внутренняя трассировка размышлений происходит автоматически; фраза «думай шаг за шагом» в пользовательском запросе теперь только зря расходует контекст, дублируя встроенную делиберацию.</p>
<p>Текущая раскладка API на флагманах:</p>
<div class="table-wrap"><table>
<thead>
<tr>
<th>Provider</th>
<th>API-параметр</th>
<th>Уровни</th>
<th>Default</th>
</tr>
</thead>
<tbody><tr>
<td>OpenAI</td>
<td><code>reasoning_effort</code></td>
<td>none / low / medium / high</td>
<td>none (GPT-5.1)</td>
</tr>
<tr>
<td>Anthropic</td>
<td><code>budget_tokens</code>, <code>effort</code></td>
<td>low / medium / high / xhigh / max</td>
<td>off (Opus 4.7, требует явной активации)</td>
</tr>
<tr>
<td>Google</td>
<td><code>thinkingLevel</code>, <code>thinkingBudget</code></td>
<td>токены бюджета, уровни задержки</td>
<td>встроенное (рекоменд. =0 для чата)</td>
</tr>
<tr>
<td>DeepSeek</td>
<td>Streamed Trace, Dual Mode</td>
<td>Non-Think / High / Max</td>
<td>thinking on</td>
</tr>
</tbody></table></div>
<p>Минимальный пример активации extended thinking у Anthropic:</p>
<pre><code class="language-python">import anthropic

client = anthropic.Anthropic()
response = client.messages.create(
    model=&quot;claude-opus-4-7&quot;,
    max_tokens=8192,
    thinking={&quot;type&quot;: &quot;enabled&quot;, &quot;budget_tokens&quot;: 4096},
    messages=[{&quot;role&quot;: &quot;user&quot;, &quot;content&quot;: &quot;...&quot;}],
)
</code></pre>
<p><code>budget_tokens</code> ограничивает скрытый reasoning-трейс отдельно от итогового ответа. Поднимать не «потому что можно», а под конкретный профиль задачи.</p>
<h2>2. Кривая overthinking: три региона</h2>
<p>Зависимость точности от объёма test-time compute (вычислений на этапе вывода) — <strong>не монотонная</strong>. На кривой три характерных региона.</p>
<pre><code>accuracy
   ▲
   │       ╭─────╮
   │      ╱       ╲       ◄── inversion: точность падает
   │     ╱         ╲          (overthinking, доменно-специфично)
   │    ╱           ╲
   │   ╱
   │  ╱ ◄── token-burning: точность ровно,
   │ ╱     цена и latency растут
   │╱
   │ ◄── high-yield: +5–10% качества окупают токены
   │
   └─────────────────────────────────────►  thinking budget
</code></pre>
<ol>
<li><strong>High-yield</strong> — сложный код (уровень SWE-bench), аудит многопоточного, оптимизация SQL, доказательство теорем, ветвящиеся планы с жёсткими ограничениями. Здесь <code>effort: high</code> или максимальный <code>budget_tokens</code> окупают деньги.</li>
<li><strong>Token-burning</strong> — извлечение JSON-сущностей, классификация интента, заполнение шаблонов, саммаризация. Глубокое мышление генерирует сотни пустых рассуждений; точность та же, счёт выше.</li>
<li><strong>Inversion</strong> — режим, описанный в «When More Thinking Hurts» (см. <a href="https://medium.com/@Micheal-Lanham/turn-the-thinking-knob-off-most-of-the-time-1b67ab418045">обзор эффекта</a>): при чрезмерном бюджете модель начинает сомневаться в очевидном, ломает синтаксически верные конструкции, уходит в избыточное усложнение. На зафиксированных тестах точность падала с 49.6% до 48.1%, <strong>стоимость росла на 56%</strong>, latency — критически.</li>
</ol>
<p>Self-reflection не бесплатное добро. У слабых моделей самокоррекция нередко <strong>усугубляет</strong> ошибку — модель запутывается в собственных правках. Включать осознанно, как и любой глубокий режим.</p>
<h2>3. Пятислойная защита: бюджет — это не экономия, это стабильность</h2>
<p>Runaway agent (зацикленный агент) бывает не только от атаки. Гораздо чаще — от обычного бага: изменился формат API → retry-петля → 200× токенов за 40 минут. CPU/RAM при этом в норме, поэтому стандартный Prometheus такого не ловит.</p>
<p>Цифры порядка масштаба, чтобы калибровать тревогу:</p>
<ul>
<li>Развёртывание <a href="https://www.reddit.com/r/artificial/comments/1t1mhx6/uber_burned_its_entire_2026_ai_coding_budget_in_4/">Claude Code в Uber</a>: 95% инженеров подхватили инструмент, индивидуальные счета <strong>$500–2000 в месяц на разработчика</strong>. Годовой бюджет на AI-ассистентов исчерпан за 4 месяца.</li>
<li>В малом сегменте — <a href="https://www.reddit.com/r/LangChain/comments/1rpxt6q/i_kept_racking_up_150_openai_bills_from_runaway/">case из LangChain-комьюнити</a>: отсутствие <code>max_iterations</code> в цикле ресерча → бесконечные проходы валидации → <strong>более $150 за решение одной задачи</strong> через o1-preview.</li>
<li>В корпоративе — несколько тысяч долларов за выходные из-за рекурсивной обработки ошибок в фоновом воркере.</li>
</ul>
<p>Защита строится из <strong>пяти независимых слоёв</strong>. Нужны все одновременно: каждый ловит то, что пропустил предыдущий.</p>
<pre><code>запрос
  │
  ▼
┌─────────────┐  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 попытки исправить одну ошибку;
└─────┬───────┘  стоп-условие &quot;No Progress&quot; наряду с лимитами.
      │
      ▼
┌──────────────────┐  Шлюз (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.
</code></pre>
<p>Бюджетные уровни как стартовые: <strong>задача ~$0.50 / сессия ~$2 / день ~$10</strong>. Дальше калибровать по своему профилю нагрузки.</p>
<p>Один нюанс из практики LangGraph: даже защитные слои сами протекают. В <a href="https://github.com/langchain-ai/langgraph/issues/7554">Issue #7554</a> у <code>RetryPolicy</code> jitter добавлялся <strong>после</strong> ограничителя <code>max_interval</code> — фактическое ожидание уходило выше декларированного лимита. Мораль: даже backoff-логика (отступы между повторами) — это код, который надо тестировать как код.</p>
<h2>4. AI-метрики: что мерить вместо RPS</h2>
<p>Классический мониторинг — stateless: RPS, latency, ошибки HTTP. Распределённую транзакцию агента из десятков гетерогенных вызовов к разным моделям он не видит. Нужен другой набор показателей, собираемый шлюзом.</p>
<ul>
<li><strong><code>tokens_per_task</code></strong> — суммарные токены на одну прикладную задачу, включая скрытые токены reasoning.</li>
<li><strong><code>cost_per_completion</code></strong> — итоговая стоимость сессии: <code>(I × P_in + O × P_out) / 1_000_000</code>.</li>
<li><strong><code>loop_iterations</code></strong> — число итераций цикла. Рост при неизменной точности = деградация планирования.</li>
<li><strong><code>retry_overhead_tokens</code></strong> — токены, сожжённые на повторные вызовы при ошибках парсинга и валидации. Прокси к качеству системного промпта и стабильности парсеров.</li>
</ul>
<p>Алерт — при <code>2×</code> от baseline по любой из метрик, не по абсолюту.</p>
<p>Технически собирать это удобнее всего на шлюзе (Portkey, LiteLLM, MLflow Gateway), а не внутри самого агента. Шлюз видит <strong>все</strong> вызовы — включая ретраи и fallback-переключения — и аннотирует их одним <code>session_id</code>. Атрибуты OpenTelemetry <code>gen_ai.usage.input_tokens</code> / <code>gen_ai.usage.output_tokens</code> плюс <code>session_id</code> дают сквозную трассировку одной агентской задачи поверх десятков гетерогенных LLM-вызовов. Бонус: вынос retry-логики на уровень шлюза изолирует сетевые сбои от внутренней логики агента — иначе сбой одного терминального узла порождает <strong>каскадный retry-шторм</strong> у всех вышестоящих оркестраторов с взрывным ростом <code>retry_overhead_tokens</code>.</p>
<p>При достижении критических лимитов система должна делать <strong>early stopping</strong>, а не <code>hard error</code> (жёсткое падение). Контролируемая остановка персистит текущую сессию: оператор вмешивается, правит промпт, продолжает с последнего валидного шага. Жёсткое падение уничтожает прогресс и провоцирует ту же retry-петлю снаружи.</p>
<h2>5. Каскадный роутинг и budget-aware эскалация</h2>
<p>Типичная ошибка экономики — одна (самая мощная) модель на всё: «который час?» и «напиши алгоритм» стоят одинаково дорого. Роутер оценивает сложность запроса и выбирает модель. На правильно настроенном каскаде значительная часть трафика уходит на дешёвую модель, а качество держится близко к флагману — конкретные цифры см. ниже по TRACER.</p>
<pre><code>запрос
  │
  ▼
┌────────────────────┐   hit → ответ из кэша, cost = 0
│ 1. Семантический   │   miss ↓
│    кэш  (&lt;5 мс)    │
└────────────────────┘
  │
  ▼
┌────────────────────┐   simple → cheap-модель сразу
│ 2. Классификатор   │              (Haiku 4.5, GPT-4o-mini)
│    интента ~0.5B,  │   complex → дорогая модель reasoning
│    vLLM (&lt;5 мс)    │   ambiguous ↓
└────────────────────┘
  │
  ▼
┌────────────────────┐   confidence ≥ порога (≈ 0.85) → отдать
│ 3. Cheap-модель +  │   confidence &lt;  порога → escalation
│    confidence      │
│    score           │
└────────────────────┘
</code></pre>
<p>Порог confidence (старт ≈ 0.85) калибруется на 100–200 реальных запросах. Confidence получают через structured output: <code>{answer, confidence, reason}</code>. <strong>«На глаз» порог не ставят</strong> — оценка с LLM-judge или ручная разметка.</p>
<p>Калибровка через ручную разметку — затратна. Альтернатива — обучить суррогатный классификатор на <strong>traces</strong> работы флагмана: tracer-based routing. Активация через <strong>parity gate</strong>: суррогат пускают в прод только когда его согласие с моделью-учителем на тесте выше порога α. На опубликованных результатах — до 85% рутинного трафика уходит на дешёвые локальные модели при сохранении 95% качества и общем снижении затрат на 70% (<a href="https://dev.to/neilton_rocha_dev/llm-routing-how-to-cut-ai-infrastructure-costs-by-70-without-losing-quality-3d0m">разбор LLM-routing</a>).</p>
<p>Роутер бывает двух разных типов, и в проде они сосуществуют. Первый — <strong>экономический каскад по confidence</strong> (про деньги): cheap → escalate при низкой уверенности. Второй — <strong>Intent / Task Router</strong>: классификация типа запроса («объясни термин» / «дай план» / «сделай отчёт» / «найди в документах») → выбор <strong>сценария, шаблона и источника контекста</strong>, а не модели. Плюс этот же роутер работает как guardrail (защитный фильтр): отсекает вредные запросы и prompt injection (инъекция в промпт) <strong>до</strong> «мозга». Это две разные оси, и в продакшен-системе они обычно сосуществуют.</p>
<p>И наконец <strong>Budget-Aware Agentic Routing (BAAR)</strong> — маршрутизация под бюджет как последовательная задача принятия решений, где ошибки на ранних шагах лавинообразно накапливаются. На практике это значит:</p>
<ul>
<li>остаток бюджета <strong>&lt;30%</strong> — шлюз форсит cheap-модель и <strong>перестраивает план декомпозиции</strong> в сторону минимизации шагов;</li>
<li>остаток <strong>&lt;10%</strong> — пропускаются только simple-запросы, остальное — controlled stop.</li>
</ul>
<h2>6. Architect/Editor split: архитектура экономии</h2>
<p>Самая надёжная экономия — не «уменьшить effort», а <strong>разнести роли по моделям разного класса</strong>.</p>
<pre><code>┌──────────────────┐   short JSON   ┌──────────────────┐
│ Architect        │  ─── plan ───▶ │ Editor           │
│ дорогая «умная»  │                │ дешёвая быстрая  │
│ (Opus, GPT-5.1)  │                │ (Haiku, mini)    │
│                  │                │                  │
│ ► один раз       │                │ ► каждый шаг,    │
│ ► разворачивает  │                │   свежее окно    │
│   план в JSON    │                │ ► читает прогресс│
│ ► passes: false  │                │ ► пишет passes:  │
│   для подзадач   │                │   true в Git     │
└──────────────────┘                └──────────────────┘
</code></pre>
<p>В исследованиях Anthropic это два профиля:</p>
<ul>
<li><strong>Initializer Agent</strong> (агент-инициализатор) запускается один раз: разворачивает окружение, создаёт <code>claude-progress.txt</code>, <code>init.sh</code>, формирует JSON-файл требований, где каждой атомарной подзадаче проставлен флаг <code>&quot;passes&quot;: false</code>. JSON, а не markdown — потому что модели работают со схемами точнее и <strong>реже случайно перезаписывают смежные ветки</strong>.</li>
<li><strong>Coding Agent</strong> (агент-исполнитель) запускается на каждом шаге в свежем контекстном окне: читает прогресс, выбирает подзадачу с <code>false</code>, выполняет, тестирует, переключает в <code>true</code>, коммитит в Git.</li>
</ul>
<p>Экономия — <strong>50–80%</strong> бюджета, причём качество часто выше: «редактор» не отвлекается на архитектуру.</p>
<h2>7. Контекст как переменная стоимости</h2>
<p>Каждый шаг агента передаёт в модель всю накопленную историю сессии. Стоимость растёт <strong>квадратично</strong> относительно числа итераций. Поэтому борьба с контекстом — это борьба с бюджетом.</p>
<p>Три стратегии динамического урезания, расположенные по риску потери информации:</p>
<div class="table-wrap"><table>
<thead>
<tr>
<th>Стратегия</th>
<th>Механика</th>
<th>Применять когда</th>
<th>Риск</th>
</tr>
</thead>
<tbody><tr>
<td><strong>Compaction</strong> (саммаризация)</td>
<td>Саммаризация транскрипта, рестарт сессии с summary</td>
<td>Длинные аналитические сессии, обсуждения архитектуры</td>
<td>Потеря информации по дизайну: важная деталь может потеряться</td>
</tr>
<tr>
<td><strong>Tool-Result Clearing</strong> (очистка результатов инструментов)</td>
<td>Хирургическое удаление содержимого <code>tool_result</code>, запись <code>tool_use</code> остаётся</td>
<td>Частое чтение больших файлов, тяжёлые API</td>
<td>Практически безопасна — модель просто вызовет инструмент повторно</td>
</tr>
<tr>
<td><strong>Structured Notes</strong> (внешние заметки)</td>
<td>Запись фактов во внешние файлы (<code>claude-progress.txt</code>) вне контекста</td>
<td>Сверхдлинные сессии, распределённые по времени</td>
<td>Нужен бэкенд, инструменты чтения/записи</td>
</tr>
</tbody></table></div>
<p>Tool-Result Clearing — <strong>средний путь</strong> между compaction (агрессивная потеря) и context reset (полный сброс). В заметках про context engineering этот рычаг часто пропускают.</p>
<p>Архитектурное правило, которое стоит запомнить: <strong>программная обвязка кодирует предположения о недостатках текущей модели, которые быстро устаревают по мере обновления моделей</strong>. Пример: Claude Sonnet 4.5 страдал «контекстной тревожностью» — при приближении к лимиту окна модель преждевременно завершала задачи и декларировала успех без тестов. Под это в harness (программная обвязка) добавили жёсткую логику context reset. С переходом на Opus 4.5/4.6 поведение исчезло на уровне весов, а логика сбросов осталась — как технический долг.</p>
<p>Под масштабирование долгоживущих агентов в 2026 закрепилась трёхслойная архитектура <a href="https://www.anthropic.com/engineering/managed-agents"><strong>Managed Agents</strong></a>:</p>
<ul>
<li><strong>Brain</strong> — stateless LLM. Не хранит истории; восстанавливает контекст через <code>wake(sessionId)</code> из внешней БД, выбирает срез событий через <code>getEvents(start, end)</code>. Это и есть «стабильная утилизация prompt-кэша».</li>
<li><strong>Hands</strong> — одноразовые песочницы (Docker, Python-интерпретатор) с минимальным интерфейсом <code>execute(name, input) → string</code>. Сбой контейнера = обычная ошибка инструмента, оркестратор не падает.</li>
<li><strong>Session</strong> — персистентный append-only лог событий <strong>вне контекстного окна</strong>.</li>
</ul>
<p>Метрики эффекта на проде: −60% p50 TTFT, более −90% p95 latency за счёт ленивой инициализации песочниц. Паттерн уже воспроизведён в enterprise — те же три слоя ложатся на стек Azure AI Foundry (Foundry Agent Service → brain, Container Apps Dynamic Sessions → hands, Cosmos DB → session log).</p>
<h2>FAQ</h2>
<h3>Когда повышать reasoning effort, а когда держать минимальным?</h3>
<p>Высокое усилие окупается примерно на одной задаче из пяти — там, где есть верифицируемая глубина: сложный код, аудит многопоточного, оптимизация SQL, доказательства, ветвящиеся планы с жёсткими ограничениями. На извлечении сущностей, классификации, шаблонах и саммаризации глубокий reasoning жжёт токены и latency без прироста точности, а в режиме inversion даже снижает его.</p>
<h3>Что такое overthinking и как его поймать?</h3>
<p>Overthinking — участок кривой, где рост test-time compute не помогает или вредит: модель сомневается в очевидном и переусложняет. Ловится по метрикам — <code>tokens_per_task</code> и <code>loop_iterations</code> растут при неизменной точности. Лечение: снижать <code>budget_tokens</code>/<code>effort</code> под профиль задачи и не включать self-reflection у слабых моделей, где она чаще усугубляет ошибку, чем исправляет.</p>
<h3>Как защититься от runaway-агента?</h3>
<p>Пятью независимыми слоями одновременно: timeout (async queue вместо синхронного запроса), anti-loop (<code>max_iterations</code> 10–15 плюс стоп «No Progress»), cost circuit breaker на шлюзе ($50 warning / $100 halt), model pinning (фиксированные версии вместо алиасов) и audit log (OpenTelemetry <code>gen_ai.usage.*</code> + <code>session_id</code>). Каждый слой ловит то, что пропустил предыдущий.</p>
<h3>Какие метрики мерить у агента вместо RPS?</h3>
<p>Классический stateless-мониторинг (RPS, latency, HTTP-ошибки) не видит распределённую транзакцию агента. Собирайте на шлюзе: <code>tokens_per_task</code> (с учётом скрытого reasoning), <code>cost_per_completion</code>, <code>loop_iterations</code> и <code>retry_overhead_tokens</code>. Алертьте при <code>2×</code> от baseline по любой из них, а не по абсолютному порогу.</p>
<h3>Сколько закладывать в бюджет на задачу, сессию и день?</h3>
<p>Стартовые порядки величины: задача ~$0.50, сессия ~$2, день ~$10; на уровне cost circuit breaker — $50 warning / $100 halt, per-task ≈ $5. Это калибровочные ориентиры, а не универсальные значения — подстраивайте под свой профиль нагрузки и набор моделей.</p>
<h2>Источники</h2>
<ul>
<li>Anthropic — <a href="https://www.anthropic.com/engineering/managed-agents">Managed Agents</a>: трёхслойная архитектура Brain/Hands/Session и метрики latency.</li>
<li><a href="https://github.com/langchain-ai/langgraph/issues/7554">LangGraph Issue #7554</a> — jitter поверх <code>max_interval</code> в <code>RetryPolicy</code>.</li>
<li>Кейсы runaway-стоимости: <a href="https://www.reddit.com/r/artificial/comments/1t1mhx6/uber_burned_its_entire_2026_ai_coding_budget_in_4/">Uber — бюджет за 4 месяца</a>, <a href="https://www.reddit.com/r/LangChain/comments/1rpxt6q/i_kept_racking_up_150_openai_bills_from_runaway/">$150 за задачу на o1-preview</a>.</li>
<li><a href="https://dev.to/neilton_rocha_dev/llm-routing-how-to-cut-ai-infrastructure-costs-by-70-without-losing-quality-3d0m">LLM routing: cut costs by 70% without losing quality</a> — экономика каскадного роутинга.</li>
<li><a href="https://medium.com/@Micheal-Lanham/turn-the-thinking-knob-off-most-of-the-time-1b67ab418045">Turn the thinking knob off most of the time</a> — обзор эффекта overthinking.</li>
<li><a href="https://mlflow.org/blog/agent-costs-mlflow-gateway/">Agent costs with MLflow Gateway</a> — сбор token/cost-метрик на шлюзе.</li>
</ul>
<p>Числовые ориентиры из текста (15–20× разница цены между tiers, 49.6%→48.1% при росте стоимости на 56%, бюджеты $0.5/$2/$10, −60% p50 / −90% p95) — это порядки величины и значения из конкретных кейсов; на вашем профиле нагрузки они будут другими.</p>
]]></content:encoded>
  </item>
  <item>
    <title>ИИ-агенты в 2026: устройство, выбор модели и провалы в проде</title>
    <link>https://nikolskiy.dev/posts/ai-agents-2026/</link>
    <guid isPermaLink="true">https://nikolskiy.dev/posts/ai-agents-2026/</guid>
    <pubDate>Thu, 28 May 2026 00:00:00 GMT</pubDate>
    <description>Лестница зрелости от чат-бота до агента, четыре компонента анатомии, обрыв контекста при росте каталога инструментов, четыре критерия выбора модели, бенчмарки 2026 с поправкой на обвязку и типология провалов агентов в проде.</description>
    <content:encoded><![CDATA[<p>Под «AI-агентом» в 2026 году называют что угодно — от хитрого промпта до ChatGPT с памятью. Если вернуть слову смысл, окажется, что большинству задач достаточно обычного workflow, а провалы в проде — про границы, бюджеты и качество данных, а не про «выбор модели».</p>
<h2>1. Чат-бот, LLM, агент — три уровня зрелости</h2>
<p>Под «AI-агентом» сейчас называют что угодно. Полезная градация:</p>
<ul>
<li><strong>Чат-бот</strong> — реактивный: <code>триггер → ответ → конец</code>. Stateless, без памяти о цели после диалога.</li>
<li><strong>LLM с RAG</strong> — генерирует и рассуждает по контексту, но не выполняет действий в системах.</li>
<li><strong>Workflow</strong> — оркестрация модели и инструментов по предопределённому коду; разработчик пишет шаги, LLM встроена в поток, но не управляет им.</li>
<li><strong>AI-агент</strong> — <em>stateful, multi-step</em>: получает цель → декомпозирует → выбирает инструменты → исполняет → проверяет результат → повторяет.</li>
</ul>
<pre><code>Чат-бот     ──&gt;  LLM + RAG    ──&gt;  Workflow         ──&gt;  Agent
триггер →        генерация          фикс. шаги           цель + цикл
ответ            по контексту       (логика в коде)      (логика в модели)
</code></pre>
<p>Полезная переформулировка: <strong>агент — это надёжная система-обвязка вокруг ненадёжной вероятностной модели</strong>. Ценность не в «уме» LLM, а в слое надёжности вокруг — оркестрация, инструменты, логи, evals, guardrails.</p>
<h2>2. Когда нужен агент, а когда — workflow</h2>
<p>Agentic-подход повышает latency и стоимость; оправдан он не всегда. Эмпирика: <strong>~80% задач закрываются обычным workflow</strong> — последовательностью шагов, которую пишет разработчик, а LLM встроена как одно из звеньев.</p>
<p>Anthropic в гайде <a href="https://www.anthropic.com/engineering/building-effective-agents">«Building Effective AI Agents»</a> предлагает не одно бинарное «agent vs не agent», а <strong>пять базовых паттернов</strong>, которые перекрывают большинство задач:</p>
<div class="table-wrap"><table>
<thead>
<tr>
<th>Паттерн</th>
<th>Механика</th>
<th>Latency</th>
<th>Когда применять</th>
</tr>
</thead>
<tbody><tr>
<td><strong>Chain</strong></td>
<td>Шаги последовательно, каждый берёт результат предыдущего</td>
<td>средняя</td>
<td>Линейная задача с понятной структурой</td>
</tr>
<tr>
<td><strong>Parallelization</strong></td>
<td>Подзадачи независимо + голосование/секционирование</td>
<td>низкая</td>
<td>Категоризация, multi-perspective validation</td>
</tr>
<tr>
<td><strong>Routing</strong></td>
<td>Классификатор разруливает вход в специализированные ветки</td>
<td>низкая</td>
<td>Триаж разнородных запросов</td>
</tr>
<tr>
<td><strong>Orchestrator-Workers</strong></td>
<td>Центральная модель декомпозирует, делегирует sub-agents, синтезирует</td>
<td>высокая</td>
<td>Большие открытые задачи: deep research, написание по плану</td>
</tr>
<tr>
<td><strong>Evaluator-Optimizer</strong></td>
<td>Цикл генератор + критик до приемлемого качества</td>
<td>очень высокая</td>
<td>Качественно-критичные задачи: код, юр-документы</td>
</tr>
</tbody></table></div>
<p>Это лестница сложности: один LLM-call → workflow → агент. Поднимайся только при необходимости.</p>
<p>Триггеры, когда нужен именно agent:</p>
<ul>
<li>задача занимает <strong>≥3 шагов</strong> или <strong>&gt;1 системы</strong>;</li>
<li>решения зависят от контекста на ходу, исход не предопределён;</li>
<li><strong>результат можно проверить автоматически</strong> — тесты, ответ API, изменение состояния.</li>
</ul>
<p>Если хотя бы одного из этих условий нет — workflow надёжнее и дешевле.</p>
<h2>3. Анатомия: четыре компонента</h2>
<p>Агент раскладывается на 4 компонента:</p>
<pre><code>                         ┌─────────────────────┐
                         │   Цель пользователя │
                         └──────────┬──────────┘
                                    ▼
                            ┌───────────────┐
                            │  Мозг — LLM   │  reasoning, планирование
                            └───────┬───────┘
                                    │
              ┌─────────────────────┼─────────────────────┐
              ▼                     ▼                     ▼
        ┌──────────┐         ┌──────────┐         ┌──────────────┐
        │ Tools    │         │ Memory   │         │ Knowledge    │
        │ API,     │         │ short /  │         │ base (RAG)   │
        │ shell,   │         │ session /│         │ доменные     │
        │ DB       │         │ long     │         │ документы    │
        └──────────┘         └──────────┘         └──────────────┘
</code></pre>
<ul>
<li><strong>Мозг — LLM</strong>: reasoning + planning, решает «что делать дальше».</li>
<li><strong>Tools</strong> (инструменты, «руки»): function calling — API, shell, браузер, БД, вычисления.</li>
<li><strong>Memory</strong>: working memory (контекст в промпте сейчас), session history (прошлые ходы сессии), long-term (vector DB / файлы / логи прошлых траекторий).</li>
<li><strong>Knowledge base — RAG</strong>: справочники и доменная документация, защита от галлюцинаций.</li>
</ul>
<p>Контринтуитивный факт из AgentBench: главная причина провала агентов — <strong>слабые long-term reasoning и decision-making у мозга-LLM</strong>, а не нехватка инструментов. «Дать агенту 50 функций» — анти-паттерн.</p>
<h2>4. Tool calling и обрыв контекста</h2>
<p>Tool calling (вызов инструментов) под капотом работает просто: модель возвращает JSON с именем функции и аргументами, рантайм исполняет, результат возвращается в контекст следующим шагом цикла.</p>
<pre><code class="language-json">{
  &quot;name&quot;: &quot;find_customers&quot;,
  &quot;description&quot;: &quot;Поиск клиентов по запросу. Топ-5 совпадений.&quot;,
  &quot;parameters&quot;: {
    &quot;query&quot;: {&quot;type&quot;: &quot;string&quot;},
    &quot;limit&quot;: {&quot;type&quot;: &quot;integer&quot;, &quot;default&quot;: 5}
  }
}
</code></pre>
<p>Эмпирическое правило: <strong>хороший <code>description</code> инструмента решает больше, чем выбор модели</strong>. <code>find_customers(query, limit=5)</code> — узкий контракт с понятными границами. <code>database(query)</code> — «делай что хочешь», и модель действительно начнёт «делать что хочет».</p>
<p>Когда инструментов в каталоге становится много, проявляется <strong>context cliff</strong> (обрыв контекста): схемы всех инструментов кладутся в активный prompt, и качество выбора падает не линейно, а скачком.</p>
<pre><code>selection accuracy
   ▲
95 │ ████████  ←  ~10 tools
   │ ████████
85 │ ███████   ←  ~50 tools
   │ ████
15 │ ██        ←  ~100 tools
   │ ▏         ←  ~700 tools
 0 │
   └────────────────────────────►
    10   50   100        700+   tools
</code></pre>
<p>Три механизма деградации:</p>
<ol>
<li><strong><a href="https://arxiv.org/abs/2307.03172">Lost-in-the-middle</a></strong> (потерянное в середине): трансформер распределяет внимание неравномерно — токены в середине длинного контекста получают меньший вес. Описание инструмента, оказавшееся в середине каталога, модель «не видит».</li>
<li><strong>Tool collision</strong> (коллизия инструментов): при росте каталога границы между близкими endpoints (<code>search_issues</code> / <code>list_issues</code> / <code>get_issue</code>) размываются — модель путает или смешивает параметры.</li>
<li><strong>Prompt budget starvation</strong> (голод бюджета промпта): под схемы съедается столько токенов, что для system prompt и guardrails места не остаётся.</li>
</ol>
<p>Митигации:</p>
<ul>
<li><strong>Semantic top-K</strong> — эмбеддинг запроса + cosine similarity по описаниям инструментов → в активный prompt идут только k наиболее релевантных схем.</li>
<li><strong>Progressive disclosure</strong> — инструменты разнесены по namespaces (<code>github__*</code>, <code>notion__*</code>), быстрый классификатор определяет нужный набор под шаг.</li>
<li><strong>Schema minimization</strong> — короткие descriptions, примитивные типы, fixed enums вместо свободного текста.</li>
</ul>
<h2>5. Выбор модели: 4 критерия, не «возьми флагман»</h2>
<p>«Один флагман на всё» — главный источник перерасхода. Четыре критерия:</p>
<ul>
<li><strong>Качество</strong> — общий бенчмарк + свои evals на домене. Общие лидерборды ≠ прод.</li>
<li><strong>Контекст</strong> — размер окна и <strong>эффективный recall</strong> в его середине. Окно 1M токенов не значит, что модель удержит 1M (lost-in-the-middle).</li>
<li><strong>Стоимость</strong> — $/1M токенов на input/output. Агент делает десятки вызовов на задачу, цена умножается.</li>
<li><strong>Latency + tool use</strong> — reasoning-режимы дают +5–10% качества ценой 2–5× по времени. Голосовому агенту это смерть UX, code-агенту — норма.</li>
</ul>
<p>Практика: подбирай модели <strong>на роли</strong>. Дешёвая на классификацию и tool-execution, средняя на «исполнителя», флагман — только на gatekeeping (compliance, финансовые согласования).</p>
<p>Архитектурный приём экономии — <strong>Architect/Editor split</strong>:</p>
<pre><code>┌──────────────────┐                   ┌──────────────────┐
│ Architect        │   short JSON      │ Editor           │
│ дорогая «умная»  │ ──── plan ─────►  │ дешёвая быстрая  │
│ модель           │                   │ модель           │
│                  │                   │                  │
│ ► короткий план  │                   │ ► основной объём │
└──────────────────┘                   └──────────────────┘
</code></pre>
<p>Экономия 50–80% бюджета, причём качество часто выше: «редактор» не отвлекается на архитектуру.</p>
<h2>6. Бенчмарки 2026: что меряют и scaffold effect</h2>
<p>Классические MMLU/GSM8K/HumanEval насыщены — все фронтиры выше 95%. Что реально меряют:</p>
<ul>
<li><strong><a href="https://www.swebench.com/">SWE-bench Verified</a></strong> — 500 GitHub-issue, отобранных вручную; модель пишет patch, проходящий тесты.</li>
<li><strong>SWE-bench Pro</strong> — то же, но архитектурно сложные multi-file задачи под enterprise-структуру кода.</li>
<li><strong><a href="https://os-world.github.io/">OSWorld-Verified</a></strong> — desktop computer-use: файловая система, браузер, Linux-окружение.</li>
<li><strong><a href="https://arcprize.org/">ARC-AGI-2</a></strong> — невербальное логическое рассуждение по визуальным паттернам.</li>
<li><strong>ARC-AGI-3</strong> — интерактивные игровые среды, цель не задана; модель должна сама её вывести. Все фронтиры пока около нуля — это сдвинутая граница.</li>
<li><strong><a href="https://github.com/sierra-research/tau-bench">τ-bench</a></strong> (Tau-bench) — многоходовая надёжность в обслуживающих диалогах: транзакции, удержание состояния через 20+ ходов.</li>
</ul>
<p>Главная ловушка чтения — <strong>scaffold effect</strong> (<a href="https://layerlens.ai/blog/why-ai-benchmarks-are-misleading">почему бенчмарки обманчивы</a>): балл модели = веса + обвязка (verification, retry-loops, state-saving, инжиниринг харнесса). Смена scaffold вокруг тех же весов сдвигает результат на <strong>10–18 п.п.</strong> Поэтому к vendor-score применяют <strong>дефлятор ×0.7</strong> — грубая, но рабочая оценка «как будет в вашем окружении без оптимизированной обвязки».</p>
<p>Пять правил чтения:</p>
<ol>
<li><strong>3+ бенчмарка</strong> под свою задачу, не одну цифру.</li>
<li><strong>Дата старше 6 месяцев</strong> — устарело.</li>
<li>Vendor-score умножай на <strong>~0.7</strong> (best-case scaffold).</li>
<li>Scaffold (Claude Code, Aider, Codex и пр.) смещает результат на 10–20%.</li>
<li><strong>Verified vs Pro</strong> — на сложных закрытых данных балл падает примерно в 3×; в проде реальность ближе к Pro.</li>
</ol>
<p>Финал — <strong>свои evals на 50–200 примерах своего домена</strong>. Не пытайся построить идеальный набор сразу: 20 примеров → найди где сыпется → добей до 50–100 на проблемных кейсах.</p>
<h2>7. Почему агенты падают в проде</h2>
<p>Типология провалов, повторяющаяся из обзора в обзор:</p>
<ul>
<li><strong>Scope creep</strong> — пилот расширяют новыми инструментами и ветками, state-tracking растёт, систему уже не отладить. <em>Лекарство:</em> v1.0 решает одну задачу хорошо; расширение — через sub-agents с узкой ролью.</li>
<li><strong>Data quality drift</strong> — на чистых тестах работает, на боевых данных рассыпается из-за пропусков, форматов, дубликатов. У агента ошибки накапливаются по цепочке. <em>Лекарство:</em> до интеграции — аудит данных, не код.</li>
<li><strong>Security &amp; governance</strong> — нет access controls, audit logs, защиты от prompt injection. Не проходит security review.</li>
<li><strong>Integration debt</strong> — хрупкие хардкод-интеграции с legacy. <em>Лекарство</em> — стандартизированные интерфейсы (MCP).</li>
<li><strong>Cost overruns</strong> — runaway-циклы без бюджетных лимитов жгут токены. Нужны <code>max_iterations</code>, <code>max_tokens</code>, <code>max_cost</code> одновременно.</li>
<li><strong>Governance gaps</strong> — единая бинарная политика на все агенты: read-only не нужны те же ограничения, что action-executing.</li>
<li><strong>Organizational resistance</strong> — нет владельца со стороны бизнеса, нет вовлечения пользователей.</li>
</ul>
<p>Отдельно security как класс:</p>
<ul>
<li><strong>Over-permissioning</strong> (лишние права) — агенту выдают доступ шире, чем нужно для задачи; при компрометации это превращается в blast radius всей системы.</li>
<li><strong>Indirect prompt injection</strong> — модель не отличает инструкции от данных. Атакующий встраивает команду в PDF, email, веб-страницу — агент это читает и исполняет. Защита архитектурная: изоляция привилегий между «контентным» и «действующим» агентами, HITL на действиях с побочным эффектом, иммутабельный action log.</li>
</ul>
<h2>8. Локальный self-host: Ollama</h2>
<p>Self-hosted inference оправдан, когда данные не должны уходить за периметр, объёмы делают API дорогим или нужен контроль над инфраструктурой. Минимальный сетап:</p>
<pre><code class="language-bash">curl -fsSL https://ollama.com/install.sh | sh
ollama run qwen3:8b

# Длинный контекст и тюнинг под прод:
export OLLAMA_CONTEXT_LENGTH=131072    # 128K
export OLLAMA_FLASH_ATTENTION=1        # Flash Attention для длинных входов
export OLLAMA_KV_CACHE_TYPE=q8_0       # квантованный KV-cache, ~½ памяти
</code></pre>
<p>Ollama поднимает локальный inference-сервер с OpenAI-совместимым API — клиенты, агенты и оболочки подключаются меняя только base URL.</p>
<p>Что важно держать в голове про память:</p>
<pre><code>VRAM ≈ веса модели + KV-cache(растёт с длиной контекста) + активации
</code></pre>
<p>Поэтому при локальном запуске решают не только параметры модели, но и <strong>квантизация</strong> (GGUF Q4 экономит ~4× относительно FP16) и <strong>GQA</strong> (Grouped-Query Attention уменьшает KV-cache). На ноутбуке потолок — модели уровня 7–8B; «более-менее разумная» локалка требует ~12–15 ГБ RAM. На старте часто берут облачный API, а локальный inference оставляют для приватных шагов.</p>
<p>Готовые оболочки: <strong>Dify</strong> (RAG + агенты + аналитика), <strong>Open WebUI</strong> (офлайн, LDAP), <strong>RAGFlow</strong> (глубокий парсинг таблиц, GraphRAG, реранкинг). Для оркестрации цикла агента — <strong>LangGraph</strong>: граф состояний, чекпоинтеры под рестарт, conditional edges под exit-условия (<code>max_iterations</code>, <code>no_progress</code>).</p>
<h2>FAQ</h2>
<h3>Когда нужен полноценный агент, а когда хватит workflow?</h3>
<p>Workflow закрывает примерно 80% задач и почти всегда дешевле и предсказуемее. Агент оправдан, только когда выполнены все три условия сразу: задача требует ≥3 шагов или больше одной системы, ход решения зависит от контекста и заранее не определён, а результат можно проверить автоматически (тесты, ответ API, изменение состояния). Нет хотя бы одного — берите workflow.</p>
<h3>Что такое context cliff и как с ним бороться?</h3>
<p>Context cliff — скачкообразное, а не линейное падение точности выбора инструмента при росте каталога: схемы всех инструментов забивают активный prompt. Три механизма: lost-in-the-middle, tool collision и prompt budget starvation. Митигации: semantic top-K (в prompt идут только релевантные схемы), progressive disclosure по namespaces и schema minimization.</p>
<h3>Как выбрать модель для агента?</h3>
<p>По четырём критериям, а не «бери флагман»: качество (общий бенчмарк плюс свои evals на домене), эффективный recall в середине окна (а не номинальный размер контекста), стоимость $/1M токенов (агент делает десятки вызовов на задачу) и latency с tool-use. Подбирайте модели на роли: дешёвую — на классификацию и tool-execution, флагман — только на gatekeeping.</p>
<h3>Можно ли доверять бенчмаркам из карточки модели?</h3>
<p>Не как абсолюту. Балл = веса + обвязка (scaffold), и смена обвязки сдвигает результат на 10–18 п.п. Практическое правило: смотрите 3+ бенчмарка под свою задачу, игнорируйте цифры старше 6 месяцев, умножайте vendor-score на ~0.7 и помните, что на сложных закрытых данных (Pro против Verified) балл падает примерно втрое. Финальный критерий — свои evals на 50–200 примерах домена.</p>
<h3>Почему агенты падают в проде?</h3>
<p>Не из-за «выбора модели», а из-за границ, бюджетов и качества данных: scope creep, data quality drift, дыры в security и governance, integration debt с legacy и cost overruns от runaway-циклов. Отдельный класс — безопасность: over-permissioning и indirect prompt injection. Лечится архитектурно: узкие роли, аудит данных до интеграции, бюджетные лимиты и изоляция привилегий.</p>
<h2>Источники</h2>
<ul>
<li>Anthropic — <a href="https://www.anthropic.com/engineering/building-effective-agents">Building Effective AI Agents</a>: пять базовых паттернов и граница workflow ↔ agent.</li>
<li><a href="https://arxiv.org/abs/2307.03172">Lost in the Middle: How Language Models Use Long Contexts</a> — неравномерное внимание трансформера по длине контекста.</li>
<li><a href="https://dev.to/thedailyagent/mcp-tool-overload-why-more-tools-make-your-agent-worse-5a49">MCP tool overload: why more tools make your agent worse</a> и <a href="https://medium.com/google-cloud/the-tool-bloat-epidemic-a0bb614d4041">The tool-bloat epidemic</a> — деградация при росте каталога инструментов.</li>
<li>Бенчмарки: <a href="https://www.swebench.com/">SWE-bench</a>, <a href="https://github.com/sierra-research/tau-bench">τ-bench</a>, <a href="https://os-world.github.io/">OSWorld</a>, <a href="https://arcprize.org/">ARC-AGI</a>.</li>
<li><a href="https://layerlens.ai/blog/why-ai-benchmarks-are-misleading">Why AI benchmarks are misleading</a> — про scaffold effect и чтение vendor-score.</li>
</ul>
<p>Цифры обрыва контекста (≈95/85/15% на 10/50/100 инструментах), дефлятор ×0.7 и оценка «~80% задач = workflow» — практические ориентиры порядка масштаба, а не данные одного измерения; калибруйте на своём домене.</p>
]]></content:encoded>
  </item>
</channel>
</rss>
