Назад к статьям

Как ИИ пишет код

Большие языковые модели (LLM) произвели революцию в разработке программного обеспечения. Но что происходит «под капотом», когда вы просите модель написать функцию на Python или компонент на React?

Путь от текста к токенам

Прежде чем модель начнёт «думать», входной текст разбивается на токены — небольшие фрагменты слов или символов.

Например, строка:

python
def fibonacci(n):    if n <= 1:        return n    return fibonacci(n - 1) + fibonacci(n - 2)

Разбивается примерно на 30 токенов. Каждый токен — это число, которое модель понимает.

Архитектура Transformer

В основе любой современной LLM лежит архитектура Transformer, предложенная в 2017 году. Ключевой механизм — self-attention — позволяет модели «видеть» связи между любыми частями текста.

Математика внимания

Механизм внимания вычисляется по формуле:

Attention(Q,K,V)=softmax(QKTdk)V\text{Attention}(Q, K, V) = \text{softmax}\left(\frac{QK^T}{\sqrt{d_k}}\right)V

Где:

  • $Q$ — матрица запросов (queries)
  • $K$ — матрица ключей (keys)
  • $V$ — матрица значений (values)
  • $d_k$ — размерность ключей

Генерация: токен за токеном

Модель генерирует код последовательно — по одному токену за раз. На каждом шаге она оценивает вероятности всех возможных продолжений и выбирает наиболее подходящее.

typescript
interface GenerationStep {  tokens: number[];         // уже сгенерированные токены  logits: Float32Array;     // вероятности следующего токена  temperature: number;      // «креативность» (0 = детерминированно)}
function sample(logits: Float32Array, temperature: number): number {  // Масштабируем логиты температурой  const scaled = logits.map((l) => l / temperature);
  // Softmax для получения вероятностей  const maxLogit = Math.max(...scaled);  const exps = scaled.map((l) => Math.exp(l - maxLogit));  const sum = exps.reduce((a, b) => a + b, 0);  const probs = exps.map((e) => e / sum);
  // Сэмплируем из распределения  let cumulative = 0;  const random = Math.random();  for (let i = 0; i < probs.length; i++) {    cumulative += probs[i];    if (random < cumulative) return i;  }  return probs.length - 1;}

Почему ИИ иногда ошибается

LLM не «понимает» код в том смысле, в котором это делает программист. Она предсказывает статистически вероятное продолжение на основе паттернов из обучающих данных.

Сильные стороныСлабые стороны
Шаблонный код и бойлерплейтСложная бизнес-логика
Стандартные алгоритмыКонтекст большого проекта
Документация и комментарииНестандартные архитектуры
Рефакторинг и форматированиеОтладка runtime-ошибок

Заключение

ИИ-ассистенты для программирования — это мощный инструмент, но не замена разработчику. Понимание того, как они работают, помогает использовать их эффективнее и критичнее относиться к результатам.

Ключевой вывод: относитесь к сгенерированному коду как к черновику коллеги — всегда проверяйте и тестируйте перед использованием.