Skip to content

Прерывание потоковой передачи/0 Token/недействительная подпись: механизм самовосстановления и путь устранения

В Antigravity Tools при вызове /v1/messages (совместимость с Anthropic) или нативных интерфейсов потоковой передачи Gemini, если вы сталкиваетесь с проблемами типа "прерывание потокового вывода", "200 OK но 0 Token", "Invalid `signature`", этот урок дает вам путь устранения от UI до логов.

Чему вы научитесь

  • Знать, что проблемы 0 Token/прерывания в прокси обычно сначала перехватываются "peek предчтением"
  • Можете из Proxy Monitor подтвердить аккаунт и сопоставленную модель этого запроса (X-Account-Email / X-Mapped-Model)
  • Можете через логи определить, это "раннее завершение потока апстрима", "отступление повторной попытки", "ротация аккаунтов" или "повторная попытка исправления подписи"
  • Знать, какие ситуации нужно ждать самовосстановления прокси, какие нужно вмешиваться вручную

Ваша текущая проблема

Вы можете видеть эти "симптомы", но не знаете, с чего начать:

  • Потоковый вывод прерывается на полпути, клиент "застрял" и не продолжается
  • 200 OK, но usage.output_tokens=0 или контент пуст
  • В ошибке 400 появляются Invalid \signature`, Corrupted thought signature, must be `thinking`` и т.д.

Эти проблемы в основном не "вы неправильно написали запрос", а потоковая передача, ограничение скорости/колебания апстрима, или блоки подписей, переносимые историческими сообщениями, вызвали проверку апстрима. Antigravity Tools сделало несколько линий обороны на слое прокси, вам нужно только проверить, на каком шаге он застрял, по фиксированному пути.

Что такое 0 Token?

0 Token обычно относится к output_tokens=0, возвращаемому одним запросом, и выглядит "не сгенерировал контент". В Antigravity Tools чаще причина в том, что "потоковый ответ заканчивается/ошибается до реального вывода", а не модель реально сгенерировала 0 токенов. Прокси попытается перехватить этот пустой ответ с помощью peek предчтения и запустить повторную попытку.

Три вещи, которые делает прокси за кулисами (сначала создайте ментальную модель)

1) Непотоковые запросы могут быть автоматически преобразованы в потоковые

В маршруте /v1/messages, прокси внутренне преобразует "непотоковый запрос клиента" в потоковый запрос для запроса апстрима, и после получения SSE собирает в JSON и возвращает (причина в логах написана как "better quota").

Доказательство исходного кода: src-tauri/src/proxy/handlers/claude.rs#L665-L913.

2) Peek предчтение: сначала дождитесь "первого блока действительных данных", затем передайте поток клиенту

Для вывода SSE /v1/messages, прокси сначала timeout + next() предчитает, пропускает строки heartbeat/комментарии (начинаются с :), пока не получит первый блок данных, который "не пустой, не heartbeat", затем начинает реальную пересылку. Если на этапе peek ошибка/timeout/поток заканчивается, сразу перейдет к следующей попытке (следующий раунд обычно вызовет ротацию аккаунтов).

Доказательство исходного кода: src-tauri/src/proxy/handlers/claude.rs#L812-L926; у нативного потокового Gemini также есть похожий peek: src-tauri/src/proxy/handlers/gemini.rs#L117-L149.

3) Единое отступление повторной попытки + решение "ротировать ли аккаунты" по коду состояния

Прокси сделал четкую стратегию отступления для распространенных кодов состояния, и определил, какие коды состояния вызовут ротацию аккаунтов.

Доказательство исходного кода: src-tauri/src/proxy/handlers/claude.rs#L117-L236.

🎒 Подготовка перед началом

Делайте вместе со мной

Шаг 1: Подтвердите, какой маршрут интерфейса вы вызываете

Зачем Детали самовосстановления /v1/messages (claude handler) и нативного Gemini (gemini handler) различны, сначала подтвердите маршрут, чтобы не тратить время впустую на неправильные ключевые слова логов.

Откройте Proxy Monitor, найдите тот неудачный запрос, сначала запишите Path:

  • /v1/messages: смотрите логику src-tauri/src/proxy/handlers/claude.rs
  • /v1beta/models/...:streamGenerateContent: смотрите логику src-tauri/src/proxy/handlers/gemini.rs

Вы должны увидеть: В записи запроса вы можете увидеть URL/метод/код состояния (а также время выполнения запроса).

Шаг 2: Из заголовков ответа захватите "аккаунт + сопоставленная модель"

Зачем Неудача/успех одного и того же запроса, во многом зависит от "какой аккаунт выбран", "на какую модель апстрима маршрутизирован". Прокси напишет эти две информации в заголовки ответа, сначала запишите, позже в логах можно сопоставить.

В неудачном запросе найдите эти заголовки ответа:

  • X-Account-Email
  • X-Mapped-Model

Эти два элемента устанавливаются в обоих handler /v1/messages и Gemini handler (например, в ответе SSE /v1/messages: src-tauri/src/proxy/handlers/claude.rs#L887-L896; SSE Gemini: src-tauri/src/proxy/handlers/gemini.rs#L235-L245).

Вы должны увидеть: X-Account-Email - это почта, X-Mapped-Model - это имя фактически запрошенной модели.

Шаг 3: В app.log определите, не "не удалось ли на этапе peek"

Зачем Неудача peek обычно означает "апстрим вообще не начал выводить действительные данные". Для этого типа проблем чаще всего способ обработки - повторная попытка/ротация аккаунтов, вам нужно подтвердить, запустил ли прокси.

Сначала найдите файл логов (каталог логов из каталога данных logs/, и записывается по дням в app.log*).

bash
ls -lt "$HOME/.antigravity_tools/logs" | head
powershell
Get-ChildItem -Force (Join-Path $HOME ".antigravity_tools\logs") | Sort-Object LastWriteTime -Descending | Select-Object -First 5

Затем в последнем app.log* найдите эти ключевые слова:

  • /v1/messages (claude handler): Stream error during peek / Stream ended during peek / Timeout waiting for first data (src-tauri/src/proxy/handlers/claude.rs#L828-L864)
  • Нативный потоковый Gemini: [Gemini] Empty first chunk received, retrying... / Stream error during peek / Stream ended immediately (src-tauri/src/proxy/handlers/gemini.rs#L117-L144)

Вы должны увидеть: Если запущена повторная попытка peek, в логах появится похожее предупреждение "retrying...", и随后 перейдет к следующему attempt (обычно приведет к ротации аккаунтов).

Шаг 4: Если 400/Invalid signature, подтвердите, сделал ли прокси "повторную попытку исправления подписи"

Зачем Ошибки подписи часто приходят от блоков Thinking/блоков подписей в исторических сообщениях, которые не соответствуют требованиям апстрима. Antigravity Tools попытается "понижение исторических блоков thinking + введение исправленного промпта" затем повторить попытку, вы должны сначала позволить ему пройти самовосстановление.

Вы можете использовать 2 сигнала, чтобы определить, вошел ли он в логику исправления:

  1. В логах появляется Unexpected thinking signature error ... Retrying with all thinking blocks removed. (src-tauri/src/proxy/handlers/claude.rs#L999-L1025)
  2. Затем исторические блоки Thinking будут преобразованы в Text, и в последнем сообщении user будет добавлен исправленный промпт (src-tauri/src/proxy/handlers/claude.rs#L1027-L1102; gemini handler также добавит тот же исправленный промпт к contents[].parts: src-tauri/src/proxy/handlers/gemini.rs#L300-L325)

Вы должны увидеть: Прокси автоматически повторит попытку после короткой задержки (FixedDelay), и может войти в следующую попытку.

Контрольная точка ✅

  • [ ] Вы можете подтвердить маршрут запроса в Proxy Monitor (/v1/messages или нативный Gemini)
  • [ ] Вы можете получить X-Account-Email и X-Mapped-Model этого запроса
  • [ ] Вы можете найти ключевые слова peek/повторная попытка в logs/app.log*
  • [ ] При ошибке 400 подписи вы можете подтвердить, вошел ли прокси в логику повторной попытки "исправленный промпт + очистка блоков thinking"

Предупреждения о типичных ошибках

СценарийЧто вы можете сделать (❌)Рекомендуемый способ (✓)
При виде 0 Token сразу много раз вручную повторятьПостоянно нажимать кнопку повтора клиента, совсем не смотреть логиСначала посмотрите Proxy Monitor + app.log один раз, подтвердите, это ли ранняя неудача на этапе peek (автоматически повторит/ротирует)
При Invalid \signature`` сразу очистить каталог данныхУдалить весь .antigravity_tools, аккаунты/статистика все пропалиСначала позвольте прокси выполнить один раз "повторную попытку исправления подписи"; только когда лог явно показывает, что восстановление невозможно, рассмотрите ручное вмешательство
Считать "колебание сервера" как "аккаунт сломан"400/503/529一律 ротировать аккаунтыДейственность ротации зависит от кода состояния; у прокси сами есть правила should_rotate_account(...) (src-tauri/src/proxy/handlers/claude.rs#L226-L236)

Краткий итог урока

  • 0 Token/прерывание потоковой передачи в прокси обычно сначала проходит через peek предчтение; неудача на этапе peek вызовет повторную попытку и перейдет к следующему attempt
  • /v1/messages может внутренне преобразовать непотоковый запрос в потоковый затем собрать обратно в JSON, это повлияет на ваше понимание "почему похоже на проблему потоковой передачи"
  • Ошибки недействительности подписи 400, прокси попытается "исправленный промпт + очистка блоков thinking" затем повторить попытку, вы сначала подтвердите, прошел ли этот путь самовосстановления

Следующий урок预告

Следующий урок мы изучим Справочник по точкам доступа.


Приложение: Справка по исходному коду

Нажмите, чтобы увидеть местоположение исходного кода

Обновлено: 2026-01-23

ФункцияПуть к файлуСтроки
Claude handler: стратегия отступления повторной попытки + правила ротацииsrc-tauri/src/proxy/handlers/claude.rs117-236
Claude handler: внутренне преобразует непотоковый в потоковый (better quota)src-tauri/src/proxy/handlers/claude.rs665-776
Claude handler: peek предчтение (пропуск heartbeat/комментариев, избегая пустой поток)src-tauri/src/proxy/handlers/claude.rs812-926
Claude handler: повторная попытка исправления ошибки 400 подписи/неправильного порядка блоковsrc-tauri/src/proxy/handlers/claude.rs999-1102
Gemini handler: peek предчтение (предотвратить пустой поток 200 OK)src-tauri/src/proxy/handlers/gemini.rs117-149
Gemini handler: введение исправленного промпта при ошибке 400 подписиsrc-tauri/src/proxy/handlers/gemini.rs300-325
Кеш подписей (три слоя: tool/family/session, с TTL/минимальная длина)src-tauri/src/proxy/signature_cache.rs5-207
Преобразование Claude SSE: захват подписи и запись в кеш подписейsrc-tauri/src/proxy/mappers/claude/streaming.rs639-787

Ключевые константы:

  • MAX_RETRY_ATTEMPTS = 3: максимальное количество повторных попыток (src-tauri/src/proxy/handlers/claude.rs#L27)
  • SIGNATURE_TTL = 2 * 60 * 60 секунд: TTL кеша подписей (src-tauri/src/proxy/signature_cache.rs#L6)
  • MIN_SIGNATURE_LENGTH = 50: минимальная длина подписи (src-tauri/src/proxy/signature_cache.rs#L7)

Ключевые функции:

  • determine_retry_strategy(...): выбрать стратегию отступления по коду состояния (src-tauri/src/proxy/handlers/claude.rs#L117-L167)
  • should_rotate_account(...): решить, ротировать ли аккаунты по коду состояния (src-tauri/src/proxy/handlers/claude.rs#L226-L236)
  • SignatureCache::cache_session_signature(...): кешировать подпись сессии (src-tauri/src/proxy/signature_cache.rs#L149-L188)