Diseño de infraestructura para reducir costes de proxy y tokens al desplegar Agent-Reach en producción
19 июня 2026 г.
0
Computing/SoftwareComments (0)
Log in to leave a comment
No posts yet
Log in to leave a comment
No posts yet
Incluso los agentes basados en Agent-Reach que funcionan bien en un CLI local se topan con obstáculos desde todos los ángulos en el momento en que se suben a un servidor de producción. Cuando llegan decenas de miles de solicitudes de scraping, el sistema choca con protecciones CDN como Cloudflare y las IPs son bloqueadas una tras otra. Sin embargo, insistir solo en proxies residenciales de pago hace que los costes de ancho de banda sean inasumibles. Además, enviar HTML sin procesar directamente a un LLM puede agotar el contexto y provocar una factura astronómica en tokens. Para resolver este problema, se requiere una arquitectura de enrutamiento dinámico y una tubería (pipeline) de preprocesamiento.
Operar Agent-Reach sin defensas puede hacer que se gasten miles de dólares solo en costes de proxies residenciales de pago. En un sistema que procesa 100,000 solicitudes al día con un tamaño promedio de página de 150 KB, si la tasa de error sube al 50%, el volumen mensual de transferencia de datos alcanza los 675 GB. Los proxies residenciales premium como Bright Data u Oxylabs cuestan entre 4 y 8 dólares por GB. Si se dirige todo el tráfico a través de ellos, el coste mensual se dispararía hasta los 5,400 dólares.
Al desplegar Scrapoxy, un agregador de proxies de código abierto, como un “súper proxy” basado en contenedores Docker, es posible mantener un endpoint único y controlar los costes de infraestructura. Primero, cree un archivo docker-compose.yml en la raíz del proyecto y defina las imágenes valkey/valkey:7.2-alpine y fabienvauchelles/scrapoxy:latest. En el contenedor Valkey, especifique el comando --appendonly yes --requirepass [contraseña] para garantizar la persistencia del almacenamiento en caché de credenciales. Después de configurar el nombre de usuario y la contraseña en las variables de entorno de Scrapoxy, inicie los contenedores con el comando docker compose up -d. Esta configuración permite ahorrar más de 200 dólares al mes en costes de suscripción a servicios de pago.
Dependiendo de las políticas de seguridad de la plataforma objetivo, el ciclo de rotación de IP debe ser doble para evitar que las sesiones se rompan. Para solicitudes de solo lectura (Read-Only) que no requieren autenticación, establezca un TTL agresivo de entre 30 segundos y 3 minutos para asignar forzosamente una nueva IP en cada solicitud mediante el método round-robin. Esto es una medida para evitar el bloqueo basado en umbrales. Por otro lado, para plataformas basadas en autenticación donde el mantenimiento de las cookies de sesión es esencial, como X o Reddit, active la función de inyección de cookies de Scrapoxy para fijar el mismo nodo de IP residencial durante 5 a 10 minutos. Esto evita que la sesión de autenticación caduque debido a un cambio repentino en la IP geográfica.
Para reducir aún más los costes, se debe optimizar el enrutamiento de tráfico en la capa de la puerta de enlace (API Gateway) de NGINX. En el bloque upstream del archivo de configuración de NGINX (/etc/nginx/nginx.conf), defina por separado un grupo de proxies de centro de datos de bajo coste (como DataImpulse, que cuesta alrededor de 1 dólar por GB) y el grupo de proxies residenciales de Scrapoxy. Cree una ubicación /fetch/generic/ dentro del bloque server para reenviar tráfico HTML público de baja intensidad, como feeds RSS o búsquedas en GitHub, a los proxies de centro de datos. Luego, cree una ubicación /fetch/social/ para enrutar solo las solicitudes a endpoints sociales de alta fricción hacia el backend de Scrapoxy e inyectar los encabezados. Al aplicar este enrutamiento de doble vía, se evita el desperdicio de ancho de banda de los costosos proxies residenciales y se reduce el coste total de los proxies hasta en un 90%.
Los datos HTML sin procesar son un cúmulo de elementos DOM redundantes, hojas de estilo y scripts en línea. Si se introducen tal cual en un LLM, se consumen tokens innecesarios y los resultados de la inferencia se ven afectados. Convertir la página web a formato Markdown en lugar de inyectar el contenido original sin procesar en la ventana de contexto reduce el tamaño de los datos entre un 75% y un 90%. Al realizar una limpieza basada en expresiones regulares y una serialización a Markdown en la fase de preprocesamiento del pipeline, se puede reducir el consumo de tokens de la API del LLM en más de un 40% y evitar errores por exceder la ventana de contexto.
Implemente una función de Python que preprocese los datos de entrada combinando los componentes de análisis Trafilatura y html2text. Al llamar a la función trafilatura.extract(), especifique la opción favor_recall=False para excluir barras laterales o anuncios y extraer solo el texto del cuerpo. Para casos en los que la extracción del bloque de contenido principal falle, inserte un código de reserva (fallback) que cree un objeto html2text.HTML2Text() y establezca ignore_images=True y body_width=0. Ejecutar rutinas de limpieza como re.sub para eliminar etiquetas residuales como <script> y <style> del texto Markdown extraído, además de reducir los espacios en blanco consecutivos, disminuye la latencia de respuesta del agente.
Al dividir documentos largos, se debe introducir un algoritmo de segmentación que mantenga el contexto basado en la similitud semántica en lugar de una simple segmentación basada en el recuento de caracteres. Se calcula la similitud de coseno entre los vectores de incrustación (embeddings) del texto dividido en oraciones para capturar los puntos donde se produce una ruptura semántica.
Similarity(u, v) = rac{u cdot v}{\|u\| \|v\|}Después de calcular la distancia entre oraciones adyacentes, se determinan los puntos de segmentación semántica como aquellas interfaces donde la diferencia de distancia supera el percentil 95 del documento completo, generando así la lista de fragmentos (chunks). Aplicar la segmentación semántica en lugar del método de longitud fija evita el fenómeno de pérdida de información cuando los datos relacionados se dividen en diferentes fragmentos, y mejora la precisión de la recuperación de información por parte del LLM.
Plataformas como X o LinkedIn tienen límites de velocidad estrictos. Los errores HTTP 429 o 403 ocurren con frecuencia. En situaciones de fallo temporal, si los procesos de la aplicación síncrona repiten intentos de reintento de forma inmediata, los recursos del servidor se agotan y el nivel de bloqueo de IP solo aumenta. Para asegurar la resiliencia del sistema, se requiere un middleware de procesamiento de excepciones asíncrono que determine la naturaleza de la excepción y ajuste dinámicamente la carga ejercida sobre el servidor objetivo.
Al diseñar la clase del manejador de errores, es necesario diferenciar con precisión entre errores temporales y errores permanentes. Si el código de estado HTTP es 429, 502, 503, 504 o si el mensaje de error contiene 'timeout' o 'connection refused', clasifíquelo como un error temporal y márquelo para reintento. Por otro lado, errores como 401 o 400 deben ser considerados errores permanentes y aislados inmediatamente a una cola de mensajes muertos (Dead Letter Queue, DLQ). En caso de error temporal, para prevenir el problema de la “manada atronadora” (Thundering Herd) que ocurre cuando las solicitudes se concentran en el mismo momento, aplique un algoritmo de retroceso exponencial (exponential backoff) que incluya un jitter aleatorio en milisegundos. La fórmula para calcular el tiempo de espera es:
Si se establece el tiempo de retardo base inicial () en 30 segundos y se limita el máximo () a 600 segundos, se garantiza un tiempo de espera distribuido de aproximadamente 240 segundos en el tercer reintento, evitando así las políticas de bloqueo de la plataforma objetivo.
Para bloquear fallos en cadena en los que el mal funcionamiento o el refuerzo de seguridad de una plataforma específica paralice todo el flujo de trabajo, implemente un patrón de mamparo (bulkhead) basado en Redis en la capa de middleware. En lugar de una cola global única, cree listas de Redis independientes separadas por dominio de destino (queue:bulkhead:twitter, queue:bulkhead:reddit, queue:bulkhead:general). Asigne límites de concurrencia diferenciados al pool de trabajadores que consume cada cola, por ejemplo, 3 para Twitter y 25 para Web General. Para gestionar el cronograma de reintentos de las tareas fallidas, escriba una rutina de procesamiento diferido que utilice un Sorted Set de Redis para registrar la marca de tiempo de retorno como puntuación (score). Al aplicar esta estructura de mamparo, incluso si ocurre un bloqueo de API en una red social específica, solo ese trabajador específico entrará en estado de espera, manteniendo la tasa de éxito de finalización de las tareas de investigación del agente general por encima del 95%.
Los datos sin procesar recopilados aleatoriamente de diversas fuentes web contienen discrepancias de fechas o hechos falsos, lo que facilita que el LLM realice inferencias distorsionadas. Antes de proporcionar contexto a los modelos de IA generativa, es necesario integrar al final del pipeline una capa de verificación discontinua que calcule la fiabilidad del contenido del archivo Markdown y verifique la consistencia numérica, para así bloquear los fenómenos de alucinación.
Diseñe una clase de filtro determinista que calcule la validez temporal de los metadatos recopilados y la ponderación por fuente de plataforma. Los documentos que tienen una marca de tiempo futura con respecto a la hora del sistema o que contienen fechas en formatos ISO no válidos se excluyen inmediatamente del conjunto de datos. Además, declare un diccionario que asigne ponderaciones de confianza por fuente de plataforma, otorgando 0.95 a GitHub, 0.90 a Wikipedia, y asignando puntuaciones base bajas a información de redes sociales como Reddit (0.50) o Twitter (0.40). Solo si el nombre del autor y el título dentro del documento están intactos, se añade un bono de ponderación de metadatos de 0.05 a través de una lógica que genera la puntuación de confianza final. Los activos de información cuya puntuación no alcanza el umbral se excluyen totalmente en la etapa de ensamblaje del prompt del LLM.
Para garantizar finalmente la calidad de los datos de salida, ejecute un script de calificación que contraste los candidatos de respuesta generados con el contexto original.
\b\d+(?:\.\d+)?%?\b) para realizar una operación de intersección entre el conjunto de símbolos numéricos presentes en el conjunto de datos original y los conjuntos numéricos dentro de la oración generada. Si se detecta un valor numérico o unidad monetaria arbitraria que no está en la fuente, se activa una bandera de discrepancia numérica y se solicita una reejecución inmediata a través del middleware de enrutamiento.Al integrar estas capas de verificación multinivel, se bloquean a nivel de arquitectura los problemas de manipulación numérica y citas falsas que cometen los agentes basados en rastreo, y se entregan al usuario final solo resultados de investigación completamente verificados.