Сравнение 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 |
|
258 400 |
claude code |
Claude Code 2.1.220 |
|
1M |
kimi |
kimi 1.49.0 |
|
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-маршрут |
|
|
|
Валидация, контракты |
|
|
|
Клиент CRM |
|
|
|
Throttling |
Внутри роутера |
|
— |
Тестовая инфраструктура |
|
— |
— |
Тесты |
|
|
|
Правки в компонентах формы |
|
|
|
Итого в |
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)

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

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

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

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

denisemenov
04.08.2026 13:18Возможно Claude по API отличается от подписочного через VSCode (а может я стать читал криво), но я повторю свой недавний комментарий в другом посте на хабре:
У меня одного Claude постоянно врёт, сочиняет, ошибается, додумывает от себя, лезет куда не надо и игнорирует инструкции? Последние полгода Codex выглядит гораздо адекватнее и последовательнее. Я использую их параллельно на одних и тех же проектах, чтобы получать второе мнение, и количество признаний в духе «да, здесь я был неправ» от Claude просто зашкаливает.

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

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

achekalin
04.08.2026 13:18Хорошее сравнение готовых агентских систем, но не моделей в чистом виде.
Есть существенная поправка к условиям: Kimi K3 позволяет выбирать уровень рассуждений — низкий, высокий или максимальный; по умолчанию используется высокий. Поэтому говорить, что уровень рассуждений у Kimi невозможно настроить, неверно. В ИИ‑области, правда, всё постоянно меняется, но я так знаюю С исходными настройками Claude тоже стоило бы разобраться подробнее: максимальный уровень мог сохраниться в конфигурации, а не быть стандартным значением.
Самое интересное продолжение уже предложили выше в комментариях: запустить одну модель через разные агентские оболочки. Например, K3 через родной Kimi Code и через Claude Code. По три запуска на одинаковых копиях проекта, с одинаковой постановкой задачи и заранее подготовленными приёмочными тестами — тогда станет понятнее, где проявляются свойства модели, а где поведение оболочки/обвязки.
Небольшая придирка к
server-only: его подмена заглушкой в Vitest не снимает защиту в рабочей сборке, а только позволяет импортировать модуль во время тестов. Недостаток в другом: такие тесты сами по себе не обнаружат ошибочный импорт серверного кода в клиентскую часть. Это нужно отдельно проверять сборкой.А вот защиту от повторного создания заявки через поле
uniqueи обработку ответа409Claude действительно добавил очень к месту.
izogfif
04.08.2026 13:18По три запуска на одинаковых копиях проекта
Если запускать модели не на своем оборудовании, то велика вероятность, что после первого раза на стороне LLM-провайдера закешируют и эксперимент получится нечистый.

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

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

blurman
04.08.2026 13:18Развилка тут, на мой взгляд, не совсем честная. Прямой API требует заметно меньше кода, а агенты заточены именно под поиск короткого и стандартного пути к результату.
Сама задача настолько сильно ограничивает пространство решений, что совпадение архитектуры у трёх моделей не очень показательно - что, собственно, видно и из результатов.
Гораздо интереснее был бы эксперимент, где есть несколько равноценных архитектурных вариантов и моделям действительно приходится выбирать, учитывать компромиссы и обосновывать решение.
Nedomolkov_Ivan
Спасибо, что дали не только «кто лучше», но и ходы, токены и стоимость — обычно как раз этой части и не хватает.
Мы гоняли похожий эксперимент, только задача была другого класса: не «сделай фичу», а «найди причину». Три агента, один и тот же тормоз в проде учётной системы на MS SQL, одинаковый стартовый контекст и доступ только на чтение. Ждали разброса в качестве решения, а получили другое: три разных ответа о причине. Все три технически защитимы, подтвердился на замере один.
Отсюда наблюдение, которое, кажется, дополняет ваши цифры. На задачах с проверяемым ответом самая говорящая метрика — не токены и не время, а сходятся ли агенты между собой. Сошлись — задача оказалась проще, чем выглядела. Разошлись — вы только что узнали про задачу больше, чем даёт любой бенчмарк.
И камень в свой же огород: один прогон на агента — ещё не замер. У нас продолжение как раз на этом и застопорилось. Пока не прогонишь каждого по нескольку раз, нечестно утверждать, что разница между агентами больше, чем разброс между запусками одного и того же. Подозреваю, тут та же дыра: 24 минуты у codex и 24 у claude code выглядят слишком одинаково, чтобы на них опираться.
PickaPickaMan
Сходимость показывает только то что на гитхабе в обучающей выборке было много одинаковых решений этой проблемы. Шаг вправо, шаг влево - и начнутся галлюцинации
Nedomolkov_Ivan
Справедливо, формулировку надо поправить: сходимость говорит не «задача проще», а «задача типовее» — плотный паттерн в обучающей выборке. Это разные вещи, и ваша версия точнее.
Косвенно это видно и в разбросе. У нас подтвердилась причина, которой в типовых рецептах нет: запрос был не медленный, он стоял в ожиданиях. А «медленный запрос» тянет за собой индексы и планы — и туда же тянет агентов. Механизм ровно ваш, просто с другой стороны: к типовому их сносит всегда, и правильный ответ находится тогда, когда он вне плотной части выборки.
А три агента по одному прогону — это не замер, а анекдот, тут я сам себе первый рецензент.