Вчера (27 ноября) Хабр устроил «Авторский огонёк».
Было очень интересно, и меня задело одно утверждение докладчика. Оно заключалось в том, что ИИ может помочь писать простые куски кода, но не работает со сложными вещами. Таким образом, большие языковые модели уподобляются программисту-джуну.
Решил с утра накатать об этом статью, опираясь на свои знания и опыт в вычислительной математике (в прошлом занимался моделированием, а последние несколько лет преподаю вычислительную математику в МФТИ), оцените, что получилось.
Я думаю, что это главный миф вайб-кодинга. Всё ровно наоборот — ИИ хорошо пишет довольно сложные вещи и достает важную информацию, которую самостоятельно трудно найти. Но путается как раз таки в элементарных вещах. Это джун наоборот.
Проблема в том, что это опасная иллюзия и я вам сейчас наглядно объясню, почему, и чем это может быть опасно. Заваривайте кофе и готовьтесь к разоблачению, которое, может быть, в будущем спасет ваши миллионы, карьеру или даже человеческие жизни.
Вся суть.
LLM вроде ChatGPT или Claude как раз очень неплохо имитируют «сложное» — архитектуру, паттерны, dataclass’ы, даже приличные разбиения на модули. А вот на «простом» — базовая математика, циклы, численные методы, физика — они стабильно делают такие ошибки, после которых хоть сто раз рисуй UML, результат всё равно мусор.
Чтобы не быть голословным, разберу конкретный, живой пример: симуляцию полёта сверхзвуковой баллистической ракеты, которую мне сгенерировал ИИ. Полный Jupyter-ноутбук с кодом лежит в файле, на который я дам ссылку в конце. В статью весь этот километровый код, понятно, не лезет, поэтому здесь будут только характерные фрагменты.
Конечно, впечатляет скорость, с которой ИИ создает такой большой код. Но мы здесь разберем, почему порой будет проще написать всё самому, чем подчищать потом за ним.
И да, важный момент: свежая платная версия ChatGPT, если попросить её поревьюить этот код, действительно находит часть проблем — про метод Эйлера, шаг интегрирования и прочие «взрослые» вещи. Но остаётся вполне довольна местами, где лежат куда более приземлённые, но фатальные баги. О них и пойдёт речь.

Эффект «ООО Рога и Код»
Чтобы было наглядно, введём термин: эффект «ООО Рога и Код».
Представьте условную аутсорс-контору с таким названием. Они умеют делать одну вещь блестяще: писать код, который очень убедительно выглядит как настоящий.
Открываешь репозиторий — красота. Есть слои core, domain, infrastructure. В коде мелькают UserRepository, PaymentService, Factory, Strategy, иногда даже AggregateRoot. В файле на триста строк ни одного goto и одинокий TODO. Менеджер счастлив, заказчик спокоен, архитектор аккуратно двигает квадратики в Miro.
А потом система выходит в прод. Под нагрузкой всплывает квадратичная сложность на горячем пути. Деньги где-то теряют копейки, потому что «ну я сделал double — а что такого». Retry реализован через вечный цикл и sleep(100) в надежде на магию.
Фасад — сеньорский. Начинка — типичный студент, которому дали книгу по паттернам и не дали курса по алгоритмам и системному анализу. Вот LLM сегодня — это ровно такой «ООО Рога и Код на стероидах». Очень убедительная форма и совершенно случайное качество содержания там, где от тебя требуются не слова, а точные числа.
Пример из личного опыта
Я давно занимаюсь репетиторством и у меня помимо школьников бывают самые разные клиенты. Несколько лет назад ко мне обратились сотрудники из одной типичной конторы, которая занимается в России импортозамещением софта. Они создавали САПР для расчетов и проектирования соединения труб. Конкретно те, кто обратились ко мне — занимались созданием импортозамещенной библиотеки вычислительной геометрии для такого САПР. Они мне давали задачи по школьной планиметрии, по 3000 рублей за задачу, которые я легко решал и полностью оформлял за 15 минут.
Оказалось, что эти разработчики САПР:
совершенно не владеют не только матрицами и производными, но и основами школьной геометрии за 7-8 класс
о вычислительной устойчивости алгоритмов они даже ничего не слышали
не были в курсе, что вообще-то всё, что они делают последние полгода, можно скачать с открытым кодом, нормально написанное в интернете. Когда им показал — сказали, что такое не пойдет, потому что им это непонятно, на работе у них сразу поймут, что они код откуда-то скачали, а не сами написали, и тогда не будут им платить. А главное, надо скрывать от своего начальство, что они делают то, что можно скачать из интернета, иначе же их просто сократят за бесполезностью.
за полгода написали очень много кода, который будет валиться на очевидных тестах. Но говорят, что у них на работе специалисты составляют тесты, и все эти тесты их код успешно прошел, так что проблем никаких нет. Интересно посмотреть на тех, кто это составляет, думаю так плохо составлять тесты не сможет даже LLM.
Я хотел принести пользу, объяснить им про то, что важны не только формулы, но и устойчивость вычислительного алгоритма, но они даже не хотели слышать — код же проходит все тесты, что им дают, зачем что-то усложнять? А такие «высокие абстракции», как число обусловленности, для них было чем-то, во что они даже не хотели вникать: очень страшно, непонятно, и на практике им было совсем не нужно.
Думаю, на рынке много таких фирм, которые можно назвать «ООО Рога и Код».
Более того, до того, как стать репетитором (то есть до 2014-го года), я работал в ГК BTLABS "Базовые технологии". Мы получали финансирование с проектов, так или иначе связанных с созданием вооружений принципиально нового типа: роев БПЛА, которые корректируют работу артиллерии. Еще в 2012-м году об этом много говорили и какой-то высокий военный чин нам даже в фирме рассказывал, что с помощью этого нового оружия Россия сможет выиграть неизбежную войну с НАТО в 2020-х — 2030-х годах. Я проработал там всего полтора года, успел позаниматься проектированием механических переключателей для СВЧ-линий (замена ими транзисторных повысит устойчивость БПЛА против РЭБ) и антенн.
Насмотрелся достаточно.
Хотя бы того, что в фирме работали в основном студенты МФТИ, и не было никого, кто работал бы по специальности (сам работал там с конца 5-го курса МФТИ, моя специальность магистратуры — физика фундаментальных взаимодействий). Всё потому, что брали на работу людей совсем без опыта и платили очень мало. Собственно, я потому оттуда и ушел: готовить детей к ОГЭ и ЕГЭ намного прибыльнее, даже если ты начинающий репетитор и берешь по минимальным ставкам на выезде, как я в 2014-м году.
Или хотя бы того, что практически все другие участники этого рынка госзаказов — всякие фирмы типа «ООО Рога и Код», на фоне которых даже мы выглядели крутыми экспертами. Просто потому, что всё-таки студенты МФТИ, знали школьную математику, вузовскую, разбирались в физике, в вычматах, код писали сами (а не копировали из интернета). А в других фирмах работали в основном люди, не обладающие даже базовыми знаниями.
Теперь перейдем к разбору на моем примере работы ИИ, который нагенерировал с утра.
Сверхзвуковая ракета: что сгенерировал ИИ
Я решил сделать с помощью LLM (использовал Gemini и Claude) для решения задачи о моделировании полета ракеты в атмосфере на активном сверхзвуковом участке.
Сначала обсудил с ИИ, как вообще это можно моделировать — он позволяет писать модели разной уровни детализации и сложности. Остановился на следующей постановке задачи (можно сделать более сложную, но для иллюстрации к статье на Хабре достаточно этой).
Есть атмосфера с высотой, температурой, давлением, плотностью, скоростью звука. Есть табличные коэффициенты аэродинамического сопротивления и подъёмной силы как функции числа Маха. Есть тяга двигателя, зависящая от расхода топлива и перепада давлений. Масса ракеты убывает линейно во времени. Требуется численно интегрировать систему ОДУ для скорости, угла траектории, координат, угловой скорости и угла тангажа. Желательно сравнить несколько методов интегрирования. На выходе — графики траектории, скоростей, углов, параметров атмосферы.
Могу сказать, что я не генерировал это за один раз, а действовал как опытный вайбкодер (а некоторый опыт у меня имеется). Разбивал задачу на маленькие шаги, каждый шаг перепроверял и тестил с помощью LLM, задавал уточняющие вопросы, просил ссылки и откуда он берет таблицы (кое-что поправлял), постепенно довел до чего-то работающего.
В итоге задача была решена. Внутри — всё, как положено в хорошей курсовой. А еще получились подробные блок-схемы и даже интерактивные диаграммы (Сlaude умеет).

Это очень удобно - есть не только код в ноутбуке, но и вот такая веб-страница, скриншот которой привел, на которой можно нажимать на кнопочки и открывать кусочки кода.
Тут есть функции atm_T, atm_p, atm_rho, atm_a, которые считают параметры стандартной атмосферы по геопотенциальной высоте.
Есть табличные массивы Mtable, Cxa, C_ya_alpha и интерполяция коэффициентов через interp1d, параболическую и линейную аппроксимацию.
Есть расчёт динамического давления q = 0.5 rho V**2, силы сопротивления и подъёмной силы, момента относительно оси. Есть чистенькие функции compute_dot_V, compute_dot_theta_c, compute_dot_x_c, compute_dot_y_c, compute_dot_omega_z, compute_dot_vartheta, каждая отвечает за свою компоненту системы.
Всё это упаковано в три метода интегрирования. Например, метод Эйлера реализован так:
def euler_method(f, y0, t0, t_end, h, params):
n = int(0.01 + (t_end - t0) / h) # для ровного значения шага
t_values = np.linspace(t0, t_end, n + 1)
y_values = np.zeros((n + 1, len(y0)))
y_values[0] = y0
for i in range(n):
y_values[i + 1] = y_values[i] + h * np.array(
[f(t_values[i], y_values[i], params) for f in [f1, f2, f3, f4, f5, f6]]
)
return t_values, y_values
Есть модифицированный Эйлер и Рунге–Кутта с аналогичным стилем. Внизу — пачка графиков: скорости от времени, высоты от дальности, углов, Mach-числа и всего подряд.
Если вы менеджер, заказчик или просто смотрите глазами без привычки разбирать численные методы, вам, скорее всего, покажется, что это вполне приличная инженерная работа. Тем более код не матчится с типичной «копипастой из Stack Overflow» — явная атмосфера, вручную вбитые таблицы, аналитические формулы, аккуратные подписи.
И вот здесь начинается самое интересное: ищем баги в этом коде. Отключаем «вайбкодера» (который опирается на составление промптов, уточнений и метод обратной связи) и включаем специалиста по вычислительной математике.
Что смогла найти сама LLM
Чтобы картинка была честной: я дал этот же ноутбук свежей платной версии ChatGPT и попросил: «разбери, что не так». На верхнем уровне она справилась неплохо.
Она обратила внимание, что явный метод Эйлера для жёсткой нелинейной системы, где аэродинамическое сопротивление растёт как ( ), а атмосфера сильно меняется по высоте, — решение, мягко говоря, рискованное.
Она сказала, что для устойчивости нужно либо брать очень маленький шаг h, либо переходить на более устойчивые методы, либо вообще использовать solve_ivp с адаптивным шагом. Она заметила, что шаг h = 0.1 секунды для такого рода задачи выглядит подозрительно крупным и что на низких высотах возможна потеря устойчивости.
То есть на уровне общих рассуждений про численные методы ИИ уже что-то «понимает». По крайней мере, воспроизводит правильные мысли из хорошего учебника. Более того, обращу внимание на то, что найденные ошибки здесь далеко не самые простые ошибки.
Но когда дело доходит до банальной машинной арифметики, индексов, типов и конкретных строк, картина резко портится. Дальше — то, к чему она не придралась вообще, а стоило бы. Для чистоты эксперимента я спрашивал о наличии других ошибок ее несколько раз, но она так больше ничего и не нашла — а ошибок этих много и они в элементарных вещах.
Ошибка с int() и количеством шагов
Давайте посмотрим на строку:
n = int(0.01 + (t_end - t0) / h)
На первый взгляд, это известный «трюк»: к результату деления добавляют небольшую константу, чтобы компенсировать ошибки представления в float, а потом берут int, который играет роль floor. Так многие писали в учебных задачах ещё до появления нормальных библиотек.
Посмотрим на реальные числа, которые подставляются в задаче. В ноутбуке задаётся, например:
t0 = 0.0
t_end = 4.23
h = 0.1
Машинное представление 4.23 / 0.1 — это не аккуратные 42.3, а нечто вроде 42.300000000000004. После прибавления 0.01 получаем 42.31000000000001. Приводим к int и внезапно получаем 42.
Дальше строится сетка времени:
t_values = np.linspace(t0, t_end, n + 1)
То есть np.linspace(0.0, 4.23, 43) даёт массив от 0.0 до 4.23 с шагом примерно 0.100714.... При этом интегрирование в цикле идёт с шагом именно h = 0.1. Состояние y_values[i] соответствует моменту времени t = t0 + i * h, а рисуем мы график по t_values, который пробегает совсем другую сетку.
В результате последняя точка по t_values — это 4.23 секунды, а физически состояние, которое ей соответствует, — это 4.2 секунды (42 шага по 0.1).

Мелкая разница, но систематическая. В учебной игрушке — ладно. В реальной задаче, где вы, например, хотите анализировать значения именно в момент выключения двигателя, это уже серьёзная рассинхронизация. И вот эту вещь платный ChatGPT пропустил. Про устойчивость метода он говорил охотно, про float и int() — нет.
В этом месте очень хорошо видно, в чём проблема. Математически «сложный» текст он воспроизводит. «Скучную» арифметику с плавающей точкой — нет.
Несогласованная временная сетка
Ошибка с int() заводит нас в следующую. Временная сетка создаётся через np.linspace, а интегрирование идёт фиксированным шагом h. Идея, судя по коду, была в том, чтобы получить ровное количество шагов и аккуратно вывести значения на график.
Правильная постановка выглядела бы так: либо мы вообще не храним t_values, а в каждой правой части считаем время как t0 + i h, либо, если уж хотим массив, строим сетку прямым циклом t[i] = t0 + i h и никуда её не «натягиваем».
В коде же получается гибрид: считаем значения в одних моментах времени, рисуем их как будто в других. Формально разница в доли процента.
Но важно то, что она появляется не как осознанная аппроксимация, а как побочный эффект неудачной манипуляции с int() и linspace. Такие ошибки потом долго ищут по логам (и порой даже не находят!), если внезапно что-то не сходится с экспериментом.
Псевдоабстракция: параметр f, который не работает
Дальше по коду — метод Эйлера и задекларированная «универсальность»:
def euler_method(f, y0, t0, t_end, h, params):
...
for i in range(n):
y_values[i + 1] = y_values[i] + h * np.array(
[f(t_values[i], y_values[i], params) for f in [f1, f2, f3, f4, f5, f6]]
)
Сигнатура намекает, что в euler_method можно подставить любую систему ОДУ через аргумент f. Внутри же этот f немедленно затеняется в списковом выражении for f in [f1, f2, f3, f4, f5, f6]. В результате реальная система жёстко зашита в глобальные f1...f6, а параметр f — бутафория, которая никогда не используется.
На архитектурном уровне это важный симптом. LLM видит большое количество примеров, где численный метод принимает функцию правых частей, и копирует этот паттерн. Но проверить, что аргумент действительно участвует в вычислении, она не в состоянии. Получается псевдоабстракция: выглядит красивым и гибким, а внутри всё прибито к конкретной глобальной реализации.
Тихая потеря точности в таблицах и псевдоокругления
Во фрагменте кода, который готовит табличные данные для вывода, встречается фокус:
P_table_01 = np.array([0.0] * L_01 )
...
for i in range(len(y_euler_01)):
massa_table_01[i] = massa(m_0, dot_m, t_euler[i])
P_table_01[i] = calculate_P(calculate_P0(dot_m), S_a, atm_p(0), atm_p(method[i, 3]))
P_table_01[i] = int((P_table_01 // 1)[i] + ((P_table_01[i] % 1) // 0.5))
На первый взгляд, LLM хотел получить в таблице аккуратные значения тяги, округлённые до 0.5 Н. Но механизм выбран очень странный.
Во-первых, там, где в исходном варианте массив создавался через [0], numpy делал его целочисленным, а затем в него записывались результаты calculate_P, то есть вещественные числа. Дробная часть при этом умирала бесследно.
В приведённом фрагменте я уже поправил на [0.0], чтобы хотя бы тип явно был float, но в исходнике ИИ именно этого не сделал.
Во-вторых, сама формула псевдоокругления:
int((P_table_01 // 1)[i] + ((P_table_01[i] % 1) // 0.5))
Если P_table_01 целочисленный, то P_table_01 // 1 даёт то же самое, P_table_01[i] % 1 всегда равно 0, и вся эта конструкция превращается в int(P_table_01[i]).
То есть стоило человеку, который всё это генерировал, хотя бы раз руками прогнать такой фрагмент и посмотреть на результат, чтобы понять, что никакого округления там нет. Но какой процент из вайбокодеров догадается это сделать?
В реальном коде эта строка делает ровно ноль полезной работы, только запутывает читающего. Опять же, не трагедия сама по себе, но показательно: LLM сгенерировала «похожий на округление» шаблон, не проверив, что он действительно что-то округляет.
Выключенная аэродинамика одной строкой
Отдельная жемчужина — работа с углом атаки:
def alpha(y):
return 0 # случай идеального управления
В дальнейшем угол атаки используется в расчёте подъёмной силы и момента:
def calculate_Ya(M, alpha, y, S_m, V):
return C_ya_alpha(M) * alpha * S_m * calculate_q(y, V)
def calculate_Mz(Y_a, X_a, alpha, l_d):
return -(Y_a * np.cos(alpha) + X_a * np.sin(alpha)) * l_d
Поскольку alpha(y) всегда возвращает ноль, у нас обнуляется подъёмная сила, исчезает момент, и всё угловое движение в модели превращается в декоративную надстройку. При этом в другом месте строятся красивые графики угла атаки, угла тангажа, угловой скорости. По коду видно, что LLM хотел связать alpha с разностью углов vartheta - theta_c, но в какой-то момент заменил это на константу «случай идеального управления» и оставил так.
В результате у нас получается ракета, которая летит как идеально стабилизированная болванка, а при этом мы честно рисуем графики, якобы отражающие её угловое поведение. Одна простая строка выключает целую подсистему уравнений.

Неверный «угол вектора скорости»
Ещё одна характерная деталь касается визуализации угла вектора скорости.
В ноутбуке есть функция:
def get_speed_vector_angle(y):
return radians_to_degrees(np.arctan2(y[:, 3], y[:, 2])) # arctan(y_c / x_c)
Комментарий говорит, что здесь вычисляется угол наклона вектора скорости. На деле берутся координаты x и y и считается arctan2(y, x), то есть угол радиус-вектора от начала координат до текущего положения. К вектору скорости это имеет не больше отношения, чем atan2(latitude, longitude) к направлению ветра.
Правильный угол скорости должен вычисляться по производным координат, то есть по (dx/dt, dy/dt). В некоторых частях кода у автора есть соответствующие величины (dot_x, dot_y), но в итоговой картинке вместо них снова используется «то, что проще», лишь бы график был.
И это опять ошибка не уровня «сложной физики», а уровня «не туда подставили аргументы арктангенса».
Что из этого всего получается
Если собрать всё вместе, картина такая. ИИ сгенерировал объёмный каркас симуляции: атмосферу, интерполяцию табличных коэффициентов, аэродинамические силы и моменты, три численных метода, визуализацию результатов. На уровне структуры и оформления код производит впечатление серьёзной инженерной работы, причем в согласии с ГОСТами.
Когда этот же ИИ попросили поревьюить код, он честно нашёл общие проблемы: выбор явного метода Эйлера, крупный шаг интегрирования, отсутствие адаптивного шага.
На бумаге всё выглядит ещё умнее: можно даже подумать, что «вот, он уже понимает численные методы». Но ровно тот же ИИ не обратил внимания на то, что:
число шагов интегрирования вычисляется через
int()от деления с плавающей точкой, из-за чего последняя точка по времени не соответствует последнему состоянию системы;временная сетка строится через
np.linspace, которая даёт другой шаг, чем тот, с которым реально интегрируются уравнения;аргумент
fвeuler_methodисключён из работы, а система жёстко прибита к глобальнымf1...f6, несмотря на красивую сигнатуру;таблица с параметрами полёта теряет дробную часть значений из-за неявного перевода типов и использует псевдоокругление, которое ничего не округляет;
угол атаки жёстко равен нулю, а значит аэродинамика по углу просто выключена;
угол вектора скорости на графике на самом деле угол радиус-вектора от начала координат.
возможно (и наверняка) на что-то еще, что я при беглой оценке не заметил
Каждый из этих багов живёт в одной-двух строчках. Каждая эта строчка выглядит «простой». И каждая по отдельности способна полностью обесценить все усилия.
Чтобы не быть голословным, я запустил этот код и сравнил его с немного более правильным решением (использовал метод Рунге-Кутты с адаптивным шагом, убрал в коде с помощью промпта описанные выше ошибки). Результат на графике ниже говорит сам за себя:

Где ещё ИИ стабильно ошибается в простом
История с ракетой не уникальна. Точно такие же паттерны всплывают в других задачах.
Если попросить LLM написать бинарный поиск вручную, она очень часто перепутает строгие и нестрогие сравнения, неправильно обновит low и high, оставит один элемент никогда не проверенным или повесит цикл на бесконечное выполнение в одном из граничных случаев. По сигнатуре и структуре это будет ровно тот бинарный поиск, который вы видели в учебнике. Но граничные условия, где «<» надо заменить на «<=», оказываются не там.
С плавающей точкой всё ещё веселее. Конструкция if a == b: для результатов вычислений встречается в сгенерированном коде с завидной регулярностью. Да, такое можно увидеть и в живых проектах. Да, мир почему-то ещё не сгорел. Но это не повод искусственно множить такие места в чужом коде. Правильное сравнение через допуск, работа с масштабами, нормализация — это опять та самая «скучная математика», которой нейросеть не уделяет внимания.
SQL-запросы ИИ очень любит собирать через f-строки. Логика при этом будет честной: запрос формируется, параметры подставляются, результаты читаются. То, что такая конструкция открывает дверь для инъекций нараспашку, модель не волнует. Она видит тысячу примеров кода с подстановкой строк и делает «как у людей». Параметризованные запросы, подготовленные выражения — это уже другая, менее представительная выборка.
Границы массивов, пустые контейнеры, перепутанные радианы и градусы, off-by-one ошибки в циклах — всё это тоже постоянно всплывает в сгенерированном коде. В том числе в таких местах, которые любой живой опытный программист увидел бы сходу, просто потому, что уже сто раз видел тот же баг в реальной системе.
Что из этого следует
Фразы типа «пусть ИИ пишет рутину, а мы займёмся архитектурой» звучит успокаивающе. В реальности пока что происходит обратное.
Архитектурный фасад — модули, классы, dataclass’ы, разделение ответственности — LLM генерирует уже прилично. Как правило, куда приличнее живого джуна, который полтора года копипастит всё подряд из Stack Overflow.
А вот там, где начинается «простое» — конкретное значение dt, условие выхода из цикла, сравнение чисел с плавающей точкой, расчёт количества шагов, сохранение инвариантов типа «масса всегда положительна, энергия не растёт в консервативной системе» — именно там нейросети продолжают стрелять промах за промахом. При этом объём кода растёт, а доверие к каждой отдельной строчке падает.
То, что свежая платная версия ChatGPT смогла сама найти в своём же коде проблемы на уровне выбора численной схемы, — это хорошо. Но то, что она при этом не заметила банальную ошибку с int() от деления и несогласованной временной сеткой, — куда более показательно. Она учится говорить как хороший преподаватель численных методов, но не научилась быть аккуратным исполнителем на уровне конкретного кода.
На практике для меня из этого следуют четыре простых вывода.
Во-первых, ИИ нельзя считать автором кода. Он — генератор черновика. Каркас архитектуры, обвязка вокруг библиотек, мёртво скучный boilerplate — да.
Всё, в чём замешана математика, физика, дискретная логика, — проверяется ровно так же, как если бы это писал совершенно неграмотный во всех этих вещах человек.
Во-вторых, нельзя делегировать ИИ «простые» вещи.
Наоборот, именно простые вещи — шаги, индексы, типы, инварианты — придётся проверять особенно тщательно. Архитектуру он нарисует за вас. А вот dt посчитает через int() от деления и уедет на 0.03 секунды в сторону.
В-третьих, джунам по-прежнему надо учить матчасть, а не только «как правильно сформулировать запрос к нейросети». Если человек не понимает, чем явный метод Эйлера отличается от Рунге–Кутты и что такое численная устойчивость, он не увидит проблемы ни в схеме интегрирования, ни в расхождении временных сеток, ни в кусках отключенной аэродинамики. При этом матчасти нужно учить особенно хорошо, начиная с самых базовых вещей, такие как ошибки из-за особенностей машинной арифметики.
В-четвёртых, то, что ИИ иногда способен найти свои же ошибки, не делает его безопасным. Это полезный инструмент для второго взгляда. Но ответственность за то, что ракета в вашей модели не превращается в численный фейерверк, всё равно на вас.
Архитектуру ИИ действительно набросает. Но dt в интеграле потеряет, шаг посчитает странно, угол перепутает, а float сравнит через ==. Проверяйте «простое». Именно там теперь живут самые дорогие баги.
Правило доверия к ИИ: чем примитивнее операция (сложение, цикл, условие), тем нередко выше вероятность, что LLM там накосячила. Считайте, что код пишет профессор философии, который прогуливал арифметику в начальной школе.
Весь исходный Jupyter-ноутбук с кодом, о котором я здесь говорю, лежит по ссылке.
С помощью LLM я там также составил описание алгоритмов и выводы, чтобы это выглядело как более-менее понятно описано, что происходит.
Прошу прочитавших это всё написать в комментариях свои личные примеры нахождения подобных ошибок от LLM. Можете также порыться в ноутбуке, который я быстро навайбокодил. Наверняка найдете еще какие-нибудь ошибки там.