
Это не история о «плохом proxy». Это история о слишком простом представлении совместимости. Команда считала, что Claude Code API proxy — обычный транспорт: меняем endpoint, сохраняем Model ID и получаем тот же Agent workflow дешевле и удобнее. Первые короткие задачи прошли идеально. Ошибка проявилась только в длинной сессии с Tools.
Сценарий знаком многим российским разработчикам. Прямой доступ к нескольким моделям неудобен, ключи разбросаны, расходы видны в разных кабинетах. OpenAI-compatible gateway кажется естественной точкой сборки. Но Claude Code — не Chat с красивым интерфейсом. Это последовательность решений, чтения файлов, Tool Calls, сжатия контекста и повторных попыток.
09:20. Миграция, которая выглядела слишком лёгкой
В тестовом проекте изменили три параметра: Base URL, API Key и имя модели. Агент открыл README, исправил одну функцию и запустил тест. Разница между прямым API и proxy была незаметна.
ANTHROPIC_BASE_URL=GATEWAY_ENDPOINT
ANTHROPIC_API_KEY=TEAM_KEY
MODEL=SUPPORTED_CLAUDE_MODELКоманда сделала типичную ошибку: признала совместимым весь workflow после проверки одного счастливого пути.
11:40. Первая странность
На задаче с шестью файлами агент дважды запросил один и тот же Tool. Затем прочитал устаревшую версию файла и подготовил patch для кода, который уже изменил на предыдущем шаге. Формально каждый HTTP-ответ был успешным. В логах не было ни 500, ни timeout.
Самые дорогие ошибки gateway выглядят не как падение. Они выглядят как нормальный ответ, после которого Agent принимает неверное следующее решение.
Что произошло на самом деле
Проблема оказалась не в качестве Claude. Разошёлся контракт на стыке клиента, gateway и upstream route. В одном ответе Stop Reason был преобразован иначе, а повтор после оборванного Streaming не сохранил связь между Tool Use и Tool Result. Клиент не упал — он продолжил с неполной картиной состояния.
Слой | Что ожидал клиент | Что могло измениться | Последствие |
Streaming | Последовательные content blocks | Склейка или потеря финального event | Неполный ответ считается завершённым |
Tool Use | Стабильный ID вызова | Преобразование формата или повтор | Tool Result не связывается с действием |
Stop Reason | Однозначный сигнал продолжения | Маппинг в универсальный finish reason | Agent выбирает неверный следующий шаг |
Usage | Input, output и cache отдельно | Упрощённая статистика | Нельзя проверить реальную экономику |
14:10. Почему короткий benchmark ничего не заметил
В коротком запросе нет состояния. Даже если gateway слегка преобразует ответ, пользователь всё равно получает текст. В Agent-сессии каждый ответ — вход для следующего решения. Небольшая несовместимость на третьем шаге становится неверным patch на пятнадцатом.
Мы разделили тесты по длине цепочки:
1–2 шага: простой вопрос и чтение файла — ошибок нет.3–8 шагов: один Tool и исправление — редкие повторы.9–20 шагов: несколько Tools, тесты и patch — проявляется рассинхронизация.20+ шагов: сжатие контекста — ошибка может закрепиться как факт.
Контрактный тест вместо демонстрации
После инцидента команда перестала задавать вопрос «работает ли Claude через proxy». Появились более точные вопросы:
· поддерживается ли Anthropic Messages без потери content blocks;
· сохраняются ли Tool Use ID через Streaming и retry;
· видит ли клиент cache creation и cache read tokens;
· что происходит при обрыве после выполнения Tool;
· фиксирован ли Model Snapshot или используется меняющийся alias;
· можно ли связать каждый шаг с Request ID в gateway;
· одинаково ли ведут себя сессии на 2, 10 и 30 шагов.
Исправление заняло меньше времени, чем расследование
Route перевели на endpoint с явно заявленной поддержкой Anthropic Messages. Автоматический retry запретили для действий с побочным эффектом. Для каждого Tool Call добавили idempotency key, а в трассировку — Model ID, Stop Reason и номер Agent step.
Gateway не убрали. Напротив, после корректной настройки он стал полезнее: один Team Key, централизованный Usage и возможность выбирать отдельные модели для объяснения ошибок, генерации тестов и сложного рефакторинга.
Как выбирать Claude Code API proxy в России
Для русскоязычной команды важны не только цена и доступность. Нужно проверить поддержку клиента, документацию на русском или понятную техническую поддержку, стабильность длинных соединений из вашего региона и политику хранения исходного кода.
OdiRouter стоит рассматривать как единый API-контур для Claude и других моделей, но подключение Claude Code всё равно должно проходить через реальный репозиторий и длинные Agent-сессии. Правильный gateway не отменяет Contract Test — он делает его результаты управляемыми.
Что мы теперь проверяем перед каждой миграцией
1. Двадцать реальных задач, а не синтетический Chat.
2. Минимум три прогона сложной задачи.
3. Tool Calling с необратимым действием только в sandbox.
4. Streaming interruption на разных шагах.
5. Prompt Caching и поля Usage.
6. Cost per accepted patch, а не цена одного ответа.
7. Ручной Code Review без указания использованного route.
Главный вывод
Замена Base URL — это начало миграции, а не её завершение. Для обычного Chat совместимость можно оценить по ответу. Для Claude Code её нужно оценивать по сохранности состояния между шагами. Proxy выгоден тогда, когда снижает инфраструктурную сложность, не превращая Agent в систему с незаметно расходящимся контекстом.