Вы собрали первого помощника на языковой модели - программе, которая по вашему текстовому запросу дописывает ответ. Он отвечает связно, вежливо... и мимо. Почти у всех первая мысль одинаковая: «модель слабая, надо взять посильнее». Я думала ровно так же.
За первый год плотной работы с моделями у меня накопилось пять ошибок. Каждая стоила недель. И ни одна не была «про модель». Ниже - все пять, с механикой: что именно ломается, почему это выглядит как проблема модели и по какому признаку отличить одно от другого. К концу вы сможете пройтись по своему проекту и проверить, не стоите ли вы прямо сейчас на одной из этих граблей.
flowchart TB
A["Ответ неверный"] --> S1{"Что нашел поиск?"}
S1 -->|"фрагменты не те"| F1["Чинить нарезку,<br/>разметку, поиск"]
S1 -->|"фрагменты те"| S2{"Что ушло в модель?"}
S2 -->|"фрагменты поданы плохо"| F2["Чинить промпт<br/>и формат подачи"]
S2 -->|"подано верно"| F3["Только теперь - <br/>вопрос к модели"]
A -.->|"соблазн: одна строчка<br/>в настройках"| F3Ошибка 1: считать, что качество упирается в модель
Поисковый ассистент отвечал неверно - и первой мыслью была смена модели. Это соблазнительно, потому что делается одной строчкой в настройках. Но реальная причина почти всегда оказывалась в подготовке данных.
Три типичных поломки:
- Нарезка документов без сохранения контекста. Длинный текст режут на куски, чтобы искать по ним по отдельности. Если резать вслепую - по количеству символов - кусок теряет, о чем он вообще: остается абзац с местоимениями и цифрами, к которому не привязан ни раздел, ни предмет разговора.
- Нет пометок категорий. У фрагмента нет ярлыка, к какому разделу, продукту или году он относится. Поиск не может ограничиться нужной областью и тянет похожее по словам из соседней.
- Слишком узкий фильтр поиска. Система отсекает подходящее еще до того, как модель его увидит. Модель не переврала ответ - ей просто не показали нужный фрагмент.
Во всех трех случаях замена модели ничего не меняет: более сильная модель так же аккуратно ответит по тем же испорченным данным.
Есть и подтверждение со стороны. В исследовании Nvidia (август 2026) одна и та же модель на тесте интерактивного рассуждения дает 30% без специальной «обвязки» и 100% с ней. Обвязка - это все, что стоит вокруг модели: подготовка данных, поиск, порядок шагов, проверки результата. Разница внутри одной модели - от 30 до 100. Держите эту цифру в голове каждый раз, когда рука тянется «поменять модель».
Ошибка 2: ставить модель туда, где хватит скрипта
У нас была регулярная проверка очереди задач. Мы повесили ее на полноценного агента - программу, которая сама решает, какие шаги сделать, и обращается к модели на каждом шаге. Звучало разумно: пусть будет умно.
А по факту работа сводилась к двум действиям: прочитать данные и подставить их в шаблон. Никакого решения там не принималось.
Платили мы за это дважды:
- Каждый запуск запрашивал у провайдера потолок токенов модели, а не реальную нужду. Токен - небольшой кусочек текста (единица, в которой считаются и лимиты, и деньги). Резервировать максимум под подстановку в шаблон - все равно что каждый раз бронировать грузовик ради одной коробки.
- Мы завели зависимость от внешнего сервиса там, где ее могло не быть. При просевшем балансе тривиальная проверка стала падать каждые 30 минут.
Правило простое: если у шага нет вариативности - если вы можете заранее описать, что он делает, без слов «в зависимости от смысла», - это скрипт. Скрипт не падает из-за баланса, не стоит денег за запуск и не выдумывает.
Ошибка 3: верить промпту как гарантии
Промпт - это текст-инструкция, который вы даете модели: кто она, что делает, чего не делает. Кажется, что записанное правило теперь соблюдается. На практике оно соблюдается почти всегда, и вся сложность прячется в слове «почти».
Самый неприятный вид нарушения - не тот, где модель выдает очевидную чушь. Хуже, когда модель уверенно выдумывает числа того же порядка, что настоящие: например, называет цену выхода 8 долларов вместо 12. Не 800, не «около десяти» - правдоподобное число, которое проходит взглядом и не вызывает подозрений. Именно такие ошибки доезжают до пользователя.
Поймать это можно только механической сверкой с выверенной фактурой: числа и названия из ответа сопоставляются с источником кодом, а не просьбой в промпте «будь внимательнее». Промпт - это пожелание. Сверка - это проверка.
Ошибка 4: проверять только результат, а не источник
Долгое время мы проверяли только текст ответа: похоже на правду - хорошо, не похоже - плохо. Пока не начали смотреть, какие именно фрагменты нашел поиск перед тем, как модель начала отвечать, отладка была гаданием.
Потому что за плохим ответом стоят две совершенно разные поломки:
- Поиск не нашел нужный фрагмент - чинить нужно данные, нарезку, пометки, фильтр.
- Поиск нашел, а модель переврала найденное - чинить нужно промпт, формат подачи фрагментов, сверку.
По тексту ответа их не различить. По списку найденных фрагментов - различить за секунды.
Логируйте то, что ушло в модель, вместе с тем, что из нее вышло; это самое дешевое улучшение из всех пяти.
flowchart LR
subgraph Q1["«Сколько осталось»"]
A1["Баланс на счете"] --> A2["Видно, что счет вырос"] --> A3["11 дней до причины"]
end
subgraph Q2["«Куда ушло»"]
B1["Вызовы: проект,<br/>модель, агент, день"] --> B2["Крупнейшая строка<br/>видна сразу"] --> B3["Минуты до причины"]
end
Q1 ==> Q2Ошибка 5: не иметь ответа на вопрос «куда ушли деньги»
Мониторинг у нас был. Он отвечал на вопрос «сколько осталось» и не отвечал на вопрос «куда ушло». Разница между этими двумя вопросами измеряется в днях расследования.
Счет вырос. С момента, когда это стало заметно, до момента «вот причина» прошло 11 дней. Все это время 45% расходов уходило на служебный опрос агента при пустой очереди задач: система исправно спрашивала, есть ли работа, получала ответ «нет» и платила за этот вопрос.
Общая сумма такого не показывает никогда. Нужен разрез: сколько потратил каждый сценарий, каждый запуск, каждый шаг. Тогда «счет вырос» и «вот причина» - это один экран, а не 11 дней.
Применить у себя
Что проверить на практике (чек-лист)
Общий знаменатель всех пяти ошибок один: соблазн решать проблему на уровне модели, потому что это одна строчка в конфиге. Настоящая починка почти всегда лежит уровнем ниже - в данных, в обвязке, в учете.
- Возьмите 5 реальных неверных ответов и для каждого посмотрите, какие фрагменты нашел поиск. Разложите на две стопки: «не нашли» и «нашли, но переврали». Пока стопок нет, вы не отлаживаете - вы гадаете.
- Откройте десяток кусков, на которые нарезаны ваши документы, и прочитайте их как отдельные тексты. Если из куска непонятно, о чем он и к чему относится, - проблема в нарезке, а не в модели.
- Проверьте, есть ли у фрагментов пометки категорий и не режет ли фильтр поиска нужное. На пробном прогоне отключите фильтр и сравните результат.
- Пройдите по списку мест, где вызывается модель, и для каждого ответьте: есть ли здесь вариативность? Если шаг сводится к чтению данных и подстановке в шаблон - переведите его в скрипт.
- Посмотрите, какой лимит токенов запрашивается на каждом вызове. Если это потолок модели по умолчанию - поставьте реальную нужду.
- Возьмите 10 ответов с числами и названиями и сверьте каждое с источником вручную. Найдете расхождения - заводите автоматическую сверку.
- Добавьте в учет расходов разрез по сценариям и шагам. Отдельно проверьте, сколько стоят регулярные фоновые проверки, когда работы нет.
Как понять, что получилось
Критерий один, и он не про «качество ответов», а про скорость диагноза.
Возьмите свежий неверный ответ и засеките время. Если за несколько минут - не перезапуская модель и не меняя ее - вы можете сказать, на каком уровне поломка (данные, поиск, промпт, обвязка или учет), значит система наблюдаемая, и дальше это вопрос обычной инженерной работы.
Если вместо этого вы начинаете перебирать модели и переписывать промпт наугад - вы все еще чините верхний уровень.
Второй признак, попроще: вы можете назвать три самые дорогие статьи расходов за прошлую неделю по памяти. Не общую сумму - именно статьи.