Прерывание потоковой передачи/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.
🎒 Подготовка перед началом
- Вы можете открыть Proxy Monitor (см. Proxy Monitor: логи запросов, фильтрация, восстановление деталей и экспорт)
- Вы знаете, что логи находятся в каталоге
logs/каталога данных (см. Первый запуск обязательно: каталог данных, логи, системный трей и автозапуск)
Делайте вместе со мной
Шаг 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-EmailX-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*).
ls -lt "$HOME/.antigravity_tools/logs" | headGet-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 сигнала, чтобы определить, вошел ли он в логику исправления:
- В логах появляется
Unexpected thinking signature error ... Retrying with all thinking blocks removed.(src-tauri/src/proxy/handlers/claude.rs#L999-L1025) - Затем исторические блоки
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.rs | 117-236 |
| Claude handler: внутренне преобразует непотоковый в потоковый (better quota) | src-tauri/src/proxy/handlers/claude.rs | 665-776 |
| Claude handler: peek предчтение (пропуск heartbeat/комментариев, избегая пустой поток) | src-tauri/src/proxy/handlers/claude.rs | 812-926 |
| Claude handler: повторная попытка исправления ошибки 400 подписи/неправильного порядка блоков | src-tauri/src/proxy/handlers/claude.rs | 999-1102 |
| Gemini handler: peek предчтение (предотвратить пустой поток 200 OK) | src-tauri/src/proxy/handlers/gemini.rs | 117-149 |
| Gemini handler: введение исправленного промпта при ошибке 400 подписи | src-tauri/src/proxy/handlers/gemini.rs | 300-325 |
| Кеш подписей (три слоя: tool/family/session, с TTL/минимальная длина) | src-tauri/src/proxy/signature_cache.rs | 5-207 |
| Преобразование Claude SSE: захват подписи и запись в кеш подписей | src-tauri/src/proxy/mappers/claude/streaming.rs | 639-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)