Traducción automática
Esta página fue traducida automáticamente por IA y puede contener errores. Si algo no está claro, consulte la fuente en inglés.
Estructura de la respuesta de la API y semántica de errores¶
Parte de la referencia de la API web de Perplexity — mapa completo en el índice de la API.
1. Aspectos esenciales de la estructura de la respuesta (disciplina de análisis)¶
- Datos sin procesar conservados en archivos exitosos:
raw_entries.json(sin formato) yraw_blocks.json(esquematizados, cuando se obtienen) se almacenan junto con los artefactos renderizados; el análisis/renderización se puede volver a ejecutar sin conexión (pplx-export re-render) sin necesidad de volver a obtenerlos. - Extracción de campos centralizada en
sites/perplexity/parsers.py(la desviación del esquema solo necesita cambiar un lugar). - Detección de modo (
normalize.detect_mode; árbol de decisión en export-pipeline.md): la señal de mayor prioridad es el camposearch_modede cualquier entrada (mapeo al final de §3.9); cuando todas las señales fallan, se recurre a — computer = URL/computer/tasks/o metadata.mode=="4" o modo de índice ∈ {ASI,COMPUTER}; council = existe un paso COUNCIL_RESEARCH; deep-research = existe un paso RESEARCH_ANSWER (basado en contenido, sin depender de etiquetas en chino); de lo contrario, search. - La interfaz de usuario de computer colapsa todo — siempre guíese por las entradas/bloques de la API; nunca use el texto de la interfaz de usuario como límite del contenido.
- Canal dual de subagente (descubierto el 2026-07-19): indicación en
workflow_payload.objective_chunksesquematizado; pasos/conclusión enbackground_entriessin formato; vinculados a través deworkflow_payload.id(toolu_X). - Los elementos de
WORKFLOW_ITEM_SOURCESa menudo llevantext_payload(texto de extracción de página del subagente / tablas de comparación; 450 ocurrencias en toda la biblioteca, 408 dentro de cargas útiles anidadas de fondo) además desources_payload.sources(lista de enlaces); el mismo contenido aparece tanto en eltextJSON de paso incrustado de la entrada de fondo sin formato como en la carga útil anidada esquematizada — los subagentes anclados renderizados a través de la ruta sin formato ya conservan el texto (verificación en toda la biblioteca 2026-07-22: 408/408 presentes, ninguno faltante). related_queries/related_query_items(resuelto 2026-07-23): cada entrada lleva recomendaciones de indicaciones para la siguiente pregunta — sugerencias de seguimiento que la plataforma genera para una respuesta completada;related_querieses una matriz de textos de recomendación,related_query_itemslos elementos estructurados (uuid/upsell_type, etc.). Conclusión forense: el uuid de un elemento no es un uuid de hilo (0/988 coincidencias cruzadas con uuids de hilo de la biblioteca), y los textos de recomendación no tienen superposición con las consultas de otros hilos — no se puede resolver en relaciones entre hilos por ahora; la hipótesis de "uuids de hilo preasignados (materializados al hacer clic)" sigue sin verificarse. Los datos se conservan naturalmente en el archivoraw_entries.json(aciertos en más de la mitad de los hilos de una biblioteca de archivo); no se necesita ninguna acción de recolección adicional; el gráfico de relaciones no construye aristas a partir de esto.
2. Semántica de errores y control de riesgos¶
| Síntoma | Significado / manejo |
|---|---|
| 403 (con página de desafío cf) | Bloqueo de Cloudflare (huella TLS / control de tasa) — retroceder; urllib + cookies del navegador generalmente no lo desencadenan |
| 401 / 403 a nivel de API (sin página de desafío cf) | Cookie de sesión caducada/inválida — la herramienta se activa inmediatamente, sin retroceso; el lote falla rápidamente después de 3 fallos de autenticación consecutivos (actualizar la cookie) |
| 429 | Limitación de tasa — retroceso exponencial (implementado en la herramienta) |
| 5xx (500/502/503/504) | Errores transitorios del servidor (504 comúnmente un tiempo de espera de Cloudflare) — retroceder y reintentar (implementado en la herramienta) |
| ENTRY_EXPIRED | Purgado por la plataforma (~3 meses) — terminal, no reintentar |
| ENTRY_DELETED | Eliminado por el usuario/remoto (también HTTP 400, código diferente) — terminal deleted, no reintentar |
_response_type: VIEW_COLLECTION_NOT_ALLOWED (HTTP 200) |
La cuenta actual no puede ver el espacio — reintentar con una cuenta que pueda |
error_code: VIEW_THREAD_NOT_ALLOWED (HTTP 403) |
La cuenta actual no puede ver el hilo (probado 2026-07-23: sondeo de uuid variante hermano; el objeto existe pero es inaccesible, no "inexistente") |
status:"failed" datos vacíos |
Misma clase (la forma de fallo de get_collection) |
Disciplina de límite de tasa (anti-bloqueo, requisito explícito del usuario): aleatorio 10–20 s entre hilos de lote, sin concurrencia, retroceso 429/403, retroceso-reintento 5xx; paginación ≥3 s; recuperación esquematizada ≥4 s; recuperación de metadatos del espacio ≥3 s. Exportación de un solo hilo = 1–2 solicitudes ≈ abrir la página una vez.
2.1 Semántica de interrupción — valores observados (2026-07-22; fuente de verdad de clasificación: parsers.classify_wf_status)¶
El campo locked_reason: aparece en thread_metadata / entries[] / background_entries[]
(tanto en el lado sin formato como en el esquematizado). Único valor observado:
| locked_reason | Significado | Distribución observada |
|---|---|---|
spending_limit_exceeded |
interrupción por límite de gasto (cuota agotada; el flujo de trabajo se detiene en el punto de interrupción) | exactamente un hilo en toda la biblioteca (marcadores tanto en raw_entries como en raw_blocks) |
Campo de estado del flujo de trabajo (workflow_block.status y workflow_payload.status anidado comparten la misma enumeración) valores observados:
| estado | Semántica | Anotación de renderizado (COMPLETED no tiene ninguna) |
|---|---|---|
WORKFLOW_COMPLETED |
finalización normal | — |
WORKFLOW_AWAITING_NEXT_STEPS |
esperando los siguientes pasos; con locked_reason=spending_limit_exceeded es una interrupción por límite de gasto (el contenido se detiene en el punto de interrupción); sin locked_reason, interrumpido pendiente de continuación |
⏸ 限额中断(内容截至中断点) (⏸ interrumpido por límite — el contenido se detiene en el punto de interrupción) / ⏸ 中断待续 (⏸ interrumpido, pendiente de continuación) |
WORKFLOW_CANCELED |
cancelado (aborto del usuario/plataforma) | ⛔ 已取消 (⛔ cancelado) |
WORKFLOW_CANCELEDobservado 19 veces (16 principales + 3 anidadas), en 7 hilos de computer (a5e8f481/cfca382d/f2e5957d/8417b02a/2dc5716d/356f833e/ed3714ff).- Nota: el estado de la carga útil del ancla de la entrada principal puede retrasarse (se observó ancla COMPLETED mientras que el fondo estaba realmente CANCELED) —
el verdadero estado de un subagente es el
workflow_block.statusdel lado del fondo. - Las tareas de fondo interrumpidas no producen una notificación de finalización de subagent_result; las cargas útiles de fondo no consumidas vuelven al apéndice del hilo (consulte "cascada de atribución" en subagents-interruptions.md).
- Respuestas vacías en modo computer (doble verificado 2026-07, irrecuperable): en modo computer, algunos turnos tienen una
respuesta vacía porque el servidor simplemente no tiene ninguna — una recuperación de API devuelve datos idénticos al archivo, y
expandir la barra de "N pasos completados" de la interfaz de usuario desencadena cero solicitudes de datos (renderizado puro del lado del cliente; la interfaz de usuario y
la API comparten una fuente), por lo que la API no puede recuperarlos. Solo un subconjunto de dichos turnos está vinculado a
locked_reason=spending_limit_exceeded; el resto no lleva ningún marcador del lado del servidor.
2.2 side_by_side_metadata: señal de variante de reescritura de respuesta (resuelto 2026-07-23)¶
Ruta del campo: entries[].side_by_side_metadata (respuesta /rest/thread/<uuid> sin formato).
Cuando la plataforma genera múltiples versiones de respuesta para la misma consulta (experimento A/B o reescritura), esta es la
única traza que queda en la entrada activa actual — el cuerpo de la variante reemplazada (texto/pasos/citas) no está en la respuesta de la API del hilo (caso real
b2d2632b: la respuesta tiene solo 1 entrada, 1 FINAL; la variante 2 completamente invisible).
Claves y valores observados (evidencia: b2d2632b sin procesar; escaneo de toda la biblioteca de 2442 entradas):
{
"experiment_role": "override-default-model-class:qwen3_instruct-01f7f",
"sibling_uuid": "00000000-0000-5000-8000-000000000000",
"experiment_override": {"override-default-model-class": "qwen3_instruct"},
"selection_status": "SELECTED",
"execution_log": {}
}
| Clave | Semántica (observada/hipotetizada) |
|---|---|
sibling_uuid |
Apunta a la variante de respuesta hermana de la misma consulta (otro identificador de entrada/contexto). 7 hilos acertaron en toda la biblioteca; la investigación forense en línea (2026-07-23) confirma un enlace muerto: las GET /rest/thread/<sibling_uuid> de ambas cuentas devuelven 403 VIEW_THREAD_NOT_ALLOWED (no 404/ENTRY_EXPIRED — el servidor lo reconoce como un objeto existente pero no visible), y abrir /search/<sibling_uuid> en el navegador (cuenta del propietario) es redirigido por SPA de vuelta al inicio — las variantes reemplazadas no se pueden recuperar a través de sibling_uuid |
selection_status |
SELECTED = la respuesta de esta entrada es la versión elegida para mostrar; las instancias del grupo de control son todas SELECTION_STATUS_UNSPECIFIED |
experiment_role |
Rol del experimento. El grupo de control lleva un prefijo [control] (6 casos en toda la biblioteca: [control]default-model-class:gpt41, etc.); el caso real no tiene prefijo (override-default-model-class:qwen3_instruct-01f7f, es decir, el grupo de tratamiento de un experimento de anulación de modelo) |
experiment_override |
Parámetros de anulación del experimento (por ejemplo, override-default-model-class: qwen3_instruct); observado solo en instancias del grupo de tratamiento |
execution_log |
Observado como un objeto vacío; semántica desconocida |
Criterios de estrechamiento (distinguir "reescritura genuina que mantiene ambas versiones" de "control A/B rutinario"):
sibling_uuid no vacío Y (selection_status no vacío y no SELECTION_STATUS_UNSPECIFIED,
O experiment_role sin el prefijo [control]) → solo b2d2632b acierta entre las 2442 entradas de toda la biblioteca
(el único caso real confirmado; precisión/recuperación son ambos 1 en esta biblioteca, pero n=1 no se puede extrapolar).
Comportamiento de la herramienta: parsers.collect_answer_variants extrae aciertos; adapter.get_thread
registra una advertencia + escribe thread.json.answer_variants (clave ausente cuando no hay aciertos);
re-render --thread-json agrega/elimina en el lugar (idempotente). Evidencia de tiempo: el delta de created→updated de la entrada del caso real
es 53.66 s (generado a las 17:13, luego reescrito/seleccionado), y la reescritura avanzó el lastUpdated a nivel de hilo (una reexportación incremental
puede desencadenar una recuperación, pero la respuesta recuperada aún contiene solo la respuesta activa; las variantes antiguas son irrecuperables).
Registro de detección y flujo de manejo (2026-07-23, sites/perplexity/variant_log.py):
- Marcador de registro: cada acierto emite una sola línea WARNING con el marcador greppable uniforme
ANSWER_VARIANT_DETECTED, incluyendo todos los campos de localización y orientación de manejo, con forma:ANSWER_VARIANT_DETECTED thread=<full uuid> uuid8=<8 chars> title="…" entry=<entry_uuid> sibling=<sibling_uuid> selection_status=SELECTED experiment_role=… | action: …La ruta en línea (adapter.get_thread) genera en cada acierto de recuperación real;re-rendersin conexión genera solo cuando se agrega/cambia contenido registrado (las ejecuciones idempotentes repetidas no saturan);batchtambién pasa un recordatorio de recuento de aciertos de una línea al final del resumen (sin romper el formato de resumen existente). - Registro central:
<out>/index/answer_variants_log.jsonl(un archivo verificado, no bajo ellogs/ignorado por git) — un JSON por línea (detected_at / source=online|offline / web_uuid / uuid8 / title / entry_uuid / sibling_uuid / selection_status / experiment_role), deduplicado por (web_uuid, entry_uuid); las exportaciones/rerenderizaciones repetidas no se agregan sin fin; detected_at mantiene la hora de la primera vista. - Acción recomendada ante un acierto: los hermanos son empíricamente enlaces muertos (consulte la tabla anterior); la respuesta alternativa generalmente
no se puede recuperar a través de la API — confirme manualmente de inmediato si la respuesta alternativa aún se puede obtener (conversación de la plataforma / memoria del usuario / capturas de pantalla); si se puede obtener,
regístrela manualmente como un archivo
rewritten_answer_variant.mden el directorio del hilo; si no,thread.json.answer_variants+ el registro jsonl sirven como el registro final trazable.