Перейти к содержанию

Машинный перевод

Эта страница была автоматически переведена ИИ и может содержать ошибки. Если что-то неясно, обращайтесь к английскому источнику.

Английский источник · Сообщить о проблеме перевода

Устранение неполадок

Формат FAQ: каждая запись — проблема → причина → исправление. Полный справочник по семантике ошибок (коды состояния, терминальные состояния, дисциплина повторных попыток) см. в разделах Ответы и ошибки и Ограничение частоты запросов и ошибки.

a. Прямые запросы к API получают Cloudflare 403

Проблема: самодельный curl / скрипт к REST-эндпоинтам www.perplexity.ai возвращает 403 со страницей проверки Cloudflare — даже с куки, скопированными из браузера, — в то время как те же эндпоинты работают через инструмент.

Причина: Cloudflare находится перед сайтом, а cf_clearance / __cf_bm привязаны к TLS-отпечатку браузера. Отпечаток «голого» клиента не совпадает, поэтому срабатывает проверка. Инструмент проходит, потому что использует Python urllib с куки, импортированными из браузера, и отпечатком User-Agent настольного Chrome (pplx_export/core/http/cookie_transport.py:29). Cloudflare также может выдавать 403 при контроле частоты запросов — в этом случае ответ имеет ту же форму проверки.

Исправление:

  • Не обходите транспорт инструмента; выполняйте вызов через pplx-export / pplx-ask вместо ad-hoc скриптов.
  • Внутри инструмента ответ 200 с телом не в формате JSON (промежуточная страница Cloudflare) классифицируется как ошибка транспорта, а не данные (pplx_export/core/http/cookie_transport.py:133).
  • Если 403 начинают появляться внутри инструмента, снизьте темп (см. Ограничение частоты запросов) и обновите куки; постоянная проверка означает повторный вход в браузере.
  • Учитывайте два лица 403: проверка риска Cloudflare (исчезает при снижении темпа) против API-уровня 403 (мертвая кука — возникает немедленно без отсрочки; см. следующий раздел). Страница проектирования описывает последнее (rate-limiting-errors.md).

Предыстория: Аутентификация API.

b. Ошибки 401 / истекшие куки

Проблема: команды завершаются с ошибкой аутентификации — AuthTransportError: 鉴权失败 401 от pplx-export, или pplx-ask ask завершается с подсказкой HTTP 401/403 обновить куку.

Причина: сессионная кука истекла или была аннулирована. 401/403 рассматриваются как сбои аутентификации и вызываются немедленно — без отсрочки, потому что отсрочка не может самостоятельно восстановить мертвую сессию (pplx_export/core/http/cookie_transport.py:82; pplx_export/core/errors.py:68). batch дополнительно быстро завершаются после 3 последовательных сбоев аутентификации, чтобы мертвая кука не сжигала очередь.

Исправление:

  1. Повторно войдите (или снова откройте сайт) в браузере, чтобы сессионные куки обновились.
  2. Обновите кеш кук инструмента. Кеш по пути <out>/index/.cookies.json повторно используется в течение 12-часового окна свежести (pplx_export/core/cookies/cache.py:22), поэтому после повторного входа либо:
  3. выполните один запуск с --cookies-from <browser> для принудительного свежего импорта из браузера, или
  4. удалите <out>/index/.cookies.json и позвольте следующему запуску автоматически переимпортировать.
  5. Каждый успешно прошедший проверку запуск повторно сохраняет кеш (pplx_export/commands/common.py:150), поэтому повседневные запуски остаются свежими сами по себе.

Подробности настройки: Начало работы · Конфигурация.

c. Расшифровка кук в Linux

Проблема: в Linux автоопределение (или --cookies-from chrome и др.) не может прочитать хранилище кук браузера, даже если браузер выполнил вход.

Механизм: браузеры семейства Chromium в Linux шифруют базу данных кук ключом, хранящимся в связке ключей ОС, который считывается во время выполнения через API Secret Service D-Bus. browser_cookie3 общается с D-Bus через чисто Python-библиотеку jeepney — уже установленную с инструментом в Linux, ничего дополнительно настраивать не нужно — и возвращается к устаревшему паролю peanuts, когда связка ключей не отвечает, что расшифровывает только те куки, которые Chrome также записал без связки ключей. Когда связка ключей существует, но сам поиск D-Bus завершается сбоем на транспортном уровне (например, сессионная шина отклоняет анонимную аутентификацию), собственная цепочка возврата browser_cookie3 никогда не задействуется; инструмент обнаруживает этот случай и повторяет попытку один раз, обходя связку ключей, используя пароль Chromium по умолчанию — тот же ключ, который Chromium использует, когда связка ключей недоступна (pplx_export/core/cookies/loaders.py:62-104, встроенный в путь загрузки в loaders.py:136-153). Firefox не требует ничего из этого: его cookies.sqlite не зашифрован.

Матрица:

Уровень Случай Что происходит
Браузер Firefox Ноль трения — cookies.sqlite не зашифрован
Браузер Chromium + доступная связка ключей Работает — ключ извлекается через Secret Service
Браузер Chromium + нет связки ключей Путь peanuts — работает только если Chrome также записал без связки ключей
Браузер Chromium + связка ключей недоступна (сбой на уровне D-Bus) Инструмент автоматически повторяет попытку с паролем Chromium по умолчанию — та же доступность, что и путь peanuts
Способ установки Нативный пакет Автоопределение (встроенные пути browser_cookie3)
Способ установки snap / flatpak Автоопределение — встроенный реестр профилей охватывает профили в ~/snap/<name>/... соотв. ~/.var/app/<app-id>/... (pplx_export/core/cookies/profiles.py:37-67)
Окружение рабочего стола GNOME Обычно работает из коробки (gnome-keyring)
Окружение рабочего стола KDE Включите Use KWallet for the Secret Service interface в настройках KWallet
Окружение рабочего стола Безголовое / минимальное Нет сессионной шины D-Bus → путь peanuts
Семейство дистрибутивов Debian / Ubuntu Установите libsecret-1-0 + gnome-keyring
Семейство дистрибутивов Fedora / RHEL Установите libsecret + gnome-keyring; минимальные / серверные установки часто вообще не имеют связки ключей — самый распространенный сбой
Семейство дистрибутивов Arch Тот же механизм, отличаются только имена пакетов

Установки в песочнице не требуют дополнительных флагов: сначала проверяется нативный путь, затем базы данных кук snap/flatpak из реестра через явный cookie_file= (pplx_export/core/cookies/loaders.py:155-168).

Сценарий → рекомендуемый канал:

Сценарий Рекомендуемый канал
Установлен Firefox --cookies-from firefox — ноль трения
Рабочий стол GNOME / KDE Автоопределение просто работает
Браузер snap / flatpak Автоопределение — реестр охватывает его; в противном случае --cookies FILE, экспортированные через расширение браузера
Безголовый сервер --cookies FILE — универсальный запасной вариант; --transport webbridge как последнее средство

d. Экспорт выполнен под неправильной учетной записью (несколько учетных записей)

Проблема: архивированные обсуждения были получены с сессией неправильной учетной записи — например, запуск --account alice извлек данные как bob, или архив показывает обсуждения, не принадлежащие целевой учетной записи.

Причина: если в один браузер выполнен вход с несколькими учетными записями, активный токен сессии (__Secure-next-auth.session-token) может принадлежать другой учетной записи, чем та, на которую вы целились. Если email целевой учетной записи не зарегистрирован в конфигурации пользователя, инструмент не может это обнаружить и только регистрирует предупреждение.

Как инструмент предотвращает это (pplx_export/commands/common.py:93): при запуске транспорт вызывает GET /api/auth/session и сравнивает текущий email с зарегистрированным. При несовпадении он автоматически перечисляет сессионные куки браузера для каждой учетной записи (__Secure-pplx.session.<user_id>), подставляет каждую в активный токен и проверяет сессию, пока целевой email не совпадет (pplx_export/commands/common.py:190; pplx_export/core/cookies/loaders.py:175). Если ни один токен не совпадает, команда прерывается с четкой ошибкой — она никогда молча не продолжает работу под неправильной учетной записью.

Исправление:

  • Зарегистрируйте email каждой учетной записи в [accounts.<name>] (см. Конфигурация) и передавайте --account явно.
  • Проверьте строку журнала запуска [auth] cookie 来源 …,当前账户: … — она называет email текущей сессии до начала извлечения.
  • Для аудита существующего архива каждый thread.json обсуждения содержит поле export_via, записывающее, какая учетная запись выполнила экспорт (pplx_export/sites/perplexity/fs_writer.py:229). pplx-export sync-deleted использует то же поле для выбора учетной записи для онлайн-проверки.

Глубина механизма: Аутентификация API · Ask и учетные записи.

e. «Файл конфигурации не найден» — ухудшенный режим

Проблема: предупреждение при запуске говорит, что файл конфигурации пользователя не найден, и команда выполняется в ухудшенном режиме; или явный --account alice завершается с ошибкой, указывающей на config.example.toml.

Причина: нет файла конфигурации ни в одном из трех мест поиска — --config PATH, переменная окружения PPLX_EXPORT_CONFIG или путь по умолчанию ~/.config/pplx-export/config.toml (pplx_export/config.py:113). Два связанных, но различных случая: явно указанный путь конфигурации, который не существует, вызывает ConfigError; поврежденный (неразбираемый) конфиг всегда вызывает ConfigError — сломанный конфиг никогда молча не ухудшается.

Эффекты ухудшенного режима:

  • Реестр учетных записей пуст, поэтому проверка владения куками пропускается с предупреждением, и команды выполняются как учетная запись-заполнитель default (pplx_export/commands/common.py:51). Явный --account вместо этого завершается ошибкой.
  • pplx-ask ask пропускает автоматическое перемещение в пространство BOT (moved_to_bot остается false в результирующем JSON), а телеметрия содержит пустой идентификатор пользователя; запросы и архивирование в остальном работают.
  • Архивы помещаются в папку запасной учетной записи, производную от имени пользователя.

Исправление: скопируйте config.example.toml в ~/.config/pplx-export/config.toml, заполните [accounts.<name>] (display_name / email / user_id), [bot_space] и default_account — см. Конфигурация.

f. ENTRY_EXPIRED против ENTRY_DELETED

Проблема: экспорт или повторная синхронизация обсуждения сообщает ENTRY_EXPIRED или ENTRY_DELETED, и обсуждение больше никогда не может быть получено.

Причина: оба приходят как HTTP 400 от GET /rest/thread/<uuid> с разными кодами ошибок, и оба являются терминальными — обсуждение больше не существует на платформе:

Код Значение Отображение в инструменте Терминальное состояние
ENTRY_EXPIRED Платформа удалила обсуждение (~3 месяца хранения) EntryExpiredError (pplx_export/core/errors.py:24) expired
ENTRY_DELETED Обсуждение было активно удалено пользователем / удаленной стороной (нисходящий эффект DELETE /rest/thread/delete_thread_by_entry_uuid) EntryDeletedError, подкласс EntryExpiredError (pplx_export/core/errors.py:30) deleted

Что это значит для вашего архива:

  • Ни одно из состояний никогда не повторяется — ни при инкрементальной синхронизации, ни с --force. Терминальная отметка хранится в <out>/index/batch_state.json.
  • Ваша локальная копия архива никогда не удаляется и не перемещается инструментом — копия в репозитории является резервной. Команда экспорта регистрирует терминальное состояние и завершается корректно (pplx_export/commands/export_cmd.py:51).
  • Поскольку отношение подкласса является преднамеренным, пути кода, которые знают только EntryExpiredError, все равно обрабатывают ENTRY_DELETED как терминальное; осведомленные пути (пакетный / экспорт / синхронизация удаленных / обратное заполнение режима поиска) классифицируют его точно как deleted.
  • Практический вывод: экспортируйте своевременно. После ~3-месячного удаления ссылки на источники артефактов/отчетов также истекают безвозвратно.

Связано: Инкрементальная синхронизация · Ответы и ошибки.

g. Ресурсы, которые невозможно загрузить (обработка toolu_)

Проблема: некоторые записи в assets/assets_manifest.json имеют версии, помеченные "no_download_channel": true, и соответствующий файл отсутствует в assets/files/.

Причина: дескрипторы облачного рабочего пространства с префиксом toolu_ (DOC_FILE / CODE_FILE / UNKNOWN без формы URL) не имеют канала загрузки через API: GET /rest/assets/<asset_uuid>/data возвращает 404 ASSET_NOT_FOUND для них, а file-repository/download отклоняет дескрипторы file:repo/... (400). Это известная граница полноты архива, а не ошибка в экспорте. pplx-export assets-backfill помечает эти версии как no_download_channel и пропускает их (pplx_export/commands/assets_backfill_cmd.py:356).

Исправление:

  • Сегодня загружать нечего — флаг является преднамеренной записью границы.
  • Содержимое часто сохраняется встроенным: текст извлечения страниц субагента и полезные данные шагов сохраняются в необработанном JSON обсуждения (raw_entries.json / raw_blocks.json) и в отрендеренном turns/ — проверьте там в первую очередь.
  • file-repository/list-files отслеживается как потенциальный будущий путь восстановления; см. Дорожная карта обнаружения API.

Структура манифеста: Структура архива.

h. Команда кажется зависшей / долгие паузы

Симптом: index / batch / export, кажется, зависает; внешний менеджер задач может убить его как «превышено время ожидания».

Причина: почти всегда ожидание отсрочки или ожидание выполняющегося запроса, а не зависание. При ошибках 429 / 5xx / сетевых ошибках транспорт ожидает между попытками — до 300 с на ожидание (pplx_export/core/throttle.py, Throttle.backoff).

Что вы теперь видите (уровень подробности по умолчанию, -v не требуется): ожидание отображается информационными «сердцебиениями». Отсрочка печатает начальную строку, а затем тик обратного отсчета каждые ~10 с (Throttle.heartbeat_interval); один запрос, который зависает перед ответом, печатает тик «все еще ждем ответа»; а потоки pplx-ask печатают тик «все еще ждем поток ответа», пока выполняется глубокое исследование / совет молчит:

22:27:24 [auth] 正在校验账户 cookie(来源 cache)…
22:27:40 退避 ~51s(连续失败 1 次,网络异常重试中)
22:27:50 仍在等待重试,剩余 ~41s
22:28:00 仍在等待重试,剩余 ~31s

Общее время ожидания не изменилось — «сердцебиения» только делают его видимым; прерывание безопасно в любой момент (состояние записывается атомарно, и следующий запуск восстанавливает пробел). -v / --log-file по-прежнему добавляют полную трассировку запросов DEBUG.

Пропустить проверку при запуске: index / batch начинаются с проверки сессии, которая следует тем же правилам отсрочки, поэтому при плохой сети первое ожидание может быть этим шагом проверки учетной записи. Передайте --skip-auth-check, чтобы пропустить его и сразу перейти к работе, доверяя текущей выполнившей вход учетной записи — см. Конфигурация.

Антипаттерн: обертывание CLI в менеджер задач с коротким жестким таймаутом (фоновые задачи агента, обертки cron в стиле timeout(1)) при объединении учетных записей с && — каскад отсрочек первой учетной записи сжигает весь таймаут, и объединенная учетная запись никогда не запускается. Одна учетная запись на вызов, щедрый бюджет: см. Бюджет времени выполнения для вызывающих.

i. Где журналы?

Консоль: по умолчанию прогресс на уровне INFO; -v / --verbose переключает на DEBUG (трассировка запросов, внутренние решения); предупреждения и ошибки всегда отображаются.

Файл: передайте --log-file, чтобы захватить полный поток DEBUG (pplx_export/core/logging.py:45):

  • --log-file без значения помещается в <out>/index/logs/<cmd>-<timestamp>.log (pplx_export/commands/common.py:218) — например, pplx-ask-ask-20260723-120000.log.
  • --log-file PATH записывает по указанному пути.

Другие файлы состояния, полезные для диагностики<out>/index/):

Файл Содержимое
.cookies.json Кеш кук (свежесть 12 ч; записывается атомарно с правами 0o600 — это учетные данные, эквивалентные входу, храните в секрете)
batch_state.json Состояние экспорта для каждого обсуждения, включая терминальные отметки expired / deleted
answer_variants_log.jsonl Реестр вариантов перезаписи ответов
library_*.json Снимки индекса библиотеки для каждой учетной записи

j. См. также