koncierge Una librería para segmentar usuarios


El post original se puede leer en mi dev.to.

Trasfondo

En donde estoy trabajando, cada nuevo feature o idea, pasa por un proceso de A/B Testing. Normalmente lo que hacemos es:

  1. Generamos una hipótesis del estilo: “Si los usuarios tuviesen una notificación cuando pasa X, entonces van a hacer Y más seguido”.
  2. Desarrollamos esta notificación, o lo que sea.
  3. Apuntamos a algún mercado para participar de esta prueba
  4. Dividimos a la mitad de los usuarios de ese mercado, tal que vean e interactúen con en nuevo feature, mientras que la otra mitad (grupo control) no.
  5. Esperamos dos semanas
  6. Comparamos las métricas entre los dos grupos.

Este último paso puede llevar a miles de ramificaciones: Activamos el feature para toda la población. Cambiamos algo y volvemos a hacer una prueba. Lo deshabilitamos por completo porque nuestra hipótesis era incorrecta. Etc, etc.

Para la segmentación de la población, estamos usando un servicio de un tercero. A este servicio, ocasionalmente le brindamos la información de segmentación de nuestros usuarios. Información como

El usuario `123` es de Madrid

para que luego, cuando queramos segmentar, podríamos segmentar solo usuarios de Madrid.

Este servicio externo, adicionalmente, solo nos provee acceso a las variantes (si un usuario pertenece al segmento, es parte del grupo de control, o es parte del grupo que participa) mediante un SDK para usar en móviles (iOS y Android).

Esto nos presentaba dos dificultades:

  1. Si quisiéramos hacer un A/B Test en alguno de los micro-servicios de backend, no podríamos consultar a este servicio.
  2. Si quisiéramos segmentar por algo de lo que no le habíamos informado al servicio, deberíamos compartirle toda esta nueva información para que este pueda segmentar.

Por esta situación, decidimos crear un micro-servicio que se encargue de segmentar y separar en variantes a nuestros usuarios.

Problemas

Rápidamente nos vimos enfrentados a resolver como hacer para obtener la información para segmentar.

Normalmente segmentamos por país, lo que sería sencillo hacer que el nuevo micro-servicio consultara con otro micro-servicio de información; y obtuviese el país del usuario. Con esta nueva información, podríamos segmentar.

Lo que presenta un desafío interesante:

Como evitar que este micro-servicio crezca
cada vez introduzcamos un nuevo micro-servicio que almacene
alguna información del usuario?

Por eso, pensamos que podríamos delegar la responsabilidad de obtener el contexto del usuario, a quien consuma este micro-servicio; por lo que una llamada podría ser:

Dado el usuario `123`, de Madrid;
a qué variante pertenece?

De esta manera, es quien consume quien necesita saber todas las dependencias del experimento, y cada experimento puede tener dependencias distintas, de distintas formas de computarse, y el micro-servicio podría no crecer.

DSL (Domain-specific language - Lenguaje específico de dominio)

Ya sabíamos como querríamos que se comporte el micro-servicio, ahora necesitábamos una forma de expresar como querríamos segmentar nuestra población. Hacía poco estaba trabajando mucho con Mongo y se me ocurrió que un lenguaje de consultas como el de mongo podría ser interesante de explorar. De tal forma que una segmentación como:

Quiero que solo participen del experimento `EXP001`,
usuarios quienes sean de Madrid.
De estos, la mitad estarán en el grupo de participando
y el esto en control.

Se transformaría en:

{
  "EXP001": {
    "ubicación": "Madrid",
    "$children": {
      "participando": { "$rand": { "$gt": 0.5 } },
      "control": {}
    }
  }
}

Playground

De esta manera, quien consuma al micro-servicio debería proveer, al menos, la información de la "ubicación" del usuario. Una posible consulta podría ser con el contexto:

{
    "ubicación": "Madrid",
    "userId": 5
}

El micro-servicio debería responder que pertenece al EXP001 (dado que la ubicación empareja con la definición), y podría pertenecer a la variante participando o control. Los usuarios deberían estar distribuidos 50%-50%; dado que hay un 50% de probabilidad que un numero al azar, uniformemente distribuido entre 0 y 1 (como es $rand) sea mayor a 0.5.

Con esta idea, sabiendo que la intención era que el micro-servicio no dependiente de ninguna otra parte de arquitectura de nuestro ecosistema; se me ocurrió que podría desarrollarlo como una librería pública; por si alguien más tiene la necesidad que tuvimos nosotros.

koncierge 🛎

La librería está en GitHub :: jazcarate/koncierge

Melian

Random Posts

Limit the Problem Space!

Simply put, the “problem space” is the entire spectrum of inputs that exists in the process of finding a solution to a problem. How can we make our code less error-prone? In this post I explore some of the ways we can do so. Join me! #xpost

Desire Driven Development

Long have I heard and reaped the benefits of Test Driven Development. But I'm starting to sense that much of the material written and explained about TDD is by fanatics. In this post I'll explore my own take on TDD, and the journey → Desire Driven Development. #rambling #coding

The essence of Event Sourcing

Event Sourcing is a somewhat trending topic, and you can find a lot of blog posts on what event sourcing supposedly is. I’ll throw my wrench in the works and try to explain what I see as “Event Sourcing”. #xpost

Cuándo intervenir en un juego

Durante mucho de mi jueceo, tuve este conflicto interno de cuándo intervenir en un partido de Magic, o si siquiera hacerlo! Una persona mucho más inteligente que yo una vez me dijo: Si alguna vez no sabes algo, escribí un post al respecto. Así que aquí estoy. La respuesta a la pregunta de si ¿Debo intervenir?, como muchas otras respuestas en la vida es “depende”. #xpost #mtg