Введение в AI-разработку и базовый Vibecoding

Быстрый вход в AI-разработку через парадигму Vibecoding. Вы научитесь делегировать написание кода инструментам Cursor и Claude Code, создав работающее приложение на Python без предварительного изучения синтаксиса.

Смена парадигмы: от ручного кодинга к Vibecoding для Senior-разработчика

Смена парадигмы: от ручного кодинга к Vibecoding для Senior-разработчика

Вспомните свой типичный рабочий день. Сколько времени вы, как Senior Go-разработчик, тратите на проектирование архитектуры микросервиса, продумывание контрактов API или обработку состояний гонки? А сколько — на монотонное написание структур, тегов JSON, маппинга данных и бесконечных проверок if err != nil? Скорее всего, ваш мозг решает задачу за первые 10 минут, а остальные часы уходят на то, чтобы «объяснить» это решение компилятору через клавиатуру.

Переход в новую сферу — например, в AI-разработку на Python — обычно пугает именно этим. Кажется, что придётся снова стать джуном: гуглить базовый синтаксис, бороться с менеджерами пакетов и медленно набивать незнакомый код. Но в эпоху больших языковых моделей (LLM) правила игры изменились.

Что такое Vibecoding?

Термин Vibecoding начинался как ироничный интернет-сленг, но быстро стал обозначать вполне реальную инженерную практику. Это процесс разработки, при котором программист не пишет код построчно, а транслирует нейросети свой замысел (тот самый «вайб» или intent), контекст и ограничения, а ИИ берет на себя генерацию синтаксиса.

Исторически программирование всегда двигалось в сторону повышения уровня абстракции:

  1. Перфокарты (физическое управление железом).
  2. Ассемблер (мнемоники вместо нулей и единиц).
  3. C (процедурные абстракции и управление памятью).
  4. Go / Python (сборка мусора, богатая стандартная библиотека, горутины).

Vibecoding — это следующий логичный шаг. Теперь вашим «компилятором» становится LLM. Вы пишете на естественном языке, а модель транслирует это в Python, Go, Rust или любой другой язык.

Преимущество Senior-разработчика

Существует миф, что ИИ заменит программистов, потому что теперь «любой может написать код». На практике джуниоры, использующие ИИ, часто создают неработающих монстров. Почему? Потому что они не знают, о чём просить нейросеть, и не могут проверить результат.

Ваша суперсила как Senior-разработчика — это системное мышление. Вы уже умеете декомпозировать сложные системы, понимаете, где возникнут узкие места (bottlenecks), как данные перетекают из одного состояния в другое, и почему важно обрабатывать краевые случаи (edge cases).

При переходе к Vibecoding ваши навыки не обнуляются, они становятся вашим главным инструментом. Разница лишь в том, что теперь вы управляете не потоком выполнения внутри функции, а контекстом для AI-агента.

Сравните два подхода к постановке задачи (промптингу):

Подход Как мыслит разработчик Результат генерации
Уровень Junior Фокус на шагах: «Открой файл, сделай цикл по строкам, найди слово 'error', запиши в новый массив». Хрупкий скрипт. Упадёт с нехваткой памяти на файле в 10 ГБ. Не обработает блокировки файлов.
Уровень Senior Фокус на контрактах: «Напиши потоковый парсер логов. Вход: путь к файлу. Выход: JSONL. Ограничение по RAM: 100MB. Обработай ошибки доступа к файлу». Надежный production-ready код с использованием генераторов и правильной обработкой исключений.

В парадигме Vibecoding вы выступаете в роли техлида, а AI — в роли очень быстрого, но безынициативного мидла. Вы задаете архитектурные рамки, а он пишет реализацию. Если реализация плохая — проблема чаще всего в том, что вы не задали нужные ограничения.

От синтаксиса к оркестрации

Главный психологический барьер, который нужно преодолеть — это желание контролировать каждую строчку кода.

Когда вы начнете изучать AI-экосистему, вам придется работать с библиотеками OpenAI, LangChain, PyTorch. Если вы попытаетесь изучать их так же, как когда-то изучали Go (читая исходники, заучивая методы), вы потеряете недели.

Вместо этого мы будем использовать подход оркестрации:

  1. Понимание концепции: Вы должны понять, что делает инструмент (например, как работает векторная база данных).
  2. Формирование контекста: Вы передаете документацию или примеры в AI-инструмент (Claude Code или Cursor).
  3. Делегирование реализации: Вы просите AI написать интеграцию, описывая только бизнес-логику и контракты.
  4. Ревью и корректировка: Вы читаете сгенерированный код, опираясь на свой инженерный опыт, и просите AI исправить архитектурные огрехи.

В этом курсе мы не будем учить вас писать циклы на Python. Мы научим вас использовать современные инструменты (Cursor и Claude Code), чтобы ваш путь от идеи до работающего AI-продукта занимал часы, а не месяцы. В следующей главе мы подготовим рабочее окружение и настроим эти инструменты так, чтобы они стали естественным продолжением вашей IDE и терминала.

Настройка среды: Интеграция Cursor и Claude Code в рабочий процесс

Настройка среды: Интеграция Cursor и Claude Code в рабочий процесс

Для Senior-разработчика смена языка программирования часто ощущается как потеря суперсилы. В Go у вас есть мышечная память: вы знаете, как работает go mod, как настроить линтеры, как быстро запустить дебаггер. Переход в экосистему Python для AI-задач означает столкновение с незнакомыми инструментами (виртуальные окружения, pip, poetry). Однако в парадигме Vibecoding вам не нужно перестраивать эту мышечную память вручную — вам нужно настроить среду, которая сделает это за вас.

Оркестрация кода требует правильных инструментов. Обычного автодополнения (как в GitHub Copilot) уже недостаточно. Нам нужны агенты, способные читать весь проект, анализировать ошибки и самостоятельно выполнять команды. В современном AI-стеке эта задача решается связкой двух инструментов: визуального IDE (Cursor) и терминального агента (Claude Code).

Cursor: IDE, которая видит весь проект

Cursor — это форк VS Code, переписанный с упором на глубокую интеграцию больших языковых моделей. Если вы привыкли к VS Code, ваш переход займет ровно ноль минут: все расширения, шорткаты и темы подтянутся автоматически.

Главное отличие Cursor от классических плагинов заключается в работе с контекстом. Когда вы просите обычный ИИ «добавить обработку ошибок в функцию», он видит только текущий файл. Cursor работает иначе благодаря инструменту Cursor Composer.

Composer позволяет генерировать код сразу в нескольких файлах, опираясь на глобальный контекст. Вы формулируете задачу, а IDE сама решает, какие файлы нужно изменить, создает diff-ы (различия) и предлагает вам принять или отклонить изменения.

Чтобы Cursor работал эффективно, Senior-разработчику нужно управлять тем, что попадает в контекстное окно:

  • Символ @: Позволяет явно указать файлы, папки или даже официальную документацию фреймворков. Вы можете написать @main.py @utils.py реализуй логику из utils в main.
  • Codebase Indexing: Cursor строит векторный индекс вашего проекта. Когда вы задаете вопрос глобально, он ищет релевантные куски кода по всему репозиторию, подобно тому, как работает RAG-система.

Claude Code: Автономный агент в вашем терминале

Если Cursor — это ваш умный редактор, то Claude Code — это ваши «руки» в операционной системе. Это официальная CLI-утилита от Anthropic, которая работает прямо в терминале.

Для бэкенд-разработчика терминал — естественная среда обитания. Claude Code превращает терминал из места, где вы вводите команды, в место, где вы ставите цели. Утилита обладает правами на чтение файловой системы и выполнение bash-команд (с вашего разрешения).

Ключевая особенность Claude Code — агентный цикл (Agentic Loop). Получив задачу, он не просто выдает текст. Он рассуждает, выполняет действие, проверяет результат и, если видит ошибку, исправляет её сам.

Пример из практики: вы хотите развернуть базовую структуру Python-проекта, но не помните синтаксис создания виртуального окружения. Вы пишете в терминале: claude "Инициализируй Python проект, создай виртуальное окружение и установи библиотеку requests"

Claude Code самостоятельно:

  1. Выполнит python3 -m venv venv.
  2. Активирует окружение.
  3. Выполнит pip install requests.
  4. Создаст requirements.txt.
  5. Сообщит вам об успешном завершении.

Синергия: Разделение зон ответственности

Эффективный Vibecoding строится на грамотном разделении задач между этими двумя инструментами. Использование только одного из них замедлит работу.

Характеристика Cursor (Composer) Claude Code (CLI)
Основная роль Проектирование, ревью, сложный рефакторинг Scaffolding, дебаг, инфраструктура
Интерфейс Визуальный (IDE, Diff-редактор) Текстовый (Терминал)
Сильная сторона Понимание связей в большом объеме существующего кода Автономное выполнение команд и скриптов
Когда использовать «Измени контракты API в этих трех файлах» «Найди, почему падают тесты, и почини их»

Типичный рабочий процесс (Workflow)

  1. Инициализация (Claude Code): Вы начинаете в пустой папке терминала. Просите агента создать базовую структуру, установить зависимости и написать каркас (scaffolding).
  2. Разработка логики (Cursor): Вы открываете сгенерированный проект в IDE. Используя Composer, вы описываете бизнес-требования на естественном языке, указываете нужные файлы через @ и ревьюите предложенные diff-ы, применяя свой опыт проектирования архитектуры.
  3. Отладка (Claude Code): Вы запускаете код в терминале. Если скрипт падает с ошибкой (например, конфликт версий библиотек), вы просто передаете вывод ошибки обратно в claude и просите исправить конфигурацию окружения.

Такая настройка среды позволяет вам, как Senior-разработчику, оставаться на уровне архитектурных решений. Вы больше не тратите часы на чтение документации по настройке линтеров в новом языке — вы делегируете это терминальному агенту, а сами фокусируетесь на логике в умном IDE. Инструменты готовы, и следующим шагом мы разберем, как именно нужно формулировать задачи, чтобы ИИ выдавал production-ready результат с первого раза.

Анатомия промпта для генерации кода: контекст, системные инструкции и итерации

Анатомия промпта для генерации кода: контекст, системные инструкции и итерации

Если попросить нейросеть «написать скрипт для скачивания данных по API», она выдаст рабочий код. Но этот код будет похож на студенческую поделку: без обработки таймаутов, без ретраев, с захардкоженными ключами и глобальными переменными. Senior-разработчик тратит на ревью и исправление такого кода больше времени, чем написал бы сам. Проблема не в интеллекте модели, а в отсутствии архитектурных границ в запросе.

Взаимодействие с LLM при генерации кода — это не поиск в Google. Это постановка задачи Junior-разработчику, который обладает абсолютной памятью на синтаксис всех языков мира, но полностью лишен понимания бизнес-контекста вашего проекта.

Математика контекста: почему больше не значит лучше

При работе с Cursor Composer или Claude Code легко поддаться искушению добавить в контекст весь проект целиком. Однако архитектура современных Трансформеров (базы для LLM) имеет особенность: чем больше «шума» в контекстном окне, тем хуже модель фокусируется на главном.

Эффективность контекста можно выразить математически:

E=TrelevantTtotalE = \frac{T_{relevant}}{T_{total}}

Где EE — эффективность промпта (в идеале стремится к 1), TrelevantT_{relevant} — количество токенов, содержащих строгие ограничения, интерфейсы и бизнес-логику для конкретной задачи, а TtotalT_{total} — общий объем переданных токенов (сам промпт плюс прикрепленные файлы).

Практический пример: вы хотите добавить новый эндпоинт. Вы прикрепляете к запросу весь репозиторий на 100 000 токенов (TtotalT_{total}), хотя для задачи нужны только файлы роутера и одной модели на 1 000 токенов (TrelevantT_{relevant}). Эффективность E=0.01E = 0.01. В результате модель «размывает» внимание, начинает выдумывать несуществующие методы из других модулей (галлюцинировать) или менять стиль форматирования.

Четыре столпа production-ready промпта

Чтобы максимизировать TrelevantT_{relevant} и получить код уровня Senior, промпт должен состоять из четырех структурных элементов. Промпт = Контекст + Намерение + Ограничения + Формат вывода.

Элемент Суть Пример для генерации кода
Контекст Где мы находимся и с чем работаем. «Мы пишем CLI-утилиту на Python для работы с OpenAI API. Используй файл @config.py для настроек».
Намерение Какое действие нужно совершить. «Реализуй функцию отправки запроса к модели gpt-4o-mini».
Ограничения Как нельзя делать (самая важная часть для Senior). «Не используй сторонние библиотеки кроме requests. Обработай таймауты (10s) и HTTP 429 (Rate Limit) через экспоненциальную задержку».
Формат вывода Как должен выглядеть результат. «Выведи только измененный блок кода функции, добавь type hints и docstring».

Обратите внимание на блок ограничений. Именно здесь ваш опыт в Go транслируется в Python. Вы можете не знать, как пишется экспоненциальная задержка на Python, но вы знаете, что при работе с внешним API она обязана быть. Вы делегируете синтаксис, но контролируете инженерию.

Системные инструкции: программирование среды

Писать ограничения вроде «всегда используй строгую типизацию» или «пиши логи в формате JSON» в каждом промпте утомительно. Для этого в Cursor существует механизм глобального контекста — файл .cursorrules.

Это скрытый файл в корне проекта, который Cursor автоматически подмешивает в системный промпт (System Prompt) при каждом обращении к нейросети. Системный промпт — это базовая инструкция, которая определяет «личность» и фундаментальные правила поведения модели до того, как она увидит ваш пользовательский запрос.

Системные инструкции — это конституция вашего проекта. Они не описывают конкретные задачи, они описывают инженерную культуру.

Пример эффективного .cursorrules для Go-разработчика, начинающего писать на Python:

You are an expert Python developer.
Follow these rules strictly:
1. Use Python 3.10+ syntax.
2. ALWAYS use static type hints (typing module) for function arguments and return values.
3. No silent failures. Raise explicit exceptions.
4. Prefer standard library where possible. Do not introduce new dependencies without asking.
5. Write code as if it's a Go project: explicit error handling, clean architecture, no magic metaprogramming.

Создав такой файл один раз, вы освобождаете пользовательский промпт от рутины, повышая ту самую эффективность контекста EE.

Итеративный Vibecoding: цепочка промптов

Попытка написать идеальный мега-промпт, который сгенерирует готовую систему из 10 файлов с первого раза — это антипаттерн. Vibecoding предполагает итеративный подход, называемый Prompt Chaining (цепочка промптов).

Процесс разбивается на контролируемые шаги:

  1. Scaffolding (Каркас): Создание структуры. Промпт: «Создай структуру директорий для проекта. Нужны файлы для конфигурации, клиента API и точки входа. Сгенерируй только пустые файлы и интерфейсы (заглушки) с комментариями».
  2. Core Logic (Ядро): Реализация конкретного интерфейса. Промпт: «В файле @client.py реализуй интерфейс отправки запроса. Учти ограничения из .cursorrules».
  3. Refinement (Полировка): Добавление нефункциональных требований. Промпт: «Код работает, но нет обработки обрывов сети. Добавь паттерн Circuit Breaker для метода X».

Такой подход позволяет вам проводить код-ревью на каждом этапе. Если нейросеть пошла не туда на этапе каркаса, вы исправляете это одним коротким сообщением, а не переписываете 500 строк сгенерированной бизнес-логики. Вы управляете вектором развития кода, а ИИ выполняет черновую работу по прокладке пути.

Практика: Создание скрипта для работы с OpenAI API через Composer и терминал

Практика: Создание скрипта для работы с OpenAI API через Composer и терминал

У нас есть пустая директория, API-ключ и ровно 10 минут. Задача: написать production-ready интеграцию с OpenAI на Python, не погружаясь в чтение документации по синтаксису языка. Мы применим системный подход, заложенный ранее: делегируем инфраструктуру терминальному агенту, а бизнес-логику — Composer, управляя процессом через контракты и ограничения.

Шаг 1: Инфраструктура через Claude Code

Вместо того чтобы гуглить, как в Python настраиваются переменные окружения и устанавливаются пакеты, мы отдаем эту рутину автономному агенту. Открываем терминал в пустой папке проекта и запускаем Claude Code.

Формулируем намерение: claude "Проинициализируй проект для работы с OpenAI. Установи библиотеки openai, pydantic и python-dotenv. Создай файл .env.example с заглушкой для OPENAI_API_KEY и пустой main.py."

Агентный цикл запускается: Claude Code самостоятельно определяет ОС, создает виртуальное окружение, вызывает пакетный менеджер pip, создает нужные файлы и отчитывается о готовности. Инфраструктурный фундамент заложен без единой строчки ручного кода.

Нам остается только скопировать .env.example в .env и вставить свой реальный ключ от OpenAI.

Шаг 2: Проектирование контракта данных

Как Senior Go-разработчик, вы знаете: работа с нетипизированным JSON — прямой путь к паникам в рантайме. В Python нет строгой типизации из коробки, но есть библиотека pydantic, которая позволяет описывать модели данных аналогично структурам в Go.

Современное API OpenAI поддерживает механизм Structured Outputs — он гарантирует, что ответ модели будет строго соответствовать переданной JSON-схеме. Мы используем это как жесткое ограничение.

Открываем main.py, вызываем Cursor Composer и пишем первый промпт, соблюдая структуру (Контекст + Намерение + Ограничения + Вывод):

Напиши скрипт для запроса к модели gpt-4o-mini. Намерение: получить объяснение сложного IT-термина простыми словами. Ограничения:

  1. Используй библиотеку openai версии 1.x.
  2. Используй pydantic для описания структуры ответа (поля: term, simple_explanation, complexity_level_1_to_5).
  3. Запрашивай данные через метод client.beta.chat.completions.parse для гарантии структуры. Вывод: только код main.py, который можно сразу запустить.

Composer генерирует следующий код:

import os
from dotenv import load_dotenv
from openai import OpenAI
from pydantic import BaseModel

# Загрузка переменных окружения
load_dotenv()

# Инициализация клиента
client = OpenAI(api_key=os.getenv("OPENAI_API_KEY"))

# Описание контракта (аналог struct в Go)
class TermExplanation(BaseModel):
    term: str
    simple_explanation: str
    complexity_level_1_to_5: int

def explain_term(term_name: str) -> TermExplanation:
    response = client.beta.chat.completions.parse(
        model="gpt-4o-mini",
        messages=[
            {"role": "system", "content": "Ты эксперт, объясняющий IT-термины."},
            {"role": "user", "content": f"Объясни термин: {term_name}"}
        ],
        response_format=TermExplanation,
    )
    return response.choices[0].message.parsed

if __name__ == "__main__":
    result = explain_term("Vibecoding")
    print(f"Термин: {result.term}")
    print(f"Объяснение: {result.simple_explanation}")
    print(f"Сложность: {result.complexity_level_1_to_5}/5")

Шаг 3: Итеративное усложнение (Prompt Chaining)

Код выше работает, но он «хрупок». Сеть может моргнуть, API OpenAI может вернуть ошибку таймаута. Вместо того чтобы писать мега-промпт, в котором мы сразу требуем и бизнес-логику, и обработку ошибок, мы применяем Prompt Chaining. Каркас уже есть, теперь наращиваем «мясо».

Выделяем функцию explain_term в Cursor и пишем уточняющий промпт в Composer:

Добавь отказоустойчивость для этой функции. Используй библиотеку tenacity для реализации 3 ретраев с экспоненциальной задержкой при сетевых ошибках или ошибках таймаута от OpenAI.

Cursor мгновенно импортирует tenacity и оборачивает функцию в декоратор @retry, добавляя нужные исключения из библиотеки openai. Разработчику остается лишь нажать Accept, чтобы применить diff.

Шаг 4: Запуск и верификация

Переходим в терминал и выполняем: python main.py

Скрипт идет в сеть, обращается к LLM и возвращает четко структурированный объект, поля которого мы выводим в консоль.

Вы только что написали надежный интеграционный скрипт на Python с валидацией данных и ретраями. Вы не искали, как импортировать переменные окружения, не читали документацию по методу parse в OpenAI SDK и не изучали синтаксис декораторов для tenacity. Вы выступили в роли архитектора: задали зависимости, определили контракт данных и требования к отказоустойчивости.

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

Отладка и рефакторинг AI-кода: как Senior-опыт помогает контролировать генерацию

Отладка и рефакторинг AI-кода: как Senior-опыт помогает контролировать генерацию

Современные LLM практически перестали допускать синтаксические ошибки. Если вы попросите ИИ написать скрипт, он запустится с первого раза в 95% случаев. Но именно здесь кроется главная ловушка Vibecoding: код, который выглядит идеально и проходит базовый тест, может оказаться бомбой замедленного действия в production.

В прошлой главе мы создали рабочий Python-скрипт для опроса OpenAI API, добавили строгие контракты через Pydantic и базовые ретраи. Теперь пора надеть шляпу Senior-разработчика. Ваша задача — не писать код, а проводить жесткое архитектурное ревью того, что сгенерировала машина, и направлять ее на исправление логических дыр.

Ловушка «Счастливого пути» (Happy Path)

Нейросети обучаются на миллионах строк кода из открытых репозиториев (GitHub, StackOverflow). Большинство примеров в сети демонстрируют идеальные условия: сеть стабильна, API отвечает мгновенно, данные всегда валидны. Поэтому ИИ по умолчанию генерирует код для «счастливого пути».

Представьте, что мы расширили наш скрипт из прошлой главы, чтобы он обрабатывал не один запрос, а массив из 100 элементов в цикле. Оценим надежность такого подхода математически.

Пусть pp — вероятность успешного ответа API на один запрос. Тогда вероятность успешного завершения всего цикла из NN запросов вычисляется как:

Psuccess=pNP_{success} = p^N

Где PsuccessP_{success} — общая вероятность успеха, pp — надежность одного вызова (например, 0.99), а NN — количество итераций (например, 100). Даже при высокой надежности API в 99%, вероятность того, что скрипт успешно обработает все 100 элементов без единого сбоя: 0.991000.360.99^{100} \approx 0.36. То есть в 64% случаев скрипт упадет, потеряв весь прогресс.

ИИ редко сам задумывается о сохранении промежуточного состояния (checkpointing) или идемпотентности операций. Это зона ответственности человека.

Трансляция Go-опыта в Python-реалии

Как Senior Go-разработчик, вы привыкли к определенным паттернам надежности. В Go они часто встроены в стандартную библиотеку или диктуются идиомами языка. При Vibecoding на незнакомом языке ваша задача — заставить ИИ реализовать эти же паттерны.

Сравним привычные Go-концепции с типичными ошибками ИИ при генерации на Python, и посмотрим, как это исправлять промптами.

Паттерн в Go Типичная генерация ИИ (Python) Как исправить через промпт (Vibecoding)
context.Context (таймауты и отмена) Запросы через requests.get(url) без таймаутов. При зависании сети скрипт висит вечно. «Добавь явные таймауты (connect, read) ко всем сетевым вызовам. Используй httpx вместо requests для лучшей работы с асинхронностью».
Явная проверка if err != nil Обертывание большого блока в try...except Exception: pass (тихое проглатывание ошибок). «Убери глобальный except. Перехватывай только конкретные исключения API. Логируй stack trace при падении».
Горутины и sync.WaitGroup Синхронный цикл for (очень медленно) или запутанный asyncio.gather без ограничения конкурентности. «Сделай обработку асинхронной, но ограничь concurrency до 10 одновременных запросов через asyncio.Semaphore».

Эффективный цикл отладки: Контекст + Гипотеза

Когда сгенерированный скрипт падает, инстинкт программиста велит открыть файл и исправить баг руками. В парадигме Vibecoding это антипаттерн. Если вы правите код руками, вы рассинхронизируете контекст в Cursor/Claude Code, и при следующей генерации ИИ может затереть ваши правки.

Правильный процесс отладки (Debugging Loop) выглядит так:

  1. Захват ошибки: Скопируйте полный stack trace (или позвольте Claude Code прочитать вывод терминала).
  2. Формирование гипотезы: Не пишите просто «оно не работает». Используйте свой Senior-опыт, чтобы указать направление.
  3. Делегирование исправления: Отправьте ошибку и гипотезу агенту.

Пример плохого промпта: Скрипт упал с ошибкой RateLimitError. Почини.

Пример Senior-промпта: Мы получаем RateLimitError от OpenAI. Наш декоратор tenacity сейчас ретраит любые исключения. Это неверно. Измени логику: ретраить нужно только 429 (Rate Limit) и 5xx ошибки. Если приходит 400 (Bad Request), ретрай не нужен — сразу пробрасывай ошибку выше.

Рефакторинг через Cursor Composer

Наш скрипт работает и устойчив к ошибкам, но пока это просто процедурный код в одном файле main.py. Для интеграции в будущий бэкенд (что мы будем делать в следующих главах) нам нужна нормальная архитектура.

Вместо того чтобы переписывать всё вручную, мы используем Cursor Composer для структурного рефакторинга. Выделяем весь код и пишем архитектурный промпт:

«Проведи рефакторинг этого скрипта. 1. Выдели логику работы с OpenAI в отдельный класс OpenAIClient. 2. Зависимости (API ключ, модель) должны передаваться через конструктор (Dependency Injection). 3. Вынеси Pydantic-модели в отдельный файл models.py. 4. В main.py оставь только инициализацию клиента и точку входа. Обнови импорты.»

Cursor Composer автоматически создаст новые файлы, распределит по ним код и покажет вам diff для утверждения. Вы выступаете в роли Tech Lead, который проводит Code Review перед мерджем. Вы не написали ни строчки синтаксиса Python, но получили production-ready модуль, спроектированный по законам качественной инженерии.