Дайте Claude Code и Codex одинаковый каталог, пять коротких задач и общую шкалу оценки. Сравнивайте исправленный код, проверки и ваши вмешательства. Так выбор инструмента будет опираться на работу, которую вы понимаете и можете повторить.

Для сравнения берём одинаковый исходный проект, одни задачи и общий список проверок. Иллюстрация показывает принцип сравнения, а не результат эксперимента.

Выберите, что хотите сравнить

Оба инструмента могут читать локальный проект, менять файлы и выполнять команды. Это описано в руководствах Claude Code и Codex CLI. Но одинаковое назначение не обещает одинакового результата.

Сравнительный опыт в этом материале не проводился. Ниже есть всё для собственного запуска: исходные файлы, задания и шкала оценки. Результат получите на своей машине; время, стоимость и победителя можно назвать только после реальных запусков.

Для упражнения нужны установленные CLI, рабочий доступ к обоим инструментам, Git, браузер, Node.js со встроенным модулем node:test и Python 3 для локальной страницы. Установку пройдите по официальным ссылкам. Если пока работали только с одним агентом, полезно сначала разобрать пример запуска Qwen Code: общий принцип работы с папкой проекта похож.

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

Соберите одинаковый исходный проект

Создайте папку agent-compare-baseline. В ней будут три файла. Все товары вымышлены; внешних запросов и зависимостей у страницы нет.

В catalog.mjs сохраните:

export const products = [
  {id: 'cup', name: 'Кружка', price: 450},
  {id: 'card', name: 'Открытка', price: 0},
  {id: 'lamp', name: 'Лампа', price: 1200}
];

export function formatPrice(value) {
  return value ? `${value} ₽` : '—';
}

export function searchProducts(items, query) {
  return items.filter((item) => item.name.includes(query));
}

export function sortProducts(items) {
  return items.sort((a, b) => a.price - b.price);
}

export function getProduct(items, id) {
  return items.find((item) => item.id === id);
}

export function getStatus(items) {
  return `Найдено: ${items.length}`;
}

Здесь есть пять мест для улучшения. Они намеренные: функция цены смешивает ноль и отсутствие значения, поиск учитывает регистр, сортировка меняет исходный массив. Остальные пограничные случаи зададим ниже.

В catalog.test.mjs добавьте исходные проверки:

import test from 'node:test';
import assert from 'node:assert/strict';
import {
  products, formatPrice, searchProducts,
  sortProducts, getProduct, getStatus
} from './catalog.mjs';

test('цена обычного товара', () => {
  assert.equal(formatPrice(450), '450 ₽');
});

test('поиск точного названия', () => {
  assert.equal(searchProducts(products, 'Кружка').length, 1);
});

test('порядок по цене', () => {
  assert.deepEqual(
    sortProducts([...products]).map((item) => item.id),
    ['card', 'cup', 'lamp']
  );
});

test('существующий товар', () => {
  assert.equal(getProduct(products, 'cup').name, 'Кружка');
});

test('статус непустого списка', () => {
  assert.equal(getStatus(products), 'Найдено: 3');
});

Встроенный тестовый модуль Node.js позволяет выполнить этот файл без установки библиотеки. Эти пять тестов проверяют обычные случаи. Прохождение исходной проверки ещё не доказывает, что будущая задача решена.

В index.html сохраните страницу:

<!doctype html>
<html lang="ru">
  <head>
    <meta charset="utf-8">
    <title>Каталог для сравнения агентов</title>
  </head>
  <body>
    <main>
      <h1>Учебный каталог</h1>
      <label for="query">Название товара</label>
      <input id="query" type="search">
      <p id="status" role="status"></p>
      <ul id="products"></ul>
    </main>
    <script type="module">
      import {
        products, formatPrice, searchProducts, getStatus
      } from './catalog.mjs';

      const input = document.querySelector('#query');
      const list = document.querySelector('#products');
      const status = document.querySelector('#status');

      function update() {
        const matches = searchProducts(products, input.value);
        list.replaceChildren();
        for (const product of matches) {
          const item = document.createElement('li');
          item.textContent =
            product.name + ': ' + formatPrice(product.price);
          list.append(item);
        }
        status.textContent = getStatus(matches);
      }

      input.addEventListener('input', update);
      update();
    </script>
  </body>
</html>

Модуль с функциями используется и тестами, и страницей. Поэтому можно проверить вычисления отдельно, а затем посмотреть, что видит посетитель.

Проверьте исходные файлы до агента

Выполните из папки проекта:

node --test catalog.test.mjs
python3 -m http.server 8000 --bind 127.0.0.1

На Windows вместо второй команды можно использовать py -m http.server 8000 --bind 127.0.0.1, если Python установлен с этим launcher. Команда http.server запускает учебный сервер. Откройте http://127.0.0.1:8000. Сервер привязан к локальному адресу; остановить его можно сочетанием Ctrl+C в терминале.

Исходные тесты должны пройти, а страница показать три товара. У открытки цена будет «—». Это известный дефект, который войдёт в первое задание. Если проект не открывается до работы агента, сначала исправьте среду: её сбой нельзя записывать в оценку инструмента.

Сохраните исходную папку. Для каждого задания создавайте две новые копии: одну для Claude Code, другую для Codex. Получится десять рабочих копий. Не переносите решение первого агента второму и не продолжайте следующую задачу поверх предыдущего исправления.

В каждой копии инициализируйте Git и сделайте исходный коммит. Проверьте git status --short: перед запуском изменений быть не должно. Этот снимок нужен для просмотра результата, а не для отправки в удалённый репозиторий.

Запишите условия сравнения

Для каждого запуска сохраните дату, версию CLI, выбранную модель и её настройки, операционную систему, рабочую папку и доступные инструменты. Используйте сведения текущей сессии, а не номер модели из чужого примера.

У Codex команды /status, /model и /permissions помогают проверить параметры сессии. У Claude Code тоже проверьте модель и разрешения в интерфейсе. На время упражнения обоим агентам нужны чтение, правка учебных файлов и запуск локальных тестов. Не подключайте дополнительные MCP-сервисы одному участнику сравнения.

Документированное различиеКак учесть в опыте
Claude Code использует инструкции CLAUDE.md и поддерживает AGENTS.md при описанных в документации условияхПроверьте фактически загруженный контекст; не предполагайте, что файлы читаются одинаково.
Codex собирает инструкции из AGENTS.md и AGENTS.override.md по иерархии проектаПроверьте, какие личные и проектные инструкции действуют в копии.
У инструментов разные режимы и механизмы разрешенийЗапишите возможности каждого режима словами: где разрешена запись, какая команда требует подтверждения.

Порядок инструкций описан в руководстве Claude Code и руководстве OpenAI. У Codex актуальные профили разрешений отделены от политики подтверждений. Не переносите поля конфигурации одного инструмента другому.

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

Дайте пять независимых задач

Для каждого задания отправьте обоим агентам общий текст ниже, дополнив его ровно одной строкой из таблицы.

Прочитайте три файла учебного каталога.
Решите только задачу ниже.
Сохраните существующее поведение остальных функций.
Не добавляйте зависимости и не меняйте данные товаров.
Добавьте проверку нового пограничного случая.
Запустите node --test catalog.test.mjs.
В конце перечислите изменения, выполненные проверки
и то, что осталось непроверенным.
ЗадачаСтрока запроса и приёмка
1. Нулевая ценаformatPrice(0) возвращает «0 ₽»; для null и undefined результат «—»; для 450 результат «450 ₽».
2. Нормализация поискаЗапрос « КРУЖ » находит кружку; пустая строка возвращает все товары; «палатка» даёт пустой массив.
3. Сортировка без изменения входаsortProducts возвращает порядок card, cup, lamp; исходный массив и порядок его элементов сохраняются.
4. Отсутствующий товарgetProduct возвращает null для неизвестного id; существующий товар возвращается как прежде.
5. Сообщение пустого спискаgetStatus([]) возвращает «Ничего не найдено»; для трёх товаров остаётся «Найдено: 3».

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

После каждого ответа сами запускайте тесты и читайте git diff. Для задач 1, 2 и 5 обновляйте страницу: смотрите цену открытки, поиск и сообщение. Для сортировки отдельно проверяйте исходный порядок массива. Наличие слова «immutable» в объяснении ничего не доказывает.

Оцените результат по одной рубрике

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

Критерий0 баллов1 балл2 балла
ПоведениеЗадача не решенаЧасть случаев работаетВсе случаи задания проходят
РегрессииСломано прежнее поведениеПроверено не всёИсходные проверки проходят
Объём правкиПосторонние измененияЕсть лишние строкиПравка ограничена задачей
ПроверкиНе выполнены или выдуманыЧастичныРеальный запуск и нужные утверждения
ОтчётНельзя сверитьНе хватает конкретикиФайлы, команды и ограничения указаны

Время и вмешательства записывайте отдельно. Заранее определите начало и конец отсчёта: например, от отправки задания до проверенного diff. Запишите каждый дополнительный запрос и его причину. Обычное подтверждение разрешённой команды отделяйте от подсказки о способе решения.

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

Сделайте вывод для своей работы

Сначала сравните пары по задачам: где агент сохранил данные, где добавил полезный тест, где потребовалось больше пояснений. Затем посмотрите общий балл и ограничения среды. По одному удачному ответу нельзя судить обо всех проектах, моделях и версиях.

Практический вывод может быть узким: выбранная конфигурация лучше подошла для небольших правок вашего каталога. Такой результат полезнее обещания универсального победителя. При смене модели или условий повторите опыт на свежих копиях.

После сравнения откройте бесплатный раздел курса «Разработка с AI-агентами: инженерный подход». Возьмите один сложный для обоих инструментов случай и потренируйте постановку задачи, проверку и точную обратную связь.