AI-инструменты разработчика в 2026 году
Код, на который раньше уходил день, сегодня пишется за час — если правильно ставить задачу модели и проверять результат. Пишется за день — если принимать вывод LLM на веру и потом неделю отлавливать плаузибельные баги. Разница между этими сценариями не в инструменте, а в подходе инженера, и этот подход — предмет главы.
В краткой версии ты видел обзор: Copilot дополняет, Cursor правит, Ollama держит приватный код дома. Здесь разберём глубже: как устроены инструменты внутри (контекстное окно, retrieval, агентные циклы), почему модель уверенно ошибается и как это ловить, как организовать агентный workflow «план — исполнение — проверка» и в какой момент фундаментальные знания из предыдущих двенадцати разделов становятся единственным фильтром, отличающим работающую систему от красиво оформленной ошибки.
Как устроены Copilot, Cursor и Windsurf
Заголовок раздела «Как устроены Copilot, Cursor и Windsurf»Под оболочками — три разных архитектурных подхода к одной задаче: дать модели релевантный контекст и встроить её ответ в поток работы.
GitHub Copilot — автодополнение следующего токена с учётом открытых файлов. Модель получает «префикс» (код до курсора, соседние вкладки, недавно закрытые фрагменты) и предлагает продолжение. Это generative-подход: быстро, дёшево, работает в любой IDE. Ограничение — модель мыслит локально: она видит кусок файла, но не архитектуру проекта. Отсюда классика: функция идеальна сама по себе, но использует API, которого нет в проекте, или дублирует существующую утилиту в трёх директориях выше.
Cursor — форк VS Code, где контекст собирается осознанно: индекс репозитория (эмбеддинги всех файлов, разбитых на чанки), поиск по индексу при каждом запросе, режим Composer с правками в нескольких файлах, ручное добавление файлов в контекст через @. Режимы и приёмы работы с контекстом описаны в документации Cursor. Это retrieval-подход: модель отвечает не из «своих знаний об усреднённых проектах», а из найденного в твоём коде. Отсюда главное качество Cursor — правки, которые уважают существующие соглашения проекта.
Windsurf (Codeium) — тот же retrieval-подход с акцентом на «agentic» режим: модель сама планирует последовательность правок, выполняет их, запускает команды и продолжает по результату. Разница с Cursor — скорее в UX и цене, чем в принципе.
Границы: галлюцинации и приватность
Заголовок раздела «Границы: галлюцинации и приватность»Галлюцинации — не баг, а устройство. LLM генерирует правдоподобное продолжение текста, а не истину. Самый опасный тип — плаузибельный баг: код выглядит идиоматично, использует знакомые паттерны, но неверно обрабатывает пограничный случай (off-by-one в пагинации, гонка в асинхронном коде, regex, пропускающий юникод). Тон ответа не сигнализирует об ошибке: уверенный неверный ответ выглядит как уверенный верный.
Что помогает ловить:
- Проверка пограничных случаев руками, а не взглядом: null/пустые коллекции, границы диапазонов, конкурентные вызовы, кодировки.
- Тесты как критерий приёмки: промпт, требующий тесты, не от гребущего перфекционизма — он превращает «выглядит ок» в проверяемое утверждение.
- Ревью с чек-листом классов ошибок (гонки, ресурсы, async), а не общее «посмотри код» — см. ниже.
Приватность — второй жёсткий предел. Код, отправленный в облачный сервис, покидает твой периметр: условия провайдера, судьба обучающих данных, корпоративные политики. Коммерческий код под NDA, конфиги с адресами внутренних сетей, ключи — отправлять наружу нельзя. Здесь не помогает «не показывай секреты в промпте»: репозиторий целиком может быть под NDA. Решение — локальные модели, об этом ниже.
Промпт-инжиниринг для кода: четыре части хорошей задачи
Заголовок раздела «Промпт-инжиниринг для кода: четыре части хорошей задачи»Плохой промпт — «напиши валидацию email». Модель угадывает стек, фреймворк, формат ответа и пишет что-то среднее по индустрии, что редко совпадает с твоим проектом. Хороший промпт имеет структуру: контекст → задача → ограничения → формат результата.
Контекст: Node.js 20, Express 4, TypeScript strict, проект на ESM. В проекте уже есть middleware-обработчик ошибок: next(err) → { error: string }.
Задача: Middleware validateEmail для поля email в теле POST /register.
Ограничения: - regex по упрощённому RFC 5322, максимум 254 символа, только ASCII - ошибка — через next(new HttpError(400, "invalid_email")), НЕ res.status().json() - без сторонних библиотек (zod не подключать) - существующий стиль: именованные функции, без default export
Формат: Один файл src/middleware/validate-email.ts Плюс тесты на vitest: валидный email, без "@", 300 символов, юникод в домене.Каждая часть закрывает класс галлюцинаций: контекст — от неправильного стека и API; ограничения — от несуществующих зависимостей и чужих паттернов; формат — от размазанного ответа, который приходится выковыривать.
Правила, которые стабильно работают:
- Контекст сначала. Стек, версии, соглашения — до задачи. Модель якорится на начале промпта.
- Малые задачи. Одна функция, один файл, один сценарий. «Перепиши модуль» даёт мусор, потому что модель теряет детали на длине.
- Критерий готовности. Тесты, типизация, линтер — то, чем проверить результат. Промпт без критерия — заказ без ТЗ.
- Образец сильнее описания. «Сделай как функция X ниже: <код>» передаёт стиль точнее любых прилагательных.
Ревью промптом строится иначе, чем генерация: не «оцени код», а проверка конкретных классов проблем. Общее «найди баги» модель проводит поверхностно; перечисленные классы — системно:
Ревью как senior-инженер. Ищи ТОЛЬКО:1. Гонки данных: shared state между запросами, неатомарные check-then-act.2. Утечки ресурсов: незакрытые соединения БД, таймеры без clearInterval, stream без destroy.3. Необработанные rejections в async-функциях (вызывающий код получает unhandled?).4. SQL-инъекции и непараметризованные запросы.Не предлагай стилистику и переименования. Каждая находка: файл:строка, суть, сценарий воспроизведения.Плохая и хорошая генерация: один пример целиком
Заголовок раздела «Плохая и хорошая генерация: один пример целиком»Смотреть на промпт-инжиниринг без живого примера — как учить плавание по картинке. Возьмём задачу из pet-проекта: рейтлимитер для API.
Плохой запрос и типичный результат:
запрос: «напиши rate limiter для express»проблемы: модель не знает проект — пишет middleware с хранением счётчиков в Map внутри процесса (при двух инстансах за балансировщиком лимит удваивается), без TTL (утечка памяти), с фиксированным окном (edge case: 2× лимит на границе окна), без заголовков Retry-After.Хороший запрос:
Контекст: Express 4, TypeScript, кластер из 2+ инстансов за ALB, Redis уже есть (ioredis), ключ лимита — user id из req.user.
Задача: Sliding window rate limiter: 100 запросов/мин на пользователя.
Ограничения: - счётчики ТОЛЬКО в Redis (переживает масштаб), Lua-скрипт для атомарности - при отказе Redis — пропускать запрос (fail-open) + error log, НЕ 500 - ответ 429: { error: "rate_limited", retry_after: <сек> } - заголовки: X-RateLimit-Remaining, X-RateLimit-Reset
Формат: src/middleware/rate-limit.ts + vitest-тест с ioredis-mock: 101-й запрос за минуту → 429; после сдвига окна → 200.// Результат под такой промпт — уже близок к продакшену (сокращено)import type { Request, Response, NextFunction } from "express";import Redis from "ioredis";
const lua = ` local key = KEYS[1] local now = tonumber(ARGV[1]) local window = tonumber(ARGV[2]) local limit = tonumber(ARGV[3]) redis.call('ZREMRANGEBYSCORE', key, 0, now - window) local count = redis.call('ZCARD', key) if count < limit then redis.call('ZADD', key, now, now .. ':' .. math.random()) redis.call('PEXPIRE', key, window) return {1, limit - count - 1, window} end return {0, 0, window}`;
export function rateLimit(redis: Redis, limit = 100, windowMs = 60_000) { return async (req: Request, res: Response, next: NextFunction) => { try { const now = Date.now(); const [ok, remaining, reset] = await redis.eval( lua, 1, `rl:${req.user.id}`, now, windowMs, limit, ) as [number, number, number]; res.setHeader("X-RateLimit-Remaining", remaining); res.setHeader("X-RateLimit-Reset", Math.ceil((now + reset) / 1000)); if (!ok) { return res.status(429).json({ error: "rate_limited", retry_after: Math.ceil(reset / 1000) }); } next(); } catch (err) { req.log.error({ err }, "redis down, rate limit skipped"); // fail-open next(); } };}Разница не в модели — в том, что промпт указал на: распределённое состояние, атомарность, поведение при отказе, формат ответа. Это те самые вопросы, которые ты задаёшь код-ревью, — теперь они заданы до генерации. И всё равно: тесты, гонка на границе окна, нагрузочная проверка — руками.
Агентные workflow: планирование — исполнение — проверка
Заголовок раздела «Агентные workflow: планирование — исполнение — проверка»Следующий уровень после «модель пишет по запросу» — агент, который выполняет задачу циклом: план → действие → наблюдение → коррекция. Claude Code и аналоги (aider, Continue с агентом, OpenAI Codex CLI) работают так: читают репозиторий, правят файлы, запускают команды, смотрят вывод, идут дальше. Справка по Claude Code — в документации Anthropic.
Рабочий цикл выглядит так:
1. ПЛАНИРОВАНИЕ Задача: «добавь экспорт отчёта в CSV». Агент читает код, предлагает план: новый endpoint, сервис экспорта, тесты. ТЫ утверждаешь план — до первой правки.
2. ИСПОЛНЕНИЕ Агент правит файлы, пишет тесты, запускает их сам.
3. ПРОВЕРКА Агент смотрит результат: тесты зелёные? типы сходятся? линтер? Падает — цикл исполнение↔проверка повторяется (автономно, в рамках лимита шагов).
4. ТВОЯ ПРОВЕРКА git diff. Ревью глазами + прогон тестов локально. Коммит — только после.Ключевые дисциплины, без которых агент вреднее помощника:
- Git — обязательное условие. Каждая задача — отдельная ветка/коммит, чистое состояние перед стартом. Агент правит уверенно и нечаянно: откат — единственная защита. Никогда не давай агенту работать над несколькими задачами в одной рабочей копии.
- План утверждает человек. «Сделай экспорт в CSV» агент может понять как «добавь кнопку во фронте, перепиши API, вынеси логику в новый микросервис». Десять секунд на чтение плана экономят час отката.
- Проверочные команды — часть задачи. В промпт агенту включай: «запусти npm test, npm run typecheck; работа готова только когда оба зелёные». Без этого агент считает готовым «код написан».
# Пример сессии с Claude Code — задача с критериями готовностиclaude> Задача: вынести retry-логику из src/http/client.ts в src/http/retry.ts, не меняя поведение. Критерии готовности: 1. npm run typecheck — без ошибок 2. npm test — все зелёные (тесты на retry существуют) 3. git diff --stat показывает ровно 2 файла Сначала предложи план, жди моего подтверждения.> [план] ... ок, выполняй> [правки, запуск тестов, исправление] готово# теперь ТЫ: git diff, прогон тестов руками, коммитЛокальные модели: Ollama для приватного кода
Заголовок раздела «Локальные модели: Ollama для приватного кода»Ollama — рантайм локальных LLM: скачал модель одной командой, получил API на localhost:11434, совместимый с OpenAI-клиентами. Код не покидает машину — приватность из коробки. Полный гайд по моделям и API — в документации Ollama.
# Установка и запуск (Arch Linux)sudo pacman -S ollamasystemctl enable --now ollama
# Модели для кода: качество/скорость на обычной машинеollama pull qwen2.5-coder:7b # лучшая «кодовая» 7B на 2026, ~4.7 GBollama pull deepseek-coder-v2:16b # если RAM ≥ 16 GB, заметно умнееollama pull llama3.1:8b # универсальная: объяснения, документация
# OpenAI-совместимый endpoint — подключается к Continue, aider, своим скриптамcurl http://localhost:11434/v1/chat/completions -H "Content-Type: application/json" -d '{ "model": "qwen2.5-coder:7b", "messages": [{"role": "user", "content": "Объясни, что делает этот скрипт: <код>"}]}'Честно о качестве: локальные модели 2026 года (7–16B, Q4-квантование) заметно слабее облачных флагманов. Они хороши для: объяснения кода, черновых комментариев и докстрингов, простых утилит по образцу, рефакторинга с чётким ТЗ. Они плохи для: архитектурных решений, хитрых пограничных случаев, кода, где ошибка дорога. Гибридная стратегия: приватный код и конфиги — локально; несекретные черновики и тесты — облачные флагманы. Критерий — тип данных, не удобство.
RAG по кодовой базе кратко
Заголовок раздела «RAG по кодовой базе кратко»Cursor и Windsurf делают retrieval внутри себя; для своих инструментов принцип тот же и прост:
- Индекс: репозиторий разбивается на чанки (функции/классы по AST, а не по строкам), каждый чанк превращается в эмбеддинг — вектор смысла.
- Поиск: вопрос → эмбеддинг → ближайшие чанки по косинусной близости → они попадают в контекст модели.
- Ответ модель строит уже на реальном коде проекта, а не на догадках.
Инструменты для своего RAG: continue.dev (поддерживает локальные эмбеддеры через Ollama — и тогда даже эмбеддинги не уходят в облако), Sourcegraph Cody для больших монореп. Эффект тот же, что у Cursor, но под твоим контролем — важно для корпоративных репозиториев.
AI для тестов, документации и legacy
Заголовок раздела «AI для тестов, документации и legacy»Три задачи, где агенты сегодня дают максимум пользы при минимуме риска:
- Тесты. «Напиши тесты на эту функцию, покрывай пограничные случаи: пустые входы, границы диапазонов, ошибки зависимостей». Агент методичен там, где человеку скучно. Проверка твоя: тесты должны реально падать при сломанном коде (мутируй функцию — тесты должны зазеленить обратно).
- Документация. Docstrings, README, ADR (architecture decision records) по diff’у. Черновик — агенту, точность — тебе.
- Legacy-код. Классический первый шход перед рефакторингом: «прочитай модуль, объясни, что он делает, от чего зависит, где опасные места; НЕ предлагай правки». Карта незнакомого кода за минуты вместо дней чтения. Сверяй с реальным поведением — модель иногда домысливает намерения по коду, который их давно утратил.
Почему фундамент стал дороже, а не дешевле
Заголовок раздела «Почему фундамент стал дороже, а не дешевле»Парадокс эпохи: чем сильнее инструменты, тем дороже неумение ими пользоваться. Человек без базы не отличит правильный ответ LLM от красиво оформленной ошибки — для него оба одинаково убедительны. Твой фильтр — двенадцать разделов этого учебника:
- Знаешь сети — увидишь, что сгенерированный Nginx-конфиг ломает WebSocket (нет
Upgrade-заголовков) или что retry-шторм создаст, потому что понимаешь TCP. - Знаешь SQL и транзакции — заметишь, что запрос из LLM положит таблицу seqscan’ом, а «проверь, потом вставь» в идемпотентности — гонка.
- Знаешь CAP и репликацию — поймёшь, почему «просто синхронизируем два дата-центра» из ответа модели — фантастика, и сформулируешь правильный вопрос (async-репликация и read-your-writes).
- Знаешь экономику облака — рассчитаешь, что предложенная архитектура стоит $2000/мес там, где хватит $40, и спросишь модель заново с ограничением бюджета.
- Знаешь безопасность — увидишь в сгенерированном коде SQL-инъекцию, секрет в env-примерке, открытый CORS.
AI — ускоритель, а не замена. Пилот без понимания аэродинамики не садит самолёт даже с автопилотом: он не знает, когда автопилот ошибается. Твоя ценность — ставить задачу, проверять результат и отвечать за систему. Этому и учили предыдущие разделы.
Типичные ошибки и грабли
Заголовок раздела «Типичные ошибки и грабли»- Принятие вывода без запуска. «Код выглядит правильно» ≠ «код работает». Минимальный барьер: тесты и typecheck прогнаны. Максимальный: пограничные случаи проверены руками.
- Промпт без контекста проекта. «Напиши X» → модель выдумывает стек и соглашения. Следствие: код в чужом стиле с несуществующими зависимостями. Контекст — первый абзац, всегда.
- Агент без git-дисциплины. Работа в «грязной» рабочей копии: агент затронул не те файлы, откат невозможен. Правило: ветка на задачу, чистый diff, коммит до и после.
- Отправка приватного кода в облако. «Только один файлик» с внутренним доменом и структурой БД — утечка архитектуры. Решение принимается по типу данных до открытия чата, не по настроению.
- Доверие к уверенности модели. Тон ответа не коррелирует с правильностью. Ловушка особенно коварна у опытных: чем грамотнее сгенерированный код, тем меньше подозрений — а плаузибельные баги пишутся грамотно.
- Деградация навыка. Месяц «пусть AI напишет» без ручной работы — и скорость печати кода падает, и чувство пограничных случаев тупится. Используй AI как спарринг-партнёра: сначала сам, потом сравнить.
Вопросы на собеседовании
Заголовок раздела «Вопросы на собеседовании»- Как устроен Cursor и чем отличается от Copilot? Copilot — автодополнение по префиксу (генерация), Cursor — чат с retrieval: индекс репозитория через эмбеддинги, контекст собирается поиском по нему, правки в нескольких файлах. Разница — локальная генерация против поиска по проекту.
- Что такое галлюцинация LLM и как с ней работать? Генерация правдоподобного, но неверного: несуществующие API, плаузибельные баги. Работа: критерии приёмки в промпте, проверка пограничных случаев руками, тесты, ревью по чек-листу классов ошибок.
- Структура хорошего промпта для кода? Контекст (стек, соглашения) → задача → ограничения (что нельзя, какие зависимости, поведение при ошибках) → формат результата (файлы, тесты).
- Как безопасно работать с AI-агентом в репозитории? Чистая ветка, утверждение плана до правок, проверочные команды как критерий готовности, git diff и прогон тестов человеком перед коммитом. Никогда без отката.
- Когда локальные модели через Ollama предпочтительнее облачных? Когда код, конфиги или данные не должны покидать периметр: NDA, коммерческие секреты, внутренние инфраструктурные детали. Цена — качество ниже флагманов; выбирают по типу данных.
- Почему фундаментальные знания важнее в эпоху AI? Без них невозможно отличить верный ответ LLM от плаузибельной ошибки: человек без базы принимает оба. Знания — фильтр, через который проходит каждый AI-вывод, и единственная основа для постановки задачи и проверки результата.
Практика
Заголовок раздела «Практика»- Возьми одну реальную задачу pet-проекта. Сначала напиши решение сам. Затем сгенерируй тем же требованиям через хороший промпт (контекст → задача → ограничения → формат). Сравни: что предложила модель, чего не хватило твоему решению, какие пограничные случаи упустили оба.
- Составь промпт-чек-лист ревью (5–7 классов проблем: гонки, ресурсы, async, инъекции, секреты, обработка ошибок). Прогони им три последних коммита проекта. Запиши: что нашла модель, что пропустила, что нашёл ты и она нет.
- Подними Ollama с
qwen2.5-coder:7b, подключи Continue.dev или aider к локальному endpoint. Реши одну несекретную задачу локально: черновик документации или утилита. Замерь скорость и качество против облачной модели на той же задаче. - Делегируй агенту (Claude Code/aider) генерацию тестов на модуль с самой сложной логикой проекта. Мутируй код (сломай условие) и проверь: какие тесты ловят поломку, какие — нет. Доработай недостающие тесты вручную.
- Найди участок legacy-кода, который давно боишься трогать. Попроси агента объяснить его и построить карту зависимостей, без предложений правок. Сверь с реальным поведением: запусти, поставь логи, проверь один сценарий end-to-end.
Что почитать
Заголовок раздела «Что почитать»- Cursor Documentation — индексация, режимы, контекст
@-ссылками. - Ollama — каталог моделей и OpenAI-совместимый API.
- Aider — агент в терминале, работающий через git.
- Anthropic — Effective context engineering for agents — как собирать контекст агенту.
- Prompting Guide — Code Applications — систематизация промптов для кода.