Спецификации функций, которые выдерживают смену моделей в реальных продуктах
Спецификации функций, которые выдерживают смену моделей, сохраняют продуктовый замысел стабильным, разделяя правила задачи, примеры и политики безопасности на отдельные части.

Почему спецификации для одной модели так быстро ломаются
Большинство команд начинают с одного большого промпта. В нем собраны задача, несколько примеров, правила форматирования, крайние случаи и заметки по безопасности в одном блоке. Сначала это кажется быстрым, но вскоре проявляется скрытая проблема: поведение продукта зависит от привычек одной модели, а не от чёткой спецификации.
Когда вы меняете модель, различия проявляются быстро. Одна модель может копировать примеры слишком буквально. Другая — строже следовать заметке по безопасности и становиться чересчур осторожной. Третья может поменять тон, пропустить поле или обернуть ответ дополнительным текстом. Промпт почти не изменился, но фича вдруг ведёт себя как другой продукт.
Это происходит потому, что реальный замысел спрятан в формулировках. Если инструкция говорит «классифицируй этот тикет», а пример одновременно обучает приоритету, маршрутизации и правилам отказа, модель усваивает путаную смесь правил. Новая модель может решить, что примеры важнее инструкции. Другая — поступит наоборот. Тогда команды начинают править фразы по одному слову, надеясь вернуть старое поведение.
На это уходит время. QA уже не просто тестирует фичу. Они гоняются за регрессиями в промпте:
- Смена формата вывода, хотя сама задача не изменилась
- Другие ответы на крайние случаи после смены модели
- Изменение поведения по безопасности, потому что оно было спрятано в примерах
- Простые правки промпта решают один кейс и ломают два других
Через несколько итераций никто не понимает, какое предложение за какое поведение отвечает. Промпт превращается в груду заплаток.
Если вы хотите спецификации функций, которые переживут смену модели, относитесь к промпту как к формату доставки, а не как к самой спецификации. Спецификация должна чётко описывать, что фича должна делать, какие примеры это иллюстрируют и какие ограничения безопасности всегда применяются. Когда эти части живут отдельно, смена модели перестаёт ощущаться как переписывание и становится обычным циклом тестирования.
Это звучит просто. На практике оно экономит командам недели хрупкой подстройки промптов и даёт QA что-то стабильное для проверки.
Что должна разделять каждая спецификация
Команды получают спецификации функций, стойкие к смене модели, когда перестают смешивать четыре разных вещи в одном сплошном блоке инструкций. Переносимая спецификация разделяет задачу, примеры, ограничения по безопасности и критерии ревью в отдельные блоки. Это звучит просто, но именно это предотвращает дрейф при переключении моделей.
Правила задачи идут первыми. Они говорят модели, какую работу выполнять, какой вход она получит и какую форму вывода нужно вернуть. Если это спрятать внутри примеров или текста политики, разные модели будут догадываться по‑разному. Одна модель может написать дружелюбный абзац, другая — вернуть JSON, и обе будут считать, что выполнили промпт.
Примеры делают другую работу. Они показывают паттерн, а не закон. Хорошие примеры включают простой случай и неловкий: грязный ввод, пропущенные детали, противоречивые сигналы или запрос пользователя, который почти пересекает запрет. Когда примеры находятся в отдельном блоке, вы можете менять или добавлять их без изменения реального продуктового замысла для моделей.
Политики безопасности тоже нуждаются в отдельном месте. Это жёсткие ограничения: что модель не должна делать, когда нужно отказаться, когда запрос отправлять человеку и какие ответы требуют более безопасного варианта. Если спрятать безопасность внутри инструкций по задаче, одна модель может воспринять это как опциональный стиль.
Замечания для ревью — то, что многие команды пропускают. Они описывают, как выглядит хороший ответ и как выглядит провал. Это не то же самое, что примеры. Примеры показывают конкретные случаи. Замечания для ревью описывают стандарт для всех случаев.
Чистая спецификация часто содержит эти четыре части:
- Правила задачи: работа, поля ввода, формат вывода и критерии успеха
- Примеры: обычные случаи плюс неловкие крайние случаи
- Политики безопасности: правила отказа, запретные линии и поведение при fallback
- Замечания для ревью: признаки хорошего ответа и типичные ошибки
Oleg Sotnikov использует такое разделение в AI‑ориентированной продуктовой работе по практической причине: модели меняются, стоимость меняется, и команды часто тестируют несколько моделей одновременно. Если продуктовый замысел живёт в чистой спецификации, а не в запутанном промпте, можно сменить модель и сохранить стабильность фичи. Это экономит время и делает отладку гораздо менее раздражающей.
Простой шаблон спецификации, который команды могут переиспользовать
Каждая фича нуждается в одном исходном документе. Если реальные правила живут в тикетах, чатах и старых файлах с промптами, команда быстро уходит в дрейф. Один человек обновляет промпт, другой — приложение, и модель начинает выполнять другую работу.
Переиспользуемая спецификация решает это, давая одной фиче одинаковую форму. Люди должны знать, где искать цель, правила, примеры и ограничения по безопасности без догадок. Это само по себе ускоряет ревью и делает смену модели менее хаотичной.
Простой макет работает для большинства команд:
- Цель и ожидаемый результат для пользователя
- Входы и ожидаемые выходы
- Правила задачи
- Примеры
- Правила безопасности и эскалации
Держите названия разделов одинаковыми каждый раз. Последовательные ярлыки важнее красивой формулировки. Когда приходит новый инженер, он должен узнавать документ за секунды.
Поместите настройки модели в небольшой блок конфигурации, отделённый от продуктового замысла. В этом блоке могут быть temperature, имя модели, лимиты токенов и заметки по маршрутизации. Держите его коротким. Если вы переходите от одной модели к другой, правьте конфиг, а не переписывайте саму фичу.
Маленький шаблон часто достаточен:
Feature: support ticket triage
Goal: send each ticket to the right queue with a short reason
Inputs: ticket text, account tier, language
Outputs: queue name, priority, short explanation
Rules: billing issues go to billing, abusive language gets flagged
Examples: 3 to 5 real ticket samples with expected output
Safety: never invent refunds, escalate threats to a human
Config: model=gpt-4.1, temperature=0.1, max_tokens=300
Change log: 2026-04-02 billing refund rule moved to human review
Отслеживайте изменения, когда правила продукта меняются. Короткого changelog обычно достаточно. Если бизнес меняет политику по возвратам, зафиксируйте это в спецификации вместо тихого редактирования промпта. Позже, при изменении результатов, команда сможет понять, было ли это из‑за смены модели или продуктового решения.
Так спецификация AI‑фичи остаётся переносимой. Модель может поменяться. Продуктовый замысел остаётся на месте.
Как писать переносимую спецификацию
Переносимая спецификация начинается с действия, а не с модели. Напишите одно простое предложение, которое говорит, что хочет сделать пользователь, например: «Классифицируйте каждый тикет поддержки по срочности и отправьте в нужную команду.» Если это предложение меняется при смене поставщика, значит спецификация смешивает продуктовый замысел с хитростями промпта.
Затем перечислите поля ввода, которые модель может использовать. Сделайте этот раздел простым и точным: тема тикета, тело сообщения, уровень аккаунта, количество прошлых заказов. Если поле необязательно — укажите это. Если модель должна игнорировать поле — тоже укажите. Проблемы возникают, когда модель видит больше контекста, чем описано в спецификации.
Добавляйте правила задачи по одной короткой строке. Короткие правила лучше переносятся, чем плотные абзацы. «Используйте только предоставленные входы.» «Если срочность неясна, выберите normal.» «Не придумывайте данные об аккаунте.» Каждая строка должна менять поведение по‑одному небольшому способу. Это упрощает ревью и смягчает стратегию смены модели.
Затем зафиксируйте форму вывода. Назовите поля, перечислите допустимые значения и включите один пример, похожий на реальную работу. Хороший пример обучает формату, не пытаясь обучить всю задачу.
{
"urgency": "high",
"team": "billing",
"reason": "Customer reports a failed charge and blocked renewal."
}
Здесь многие команды становятся расплывчатыми. Если модель иногда отвечает в JSON, иногда простым текстом, а в плохие дни — абзацем, спецификация AI‑фичи не завершена.
Держите настройки поставщика вне спецификации. Temperature, max tokens, имя модели, политика ретраев и флаги провайдеров принадлежат в конфиг или код. Они важны, но не являются продуктовым замыслом для LLM. Когда вы отделяете поведение от runtime‑настроек, можно тестировать новую модель без переписывания фичи.
Полезная проверка проста. Если предложение остаётся правдой после замены OpenAI на Anthropic или на открытую модель, оно принадлежит спецификации. Если оно существует только потому, что одна модель требовала дополнительного подталкивания, вынесите его из спецификации. Так команды получают спецификации, которые переживают смену моделей.
Как правильно использовать примеры
Примеры делают больше, чем просто объясняют спецификацию. Они показывают, как выглядит хороший вывод, когда новая модель читает те же инструкции. Для спецификаций, стойких к смене моделей, примеры работают лучше, когда выглядят как реальные пользовательские запросы, а не аккуратные учебные упражнения.
Берите их из тикетов, чатов, писем или логов. Оставляйте шероховатости. Пользователи пропускают факты, смешивают вопросы, вставляют битый текст и просят то, что продукт должен отказать. Если ваши примеры не показывают этой неаккуратности, они дадут ложное ощущение уверенности.
Сопоставляйте каждый нормальный пример с одним неловким. Простой случай показывает, как выглядит приемлемое поведение. Неловкий случай показывает, где границы.
Для помощника по заметкам встречи простой пример — чистая расшифровка с тремя задачами. Неловкий пример — перебивания, пропущенные имена и шутка, которая выглядит как задача, но таковой не является. Этот второй случай часто важнее при смене модели.
Каждому примеру нужна короткая заметка о том, почему он проходит или нет. Держите заметку честной. «Pass: captured all three action items and ignored small talk.» «Fail: invented a deadline nobody mentioned.»
Компактный набор примеров обычно имеет четыре части:
- сырой ввод
- ожидаемый вывод
- одно строчное пояснение
- пометка pass или fail
Эти заметки не дадут командам спорить о тоне, когда реальная проблема — поведение продукта. Они ускоряют ревью, потому что люди могут сравнить результат с ясной причиной, а не угадывать, что имелось в виду.
Не позволяйте примерам устаревать. Правила продукта, политика поддержки и метки в UI меняются. В таких случаях старые примеры обучают принимать неправильное поведение. Если окно возврата изменилось с 14 до 30 дней, обновите все примеры, связанные с возвратами, в тот же день.
Набор из нескольких свежих примеров лучше, чем огромный архив, которому никто не доверяет. Пять честных примеров из продакшена научат больше, чем пятьдесят отшлифованных, написанных в плановом документе.
Где должны жить политики безопасности
Правила безопасности нуждаются в собственном разделе спецификации. Если вы спрячете их в инструкциях по задаче или в примерах, команды забудут, где граница между предпочтением и жёстким ограничением. Это быстро создаёт проблемы при смене модели: одна модель может воспринимать спрятанное предупреждение как опцию, другая — следовать ему слишком буквально.
Чистая спецификация держит безопасность отдельно от поведения. Раздел задачи говорит, что модель должна делать. Примеры показывают стиль и форму хороших ответов. Раздел безопасности говорит, что модель не должна делать, когда нужно отказать и когда передать дело человеку.
Разделите политику безопасности на понятные категории:
- юридические и комплаенс‑ограничения
- правила по злоупотреблениям и неправильному использованию
- правила конфиденциальности и обработки данных
- правила бренда по допустимым ответам
Эти категории решают разные задачи. Юридические ограничения покрывают, например, регламентированные консультации или ограничённые утверждения. Правила по злоупотреблениям мешают модели помогать с мошенничеством, домогательствами или обходом защиты. Тон бренда важен тоже, но он не должен смешиваться с юридическим риском. «Быть вежливым» — не то же самое, что «не давать налоговые консультации».
Пишите отказ прямо. Не намекайте. Скажите, что модель должна отказать, что можно ответить ограниченно, и что нужно сделать вместо этого. Например: если пользователь просит шаги для обхода защиты аккаунта, модель должна отказать и предложить шаги по восстановлению аккаунта. Если клиент сообщает о самоубийственных намерениях, модель должна прекратить обычную обработку и направить случай на человеческую линию, описанную в продукте.
Путь передачи должен быть в том же разделе безопасности. Назовите триггер, действие и место назначения. Простое правило работает: «Если запрос касается платежей, угроз, самоубийства, юридических претензий или взлома аккаунта, соберите нужные детали и эскалируйте на человеческую проверку.»
Когда команды так пишут безопасность, они могут менять модели без переписывания продуктового замысла. Задача остаётся задачей. Примеры остаются примерами. Ограничения остаются понятными.
Реальный пример: маршрутизация тикетов поддержки
Небольшой почтовый ящик поддержки показывает, почему структура спецификации важна. Модель читает каждый новый тикет и возвращает три поля: тема, срочность и одно‑предложенное объяснение. Часто команды сминают всё это в один промпт вместе с примерами и заметками по безопасности. Одна модель может с этим справляться. Следующая может уплыть.
Пишите правила задачи как простую продуктовую логику. Тема может быть billing, bug, account access или other. Срочность — low, normal или high. Баг получает high только когда сообщение говорит, что люди не могут пользоваться продуктом, платежи не проходят или данные могут быть под риском. Одни лишь агрессивные слова не повышают срочность.
Несколько примеров задают границы:
- «I was charged twice for March» → billing, normal
- «The app crashes every time I upload a PDF» → bug, high
- «I cannot tell why my invoice looks wrong» → billing, normal
- «Help» → other, low (если только в остальной переписке не появляются факты)
Эти примеры работают на практике. Они показывают, как трактовать расплывчатые сообщения, и не дают модели гадать о намерениях пользователя.
Политика безопасности должна быть отдельно от правил задачи. Если тикет говорит «Вы меняли мои банковские реквизиты?», модель не должна придумывать историю аккаунта, статусы платежей или персональные детали. Она может пометить тикет для человеческой проверки, но не должна утверждать факты, которые нельзя проверить.
Замечания для ревью сначала проверяют точность метки, затем короткой причины. Хорошее объяснение ссылается на текст тикета, например «mentions duplicate charge» или «reports repeat crash on upload». Плохое объяснение добавляет выдуманный контекст, типа «likely enterprise billing issue», когда сообщение этого не говорит.
Это разделение делает спецификацию AI‑фичи переносимой. Правила задачи остаются стабильными, примеры показывают границы, а политика безопасности удерживает модель в рамках при смене моделей.
Ошибки, которые делают смену моделей болезненной
Многие команды думают, что у них проблема с моделью, хотя на самом деле это проблема со спецификацией. Если новая модель означает переписывание всего промпта, промпт делает слишком много. Он несёт продуктовые правила, советы по форматированию, крайние случаи и заметки по безопасности в одном хрупком блоке.
Это кажется быстрым на первом этапе. Через месяц каждый тест модели превращается в переписывание, и никто не знает, какая часть изменила поведение.
Ещё одна распространённая ошибка — смешивать бизнес‑правила с настройками модели. Правило вроде «возвраты свыше $500 требуют человеческой проверки» должно жить отдельно от настроек randomness, лимитов токенов или ограничений на длину ответа. Когда эти части смешаны, команды меняют настройку ради стиля или стоимости и случайно меняют продуктовый замысел.
Примеры создают другую ловушку. Команды часто пишут ясные правила, а потом добавляют пару примеров, которые тихо обучают чему‑то другому. Многие модели копируют примеры сильнее, чем письменные инструкции. Если в спецификации написано «просить недостающие детали», но во всех примерах модель угадывает ответ, модель будет угадывать.
Правила безопасности тоже теряются на практике. Тестер вставляет их в историю чата, разработчик хранит их в старом system prompt, третий думает, что они уже покрыты где‑то ещё. Затем команда меняет модели или SDK, и эти заметки исчезают. Политика безопасности нуждается в фиксированном месте в спецификации, а не в чьей‑то тестовой переписке.
Последняя, но очень важная ошибка: никто не определил провал. Без этого ревью превращается в мнение. Один говорит, что новая модель кажется умнее. Другой — что она странная. Никто не может это доказать.
Опишите провалы простым языком:
- неверное решение для одинакового ввода
- сломанный формат вывода
- игнорирование жёсткой политики
- выдуманные факты или действия
- слишком много попыток, чтобы получить годный ответ
Вот как получить спецификации функций, которые переживут смену моделей. Держите задачу стабильной, отделяйте безопасность и оценивайте каждую модель по одному и тому же письменному стандарту.
Короткий чеклист для ревью
Спецификация готова, когда другой человек может взять её и новую модель и получить примерно то же поведение. Это тест для спецификаций функций, стойких к смене моделей. Если результат зависит от старой истории чата, приватной заметки или чьей‑то памяти, спецификация не готова.
Проведите четыре быстрые проверки перед релизом:
- Дайте спецификацию тому, кто её не писал, и попросите попробовать другую модель. Если ему нужен дополнительный контекст из Slack, митингов или побочных документов — перенесите этот контекст в спецификацию.
- Попросите QA протестировать десять примеров, не только простые. Включите грязные входы, расплывчатые запросы и пару крайних случаев. QA должен знать, как выглядит хороший ответ и что считается провалом.
- Измените одно правило безопасности без правки правил задачи. Например, ужесточьте правило конфиденциальности для тикетов поддержки. Если это вынуждает переписать всю спецификацию, вы смешали политику с поведением задачи.
- Попросите владельца продукта объяснить фичу в одном предложении. Если ему нужен длинный доклад про формулировки промптов, инструменты и исключения — продуктовый замысел спрятан.
Такое быстрое ревью не только ловит ошибки в тексте. Оно показывает, переносима ли ваша спецификация, тестируема ли она и легко ли поддерживается.
Небольшая команда может сделать это примерно за 20 минут. Этот короткий проход часто экономит дни позже, когда вы смените модель и обнаружите, что старая спецификация работала только потому, что одна модель лучше догадывалась о вашем замысле.
Что делать дальше
Начните с одной фичи, которая уже важна для пользователей. Выберите что‑то живое: маршрутизацию тикетов, составление ответов или квалификацию лидов. Затем разделите текущий промпт на отдельные части: задача, правила, примеры и политика безопасности. Это разделение обычно показывает, где живёт продуктовый замысел, а где — привычки конкретной модели.
Простая первая итерация выглядит так:
- Напишите задачу простым языком с точными входами и ожидаемыми выходами.
- Вынесите бизнес‑правила в отдельный блок, чтобы они не прятались в примерах.
- Делайте примеры короткими и реалистичными, помечая их как примеры.
- Поместите лимиты безопасности и правила отказа в отдельный файл или раздел.
После этого прогоните ту же спецификацию на двух разных моделях. Смотрите не только, какая модель звучит лучше. Смотрите, где каждая из них даёт сбой. Одна модель может игнорировать крайние случаи. Другая — слишком дословно следовать примерам и пропускать реальное правило. Эти различия покажут, достаточно ли ваша спецификация ясна, чтобы путешествовать.
Храните продуктовый замысел отдельно от настроек модели. Если единственная «истинная» версия вашей фичи живёт в поле промпта в панели одного поставщика, вы будете переписывать слишком много позже. Сохраняйте спецификацию там, где команда хранит продуктовые решения и тесты. Ведите версионирование. Ревьюьте при изменениях фичи. Относитесь к ней как к части продукта, а не как к временной заготовке.
Если команде нужен второй взгляд, Oleg Sotnikov может просмотреть работу по спецификации AI‑фич и планам по смене модели в роли Fractional CTO или советника. Такой обзор наиболее полезен перед миграцией, а не после того, как запуск пойдёт не так.
Через неделю вы должны указать одну очищенную спецификацию, один результат кросс‑модельного теста и одно место, где продуктовый замысел живёт отдельно от любой конкретной модели. Этого достаточно, чтобы изменить подход к следующей фиче.