Попросите любую современную LLM (GPT-5, Claude 3.7, Gemini 2.0 или вашу локальную красавицу) решить задачку вроде ((17 * 24) + (132 / 11)) - 5^3. Шанс получить правильный ответ - примерно как угадать, какой палец я сейчас покажу за спиной. Модель на 400 миллиардов параметров. Она пишет поэзию, генерирует SQL, объясняет квантовую хромодинамику. Но элементарная арифметика - её личный Ахиллес.
Почему ваша LLM врёт в арифметике? (И это не её вина)
Трансформеры - архитектура, на которой построены все современные LLM - не арифметические сопроцессоры. Они угадывают следующее токен на основе статистических закономерностей в тренировочных данных. Умножение для модели - это не операция, а паттерн символов.
Наглядный пример: спросите у GPT-4o (релиз 2025) "Сколько будет 12345 * 67890?". Вы получите красивый, уверенный и почти наверняка неправильный ответ. Потому что в её весах нет таблицы умножения - есть вероятности появления цифр после других цифр.
Вот что происходит внутри:
- Модель видит последовательность токенов
"12345","*","67890","=" - Она не вычисляет 12345 × 67890
- Она вспоминает, какие цифры чаще всего встречались после подобных последовательностей в её датасете
- И генерирует наиболее вероятную последовательность цифр в ответе
Это фундаментальное ограничение архитектуры. Не баг, а фича. Трансформеры созданы для языка, не для арифметики. Можно дообучать на математических датасетах (и Meta это делает с Llama-Math), но проблема остаётся - модель всё равно угадывает, а не вычисляет.
Хак: превращаем LLM в компилятор
Решение гениальное в своей простоте: не просим LLM считать. Просим её написать код, который посчитает.
Разница принципиальная:
- СЛОМАННЫЙ ПОДХОД: "Посчитай 15% от 8732.45"
- РАБОЧИЙ ПОДХОД: "Напиши функцию на Python, которая вычисляет процент от числа. Затем вызови её с аргументами 8732.45 и 15"
LLM прекрасно генерирует код. Потому что код - это язык. А языковые модели... ну, вы поняли. После генерации кода вы выполняете его в изолированном окружении (санитайзер, песочница, контейнер - что угодно) и получаете точный результат.
| Задача | Плохой промпт | Хороший промпт |
|---|---|---|
| Сложный расчёт | ((17.8 + 32.1) * 1.19) / 0.47 | Напиши код на Python с использованием decimal для точных вычислений |
| Финансовые проценты | Сумма 10000 под 5.7% годовых на 3 года | Создай функцию compound_interest(principal, rate, years) |
| Статистика | Среднее и стандартное отклонение для [1.2, 3.4, 5.6] | Импортируй numpy и вычисляй mean и std |
1 Формулируем задачу как ТЗ для программиста
Первое правило: говорите с LLM как с junior-разработчиком. Конкретно, чётко, с примерами. Не "посчитай", а "напиши скрипт, который...".
# Пример промпта для сложных финансовых расчётов:
"""
Напиши функцию на Python, которая вычисляет ежемесячный платёж по ипотеке.
Используй формулу: M = P * r * (1+r)^n / ((1+r)^n - 1)
Где:
P - основная сумма кредита
r - месячная процентная ставка (годовая ставка / 12 / 100)
n - количество платежей (лет * 12)
Функция должна принимать:
- principal (float)
- annual_rate (float в процентах, например 7.5)
- years (int)
Возвращать округлённое до 2 знаков значение.
Добавь обработку ошибок для некорректных входных данных.
"""
2 Выбираем язык и библиотеки
Python - король для таких задач. Но иногда нужна производительность или специфичная экосистема.
- Python с decimal/math: для точной арифметики с фиксированной точностью
- Python с numpy: для научных вычислений, статистики
- JavaScript: если код будет выполняться в браузере
- SQL: для вычислений непосредственно в базе данных
- Rust/Go: когда нужна скорость и безопасность памяти
Важно: явно укажите в промпте, какие библиотеки использовать. Особенно если нужны точные вычисления с decimal. Без указания LLM может использовать обычные float и получить ошибки округления.
3 Генерируем код с контекстом и ограничениями
Чем больше контекста дадите, тем лучше код. Опишите:
- Точность вычислений (сколько знаков после запятой)
- Обработку edge-кейсов (деление на ноль, отрицательные числа)
- Требования к производительности (если критично)
- Формат вывода (JSON, чистый текст, число)
# Пример промпта с ограничениями:
"""
Напиши функцию calculate_statistics(data: list[float]) -> dict:
- Вычисляет среднее, медиану, стандартное отклонение
- Используй библиотеку numpy для вычислений
- Округляй все значения до 4 знаков после запятой
- Если список пустой, возвращай {'error': 'empty dataset'}
- Если в списке есть нечисловые значения, обрабатывай исключение
- Добавь docstring с примерами использования
"""
4 Выполняем в безопасном окружении
Сгенерированный код нельзя слепо доверять. Запускайте его в песочнице:
# Базовый пример выполнения кода в Python с изоляцией
import subprocess
import tempfile
import os
def execute_generated_code(code: str, timeout: int = 5):
"""Безопасное выполнение кода в отдельном процессе"""
with tempfile.NamedTemporaryFile(mode='w', suffix='.py', delete=False) as f:
f.write(code)
temp_path = f.name
try:
result = subprocess.run(
['python', temp_path],
capture_output=True,
text=True,
timeout=timeout,
env={**os.environ, 'PYTHONPATH': ''} # Изолируем от системных библиотек
)
return {
'success': result.returncode == 0,
'stdout': result.stdout,
'stderr': result.stderr
}
except subprocess.TimeoutExpired:
return {'success': False, 'error': 'timeout'}
finally:
os.unlink(temp_path)
Или используйте готовые решения: Docker-контейнеры, Google Colab kernels, изолированные среды выполнения вроде AWS Lambda.
5 Обрабатываем ошибки и валидируем результат
Сгенерированный код может:
- Не компилироваться (синтаксические ошибки)
- Падать при выполнении (runtime errors)
- Возвращать не тот формат
- Содержать уязвимости (инъекции, бесконечные циклы)
Добавьте валидацию:
def validate_and_execute(code: str, test_cases: list):
"""Валидация кода на тестовых примерах"""
# 1. Статический анализ (можно использовать ast.parse)
# 2. Проверка на запрещённые конструкции (eval, exec, os.system)
# 3. Запуск на тестовых данных
# 4. Сравнение с ожидаемыми результатами
for input_data, expected_output in test_cases:
# Выполняем код с input_data
# Сравниваем результат с expected_output
# Если не совпадает - возвращаем ошибку
pass
Какие модели лучше всего подходят для генерации кода в 2026?
Ситуация меняется каждый квартал. На момент написания (март 2026) лидеры:
- DeepSeek-Coder-33B-Instruct (2025 релиз): специально обучена на кодек, понимает контекст длиной 128К токенов
- Claude 3.7 Sonnet: лучшая в понимании сложных инструкций, но дорогая для массовой генерации
- GPT-5 Code Specialized: если верить утечкам, OpenAI готовит отдельную кодогенерирующую версию
- Qwen2.5-Coder-32B: открытая модель от Alibaba с отличной поддержкой азиатских языков в комментариях
Для локального запуска смотрите мой обзор лучших LLM с поддержкой Tool Calling. Важно: Tool Calling (или Function Calling) - это следующий уровень, где модель сама решает, когда генерировать код.
Предупреждение: Не используйте маленькие модели (7B параметров и меньше) для генерации критичного кода. Они слишком часто ошибаются в синтаксисе и логике. Проверяйте каждый сгенерированный фрагмент.
Чего НЕ делать: топ-3 ошибки
-
Доверять сгенерированному коду без проверки
Особенно если код работает с файловой системой, сетью или выполняет системные команды. Одна ошибка - и ваш сервер майнит крипту. -
Использовать eval() или exec() напрямую
Даже если очень хочется. Даже если "ну всего один разочек". LLM может сгенерировать__import__('os').system('rm -rf /')просто потому, что такой паттерн встречался в датасете. -
Генерировать код без ограничений по времени и памяти
Бесконечный цикл в сгенерированном коде заблокирует поток выполнения. Всегда добавляйте timeout и лимиты на использование памяти.
Альтернативы: когда код - слишком тяжёлая артиллерия
Иногда проще использовать встроенные инструменты:
- Калькулятор Tools: многие LLM теперь поддерживают плагины-калькуляторы (ChatGPT с Wolfram, Claude с калькулятором)
- Нейросимвольный подход: встраивание алгебраического процессора прямо в пайплайн LLM - читайте в статье про нейросимвольный ИИ
- Внешние API: вызывайте математические сервисы (Microsoft Math Solver, Symbolab) через REST
Частые вопросы (FAQ)
Этот метод работает только для простой арифметики?
Нет. Вы можете генерировать код для любых вычислений: статистический анализ, финансовое моделирование, инженерные расчёты, машинное обучение (предобработка данных). Главное - правильно сформулировать задачу.
Насколько это медленно по сравнению с прямым вычислением?
В 10-100 раз медленнее. Генерация кода + выполнение в песочнице + валидация занимает время. Но если точность важнее скорости (финансы, научные расчёты), это приемлемая цена.
Можно ли использовать этот подход в продакшене?
Можно, но с осторожностью. Нужна многоуровневая валидация, мониторинг, лимиты. И обязательно прочтите статью про Delegation Filter - там есть чек-лист для продакшн-решений.
И последний совет, который никто не даст: иногда лучше вообще не использовать LLM для вычислений. Если задача решается обычным кодом (который вы можете написать или найти на Stack Overflow), сделайте так. LLM - это не магическая палочка, а сложный инструмент со своей ценой ошибки.
Мой прогноз на 2027 год: мы увидим появление специализированных "вычислительных LLM" с архитектурными изменениями специально для точной математики. А пока - генерируйте код, проверяйте его, и спите спокойно.