Я протестировал Claude Code и OpenCode на реальном рефакторинге. Вот что получилось
Каждую неделю кто-нибудь пишет: «Ну всё, мы приплыли. ИИ отобрал у нас работу». А ещё через неделю кто-то выкладывает скриншот, как очередной агент удалил .env-файл, и подписывает его: «лол».
Обе реакции понятны. Но ни одна из них ничего не доказывает. Поэтому вместо споров я взял и сравнил два терминальных ИИ-агента — Claude Code и OpenCode — на одной и той же реальной задаче: переносе сложного дашборда на Next.js 15 и React 19 с глубокой цепочкой пропсов на Zustand.
Меня интересовала не генерация кода с чистого листа, а реальная миграция большого проекта — где есть TypeScript, callback-пропсы, общее состояние интерфейса, проверка сборки и такая вложенность компонентов, что прокидывание пропсов начинает восприниматься как личное оскорбление.
Спойлер: результат не в духе «ИИ заменил разработчиков» и не «агенты бесполезны». Оба справились, оба споткнулись об одинаковые проблемы окружения, но один сделал более чистый первый проход. И самое интересное — в ошибках, а не в успехах.
Что именно тестировалось
Claude Code — официальный терминальный агент от Anthropic. Читает и меняет файлы, выполняет команды, анализирует кодовую базу, работает с MCP-инструментами. По умолчанию просит подтверждения для действий, меняющих состояние проекта — удобно, когда не хочется внезапно обнаружить половину репозитория переписанной без спроса.
OpenCode — открытый ИИ-агент с поддержкой разных моделей (Claude, GPT, Gemini, локальные LLM). Основной акцент — на гибкости и прозрачности работы.
Для чистоты эксперимента оба работали на одной модели — Claude Opus 4.6. Так оценивалась не сама модель, а уровень оркестрации и управления процессом, который даёт каждый агент.
Важно: это не научное исследование. Один проект, одна задача, один компьютер и один промпт. Практический отчёт, а не абсолютный рейтинг.
Задача рефакторинга
Тестовый проект — дашборд на Next.js 15, React 19, TypeScript и Tailwind. Кодовая база была намеренно неприятной, но реалистичной:
- дашборд управления проектами;
- моковые данные;
- шесть уровней вложенности компонентов;
- callback-пропсы, проходящие через компоненты, которые ими вообще не пользуются;
- глобальное состояние, поднятое слишком высоко в дереве компонентов.
Всё состояние находилось в dashboard/page.tsx и передавалось вниз через множество компонентов:
DashboardPage├─ DashboardHeader├─ Sidebar├─ ContentArea│ ├─ ProjectList│ │ └─ ProjectCard│ │ └─ TaskRow│ └─ StatsFooter└─ TaskModal
Один только ProjectCard получал восемь пропсов, большинство из которых просто прокидывал дальше в TaskRow. Идеальный кандидат на миграцию в Zustand.
Требования:
- создать Zustand Store для пользователя, проектов и UI;
- убрать prop drilling;
- удалить неиспользуемые пропсы;
- сохранить полную типобезопасность TypeScript;
- не сломать существующее поведение приложения.
Промпт
Оба инструмента получили одинаковое задание:
- полностью изучить кодовую базу;
- создать Zustand Store;
- перевести компоненты на работу со Store;
- удалить лишние пропсы;
- запускать tsc после каждого серьёзного изменения;
- в конце выполнить сборку;
- вести файл MISTAKES.md — записывать все ошибки, причины и способы исправления.
Последний пункт оказался особенно полезным. Вместо магического «оно как-то заработало» агенты были вынуждены документировать свои ошибки и ход рассуждений — а это критически важно, если хотите понимать, что именно ИИ делает в вашем проекте.
Как справился Claude Code
Claude Code начал правильно — сначала подробно изучил кодовую базу: открыл page.tsx, проследил импорты, проанализировал дочерние компоненты, составил карту состояния и связей. И только потом начал писать.
Созданный Zustand Store выглядел логично: состояние пользователя, проектов, интерфейса и отдельные действия для обновления задач и управления модальными окнами.
Ошибка №1. Поломка npm-шима. Первая проблема вообще не относилась к коду:
npx tsc --noEmitCannot find module '../lib/tsc.js'
После установки Zustand пересоздались скрипты в node_modules/.bin, и обёртка TypeScript стала ссылаться на неверный путь. Claude правильно диагностировал это как ошибку окружения и начал запускать бинарники напрямую:
node node_modules/typescript/lib/tsc.js --noEmitnode node_modules/next/dist/bin/next build
Типичная проблема реальных проектов, которую редко показывают в красивых демо.
Ошибка №2. Порядок миграции. Claude местами шёл сверху вниз — правил родительский компонент раньше, чем дочерние переставали зависеть от старых пропсов. Исправление простое, но ситуация хорошо показывает, насколько тесно связаны компоненты в глубоко вложенных React-приложениях.
Итог Claude Code:
- Время: 14 минут
- Ошибки TypeScript: 0
- Сборка: успешна
- Ошибок в журнале: 4 — из них 2 окружения и 2 кода
Как справился OpenCode
OpenCode начал иначе. Первым делом построил карту проекта через поиск всех .tsx-файлов, извлёк типовую информацию — и только потом приступил к изменениям. Создал практически такой же Zustand Store и не стал изобретать лишние абстракции вроде middleware или дополнительных провайдеров.
И дальше произошло самое скучное для любителей драматичных сравнений: оно почти сразу заработало.
OpenCode столкнулся ровно с теми же проблемами окружения — сломанный tsc и сломанная команда сборки Next.js. Но в отличие от Claude:
- не допустил ошибок в порядке рефакторинга;
- не пропустил зависимые компоненты;
- завершил миграцию без ошибок на уровне кода.
Результат — чище и быстрее. Но это не делает Claude Code плохим инструментом: его ошибки были понятными, легко исправлялись и оставляли хороший след для анализа. Более того, Claude лучше объяснял, какие побочные эффекты приложения нужно сохранить при миграции.
Что на самом деле показал этот тест
Самый важный вывод оказался неожиданным. Тест не про то, что один агент лучше другого. Он показал три вещи.
1. Модель — это ещё не весь инструмент. Оба агента использовали одну модель, но вели себя по-разному.
2. Порядок рефакторинга критически важен. Большинство ошибок возникает не из-за кода, а из-за неправильной стратегии миграции.
3. Проверка должна быть частью промпта. Регулярный запуск TypeScript и сборки спасает от постепенного накопления ошибок.
Как правильно писать промпты для CLI-агентов
После этого теста я бы всегда добавлял в большие рефакторинги такие правила:
- Работать снизу вверх — сначала листовые компоненты, потом родительские.
- Логировать каждое изменение — даже если ошибки не было.
- Не позволять агенту расширять область задачи — никаких лишних middleware, провайдеров и «улучшений архитектуры», если их не просили.
- Проверять побочные эффекты — любой callback может содержать аналитику, уведомления или навигацию; её легко случайно потерять.
Claude Code или OpenCode: что выбрать
Оба инструмента рабочие, выбор зависит от задачи:
- Claude Code — если нужна осторожность, строгие подтверждения действий и подробные объяснения каждого шага. Удобно на критичном или незнакомом коде, плюс тесная интеграция с экосистемой Claude и MCP.
- OpenCode — если важна гибкость в выборе моделей (Claude, GPT, Gemini, локальные), прозрачность и максимально чистый первый проход на рутинной миграции.
На этом тесте OpenCode сделал задачу быстрее и без ошибок на уровне кода, но Claude Code лучше документировал решения.
Вывод
Этот тест изменил мой взгляд на терминальных ИИ-агентов. OpenCode оказался быстрее и аккуратнее в конкретной задаче. Claude Code — осторожнее и лучше объяснял решения. Но главный вывод вообще не про инструменты.
CLI-агенты не заменяют инженерное мышление. Они ускоряют работу тех, кто умеет:
- выбрать правильную стратегию миграции;
- понимать архитектуру проекта;
- определять риски;
- отличать успешную сборку от действительно правильного результата.
Больше всех выиграют не те, кто игнорирует ИИ, и не те, кто слепо ему доверяет. А те, кто способен сказать агенту: с чего начать, где остановиться и что ни в коем случае нельзя сломать.
Оставьте себе агента, компилятор и файл MISTAKES.md. Именно там происходит настоящая работа разработчика.
Разбираю ИИ-кодинг каждый день — без хайпа и паники. Telegram: @codautomat. Оригинал статьи: codautomat.tech