Сравнение Codex, Claude Code и Kimi. Кто лучше на практических задачах

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

Что на входе

Экспериментальный проект — рабочий лендинг агентства. Стек: Next.js 16.2.10, React 19, TypeScript, Tailwind v4, next-intl. Сайт собирается в два отдельных билда под два домена ru/en, для тестов используются vitest и Cypress, настроен CI/CD.

Одна важная деталь: серверного кода в проекте не было вообще. Все страницы пререндерены заранее в SSR, а все переменные окружения имеют префикс NEXT_PUBLIC_ — это значит, что они попадают в собранный бандл и видны любому, кто откроет исходники страницы. Форма заполнения заявки уже была отрисована, но данные никуда не отправляла.

Это то, что необходимо было доделать — отправку заявки в CRM систему. Задачу я скопировал в каждую сессию дословно, вместе с опечатками:

Разработка CRM-хука для формы отправки данных

Сейчас на всех кнопках отправки заявкина проект ничего не происходит. Нужно чтобы заполненные поля валидировались и отправлялись в CRM систему. Это будет Система X - отдельная очередь Лиды.

Сервис должен дергаться на бекенде сайта, не отсвечивая конечный адрес в исходниках фронта, отдающихся на клиент.

Нужно рассмотерть два варианта создания задач: либо напрямую дергается апи crm, либо создать отдельную форму в яндекс формах, автоматически заполнять ее, а потом уже интегрировать форму и crm.

Задача понравилась мне тем, что в ней есть и элементы ресерча, несколько вариантов решения без готового ответа и по объему она небольшая и изолированная, легче будет анализировать результат. Я намеренно предложил два направления решения — интересно было посмотреть, как агент обойдётся с неопределённостью.

Кто участвует в сравнении:

CLI

версия

модель

контекст

codex

codex-cli 0.145.0

gpt-5.6-sol

258 400

claude code

Claude Code 2.1.220

claude-opus-5

1M

kimi

kimi 1.49.0

kimi-k3 (Moonshot API)

1M

Прогонов на самом деле было четыре. Первый codex я запустил на дефолтных настройках и только потом, уже разбирая цифры, заметил, что дефолтный уровень рассуждений у codex-cli — low, а у Claude Code — xhigh. То есть при сравнении уровень effort’a был нерелевантен, поэтому прогон в codex пришлось повторить увеличив уровень до extra high. Проход на Low уровне я из сравнения убрал, но для информации могу отметить, что переключение уровня добавило к реализации на codex вчетверо больше тестов и в 4.6 раза дороже.

Первый шаг: Анализ кодовой базы

Перед стартом задачи я прогнал в каждой копии команду /init. Она просит агента изучить проект и написать документацию для будущих сессий — что-то вроде шпаргалки, которую студент готовит себе перед экзаменом.

В результате получились файлы в 37 строк у codex, 94 у claude и 126 у kimi. В целом во всех трех файлах не было чего-то надуманного или некорректного, но вот что каждый счёл нужным включить в файл, сильно отличалось.

Codex написал документ, больше описывающий процесс разработки. Он взял шаблон «Repository Guidelines» за основу и из него включил в описание: структуру модулей, команды, стиль кода, а также правила коммитов и пулл-реквестов. Двухдоменную сборку он упомянул одним абзацем, зато единственный расписал, что должно быть в описании PR.

Claude написал документ больше про архитектуру проекта с обоснованиями. Первый раздел у него называется «Two single-locale builds, one codebase» и в нем описывается: почему в маршрутах нет языкового сегмента, почему переключатель языка это обычная ссылка на соседний домен и почему публичные переменные приходится передавать в Docker аргументами сборки.

Kimi написал скорее полноценную документацию reference. Самый длинный из трёх: версии всего стека, дерево репозитория с комментарием к каждому каталогу, модель хранения контента, тестирование, сборка и деплой вплоть до перечня секретов в CI. Он единственный вынес критерий приёмки отдельной именованной строкой — «verification gate for a change».

И у него же в конспекте оказался раздел «Security considerations», а в нём вот такое:

No server-side secrets exist. Every env var is NEXT_PUBLIC_* and therefore public in the client bundle — never introduce a private secret with that prefix.

The contact form submits nowhere (no backend). If a backend is added, treat validation, consent checkbox, and rate limiting as server responsibilities.

Получается, что kimi сразу подметил момент связанный с безопасностью, что нельзя хранить сенситив данные во фронтовой сборке. И задаче требовалось именно то, о чём он написал — сделать бэкенд и спрятать от клиента адрес внешнего API.

Второй шаг: выполнение задачи

Дальше каждый агент получил одинаковые инструкции с исходной задачей и начался процесс ее выполнения.

Я ожидал разного поведения на развилке из двух вариантов, но прямой вызов API CRM выбрали все три, связку через Яндекс Формы не стал делать никто. Все агенты делали полноценный ресерч: Claude сделал 10 запросов на чтение страниц и два поиска. Codex — 4 серверных поиска с прицельными запросами вида site:yandex.ru/dev/. Kimi запустил для ресерча отдельного субагента, тот сходил по докам 8 раз.

Контракт для работы с API в итоге получился у всех один и тот же:

POST https://api.crm.com/v1/leads/
Authorization: OAuth <token>  |  Bearer <IAM-token>
X-Org-ID  |  X-Cloud-Org-ID

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

Назначение

codex

claude code

kimi

API-маршрут

app/api/contact/route.ts

app/api/lead/route.ts

app/api/lead/route.ts

Валидация, контракты

lib/contact.ts

lib/lead.ts

lib/lead.ts

Клиент CRM

lib/crm.ts

lib/crm.ts

lib/crm.ts

Throttling

Внутри роутера

lib/rate-limit.ts

Тестовая инфраструктура

test/server-only.ts

Тесты

app/api/contact/route.test.tslib/contact.test.tslib/crm.test.ts

app/api/lead/route.test.tslib/lead.test.tslib/rate-limit.test.tslib/crm.test.ts

app/api/lead/route.test.tslib/lead.test.ts

Правки в компонентах формы

ContactForm.tsx

ContactForm.tsxContactFormWithToast.tsxContactModal.tsxContactBlock.tsxContactSection.tsx

ContactForm.tsx

Итого в src/

7 новых, 2 изменённых

8 новых, 6 изменённых

5 новых, 2 изменённых

В этот момент мне показалось, что сравнивать особо и нечего, все агенты справились с задачей.

Сравнение результатов

Форма заявки на сайте используется в трёх местах: в модальном окне, в блоке на странице контактов и в секции на лендинге. В каждом месте она подключается чуть по-своему. Claude Code поправил каждое из этих мест. Два других агента поправили сам компонент формы и на этом закончили.

Далее кратко какие функции добавили агенты сами на основе своих знаний и своего харнеса:

codex

claude code

kimi

Валидация данных на сервере

+

+

+

Honeypot от ботов

+

+

Throttling

+

+

Защита от повторной отправки

+

Ретраи при ошибке сервера

+

+

Проверка источника запроса

+

XSS защита

+

Если считать по перечисленным функциям, то вперёд вырывается codex: 6 пунктов из 7 против 5 у claude и 1 у kimi. Причём два из них: проверка источника запроса и XSS защита больше никто не сделал. Но это не самый правильный подход к оценке, потому что codex проявил фантазию и вообще очень много сделал сверх того о чем его просили.

Единственное, чего codex не сделал — защиту от повторной отправки, в отличие от Claude Code. Claude передаёт в CRM поле unique и если запрос оборвётся уже после того, как заявка создалась, повторная попытка вернет код 409, который понимается как успешный и не требующий ретрая. Без этого пользователь, дважды нажавший кнопку, получит две одинаковые заявки в очереди.

И по другому направлению claude code уходит вперёд заметно: 39 написанных тест-кейсов против 16 у codex. Claude code берёт не количеством дополнительных функций, а покрытием тестами того, что сделано.

Kimi throttling не сделал, но написал замечание в результатах своей работы: «rate limiting / anti-spam is NOT implemented yet, add it if the endpoint gets abused». Т.е. он остался в рамках исходной задачи, отложив на будущее решение о том, делать ли это или нет, что тоже неплохо.

Вот как выглядит покрытие тестами:

Функционал

codex

claude code

kimi

Валидация

5

12

15

API-роут

5

8

8

Клиент CRM

4

7

Throttling

4

Форма заявки

+2

+8

+4

Итого кейсов

16

39

27

Claude code заметно опережает других агентов. И еще важно отметить, что клиент CRM — единственный модуль, который использует внешний API, то есть самая важная часть всей задачи. И у kimi он вообще не покрыт автотестами.

Как выглядит код

Отдельно хочу показать как выглядит код разных агентов на двух одинаковых по назначению блоках. Файлы клиента CRM получились объемом в 181, 179 и 112 строк.

Чтение конфигурации CRM

Та самая развилка с двумя схемами авторизации решена тремя разными способами.

Осторожно, много кода
// codex — явные типы источника токена, валидация формата очереди регуляркой,
// собственный класс ошибки. И только IAM: ветки OAuth нет вовсе.
function getTrackerConfig(): TrackerConfig {
  const iamSource = process.env.CRM_IAM_SOURCE?.trim() || "env";
  const iamToken = process.env.CRM_IAM_TOKEN?.trim();
  const cloudOrganizationId = process.env.CRM_CLOUD_ORG_ID?.trim();
  const queue = process.env.CRM_QUEUE_KEY?.trim() || DEFAULT_QUEUE;

  if (iamSource !== "env" && iamSource !== "metadata") {
    throw new TrackerConfigurationError("CRM_IAM_SOURCE must be env or metadata");
  }
  if (!cloudOrganizationId) {
    throw new TrackerConfigurationError("CRM_CLOUD_ORG_ID is not configured");
  }
  if (!/^[A-Z][A-Z0-9_-]{1,49}$/.test(queue)) {
    throw new TrackerConfigurationError("CRM_QUEUE_KEY has an invalid format");
  }

  return {
    iamSource,
    iamToken,
    cloudOrganizationId,
    queue,
  };
}
// claude — отдельный рубильник AUTH_SCHEME, независимый от типа организации,
// плюс переопределяемый базовый URL. Нет конфига — возвращает null, не бросает.
function readConfig(): TrackerConfig | null {
  const token = process.env.CRM_TOKEN?.trim();
  const orgId = process.env.CRM_ORG_ID?.trim();
  const cloudOrgId = process.env.CRM_CLOUD_ORG_ID?.trim();
  if (!token || !(orgId || cloudOrgId)) return null;

  return {
    apiUrl: process.env.CRM_API_URL?.trim() || "https://api.crm.com/",
    token,
    // OAuth token by default; "Bearer" when a IAM token is used.
    authScheme: process.env.CRM_AUTH_SCHEME?.trim() || "OAuth",
    orgHeader: cloudOrgId ? "X-Cloud-Org-ID" : "X-Org-ID",
    orgId: (cloudOrgId || orgId) as string,
    queue: process.env.CRM_QUEUE?.trim() || "LEAD",
  };
}
// kimi — самодокументируемые типы и зафиксированное ограничение API:
// IAM бывает только у облачных организаций, значит заголовок форсится.
export function trackerConfig(): TrackerConfig | null {
  const token = process.env.CRM_TOKEN;
  const orgId = process.env.CRM_ORG_ID;
  if (!token || !orgId) return null;
  const iam = process.env.CRM_TOKEN_TYPE === "iam";
  return {
    authorization: iam ? `Bearer ${token}` : `OAuth ${token}`,
    orgId,
    // IAM auth exists only for Cloud organizations
    orgHeader:
      iam || process.env.CRM_ORG_TYPE === "cloud" ? "X-Cloud-Org-ID" : "X-Org-ID",
    queue: process.env.CRM_QUEUE || "LEAD",
  };
}

Результат работы агентов показывает три разных подхода к организации кода. Codex вводит явные переменные-перечисления и проверяет формат ключа очереди регулярным выражением. Claude Code даёт максимум управляемых параметров, включая подмену базового адреса, что удобно для тестов. Kimi хардкодит ограничение самого API прямо в логике.

Отправка запроса в CRM

Один и тот же POST запрос, но три разных подхода к тому, что делать с ошибкой.

Осторожно, много кода
// codex — один вызов, ошибки заворачиваются в типизированные классы
try {
  response = await fetch(CRM_ENDPOINT, {
    method: "POST",
    headers: {
      Authorization: `Bearer ${iamToken}`,
      "Content-Type": "application/json",
      "X-Cloud-Org-ID": config.cloudOrganizationId,
    },
    body: JSON.stringify({
      summary: `Лид с сайта — ${inline(submission.name).slice(0, 100)}`,
      queue: config.queue,
      description: buildDescription(submission),
    }),
    cache: "no-store",
    signal: AbortSignal.timeout(REQUEST_TIMEOUT_MS),
  });
} catch (error) {
  throw new TrackerRequestError(null, error);
}
if (!response.ok) {
  throw new TrackerRequestError(response.status);
}
// claude — три попытки с бэкоффом и разной трактовкой кодов ответа
for (let attempt = 1; attempt <= MAX_ATTEMPTS; attempt++) {
  const response = await fetch(`${config.apiUrl}/issues/`, { /* … */ });

  if (response.ok) {
    const issue = (await response.json().catch(() => null)) as { key?: string } | null;
    return { ok: true, key: issue?.key ?? null, duplicate: false };
  }

  // Same `unique` already in the queue — the lead is registered.
  if (response.status === 409) {
    return { ok: true, key: null, duplicate: true };
  }

  // 4xx is our fault (bad token, missing queue, malformed payload) and
  // will not fix itself on retry.
  if (response.status < 500 && response.status !== 429) {
    return { ok: false, reason: "rejected" };
  }

  if (attempt < MAX_ATTEMPTS) await sleep(BACKOFF_MS[attempt - 1]);
}
return { ok: false, reason: "unavailable" };
// kimi — один вызов, но с тегами и разбором тела ошибки
const res = await fetch(TRACKER_API_URL, {
  method: "POST",
  headers: {
    "Content-Type": "application/json",
    Authorization: config.authorization,
    [config.orgHeader]: config.orgId,
  },
  body: JSON.stringify({
    queue: config.queue,
    summary: `Заявка с сайта: ${lead.name} — ${lead.interest}`,
    description: buildDescription(lead),
    markupType: "md",
    tags: ["site-lead", lead.locale],
  }),
  signal: AbortSignal.timeout(REQUEST_TIMEOUT_MS),
});
if (!res.ok) {
  // Safe to log: the CRM error body never contains our token.
  const body = await res.text().catch(() => "");
  throw new Error(`CRM API responded ${res.status}: ${body.slice(0, 500)}`);
}

Здесь есть один важный момент — Codex единственный защитил свой модуль от импорта на клиент программно: первой строкой файла стоит import "server-only" и любая попытка подтянуть этот код в браузерный компонент не позволит выполнить сборку. У claude code и kimi на том же месте только комментарий в шапке — «SERVER ONLY, never import from client components».

Что мне не понравилось

Пока всё выглядит так, что будто «сделал больше» означает «сделал лучше», но это не так. Codex своей инициативностью надобавлял лишнего.

Он добавил получение облачного IAM-токена, о котором никто не просил. Мало того, что он сделал его единственным способом авторизации, токен для него берется из метадата-сервиса Yandex Cloud, который доступен только изнутри виртуальной машины, который отдаёт временные учётные данные. Если проект деплоится докер-контейнером на обычный сервер, где никакого метадата-сервиса нет, то это решение просто не заработает.

Он также влез в глобальный конфиг тестов, чтобы сделать тесты на модуль, помеченный как server-only, и прописал в vitest.config.ts дополнительную настройку: теперь server-only во всех тестах разрешается в файл-заглушку. Это конечно сработает, но эта подмена действует на весь тестовый прогон целиком. Получается, что программная защита, которую агент сам же и поставил, он же и снял внутри всей тестовой среды. Claude обошёлся без правки конфига именно потому, что у него на этом месте комментарий.

Третий факт уже про харнес codex. Решение по двумя вариантами реализации claude и kimi представили мне на подтверждение «какой вариант интеграции выберем», обосновав рекомендуемые варианты. Codex ничего не спрашивал, просто сам обосновал, принял решение и начал делать. В данном конкретном случае он сделал правильно, но практика показывает, что не всегда рекомендуемые агентами решения являются верными.

Результаты в цифрах

Статистика сессий по результатам выполнения задачи показала следующие цифры:

codex

claude code

kimi

Уровень рассуждений

xhigh

xhigh

всегда включён

Время работы

24 мин

24 мин

63 мин

Ходов модели

12

48

70

Вызовов инструментов

87

67

190

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

16

8

25

Выходных токенов

39 289

54 491

77 041

Прочитано из кэша

13.2M

7.06M

4.94M

Стоимость

$8.76

$5.43

$3.33

Kimi сгенерировал вдвое больше токенов (это связано с тем, что у него нет как таковой настройки уровня рассуждений, то возможность включить или отключить ризонинг), чем codex, но при этом обошёлся в два с половиной раза дешевле из-за цены токенов.

Строка про вызовы инструментов тоже требует отдельного пояснения. У kimi 94 вызова из 190 — это вызовы внутри субагентов: он создает отдельные экземпляры для ресерча, и работают они в своих контекстах. Т.е. это не говорит о том, что он задействует больше инструментов, а просто о другой архитектуре, заложенной в харнес cli агента.

Что хотелось бы еще отметить: был запущет только один прогон. Одна задача, один стек и один запрос агенту, без каких-либо уточнений. Значение параметра «Ходов модели» нельзя просто сравнивать без контекста. В журналах трёх агентов это структурно разные сущности, и числа 12, 48 и 70 говорят лишь о подробности логов, а не о поведении.

Итоги

Все три агента решили реальную задачу в живом проекте с первого раза. Еще год-два назад это было не так. Я раньше много экспериментировал с qwen code, но в итоге отказался от него. Руками писать код получалось быстрее, чем объяснять агенту что я от него хочу. Теперь фокус смещается с вопроса «справится ли?» на «что именно напишет и сколько это будет стоить?».

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

Я в итоге продолжаю использовать claude code и не потому что он победил, а потому что его подход ближе к моему: покрытие тестами, согласование подходов к реализации, стиль кода.

А главный вывод, который из этого следует: уже достаточно много сильных агентов, которые умеют писать код хорошо. И все начинает упираться в качественную постановку задачи, а также наличие инструкций (скиллов) для агентов, которые говорят как им нужно писать код в данном конкретном проекте.

Комментарии (20)


  1. Nedomolkov_Ivan
    04.08.2026 13:18

    Спасибо, что дали не только «кто лучше», но и ходы, токены и стоимость — обычно как раз этой части и не хватает.

    Мы гоняли похожий эксперимент, только задача была другого класса: не «сделай фичу», а «найди причину». Три агента, один и тот же тормоз в проде учётной системы на MS SQL, одинаковый стартовый контекст и доступ только на чтение. Ждали разброса в качестве решения, а получили другое: три разных ответа о причине. Все три технически защитимы, подтвердился на замере один.

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

    И камень в свой же огород: один прогон на агента — ещё не замер. У нас продолжение как раз на этом и застопорилось. Пока не прогонишь каждого по нескольку раз, нечестно утверждать, что разница между агентами больше, чем разброс между запусками одного и того же. Подозреваю, тут та же дыра: 24 минуты у codex и 24 у claude code выглядят слишком одинаково, чтобы на них опираться.


    1. PickaPickaMan
      04.08.2026 13:18

      Сходимость показывает только то что на гитхабе в обучающей выборке было много одинаковых решений этой проблемы. Шаг вправо, шаг влево - и начнутся галлюцинации


      1. Nedomolkov_Ivan
        04.08.2026 13:18

        Справедливо, формулировку надо поправить: сходимость говорит не «задача проще», а «задача типовее» — плотный паттерн в обучающей выборке. Это разные вещи, и ваша версия точнее.

        Косвенно это видно и в разбросе. У нас подтвердилась причина, которой в типовых рецептах нет: запрос был не медленный, он стоял в ожиданиях. А «медленный запрос» тянет за собой индексы и планы — и туда же тянет агентов. Механизм ровно ваш, просто с другой стороны: к типовому их сносит всегда, и правильный ответ находится тогда, когда он вне плотной части выборки.

        А три агента по одному прогону — это не замер, а анекдот, тут я сам себе первый рецензент.


  1. Suor
    04.08.2026 13:18

    Было бы интересно как справиться Кими через Claude Code


    1. master1985 Автор
      04.08.2026 13:18

      У меня тоже есть такое желание попробовать одну модель, но разные cli, чтобы сравнить харнесс. Если руки дойдут, обязательно поделюсь результатом.


  1. deadlydd
    04.08.2026 13:18

    У Кими k3 три уровня effort - low, high и max. По крайней мере на сегодняшний день, по крайней мере в Kimi code.


    1. Amareis
      04.08.2026 13:18

      Так и есть, отключать/менять ризонинг нельзя у k2.7


  1. VesterOne
    04.08.2026 13:18

    Один из плюсов Codex - щедрые лимиты. На подписке за 20$ насыпают достаточно щедро. Плюс бывает восстанавливают лимиты раньше обещаного, что вообще удивительно. Правда я за день могу израсходовать этот недельный лимит, но нужно учитывать что я даю обширные промты (по 400-500 строк). И так с утра до самого вечера. Обычно всегда хватает на сутки

    Если работать размеренно, то в целом за 20$ это прям очень выгодно


  1. PlatinumArcade
    04.08.2026 13:18

    Не катастрофа, что кто-то что-то не сделал с первого раза. Вторым, третьим промптом все можно изменить и добавить. Codex за $20 топ.


  1. denisemenov
    04.08.2026 13:18

    Возможно Claude по API отличается от подписочного через VSCode (а может я стать читал криво), но я повторю свой недавний комментарий в другом посте на хабре:

    У меня одного Claude постоянно врёт, сочиняет, ошибается, додумывает от себя, лезет куда не надо и игнорирует инструкции? Последние полгода Codex выглядит гораздо адекватнее и последовательнее. Я использую их параллельно на одних и тех же проектах, чтобы получать второе мнение, и количество признаний в духе «да, здесь я был неправ» от Claude просто зашкаливает.


    1. PickaPickaMan
      04.08.2026 13:18

      У Клода адекватность сильно зависит от размера контекста. Если скормить ему весь репозиторий разом, он начинает терять фокус и нести отсебятину


    1. 4wards1
      04.08.2026 13:18

      У меня с точностью до наоборот. Claude гораздо лучше следует ограничениям, если они изложены чётко и недвусмысленно.

      К тому же стилистика сообщений у Codex ужасная, он повторяет одну и ту же мысль многократно в разных формулировках, растягивая короткие ответы на десяток абзацев. При этом инструкции вида "излагай мысли последовательно, без повторов и не относящейся к заданному вопросу информации" он полностью игнорирует, продолжая лить воду в колоссальных объёмах. Мне физически неприятно читать такое.


      1. denisemenov
        04.08.2026 13:18

        А что у вас в AGENTS.md, если не серкет?


  1. achekalin
    04.08.2026 13:18

    Хорошее сравнение готовых агентских систем, но не моделей в чистом виде.

    Есть существенная поправка к условиям: Kimi K3 позволяет выбирать уровень рассуждений — низкий, высокий или максимальный; по умолчанию используется высокий. Поэтому говорить, что уровень рассуждений у Kimi невозможно настроить, неверно. В ИИ‑области, правда, всё постоянно меняется, но я так знаюю С исходными настройками Claude тоже стоило бы разобраться подробнее: максимальный уровень мог сохраниться в конфигурации, а не быть стандартным значением.

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

    Небольшая придирка к server-only: его подмена заглушкой в Vitest не снимает защиту в рабочей сборке, а только позволяет импортировать модуль во время тестов. Недостаток в другом: такие тесты сами по себе не обнаружат ошибочный импорт серверного кода в клиентскую часть. Это нужно отдельно проверять сборкой.

    А вот защиту от повторного создания заявки через поле unique и обработку ответа 409 Claude действительно добавил очень к месту.


    1. izogfif
      04.08.2026 13:18

      По три запуска на одинаковых копиях проекта

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


  1. Oeaoo
    04.08.2026 13:18

    И все начинает упираться в качественную постановку задачи

    А вообще я даже рад, до ИИ мало кто умел написать нормально ТЗ, а виноват в последствиях чаще был именно исполнитель. Теперь страдать будет недалекий "заказчик", только сжигая уже не исполнителя, а свои деньги на попытки ИИ угадывать что он хотел.


  1. PickaPickaMan
    04.08.2026 13:18

    Кодекс типичный мидл) Наворотил лишнего, прикрутил какую-то свою авторизацию и даже не спросил, надо ли оно проекту))


    1. 6095959
      04.08.2026 13:18

      А режим планирования был включён?


  1. JekaMas
    04.08.2026 13:18

    Codex sol можно и больше 256k контекст поставить. Становится лучше.


  1. blurman
    04.08.2026 13:18

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

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

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