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

Почему правила внутри модели создают проблемы
Когда команда прячет бизнес-правила внутри промптов, систему становится трудно менять и еще труднее ей доверять. Модель в итоге выполняет две разные задачи: разбирает неаккуратный человеческий ввод и одновременно решает, какова политика компании. Сначала это кажется удобным. Потом превращается в постоянную поддержку.
Первая проблема проста. Люди забывают, где живут правила. Лимит расходов, проверка прав доступа или правило согласования добавляется в ходе правки промпта и потом тонет среди примеров, инструкций и крайних случаев. Через несколько месяцев никто уже не помнит, живет ли правило «$500 требует согласования» в приложении, в промпте или сразу в обоих местах.
Небольшие изменения политики очень быстро начинают раздражать. Если финансовый отдел поднимает лимит до $750, кому-то приходится править текст промпта, тестировать несколько сценариев и надеяться, что больше ничего не сломалось. Это плохая сделка. Изменение числа должно ощущаться как обновление настройки, а не как мини-переобучение.
Еще сложнее становится объяснять решения. Если система одобряет один запрос и отклоняет другой, людям нужна причина, которую можно прочитать. Им не нужно объяснение вроде «модель так поняла промпт». Им нужен понятный ответ: сумма выше лимита, нет согласования, неверный отдел, срок действия разрешения истек.
Разные команды только усугубляют проблему. Продажи могут хотеть гибкие скидки. Финансы — строгие шаги согласования. HR — одно правило для подрядчиков и другое для сотрудников. Если все это живет в одном промпте, каждое новое исключение делает поведение еще менее понятным.
Одни и те же проблемы повторяются снова и снова:
- разные промпты в итоге содержат разные версии одного и того же правила
- мелкие правки политики слишком долго тестировать
- служба поддержки не может внятно объяснить решения
- отделы спорят о поведении, которое никто не видит напрямую
Лучшее разделение довольно простое. Пусть модель оценивает размытый ввод, например действительно ли заметка звучит срочно или соответствует ли чек категории. Пусть код отвечает за пороги, права доступа и согласования. Тогда команды смогут менять политику, не переписывая каждый раз поведение модели, когда кто-то меняет число или добавляет новый путь согласования.
Что должна делать модель
Дайте модели то, с чем людям трудно справляться последовательно: читать неаккуратный текст, вытаскивать сигнал из шума и объяснять необычные случаи простыми словами. Модель хорошо превращает сырой запрос в понятный набор фактов, которые код сможет использовать позже.
Люди редко пишут запросы аккуратно. Они вставляют цепочки писем, забывают даты, смешивают мнения с фактами и используют расплывчатые слова вроде «скоро» или «небольшая покупка». Модель может разобрать этот хаос и извлечь важные части: сумму, человека, причину, время и все, чего не хватает.
Простой пример помогает лучше всего. Если кто-то пишет: «Мне пришлось забронировать отель в последний момент рядом с офисом клиента, потому что мой рейс изменился, а более дешевые варианты уже закончились», модель может выделить вероятные факты, отметить, что бронь была срочной, и пометить, что цена, возможно, требует дополнительной проверки. Это хорошее применение суждения модели. Она понимает ситуацию лучше, чем жесткая форма.
Модель помогает и тогда, когда ввод неясный. Она может сравнить возможные трактовки и сказать, какая кажется более вероятной. Если в запросе написано «ужин команды после мероприятия», но не сказано, присутствовали ли клиенты, модель может ответить: «Это может считаться клиентским мероприятием, но я не уверен: список участников отсутствует». Такая пометка о неопределенности полезна.
Когда кейс должен проверить человек, модель должна написать короткое резюме, которое экономит время. Хорошее резюме включает найденные факты, то, что выглядит необычно или неполно, почему кейс может требовать проверки и насколько модель уверена в своей трактовке.
Последний пункт особенно важен. Модель не должна притягивать за уши аккуратный ответ, если ввод этого не позволяет. Если детали противоречат друг другу или в тексте есть пробел, она должна сказать об этом прямо. «Не уверен» лучше, чем уверенная догадка, которая отправит запрос не туда.
Что должен делать код
Код должен владеть каждой жесткой границей. Модель может прочитать запрос, кратко его описать и предложить рекомендацию. А вот код должен решать, кто вообще может действовать, как далеко он может зайти и кто должен одобрить результат.
Начните с проверки прав доступа. Код должен проверить пользователя, роль, команду и состояние аккаунта еще до того, как что-то произойдет. Если сотрудник поддержки может оформлять возвраты только до определенной суммы, код должен соблюдать это правило всегда. Не важно, насколько уверенно звучит модель.
Лимиты денег и пороги оценок тоже должны жить вне модели. Держите их в конфиге, таблице базы данных или небольшом сервисе политики. Тогда команда сможет поднять лимит возврата с $200 до $300 или изменить порог оценки мошенничества с 0.70 до 0.82, не трогая промпты.
В большинстве систем код должен хорошо делать четыре вещи: проверять права, сравнивать запрос с числовыми лимитами, направлять неудачные случаи нужному согласующему и сохранять правило, входные данные и результат для последующей проверки.
Правила согласования должны оставаться явными. Не просите модель угадывать, кто кажется достаточно старшим, чтобы одобрить покупку или разблокировать данные клиента. Код должен искать нужного человека по оргструктуре, списку владельцев бюджета или настройкам аккаунта. Так согласования остаются одинаковыми, даже если команды меняются.
Не менее важно фиксировать итоговое правило, чем применять его. Сохраняйте точную версию политики, примененный порог, пользователя, который подал запрос, и причину, по которой действие прошло или было заблокировано. Когда кто-то спросит: «Почему это остановили?», ваша команда должна ответить одной понятной строкой из лога, а не расплывчатым пересказом модели.
Такое разделение делает политику безопаснее и проще для обновления. Модель занимается оценкой. Код занимается проверками прав доступа, порогами, согласованиями и журналом аудита за финальным действием.
Разделение, которое ваша команда реально внедрит
Начните с одного процесса, где уже есть понятные бизнес-ограничения. Согласование расходов и возвраты — хорошие первые кандидаты, потому что правила легко назвать, проверить и обсудить.
Запишите эти правила как обычные условия в коде. Оставьте их скучными. Если сумма меньше заданного лимита, одобрите. Если чека нет, отклоните. Если запрос подает подрядчик, отправьте его менеджеру.
Небольшой набор правил может выглядеть так:
- меньше $200 при наличии действительного чека: одобрить автоматически
- от $200 до $1,000: согласование менеджера
- больше $1,000: согласование финансового отдела
- без чека: отклонить
- дублирующийся номер чека: оставить на проверку
Затем дайте модели более узкую задачу. Попросите ее прочитать запрос и вернуть структурированные факты, а не финальное решение. Для расходной заявки это могут быть название поставщика, сумма, валюта, дата, наличие чека, вероятная категория и выглядит ли чек размытым или неполным.
Процесс простой. Модель извлекает факты в JSON. Ваше приложение проверяет эти факты по правилам в коде. Пользователь получает результат вроде «одобрено», «нужно согласование менеджера» или «отклонено — отсутствует чек».
Логируйте обе стороны каждый раз. Сохраняйте вывод модели, показатель уверенности, если вы его используете, и точное правило, которое сработало. Когда финансовый отдел спросит, почему заявку заблокировали, вы должны уметь показать что-то конкретное вроде Rule EXP-04 rejected this because no receipt was detected.
Этот лог важнее, чем ожидают команды. Когда политика меняется, вы обновляете правило, а не поведение модели. Если лимит автоодобрения смещается с $200 до $300, вы меняете одно значение и прогоняете тесты заново. Вам не нужно переписывать промпты и надеяться, что модель начнет вести себя иначе.
Согласование расходов как реалистичный пример
Мария подает расход после поездки к клиенту. Она загружает чек из отеля, вводит «$184.50» и добавляет короткую заметку: «Такси из аэропорта и одна ночь рядом с офисом клиента».
У модели узкая задача. Она читает заметку и чек, а затем превращает сырой ввод в структурированные поля. Она может извлечь сумму, пометить расход как командировочный, заметить, что в нем смешаны такси и проживание в отеле, и указать, что из заметки не ясно, какому именно клиентскому встрече была посвящена поездка.
Если изображение чека размыто или валюта неочевидна, модель может сказать и это. Это полезная оценка. Это не политика.
Потом вступает в дело код. Приложение может проверить, имеет ли Мария право подавать командировочные расходы в этом отделе, не вышла ли она за пределы бюджета, требует ли политика компании чек выше определенной суммы и нужны ли расходы сверх порога согласования менеджера.
Если заявка ниже лимита и правило по чеку соблюдено, система одобряет ее сразу. Если сумма превышает порог, система отправляет ее менеджеру Марии. Если чека нет, система сначала попросит его, а уже потом начнет проверку.
Вот как правила согласования в коде выглядят на практике. Модель помогает интерпретировать отправку. Код применяет права доступа, пороги и маршрутизацию.
Такое разделение особенно полезно, когда финансовый отдел меняет политику. Допустим, компания поднимает лимит автоодобрения с $200 до $300 перед загруженным конференц-сезоном. Инженер меняет одно значение в конфиге или одно правило в коде, и поток начинает работать по-новому уже на следующем запросе.
Переписывать промпты не нужно. Модель по-прежнему извлекает сумму, категорию и недостающие детали так же, как вчера.
Команды обычно хотят этого, потому что политика часто меняется. Бюджеты сдвигаются. Роли меняются. Правила по чекам ужесточаются во время аудитов, а потом снова ослабляются. Когда такие решения живут в коде, финансовый отдел может попросить изменение без правок логики модели, а система остается предсказуемой.
Типичные ошибки команд
Самая большая ошибка — позволять модели самой одобрять исключения. Модель может читать контекст, замечать странные паттерны и объяснять, почему запрос выглядит рискованным. Но она не должна решать, что жесткое правило вдруг перестало действовать.
Еще одна частая проблема — прятать лимиты согласования в промптах. В одном промпте написано, что расходы выше $500 требуют согласования. В другом после быстрой правки — уже $750. Через месяц никто не помнит, какой вариант соответствует реальной политике.
Команды также смешивают жесткие лимиты с расплывчатым языком. Они пишут рядом со строгими правилами о деньгах, доступе или безопасности формулировки вроде «обычно разрешать» или «одобрить, если это кажется разумным». Это оставляет модели пространство для импровизации. Если бизнес-правило фиксированное, пишите его как фиксированное. Если модель не уверена, пусть вернет «нужно проверить» и остановится.
Обычно эту проблему легко заметить:
- один и тот же запрос в двух инструментах получает разные решения
- служба поддержки не может объяснить, почему прошло исключение
- обновление политики означает правку промптов в нескольких местах
- в логах видно мнение модели, но не видно версию правила, на которой было принято решение
Еще одна ошибка — пропускать безопасный fallback. Модели иногда видят неполные данные, расплывчатые формулировки или необычные случаи. Когда это происходит, система должна остановиться, запросить недостающие детали или отправить запрос человеку. Низкая уверенность — это не разрешение гадать.
Версионирование тоже важно. Политика меняется постоянно. Финансы поднимают порог. Юристы ужесточают доступ. Стартап на один квартал режет необязательные траты. Если менять правила без версий, вы теряете возможность ответить на простой вопрос: какая именно политика приняла это решение?
Часто это одна из первых чисток, к которой подталкивает опытный Fractional CTO. Перенесите пороги, права доступа и пути согласования в код или в хранилище правил. Пусть модель оценивает факты. Пусть система применяет правила.
Сделайте изменения политики простыми
Большинство изменений политики невелики. Команда поднимает лимит возврата, добавляет второго согласующего для одного отдела или запрещает одной роли делать определенное действие. Такие изменения должны занимать минуты, а не требовать переписывания модели.
Держите лимиты, проверки прав доступа и правила согласования в коде, который читает их из файла конфигурации или из административного интерфейса. Тогда модель может продолжать делать ту же работу: классифицировать, кратко резюмировать, сравнивать или помечать крайние случаи. Команда меняет политику, редактируя число, роль или условие.
Названия важнее, чем многие думают. Если правило называется rule_17, люди будут гадать. Если оно называется «Требуется согласование менеджера выше $750» или «Подрядчики не могут утверждать платежи поставщикам», его смысл понятен сразу.
Понятные названия помогают во время проверок, поддержки, аудитов и передачи работы. Люди быстрее замечают плохое изменение, могут объяснить решение простыми словами и понимают историю правила без опоры на внутренние знания команды.
Нужна и простая история для каждого изменения правила. Показывайте, кто изменил правило, когда это произошло и каким было прежнее значение. Если финансовый отдел поднимает порог в понедельник, а проблемы начинаются во вторник, команда должна находить это изменение за секунды.
Журнал изменений не обязан быть сложным. Подойдет небольшой административный лог или история Git, если люди действительно ими пользуются. Главное, чтобы запись было легко читать и трудно потерять.
Держите проверку политики отдельно от проверки модели. Когда кто-то меняет лимит согласования, ревьюеры должны смотреть на бизнес-решение, а не заново открывать промпт. Когда кто-то обновляет поведение модели, ревьюеры должны проверять качество оценки, а не каждое правило компании.
Такое разделение экономит время и убирает путаницу. Оно еще и снижает риск. Команды могут часто менять правила, как им и нужно, а поведение модели остается достаточно стабильным для нормального тестирования.
Проверки перед релизом
Релиз не готов, если изменение политики все еще требует хирургии промпта. Перед выпуском попробуйте одно маленькое изменение: поднимите лимит расходов, измените роль пользователя или добавьте один дополнительный шаг согласования. Если кому-то приходится менять инструкции модели вместо кода или конфига, вы все еще смешиваете оценку и политику.
Короткая проверка перед релизом ловит большинство проблем:
- измените один лимит в конфиге и прогоните тот же запрос еще раз — результат должен поменяться потому, что поменялся код
- прочитайте каждое решение одним предложением — «Одобрено, потому что сумма ниже лимита, а у инициатора есть права менеджера» звучит ясно
- заставьте модель выдать неуверенный ответ — система должна остановить действие, запросить проверку или выбрать более строгий путь
- проверьте все важные ветки согласования, включая отклонение, эскалацию, повторную попытку и случаи с недостающими данными
Скучные проверки здесь лучше умных. Модель может оценить, выглядит ли чек подозрительно, неполон ли запрос или опасно ли звучит сообщение. Код должен решать, кто может одобрить, какой лимит действует и что делать, когда модель не уверена.
Когда такое разделение сделано хорошо, обновления политики занимают минуты, результаты остаются объяснимыми, а ошибки проявляются в тестировании, а не в продакшене.
Что делать дальше
Выберите один рабочий процесс с понятными шагами согласования и небольшим радиусом последствий, если что-то пойдет не так. Согласование расходов подходит хорошо. Возвраты, запросы на скидку и запросы на доступ тоже подходят, потому что большинство команд уже понимают, кто и что может одобрять.
Затем сначала вытащите правила из промпта. Перенесите пороги, проверки прав доступа и маршруты согласования в код или конфигурацию, даже если остальная часть процесса пока еще кажется ручной. Так у вас будет более безопасная стартовая точка: модель сможет оценивать ситуацию, а система по-прежнему будет решать, кто имеет право действовать.
Практичный первый шаг прост:
- выберите один процесс с описанным путем от запроса до согласования
- вынесите лимиты, роли и пути эскалации за пределы модели
- добавьте логи для каждой рекомендации, одобрения, отклонения и переопределения
- оставьте участие человека, пока логи не станут скучными и предсказуемыми
Логи важнее, чем кажется многим командам. Если модель советует одобрить запрос на $480, а ваш код блокирует все, что выше $300, вам нужно зафиксировать это расхождение. Через неделю-другую закономерности проявятся быстро. Вы увидите, где модели нужны более точные инструкции, где сотрудники обходят процесс и где сама политика написана неаккуратно.
Не автоматизируйте пять процессов сразу. Начните с одного, приведите его в порядок и только потом переносите подход на следующий кейс. Команды, которые спешат, обычно начинают спорить об исключениях уже в продакшене, а это очень плохое место для написания политики.
Если вам нужна помощь с проектированием такого разделения, Oleg at oleg.is работает как Fractional CTO и startup advisor по AI-augmented development workflows. Быстрый разбор границы между оценкой модели и политикой на уровне кода может сэкономить много переделок позже.
Часто задаваемые вопросы
Почему плохая идея держать правила согласования внутри промпта?
Потому что промпты прячут политику в месте, которое со временем начинает расходиться с реальностью. Лимит расходов или шаг согласования должны жить в коде или конфиге, где команда может поменять одно значение, протестировать его и точно понимать, что изменилось.
Что должна делать модель в этой схеме?
Пусть она читает неструктурированный ввод и превращает его в факты, которые сможет использовать приложение. Модель может извлекать суммы, даты, категории, недостающие детали и помечать, когда в запросе не хватает уверенности.
Какие правила должны жить в коде, а не в модели?
Жесткие границы должны быть в коде. Это включает права доступа, лимиты расходов, маршрутизацию согласования, проверки ролей, проверки на дубли и финальное решение разрешить или заблокировать действие.
С чего начать, если у нас уже смешаны правила и промпты?
Начните с одного рабочего процесса с простыми ограничениями, например с расходов или возвратов. Оставьте модели только извлечение фактов, а пороги и маршруты согласования сначала перенесите в код или конфиг.
Что должно происходить, когда модель не уверена?
Нужно остановить действие и выбрать более строгий путь. Попросите недостающие детали или отправьте кейс человеку, а не позволяйте модели угадывать.
Как логировать решения, чтобы поддержку и финансы было легко объяснять?
Сохраняйте обе части решения. Записывайте вывод модели, любой сигнал уверенности, который вы используете, название или версию правила, инициатора и финальный результат с причиной.
Где должны храниться пороги и лимиты?
Храните их в конфиге, таблице базы данных или небольшом сервисе политики. Так вы сможете поменять $200 на $300 без переписывания промптов и без изменения того, как модель читает запросы.
Может ли модель сама одобрять исключения?
Нет. Пусть модель замечает странный случай и объясняет, почему он выглядит необычно, но решение о том, допускает ли правило исключение и кто его должен одобрить, пусть принимает код.
Как проверить эту границу перед релизом?
Попробуйте одно небольшое изменение политики перед релизом, например поднимите лимит или добавьте дополнительный шаг согласования. Если вашей команде приходится править промпт, чтобы это сработало, разделение все еще неверное.
Какой рабочий процесс стоит разделить первым?
Выберите рабочий процесс с небольшим радиусом последствий и понятными правилами. Согласование расходов, возвраты, запросы на скидку и запросы на доступ обычно подходят, потому что команды уже знают, кто и что может одобрять.