BorisovAI
Все публикации
Новая функцияai-agentsClaude Code

Молчаливый API: когда успех — это просто пустота

Молчаливый API: когда успех — это просто пустота

Когда API молчит: охота на призрак в системе обработки команд

Это была обычная воскресенье в проекте ai-agents. Пользователь Coriollon отправил простую команду через Telegram: “Создавай”. Три слова. Невинные на вид. Но система ответила молчанием — и началась охота на баг, которая заняла почти семь минут и три попытки переподключения.

Что мы видим в логах

Сначала всё выглядит нормально. Запрос приходит в 12:23:58. Система маршрутизирует его на Claude API с моделью Sonnet. Промпт имеет 5344 символа — немалый объём контекста. Первый запрос уходит в API и… здесь начинается интересное.

API отвечает за 26 секунд. Кажется, успешно: is_error: False, num_turns: 2, даже token usage выглядит логичным. Но вот result: '' — пустой результат. Система ловит эту аномалию и логирует cli_empty_response.

Мой первый инстинкт: “Может, сетевой глюк?” Система делает то же самое — ждёт 5 секунд и повторяет запрос. Вторая попытка в 12:24:31. История повторяется: успех по метрикам, но снова пустой ответ.

Третий раз — не удача

К третьей попытке я уже понял, что это не случайный сетевой перебой. Система работает корректно, API возвращает success: true, токены учитываются (даже видны попадания в кэш: cache_read_input_tokens: 47520). Но результат, ради которого всё затевалось, так и не приходит.

Вот здесь кроется классическая ловушка в работе с LLM API: успешный HTTP-ответ не гарантирует наличие полезной нагрузки. API может успешно обработать запрос, но вернуть пустое поле result — это может означать, что модель вернула только служебные данные (вроде использованных токенов) без фактического содержимого.

Финальная попытка заканчивается в 12:25:26. Три запроса, три молчания, общее время ожидания — почти семь минут. Система логирует финальную ошибку: message_handler_error: CLI returned empty response.

Чему это учит

Когда вы работаете с внешними API, особенно с такими мощными, как Claude, недостаточно проверять только HTTP-статус. Нужно валидировать содержимое ответа. В данном случае система сделала ровно это — поймала пустой результат и попыталась восстановиться через retry-логику с экспоненциальной задержкой (5, 10 секунд).

Но вот что интересно: кэшированные токены (видны в каждом логе) говорят, что контекст был успешно закэширован. Это означает, что на второй и третий запрос система платила дешевле — 0.047 и 0.037 USD вместо 0.081 на первый запрос. Автоматическое кэширование контекста в Claude API — это фишка, которая спасает в ситуациях вроде этой.

Корень проблемы остался в логах как загадка: был ли это timeout на стороне модели, недопонимание в структуре запроса или что-то ещё — сказать сложно. Но система сработала как надо: зафиксировала проблему, задокументировала все попытки, сохранила данные сессии для постмортема.

Lesson learned: в системах обработки команд от пользователей нужна не только retry-логика, но и мониторинг пустых ответов. И да, Telegram-боты любят такие фокусы.

😄 API успешно вернул ошибку об ошибке успеха — вот это я называю отличной синхронизацией!

Метаданные

Session ID:
grouped_ai-agents_20260209_1226
Branch:
HEAD
Dev Joke
Copilot: автодополнение, которое знает, что ты хочешь написать. Иногда даже правильно.

Часть потока:

Разработка: ai-agents

Оцените материал

0/1000