Гигиена промпта и разбор типовых провалов

Тема 1/4: Промптинг как инженерная дисциплина Урок 2/3

Прежде чем прицельно чинить провалы на оценочном наборе, промпт стоит привести в порядок. В прошлом уроке мы собрали пять тестовых случаев для бота поддержки телеком-компании и увидели, что большинство из них проваливается. В этом уроке разбираем базовую гигиену промпта: как отделить роль, правила, политику и данные с помощью XML-тегов, зачем нужен контракт вывода и как закрепить формат на уровне вызова API. Затем пройдём по трём провалам нашего примера по одному: модель утаивает информацию, ошибается в расчётах и не передаёт вопрос человеку. У каждого провала своя причина и своё исправление — и каждое даёт вывод, который переносится на любые агентные системы.

Представьте промпт, который живёт в рабочей системе не первый месяц. Его правили несколько человек, у него нет владельца, внутри перемешаны политика компании, тон общения и заплатки под прежние модели. После перехода на новую модель тестовые случаи начинают проваливаться. Именно такой промпт — бот поддержки телеком-компании Meridian Mobile из прошлого урока — мы разберём сегодня. Порядок работы прежний: запускаем оценочный набор, смотрим на провалы и устраняем их по одному, проверяя каждое изменение повторным прогоном. Но сначала — общая уборка.

Что не так с исходным промптом

На первый взгляд исходный промпт выглядит прилично: задана роль, есть данные, есть инструкции про тон и расчёты. Но при внимательном чтении видны три типичные проблемы. Первая — боту говорят, что он человек. Это просто неправда, и держать ложное утверждение в основе промпта — плохая идея. Вторая — часть текста скопирована прямо с сайта компании: внутри промпта остались упоминания hero-картинки и даже уведомления о cookies. Этот мусор не помогает модели, а только засоряет контекст. Третья — все инструкции свалены в один большой абзац. Рассуждения, роль, критически важные правила и справочные данные идут сплошным текстом, и отделить политику компании от рекомендаций по тону невозможно.

Приём первый: структура через XML-теги

Первое исправление — добавить структуру. Промпт размечается XML-тегами: отдельная секция для роли, отдельная для общих правил, отдельная для политики компании, отдельная для тона общения. Содержание инструкций почти не меняется — меняется их организация. Уже одно это улучшает результат: после разметки оценочный набор показывает больше пройденных случаев, хотя ни одной новой инструкции не добавилось.

Правило простое: если, читая промпт, вы не можете отличить правила от политики и от данных — модель, скорее всего, тоже не может. Это простой способ проверить любой промпт: прочитайте его глазами постороннего и спросите себя, понятно ли, где заканчиваются справочные данные и начинаются обязательные требования.

Приём второй: контракт вывода

Второй базовый приём — задать контракт вывода: отдельную секцию промпта, где описан формат ответа. В примере модель просят оборачивать ответ в XML-теги. Но промпт — не единственный способ закрепить формат. Часть работы переносится на уровень вызова API: туда добавляется стоп-последовательность, которая распознаёт закрывающий тег и останавливает генерацию в этой точке. Так формат держится не на дисциплине модели, а на настройке самого вызова. Для бота поддержки, который отвечает разговорным текстом, это не главная забота. Но если ответ должен быть сложной структурой, например вложенным JSON, стоит использовать структурированные выводы (structured outputs) — они гарантируют формат программно, а не просьбой.

Провал первый: модель утаивает информацию

Клиент спрашивает, сколько трафика точки доступа включено в его безлимитный тариф. Клиент — на прежнем, «унаследованном» тарифе, и его реальные данные — пять гигабайт — переданы модели в контексте. Но вместо прямого ответа бот называет цифру из текущей политики и отправляет клиента проверять детали в личном кабинете.

Причина находится в промпте. Там осталась инструкция: никогда не сообщать клиенту неверные детали тарифа, вместо этого направлять его по ссылке. Это заплатка под прежнюю модель: когда-то она путала тарифы, и запрет защищал от ошибок. Современные модели, как правило, точнее следуют инструкциям — поэтому старые запреты-заплатки становятся лишними: модель подстраивается под такой запрет и молчит даже тогда, когда знает ответ. Исправление: сказать модели, что данные конкретного клиента в контексте — это достоверный источник истины, и на них можно опираться. После правки случай проходит.

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

Провал второй: расчёт пропорциональной оплаты

Клиент спрашивает, каким будет его следующий счёт, если он перейдёт на тариф с 30 гигабайтами в середине месяца. Модель рассуждает, что-то прикидывает в уме, но конкретной суммы не называет — ответ расплывчатый, и полагаться на него нельзя. В промпте на этот счёт есть требования: никогда не давать расплывчатых ответов, всегда правильно рассчитывать пропорциональные суммы, это критически важно. Проблема в том, что такие требования ничего не меняют: сказать модели «считай хорошо» — не значит научить её считать.

Исправление — дать модели инструмент calculate_proration. Для этого нужно три шага: объявить инструмент в вызове API, описать его схему — что он делает и когда его применять — и реализовать сам расчёт в коде. После этого модель вызывает инструмент, получает точную сумму и возвращает её клиенту; тестовые случаи по расчётам проходят. Главный урок: инструкции не добавляют способностей. Если задача требует точного вычисления или надёжного действия, модели нужен инструмент, а не требование постараться.

Провал третий: эскалация ошибки в счёте

У клиента ошибка в счёте, и по политике компании такой вопрос должен уходить живому оператору. Вместо этого бот пытается сам поставить диагноз и объяснить клиенту, что могло пойти не так. Смотрим в промпт и находим инструкцию: избегать эскалации, если она не абсолютно необходима, — она стоит около 8 долларов и ухудшает показатель решения вопроса при первом обращении.

Модели показали только одну сторону: цену эскалации. Цену ошибки — что будет, если бот разберётся неверно, — ей не сказали. Модель подстраивается под то, что ей назвали, и перестаёт эскалировать вовсе, а это прямо противоречит тому, чего от неё ждёт оценочный набор. Исправление — показать обе стороны компромисса: да, эскалация стоит 8 долларов, но ошибка обойдётся возвратом средств и потерей доверия клиента. С такой формулировкой модель сама взвешивает варианты и передаёт вопрос человеку там, где это оправдано. Важное наблюдение: чем умнее модель, тем важнее давать ей обе стороны компромисса — сильные модели хорошо взвешивают варианты самостоятельно, но только если им дали полную картину, а не половину.

Выводы урока

Гигиена промпта — структура, удаление мусора, контракт вывода — даёт первый прирост качества ещё до прицельных исправлений. Провалы устраняются по одному, и каждая правка проверяется повторным прогоном оценочного набора. Заплатки под прежние модели со временем начинают вредить, поэтому причину каждой защитной инструкции нужно записывать — так её можно будет осознанно убрать. Расчёты и другие точные действия закрываются инструментами, а не требованиями. А любой компромисс в инструкциях описывается целиком: и цена, и выгода. В следующем уроке пойдём дальше — разберём, когда один большой промпт стоит разбить на несколько простых и собрать их в петлю «генерация — оценка — починка».