Volver a las novedades para desarrolladores

Descubrir lo desconocido que se desconoce

16 de mayo de 2023DeAndrew Reedy

Meta cuenta con un ecosistema de productos que utilizan miles de millones de usuarios todos los días, ya sea para conexiones sociales o para interacciones comerciales. Estos miles de millones de usuarios nos piden que también ofrezcamos nuevas funcionalidades y mejoras a nuestros productos de manera continua y vertiginosa. Dada la enorme base de usuarios, entregamos miles de cambios de código todos los días para satisfacer estas expectativas.

El lanzamiento continuo de una cantidad tan grande de mejoras de productos tiene el potencial de generar regresiones en el estado de las aplicaciones, lo que puede provocar una degradación en la experiencia del usuario. En Meta, disponemos de una sofisticada combinación de herramientas de prevención en capas para evitar el lanzamiento de cambios de productos defectuosos. Estas herramientas de prevención supervisan varias señales de productos y detectan regresiones antes del lanzamiento de las apps. Las tres áreas a las que corresponden estas señales son rendimiento, confiabilidad (operativa y sistémica) y eficiencia. De manera conjunta, estas áreas se conocen como el "pre" de los productos. La prevención comienza con varios indicios de observabilidad y análisis cuando los desarrolladores escriben el código. Asimismo, se utilizan herramientas de observabilidad y supervisión para recopilar datos del uso interno de los productos en entornos de preproducción. Las herramientas de control de calidad tanto manuales como automáticas prueban los productos en estos entornos de preproducción.

Y, si bien el objetivo de estos mecanismos es evaluar la calidad de los cambios de código antes de su llegada a producción (y, de esta manera, evitar que afecte a los usuarios), puede suceder que haya cambios que afecten a los usuarios que sí lleguen a producción y, por lo tanto, deban reformularse y abordarse nuevamente. A fin de mitigar la posibilidad de que un problema afecte a una gran cantidad de gente, empleamos varios mecanismos para lanzar los cambios al público de manera incremental.

Cuando una funcionalidad no es como un usuario espera, lo definimos como una regresión. Usamos la palabra "señal" para hacer referencia a que los usuarios nos están informando que algo no cumple con sus expectativas. Recopilamos señales de regresión tan pronto como nos es sistemáticamente posible mediante estadísticas de datos y código instrumentado y, luego, trabajamos para disminuir el impacto para los usuarios mediante la implementación de correcciones. En estas instancias en las que no recibimos una señal eficaz de nuestras herramientas, confiamos en los reportes de los usuarios como la señal de que ocurrió una regresión. Estos reportes nos llegan mediante varios mecanismos, por ejemplo, los usuarios sacuden su teléfono para reportar un problema en donde están en la aplicación cuando el problema sucede.

Para garantizar que satisfacemos las necesidades de nuestros clientes lo más rápido posible (a veces, en el mismo día), Meta ha invertido mucho en una variedad de programas y sistemas de confiabilidad para hacer posible un nivel de respuesta significativa a escala.

Las señales pueden provenir de nuestros usuarios públicos (personas, empresas, grupos, etc.) o de usuarios internos. Analizamos detenidamente las señales de los usuarios internos para ayudar a evitar que cambios no deseados lleguen a producción. Ten en cuenta que las señales se agrupan; por ejemplo, incluyen la cantidad de errores por millón de usuarios. Las señales también pueden provenir de herramientas y escenarios de prueba automáticos, herramientas de desarrollo (advertimos a los desarrolladores de cambios que podrían provocar errores de tiempo de ejecución), registros del sistema y muchos otros orígenes. También disponemos de herramientas que aprovechan estas señales para identificar rápidamente las causas y las correcciones adecuadas.

Una vez que se identifica una regresión, procedemos a buscar rápidamente a los ingenieros relevantes para aplicar las correcciones y lanzarlas. Según la complejidad de la regresión, empleamos diferentes métodos para identificar a los ingenieros adecuados, lo que incluye aprovechar la perspicacia de aprendizaje automático de Meta. Por cómo funciona el aprendizaje automático, este es un proceso continuo; a medida que lanzamos nuevas funciones, volvemos a capacitar a nuestros modelos para seguir el ritmo de los cambios constantes.

Y, sin dudas, hay un objetivo: avanzamos desde la detección de las regresiones hasta mitigarlas, hasta evitarlas y hasta contenerlas de manera sostenible. En el proceso, maximizamos el nivel de respuesta, el retorno de la inversión y la eficiencia.

En la próxima sección, hablaremos más en detalle sobre cómo determinar con certeza que se produjo una regresión y, sabiendo eso, cómo respondemos.

Traducir lo desconocido a lo conocido y cuantificarlo

Cuando hablamos de lo desconocido, nos referimos a un error que un usuario o sistema está experimentando. Puede que nos enteremos sobre un posible error de una variedad de orígenes diferentes.

  • Pruebas sintéticas del funcionamiento correcto de nuestras apps y productos específicos dentro de esas aplicaciones.
  • Usuarios internos que están realizando pruebas para encontrar errores. Esto puede incluir a nuestros equipos de prueba exclusivos o la base de usuarios más amplia en Meta.
  • Usuarios externos que están experimentando un problema y que usan el diálogo de reporte de problemas en nuestras apps.

Estos errores son desconocidos hasta que los usuarios los marcan como incidentes que están experimentando. Cuando la cantidad de reportes de errores de este tipo alcanza un límite determinado, los consideramos un positivo verdadero, lo que representa un evento de regresión: un cambio de código creó un nuevo error y debemos actuar rápidamente para mitigarlo. Existen dos tipos principales de reportes:

  • "Desconocidos conocidos": cuando código instrumentado detecta y reporta la regresión y disponemos de varias herramientas para ayudar a generar la señal
  • "Desconocidos desconocidos": cuando la regresión no se identifica de manera interna y dependemos de que los usuarios la reporten

Asimismo, las regresiones entran dentro de varias categorías, por ejemplo, si representan errores de código, algo más parecido al spam u otro tipo de incumplimiento de la política de contenido. Nos enfocamos en la primera área, ya que deseamos abordar los problemas relacionados con el código en la experiencia del usuario. ¿Cómo lo logran con los usuarios que reportan miles de problemas?

Producir señales y estadísticas

A fin de administrar el gran volumen de reportes, generamos señales específicas que nos marcan problemas. El primer tipo de señal, si tiene los límites ajustados correctamente, nos informa que efectivamente se produjo un incidente o una regresión. Ten en cuenta que, según el tipo de regresión, es posible que hayan ocurrido varios eventos. Por ejemplo, una regresión puede afectar varios productos por una base de código en común. Buscamos estos aspectos comunes y los abordamos como un solo incidente para alinear recursos de manera óptima. El siguiente gráfico es un ejemplo de cómo se ve la desviación de la tendencia, lo que indica una regresión.

Luego, recopilamos más señales, algunas de las cuales indican el tipo de regresión que podemos tener. Estas señales proporcionan estadísticas sobre los síntomas relacionados con la regresión y las generan algoritmos de aprendizaje automático configurados para productos de Meta particulares. Los algoritmos analizan los reportes de los usuarios para determinar qué causó la regresión y, por lo tanto, qué equipo de ingeniería puede abordarla mejor mediante la implementación de una corrección de código u otra medida.

También se generan muchas otras señales según los datos de registro recopilados. Estos registros de diagnóstico pueden ser registros del cliente o del servidor que, con el consentimiento del usuario, se recopilan para ayudar a determinar la causa. Las aplicaciones incluyen los flujos de consentimiento correspondientes para determinar si es posible recopilar este tipo de datos según los permisos del usuario. También tenemos en cuenta la longevidad de estos datos para cumplir con las regulaciones aplicables.

La combinación de señales nos permite concentrarnos en la regresión y asignarla al equipo de productos correcto para mitigar rápidamente el problema y restaurar la experiencia del usuario a la esperada.

Las estadísticas también provienen de resultados agrupados. Examinamos los datos para encontrar causas principales en común y determinar si es necesario realizar cambios para evitar que las regresiones se repitan. Este es un aspecto clave de contar con un enfoque sólido para abordar los problemas de la experiencia del usuario, ya que nos ayuda a minimizar la superficie de regresión con el tiempo.

Nuestras apps para celulares no solo incluyen recorridos de navegación que permiten al usuario reportar un problema, sino que también brindan la capacidad de indicar un problema al sacudir el dispositivo. De esa manera, es posible recopilar telemetría en contexto. Esta telemetría se enriquece aún más con las señales de Black Box que provienen de la app. Black Box es como un registrador de vuelo que captura automáticamente determinados registros (según el consentimiento de los usuarios) sobre lo que estaba sucediendo con la app cuando se reportó el error para permitirnos diagnosticar mejor el problema.

Toda esta telemetría se une a un conjunto de vistas de línea de tiempo para ayudar a los equipos de ingeniería a determinar qué causó el problema. Debido a la rápida cadencia de lanzamiento de nuestras apps, así como a los cambios en los componentes de la app del servidor, sería difícil identificar el problema sin esta capacidad. Contar con esta telemetría a lo largo del tiempo nos ayuda a detectar patrones en las regresiones para prevenirlas en el futuro.

Escalar a superficies de productos más pequeñas

A medida que mejoramos nuestra capacidad de generar mayor precisión en nuestras señales, podemos atacar una mayor superficie de regresión y llegar a partes que anteriormente no se habrían detectado. Una superficie representa una oferta particular dentro de un producto, por ejemplo, la sección de noticias o los reels. Esto representa un desafío, ya que los productos no solo tienen muchas funciones granulares, sino que también se agregan nuevas funciones periódicamente. Por lo tanto, la superficie de regresión no solo es grande, sino que también crece con el tiempo. En consecuencia, nuestras estrategias defensivas y ofensivas deben adaptarse continuamente.

Para escalar, deben cumplirse varias condiciones:

  1. Debemos tener una cobertura precisa y una clasificación adecuada de las superficies de los productos existentes
  2. Debemos reducir la superficie de regresión para los productos existentes (léase: prevención)
  3. Debemos expandir el alcance de nuestros algoritmos a nuevas superficies de productos

Si estas condiciones no se cumplen, corremos el riesgo de tener un sistema inflado imposible de administrar debido a su tamaño, complejidad e imprecisión. Por lo tanto, nuestros esfuerzos se centran en mantener el equilibrio y, al mismo tiempo, llevar a cabo nuestras operaciones diarias de manera eficiente.

Avanzar más allá de los errores

A medida que continuamos reduciendo la superficie de regresión (sin bajar la guardia), aumentamos nuestro enfoque en otras áreas importantes: prevención y facilidad de uso.

La prevención se ocupa de lo siguiente:

  1. ¿Cómo aprendemos de las regresiones anteriores?
  2. ¿Qué defensas implementamos para que estas regresiones no vuelvan a ocurrir?
  3. ¿Cómo nos aseguramos de que la superficie de regresión siga disminuyendo con el tiempo?

Como dijimos anteriormente, agrupamos datos de regresiones anteriores para aprender de ellas. Esos aprendizajes pueden traducirse en lo siguiente:

  1. Colocar marcadores en nuestro código que nos alerten en el futuro, durante el entorno de preproducción, para poder evitar que un cambio no deseado llegue a producción
  2. Aumentar la cobertura de las pruebas en varios niveles para detectar estas regresiones
  3. Cambiar el producto en sí para abordar estos problemas

La prevención nos ayuda a seguir moviendo las regresiones hacia la izquierda en el ciclo de vida del desarrollo y, en consecuencia, a seguir reduciendo los costos. Esto se logra al obtener señales lo suficientemente valiosas en una etapa anterior en el proceso de desarrollo, comenzando con los ciclos de lanzamiento de escritura del código y preproducción. Esto no solo mejora la experiencia del usuario, sino que también reduce los costos de desarrollo y nos ayuda a destinar recursos al desarrollo de nuevos productos.

Mejorar nuestra capacidad para manejar las regresiones de manera más eficiente nos permite concentrarnos más en la confusión del usuario o los problemas de usabilidad. Estas son preocupaciones de mayor valor, ya que se centran en mejorar los productos en lugar de corregirlos. Con el tiempo, la proporción de problemas de usabilidad y regresiones debería aumentar, y la cantidad total de este tipo de problemas debería disminuir.

En última instancia, esto da como resultado una experiencia de usuario que mejora continuamente tanto en la funcionalidad como en la facilidad de uso.

Este artículo se redactó en cooperación con Bijan Marjan, director de programas técnicos de Meta.