Как Kimi переиграла Codex на многопоточке 👾
У меня начали поджимать лимиты подписки Kimi за 40$, и ради разнообразия в команду был взят Codex с подпиской за 20$. Первое впечатление — шуршит бодро, отвечает заметно быстрее, работать приятно.
Но мы же не ищем лёгких путей. Подвернулась сложная задача: разрулить состояние кэша сервисов на старте. И, конечно, первой её получил новый подопытный. GPT-5.4, effort = Medium. И тут подопытный сел в лужу. Причём с очень уверенными щами. Три итерации — результата нет. Отдала задачу Kimi: китаец шуршал как заправский ботан, медленно, вдумчиво, и в итоге таки добил. Но мне нужен был postmortem, как я уже писала это моя guilty pleasure. Так что вот чистосердечное покаяние от Codex.
Суть проблемы и исповедь Codex
Снаружи баг выглядел как обычная гонка: «сервисы стартуют раньше, чем поднимается cache». Codex честно признал, что зашел не в ту дверь. Слишком долго держался за самую правдоподобную гипотезу: «надо просто лучше ждать CacheSync». В итоге все фиксы усиливали orchestration старта и лечили симптомы, а система нормально не взлетала.
Kimi же просто копнула глубже и вышла на реальный механизм зависания — deadlock в startup pipeline.
Оказалось, что _startup не завершался exception’ом при падении, WaitForCompletionAsync мог висеть вечно, а Task.WhenAll маскировал конкретную упавшую startup task. То есть проблема была не в порядке деплоя, а в фундаментальной ошибке завершения startup-задач. Именно это и объясняло все симптомы.
Почему здесь ломаются мозги у LLM — и у людей тоже
Это как раз тот класс задач, где всем тяжело: concurrency, lifecycle, cancellation, race conditions, completion semantics.
Тут мало понять “кто кого ждёт”. Нужно ещё удерживать в голове: кто, когда, в каком состоянии, чем завершает TaskCompletionSource, как пробрасывается exception, и почему одно асинхронное ожидание может повиснуть навсегда.
На таких задачах выигрывает не скорость, а внимательность, глубина рефлексии и количество итераций “посмотреть и подумать”.
Сам Codex свёл разницу в подходах к двум строчкам:
⏺ Путь Codex: “подождать зависимость” — лечить следствие на уровне orchestration/startup ordering.
⏺ Путь Kimi: “починить pipeline, чтобы startup вообще не зависал и правильно падал”.
Собственно, в этом и весь урок.
Для агентных моделей многопоточность и state transitions — до сих пор один из самых сложных классов задач.
Очень хочется сделать далеко идущие выводы про Codex, но с учётом того, что у него стоял effort = Medium, нельзя валить на модель. На таких задачах решает не скорость генерации, а глубина размышления. Так что не жмитесь на effort и выкручивайте агентам время “подумать” на максимум, если задача сложная.