$ sudo teach IT

Вы наверняка использовали автодополнение кода или копировали сниппеты из Stack Overflow. Но с LLM работа с кодом выходит на новый уровень. Теперь вы можете:

  • Сгенерировать функцию по описанию задачи
  • Автоматически написать тесты
  • Провести ревью pull request на лету
  • Объяснить сложный код как для джуна

В этом уроке вы научитесь давать чёткие технические промпты и использовать LLM внутри редактора — с помощью GitHub Copilot, Continue или ChatGPT API.

📘 Что вы узнаете

  • Как правильно просить LLM сгенерировать или отрефакторить код
  • Как писать промпты для автотестов
  • Как проводить ревью через промпт
  • Как объяснить чужой код понятным языком
  • Как построить CLI-интерфейс на базе цепочек промптов

📚 Ключевые термины

  • Refactoring — изменение структуры кода без изменения его поведения. Улучшает читаемость и сопровождаемость.
  • Prompt-chain — цепочка запросов, где результат одного шага используется как вход для следующего (пример: сначала сгенерировать код, потом — тесты).
  • Pull request (PR) — предложение внести изменения в репозиторий на GitHub, обычно включает код, описание и обсуждение.
  • Continue.dev — расширение для VS Code, которое интегрирует GPT-модель локально или через API, позволяя общаться с кодом в редакторе.
  • Copilot — инструмент от GitHub на базе OpenAI, который предлагает автодополнение и генерацию кода прямо в процессе написания.

🧱 Генерация и рефакторинг кода

Работа с кодом через промпты — один из самых очевидных и полезных кейсов LLM. Модель может сгенерировать заготовку функции, помочь структурировать код, добавить проверки, а затем — переписать его в более читаемом виде.

🧪 Промпт для генерации:

Напиши функцию на Python, которая проверяет, является ли строка палиндромом. Добавь docstring и типы аргументов.

📌 Советы для генерации кода:

  • Указывайте язык: Python, JavaScript, Go — от этого зависит стиль синтаксиса.
  • Уточняйте парадигму: "в стиле ООП", "с использованием функциональных паттернов".
  • Добавляйте ограничения:
    • "без использования циклов",
    • "сложность O(n)",
    • "не использовать сторонние библиотеки".
  • Формат вывода:
    • return или print?
    • Ответ в виде JSON?
    • Нужно ли добавить логирование?

📎 Аналогия: Вы как архитектор описываете, что нужно построить и из чего, а LLM — как опытный строитель — делает заготовку под ключ. Чем точнее ТЗ, тем меньше переделок.

🧹 Промпт для рефакторинга:

Перепиши код ниже, улучшив читаемость и избегая дублирования. Используй современные практики ES6.

📌 Советы для рефакторинга:

  • Уточните цель: читаемость, производительность, модульность.
  • Уточните стиль: “в духе Airbnb-гайда”, “максимально декларативно”.
  • Уточните, можно ли разделить код на функции или вынести константы.
  • Просите модель объяснить изменения — это полезно для обучения.

📎 Аналогия: Представьте, что вы пишете черновик, а затем отдаёте его редактору. Он не меняет смысла, но убирает повторения, улучшает стиль и форматирует текст. То же самое и с кодом — модель оставляет поведение прежним, но делает структуру более понятной.

📌 Примеры до и после

До (код с дублированием и плохой читаемостью):

function greet(user) {
  if (user === 'admin') {
    console.log('Welcome, admin!');
  } else if (user === 'guest') {
    console.log('Welcome, guest!');
  } else {
    console.log('Welcome, user!');
  }
}

После (рефакторинг с ES6):

function greet(user) {
  const roles = {
    admin: 'Welcome, admin!',
    guest: 'Welcome, guest!',
  };
  console.log(roles[user] || 'Welcome, user!');
}

💡 Зачем это нужно

  • Генерация — помогает быстро создавать шаблоны, особенно при рутинных задачах.
  • Рефакторинг — экономит время при “уборке” чужого или старого кода.
  • Комбинация — сначала генерируйте, потом рефакторьте — в 2 шага можно выйти на идеальный код.

🧠 Комбо-промпт:

Сгенерируй функцию сортировки массива чисел на JavaScript (без использования .sort()), а затем перепиши её в функциональном стиле ES6 с комментариями.

Это уже полноценный сценарий для mid+ разработчика, проверяющий и генерацию, и рефакторинг, и объяснение.

🧪 Автогенерация тестов

LLM может значительно ускорить процесс написания тестов. Особенно когда:

  • вы только что написали функцию и хотите убедиться, что она работает корректно,
  • нужно покрыть edge cases, но вы боитесь что-то упустить,
  • хочется быстро набросать скелет тестов, а потом вручную доработать.

📌 Главная идея: вы описываете, что тестировать и на каком фреймворке, — а LLM пишет тесты.

🧾 Пример промпта:

Напиши юнит-тесты для функции get_user_age(user_dict), которая получает возраст из словаря. Используй PyTest. Учти пограничные случаи и ввод с ошибкой.

✅ Что выдаёт LLM:

import pytest
from my_module import get_user_age

def test_valid_age():
    assert get_user_age({"name": "Alice", "age": 30}) == 30

def test_missing_age():
    with pytest.raises(KeyError):
        get_user_age({"name": "Bob"})

def test_invalid_type():
    with pytest.raises(TypeError):
        get_user_age("not a dict")

📌 Рекомендации к промпту:

  • Уточняйте фреймворк: PyTest, Jest, JUnit, Mocha — от этого зависит шаблон кода.
  • Используйте формулировку: "покрой edge cases" — тогда LLM предложит:
    • пустые входные данные,
    • некорректные типы,
    • граничные значения.
  • Уточните формат тестов:
    • AAA: Arrange → Act → Assert
    • table-driven: тесты через перебор массивов входов/выходов.
  • Добавьте: "прокомментируй каждый тест" — для учебных целей или ревью.

🤖 В чём плюсы автогенерации:

  • Скорость — 10 тестов за 10 секунд.
  • Типичность — LLM почти всегда добавит стандартные проверки (null, ошибка типа, невалидный ключ).
  • Удобство — можно прогонять сразу и смотреть, какие кейсы вы забыли.

⚠️ А в чём минусы?

  • Низкая осведомлённость о побочных эффектах.
    • LLM не всегда проверяет, изменяется ли состояние (например, база данных).
  • Отсутствие проверки производительности или безопасности.
  • Переизбыточность: иногда пишет 5 почти одинаковых тестов, не приносящих ценности.

🧠 Как использовать в паре с генерацией кода

Один из мощных подходов — генерировать код и тесты сразу. Это позволяет:

  • видеть, как модель интерпретирует вашу задачу,
  • автоматически проверить корректность логики,
  • быстрее находить баги и уточнять требования.

💡 Комбо-промпт:

Напиши функцию get_user_age(dict), а затем — набор тестов на PyTest с покрытием edge cases.

📌 Почему это полезно:

  • Вы получаете сразу 2 артефакта: функцию и тесты.
  • Можете запустить тесты и проверить: работает ли код.
  • Легче отлавливать неучтённые кейсы — особенно на этапе MVP или обучения.

🔍 Пример вывода от модели:

# Функция
def get_user_age(user_data):
    if not isinstance(user_data, dict):
        raise TypeError("Input must be a dictionary.")
    return user_data["age"]

# Тесты на PyTest
import pytest

def test_valid_age():
    assert get_user_age({"name": "Alice", "age": 25}) == 25

def test_missing_age():
    with pytest.raises(KeyError):
        get_user_age({"name": "Bob"})

def test_invalid_input_type():
    with pytest.raises(TypeError):
        get_user_age("not a dict")

📎 Аналогия: как шеф-повар и дегустатор в одном лице

Представьте, что шеф готовит блюдо, а потом сразу сам его пробует. Так он сразу узнаёт, где пересолено, где не хватает гарнира, и исправляет на месте.

Комбо-промпт делает то же самое: сначала создаёт, потом тестирует. Это более зрелый способ работы с LLM.

📌 Где особенно полезно:

  • 👶 В обучении — чтобы студент понимал: один и тот же промпт может влиять и на логику, и на проверку.
  • 🚀 В быстрых MVP — где важна скорость, а ошибки на проде недопустимы.
  • 🧪 В тестировании новых фич — сразу виден результат + проверка.
  • 🤖 В автоматизированной генерации кода — можно сгенерировать функцию, сохранить и запустить пайплайн тестов.

🔍 Ревью кода через LLM

Один из самых полезных и недооценённых кейсов: использование LLM как помощника в ревью кода. Это особенно актуально, когда:

  • вы работаете в одиночку и нет второго взгляда,
  • команда большая, и ревью долгое,
  • вы хотите проверить себя перед отправкой PR.

📌 Принципы хорошего ревью-промпта:

  1. Передавайте весь контекст:
    • код (diff или полный файл),
    • описание PR (что поменялось и зачем),
    • ссылки на документацию, таску или баг-репорт.
  2. Разбивайте ревью на этапы:
    • 1️⃣ Опиши, что делает этот PR
    • 2️⃣ Найди возможные проблемы или улучшения
    • 3️⃣ Предложи альтернативные решения
  3. Уточняйте акценты:
    • хотим ли мы смотреть на стиль (PEP8, ESLint, Prettier),
    • важна ли производительность (цикл в цикле, сложность),
    • критична ли безопасность (инъекции, валидация, XSS).

🧪 Пример запроса:

Вот pull request:

Изменения:
- Добавлена функция генерации PDF
- Подключена новая библиотека reportlab
- Обновлена логика рендеринга отчёта

Вот diff кода: [вставить diff]

Проанализируй:
1. Соответствует ли код стилю Python
2. Есть ли проблемы с производительностью или безопасностью
3. Какие улучшения можно внести

🧰 Инструменты, которые помогают:

  • Continue.dev — можно встроить ревью прямо в VS Code, дать задачу LLM “проанализируй этот файл”.
  • GitHub Copilot Chat — прямо в редакторе можно задать вопрос “что не так с этим куском кода?”.

✅ Когда особенно полезно:

  • 🧪 Перед ревью в команде — ловите очевидные баги заранее.
  • 🏗 При работе с legacy-кодом — получите подсказки по рефакторингу.
  • 🧑‍🏫 В обучении — когда студент пишет PR и получает объяснение, почему так лучше.

🔄 Советы:

  • Используйте тон “ментор + инженер” — просите не просто список ошибок, а объяснение решений.
  • Не ограничивайтесь одним промптом — добавьте follow-up: “А можешь упростить эту функцию?”, “Есть ли способ вынести это в утилиту?”

💡 Объяснение чужого кода

Объясни этот код начинающему разработчику. Избегай жаргона, используй аналогии.

📌 Советы:

  • Уточняйте уровень объяснения: “для новичка”, “как для студента”, “для менеджера”
  • Можно добавить "Приведи аналогию из реальной жизни"

📎 Пример:

def is_even(n):
   return n % 2 == 0

Пояснение:

Функция проверяет, делится ли число на 2 без остатка — значит, оно чётное. Это как делить яблоки поровну между двумя людьми — если не осталось лишнего, число чётное.

🧨 Частые ошибки

  • 📉 “Сделай мне бота” — слишком общий запрос
  • 🔄 Несогласованность цепочки: один шаг не передаёт данные другому
  • 🧩 Смешение задач: генерация и тесты в одном промпте — сложнее отладить

❓ Частые вопросы

Q: Чем Copilot отличается от ChatGPT?
A: Copilot — автодополнение “по ходу”, ChatGPT — генерация по промптам. Вместе — мощно.

Q: Как избежать “галлюцинаций” в коде?
A: Уточняйте формулировку задачи, ограничивайте контекст, просите примеры.

Q: Можно ли доверять ревью от LLM?
A: Как первой итерации — да. Но финальное решение — за человеком.

📌 Итоги

Сегодня вы узнали:

  • Как использовать LLM для генерации, тестов и ревью кода
  • Как правильно формулировать технические промпты
  • Как объяснять код, даже если он вам не принадлежит
  • Как создать CLI-помощника на базе prompt-chain

👉 Эти навыки экономят часы рутинной работы, улучшают качество кода и делают работу с LLM инструментальной, а не магической.

На следующий урок