Вы когда-нибудь доверяли ИИ заполнить заявку на грант или магистратуру, а потом ловили себя на мысли, что он мог придумать что-то от себя? Эта проблема знакома многим. Языковые модели пишут убедительно, но не отличают правду от вымысла. Один разработчик нашёл способ это исправить.
Он заметил, что его заявки отклоняют не из-за плохого английского, а потому что он не угадал требования конкретной программы. Ни один помощник не знает этих требований, потому что не читал документ с описанием. Так родилась система Berkas — индонезийское слово «досье». Она читает приглашение к заявке, собирает черновик, но не даёт его отправить, пока в нём нет ни одного неподтверждённого факта.
Как это работает
- Вы загружаете документ с требованиями — PDF, ссылку или фото страницы.
- Модель извлекает дедлайн, лимиты слов, обязательные разделы, стиль написания.
- Вы проверяете и редактируете эти поля. Модель не истина в последней инстанции. Каждое изменение сохраняется рядом с исходным значением, чтобы было видно, кто решил.
- Модель задаёт уточняющие вопросы, но только о том, чего нет в ваших файлах. Уже готовые ответы не заставляет переписывать.
- После интервью она пишет черновик. Если для какого-то факта нет доказательств, вместо предложения вставляется маркер [NEEDS: ...].
- Чекер — обычный Python-скрипт, без единого вызова ИИ — проверяет жёсткие правила. Маркер [NEEDS] считается критической ошибкой. Черновик с таким маркером отправить нельзя.
Собственно, пауза между черновиком и отправкой — и есть суть. Модель может ошибаться при чтении требований, но она не может ошибаться и быть последней инстанцией одновременно. Поэтому требования возвращаются как редактируемые поля, а вердикт о готовности выносит код.
Главное решение: модель воспринимает, код решает
Если спросить языковую модель «этот текст до 500 слов?», она с высокой вероятностью ошибётся, потому что не умеет считать. А если попросить её же проверить, не выдумала ли она что-то, она легко себя «заболтает». Хороший текст убеждает любого читателя, включая самого автора.
Поэтому чекер не содержит ИИ. Это 263 строки Python, которые детерминированно решают, можно ли отправлять. Один и тот же черновик всегда получит один и тот же вердикт. Это единственная часть системы, которую можно покрыть настоящими тестами.
Два бага, которые возникли только в продакшене
Первый баг: при деплое в Cloud Run команда gcloud run deploy --source . читает .gitignore, если нет .gcloudignore. Папка с личной историей была в игноре, и сервис развернулся без данных. Всё работало, но система забыла, для кого пишет. Спасло то, что health-эндпоинт возвращал количество файлов корпуса. Если health check говорит «ок», а продукт пуст — это не health check.
Второй баг: при обращении к Secret Manager в коде передавался словарь вместо строки. Этот путь выполнялся только на Cloud Run, потому что локально ключ читается с диска. Все тесты проходили, но в проде падало с protobuf error ровно на том запросе, ради которого всё создавалось.
Чему это учит
Если вы строите подобную систему, разделяйте творчество и контроль. Генерация — модель, проверка — код.
Используйте маркеры недостающих фактов. Вместо того чтобы модель придумывала правдоподобное, она явно скажет, чего ей не хватает.
Пишите тесты для чекера. Это единственная часть, которую можно тестировать.
И помните: «кнопка неактивна» — это утверждение о браузере, а «POST /api/send возвращает 409» — о системе. Проверяйте то, что действительно важно.
Трудным было не написание текстов, а решение, что системе запрещено делать, и как сделать, чтобы это решение было трудно отменить.
Комментарии (0)
Войдите, чтобы комментировать.
Пока нет комментариев. Будьте первым.