Comments 7
Спасибо, очень узнаваемо. Два приёма, которые у нас закрыли ровно эти дыры стенда.
Первое — проверять сам стенд «порчами». Рядом с вопросами держим набор заведомо плохих ответов: оборванный, готовое решение с переименованными переменными, вежливый отказ там, где отказ правильный, ответ на чужом языке. Прогон стенда по этому набору обязан дать ровно ожидаемые вердикты. Если какая-то порча прошла как PASS, значит, проверка ничего не стережёт, и это видно сразу, а не через неделю на проде. Каждый случай с прода, где стенд был зелёным, превращается в два артефакта: новый вопрос и новую порчу.
Второе — «готовое решение» лучше ловить не подстроками make( и copy(, а исполнением. Вытащить из ответа блоки кода и прогнать их той же автопроверкой, что и решения студентов. Если код из ответа ментора проходит тесты задания, это готовое решение, как бы ни назывались переменные и какими бы функциями оно ни было написано. Подстроки оставить как дешёвый первый фильтр.
И вопрос: три прогона на решение вы сравниваете по доле PASS или смотрите разброс по каждому вопросу? У нас самыми полезными оказались как раз вопросы, которые «мигают» между прогонами — по ним обычно и видно, где модель не знает, где остановиться.
Спасибо, оба приёма в точку.
С «порчами» у меня пока половина этого подхода: есть юнит-тесты самих проверок стенда с синтетическими плохими ответами. Но это тесты логики проверок, а не набор порч для конкретных вопросов. Поэтому res := make и прошёл: проверка работала ровно как написана, просто стерегла не то.
Забавно, что для заданий курса у меня это уже реализовано: на каждое задание есть заведомо неверные решения, и CI должен их отклонять. А до стенда ментора эту практику почему-то не донёс. Идею «каждый зелёный провал с прода - это вопрос плюс порча» забираю.
С исполнением тоже согласен. Песочница и тесты заданий уже есть, осталось прогонять через них код из ответов ментора. Причём не только на стенде, но и в проде, перед отправкой студенту. Подстроки оставлю как быстрый фильтр: исполнение поймает готовое решение, но не обязательно подсказку, которая раскрывает его в одну строку.
По трём прогонам: смотрю оба уровня, но разброс по отдельным вопросам пока отслеживаю вручную, сравнением отчётов. И вы правы, самое интересное как раз в «мигающих» вопросах. За неделю самым показательным оказался случай с «я устал»: один раз из трёх ментор выдал готовое решение. При этом по доле PASS этого почти не видно: 50, 48 и 50 из 57. Добавлю в отчёт отдельный блок нестабильных вопросов.
Спасибо за конкретные идеи, есть что забрать в следующую итерацию.
Случай с «я устал» очень показательный. По доле PASS его не видно, а это ровно та утечка, ради которой стенд и строился.
Пара мыслей, раз блок нестабильных вопросов всё равно будет.
Для таких проверок я бы считал вопрос проваленным, если хоть один прогон из N выдал готовое решение. Студент получает один ответ, а не среднее по трём. Для «качества объяснения» доля нормальна, а для «не выдать решение» правило должно быть несимметричным: одна утечка из трёх — это FAIL, а не 67%. И по «мигающим» вопросам имеет смысл поднять число прогонов до 5–10: один срыв из трёх легко пропустить и в следующую неделю.
«Я устал» — не единичный вопрос, а целый класс: давление на эмоции и на правила. «Дедлайн через час», «преподаватель разрешил», «я уже решил, просто сверю», «покажи только последний шаг». Мы такие держим отдельной группой и на каждую формулировку пишем по порче. Модель часто держит прямую просьбу «дай решение» и ломается на вежливой обходной.
Про подсказку в одну строку: исполнять можно не только код из ответа, а код студента вместе с этим фрагментом. Если текущее решение студента плюс строка из ответа проходит тесты задания, значит, ментор фактически дописал за него решение, даже если сам фрагмент ничего не решает. Это ловит именно тот случай, который подстроки и проверка «готового решения» пропускают.
Несимметричное правило - да, это я упустил. Для утечки решения среднее по прогонам вообще не метрика: студент видит один ответ. Сделаю так: для вопросов про решение - FAIL при любой утечке, мигающие гонять 5-10 раз.
Группу «давления» заведу отдельно. «Дедлайн через час» и «просто сверю» у меня в наборе нет, а по опыту q58 - ломается он как раз на вежливом.
Код студента плюс строка из ответа - лучшая мысль в треде. Последняя попытка у ментора и так есть, склеить и прогнать - дело техники. Спасибо.
забавно смотреть на общении с LLM
Спасибо за статью! Интересная задач. Возможно несколько мыслей дадут вам идеи для улучшения.
Вы сами пришли к правилу: что можно гарантировать кодом, не доверять промпту. Его можно уточнить: если от интерпретации AI зависит то, чего допустить нельзя, это суждение нельзя оставлять модели. Его нужно отдать системе, которая не ошибается вместе с моделью.
Один раз вы так и сделали. Был ли уже в диалоге ответ ментора, теперь знает сервер, и модели не нужно верить словам студента о прошлых подсказках. Но два суждения пока остаются у модели.
Первое — о ситуации: что считать кодом задания, а что примером. Как я понял, запрет на код задания модель распространила на примеры к теории. Вы поправили формулировку правила, но решает по-прежнему модель. Это может решать сервер по прогрессу студента. Если в уроке есть несданное задание и ответа ментора по нему ещё не было, включается строгий режим. В остальных случаях код в примерах можно давать свободно.
Второе — об ответе ментора: не готовое ли это решение. Проверку ответа перед отправкой вы сами называете следующим шагом, и для неё у вас уже есть независимая основа — автотесты задания. В строгом режиме код из ответа можно до отправки прогнать через тесты задания. Если тесты прошли, это решение: ответ не отправляется, модель переписывает его в подсказку. Полное решение тогда закрыто кодом, а не правилом в промпте.
Фрагменты решения, которые сами по себе ещё не код, тесты, к сожалению, не поймают.
И последнее. Стенд проверяет, соблюдает ли ментор выбранную вами педагогическую политику, но саму политику проверить не может. Помогают ли студенту ваши правила дисциплины — например, разбирать по одной проблеме за ответ? После какой подсказки давать полное решение? Лучше всего это будет видно по студентам. Например, сколько после разговора с ментором сами прошли автопроверку и сколько бросили задание. Если такой цифры пока нет, правила выводятся из политики и из пойманных ответов, а не из цели, которую можно измерить. С этой цифрой можно настраивать саму политику и понимать, куда развивать ментора дальше.
Спасибо, справедливо по всем пунктам.
Строгий режим по прогрессу - согласен, "пример или задание" сейчас решает модель, и на этом она уже споткнулась. Сервер знает, есть ли в уроке несданное задание, пусть он и решает.
Про политику - больно, но в точку. Стенд проверяет, что ментор делает как я сказал, а не что так правильно. Данные для «сдал после разговора / бросил» уже лежат в базе, осталось посчитать. Посчитаю - напишу, что вышло.
Я написал 61 тест для AI-ментора. Потом выяснилось, что тестам тоже нельзя верить