Member/Customer Experience

Helping members discover communities around interests

Co-authors: Chiachi Lo, Bohong Zhao, and Elina Lin

When we launched a major redesign of LinkedIn’s mobile application and desktop web experiences a few years back, we focused the My Network tab to help professionals connect with each other on LinkedIn through our People You May Know feature. Over time, we realized there was much more we could do to help our 706M+ members discover and build communities around interests

In this blog post, we’ll talk about how we built a powerful system for members to form and nurture active communities on LinkedIn.

Introduction

It started with the idea to create an experience that enables members to not only discover other professionals, but also dive into the rest of the LinkedIn ecosystem of events, pages, hashtags, newsletters, groups, and influencers. We also wanted to rethink how we designed discovery and recommendations features across the application.

With this aspiration, we experimented with adding tabs on top of the existing People You May Know infinite scrolling experience. Almost immediately, we learned that a horizontal tab navigation was difficult to find and navigate. This caused a ‘tab-blindness’ effect, where members were not aware they could navigate to filter for various recommendation types (i.e. Pages, Groups, Newsletters). It was also challenging for our international members with longer character counts per word. Additionally, because different types of recommendations (members, pages, hashtags, newsletters, etc.) are served from various backend AI recommendation systems (first-pass ranker) and use different tracking events, we needed a solution that could both support the training of AI models across all these different types of recommendations, and serve these AI models into production (a second-pass ranker).

We set off to design and build a discovery and recommendation system with the following priorities: 

  • AI-first: To provide the most relevant recommendations to members, we needed an infrastructure that we could use to train and serve AI models that can rank across all recommendation types.

  • Scalable: To ensure that the system would evolve with similar user experiences with other parts of the app, it was important that the system could easily onboard a variety of both new recommendation types (such as Events) and recommendation cohorts (such as different cohort of people you may know), both in the UI and in the code.

  • Consistent and delightful: To deliver a seamless experience across LinkedIn, we had to offer reusable, out-of-the-box UI components that both serve as templates across the ecosystem and also provide delightful moments for discovery within a principled framework.

Designing the discovery cohorts

We came up with what we called the “discovery cohort” concept. Each discovery cohort consists of recommendations coupled with text on how it might be interesting and relevant to the viewer. A common example is a cohort of one’s coworkers or schoolmates, as shown below. We limit the number of rows for each cohort to a maximum of two rows on both the desktop and mobile apps for easy browsing at first glance. A “See all” button is grouped in close proximity for easy access to view the entire cohort.

gif-showing-discovery-cohorts-ui-on-desktop

Example of discovery cohorts UI on desktop
 

To make the system scalable, we decided to centrally serve text from the server side to render on web/iOS/Android client applications. With this, the introduction of a new cohort of recommendations becomes a purely server-side programming task that can be done by a single engineer, instead of needing 3 more engineers to make changes on the web/iOS/Android apps. More importantly, this greatly reduces the need to wait for iOS and Android app store releases (and users updating their apps) before launching a new recommendation cohort.

Once the implementation of all recommendation types are complete on the frontend, this architecture enables ours and our partner teams to quickly launch new recommendation cohorts such as “People you may know with similar roles” and “People you may know from {your region}”. A recent example of this was when an engineer from a partner team leveraged the platform to successfully launch “People you may know from {a group you are in}” cohort within 2 weeks, only needing to write code to generate recommendations without worrying about the UI or tracking. 

From the API design side, there are two use cases we need to support: 1) Have a way to render a list of discovery cohorts dynamically on each client application using data from the server-side, and 2) be able to render a page with a single cohort, with the ability to paginate, after user clicks on the “See all” button. For this we designed two API interfaces on the server, one for each use case. The second use case is fairly straightforward, but the first use case involves greater efforts to design a system that will serve and rank the recommendations. 

Ranking discovery cohorts

Our recommendation system has a two-pass architecture: the first-pass ranker (FPR) provides the ranking sequence of recommendations within a same cohort, while the second-pass ranker (SPR) determines the ranking order of these different cohorts that our member will later see on the front end.

The FPR layer consists of systems developed by our partner teams that are specialized in different types of recommendations within the LinkedIn ecosystem. For example, two of our closest partners work on recommendations for People You May Know and Communities and Interests

The platform’s recommendation-midtier service here serves as the SPR and we spin up this new microservice to extract the logic of ranking algorithms across different recommendation cohorts, new recommendation type on-boarding, caching, and aggregation of downstream FPR recommendations. In this way, we can keep the LinkedIn application API layer, also known as voyager, as thin as possible to only contain decoration logic.

This service fetches multiple downstream FPRs in parallel to retrieve raw cohort recommendations. Then, our recommendation-midtier will execute its SPR logic to determine the ordering of cohorts. This flow that integrates the FPRs and SPR is built based on our next-gen, developer-friendly workflow framework that supports asynchronous and synchronous task execution, and is integrated as part of LinkedIn’s new Pro-ML stack.

flow-chart-of-how-plugins-work-within-the-recommendation-midtier

Flow chart of how plugins work within the recommendation-midtier
 

In the above chart, we have two sets of FPR operators, each consisting of a RestDataFetchOperator and a ResultTranformerOperator. These two sets will run in parallel; as soon as both of them finish the processing, their data will flow to the MergeResultOperator, which is the SPR. The workflow then defines the sequence of these operators and their execution dependency relationships (for example, the RestDataFetchOperator needs to be completed before its ResultTranformerOperator can start). The 2 sets of RestDataFetchOperator and a ResultTranformerOperator can be executed in parallel, and both of them have to be completed before MergeResultOperator can start.

The RestDataFetchOperator, as its name suggested, will issue restful calls to each FPR downstream and fetch back raw results. Given that we have multiple downstream services maintained by different teams, they could have very different response formats that need to be massaged to be easily processed within the recommendation-midtier. The ResultTranformerOperator’s duty is to transform each FPR’s response to a unified data format defined and recognizable within the midtier for further processing. These ResultTranformerOperators transform all types of different FPR raw results to InternalDiscoveryResult and feed to MergeResultOperator for SPR processing.

For each set of FPR operators, we leverage a plug-in framework. For any onboarding clients, they simply need to implement several predefined interfaces and customize their logic to build the restful requests and define the data transformers without worrying about or touching other logic described above. We extract all the plugins for each FPR client into a plug-in pool, which, in most cases, is the only piece of code our clients need to work on. This architecture provides the necessary modularization to help make the recommendation-midtier scalable to a variety of FPRs as well as less error-prone.

The SPR logic can be categorized into two groups: one is rule-based SPR that we can easily configure through LinkedIn’s internal A/B testing platform, LiX, and the other is relevance-based SPR for which we are actively developing and iterating new relevance models. As of when this blog is written, the majority of members are seeing SPR results based on the rules configured through LiX. We have predefined keywords to represent each cohort type and product owners can easily configure the selection of cohorts and their ranking sequence through our internal a/b test portal.

Decoration

After the platform’s recommendation-midtier service finds out what are the best recommendations for the viewer, the flow will go through voyager-api, where the recommendations will be further decorated with human-readable information like texts and images, before responses are constructed and returned to the front-end platforms.

flow-chart-of-the-whole-system-to-serve-discovery-recommendations

Flow chart of the whole system to serve discovery recommendations
 

Designing the card components

We started with a single card design for all seven recommendation types, but soon ran into challenges in displaying lengthier metadata and variable visual cues. High cognitive load was required for our members to distinguish similar recommendation types, such as telling apart connections and influencers. Facing a diminishing return in uniformity on top of supporting seven recommendation types, it was all the more reason for us to reimagine the entire recommendation framework to be more flexible, clear, and delightful.

With these requirements in mind, we focused on creating recyclable templates that would support all recommendation types and the contexts they live in. Our solution consists of small, medium, large card templates. Our UI framework anticipates for new recommendation types and metadata, with clear rules on how to treat them (i.e. primary and secondary headers, social proof, truncation), and how they might be scaled across different languages, platforms, page orientation, and dynamic font sizes. This formula also generated a playbook for partner teams to reuse and recycle our components for moments of discovery. An example of this is the events cohort, which we were able to recently incorporate into our recommendation system with less time and cost than before.

When implementing these card designs on iOS/Android/web applications, we abstracted out the behaviors of the card components (i.e. click actions, tracking) into core components, separated from the visual layout. This makes it very easy for us to create and apply different layouts depending on the desired use case, without having to rewrite the whole components from scratch.

sample-of-our-recommendation-card-templates

Sample of our recommendation card templates
 

Unified funnel tracking event

In building an AI-first platform, it’s important that the infrastructure is built around helping our AI systems continuously learn and improve their recommendations for members. A key part to deliver this is by building a solid tracking system that is:

  1. Simple for partner teams to onboard and leverage

  2. Efficient for data scientists to analyze product impact

  3. Reliable for application owners to monitor and debug

  4. Comprehensive for relevance iteration and empowering AI work across the LinkedIn ecosystem.

Historically, in LinkedIn’s main application, we primarily use two types of tracking events for recommendations, one for the “followable” types and another for the “add connections” type. We needed to support both (as well as any new types that may come up in the future), so we designed a new funnel event called DiscoveryFunnelEvent.

With DiscoveryFunnelEvent, all recommendation types share the same consistent schema and tracking pattern. The process is as follow:

  • When a recommendation card exits the front-end screen to track that a recommendation has been displayed for the member, an impression record is fired.

  • An action record is fired when a member takes an action on this card (such as clicking the connect or follow button, undoing the connect or follow button, dismissing the card, or tapping the card to view more information).

  • On the back-end layers, voyager-api and the recommendation-midtier, a served record tracking event is fired in the respective layers to track what recommendations are returned.

  • A unique tracking id is generated for each recommendation when the recommendation-midtier fetches from downstream FPR services. This tracking id will be included in the tracking events that capture the lifecycle of a recommendation card from being recommended, served to front-ends, impressioned to viewers, and acted on. In this way, this tracking event can be leveraged to track the trace of every recommendation and later used for analysis, debugging, or relevance model training.

As we are emitting DiscoveryFunnelEvent to replace the firing of the other two types of tracking events for recommendations, we are careful not to break any existing flows that depend on them. We set up a Samza job to consume DiscoveryFunnelEvent and produce the old tracking events based on the DiscoveryFunnelEvent. In this way, any existing flows will enjoy no disturbance while we can ramp DiscoveryFunnelEvent emission to make the client side logic easier, given now we only need to fire one single type of tracking event instead of multiple types.

Conclusion

Since we first launched the discovery cohorts in 2019, the team has added support for recommendations for Pages, Influencers, Hashtags, Groups, Newsletters, and Online Events — all of which members can discover in the My Network tab today. The platform has become a core piece of infrastructure that allows different teams across LinkedIn to quickly launch and test new recommendation and discovery experiences for LinkedIn members, and we’re excited to continue our journey to help our members discover communities and interests to stay informed and connected.

We would like to acknowledge the contributions of Andrew Yu, Weijie Huo, Winnie Narang, Jugpreet Talwar, Judy Wang, Aakanksha Sharma, Preeti Powar, Pooja Muduganti, Kiki Chen, Yang Han, Clifford Charles, Zhiyuan Xu, Matt Winchester, Yao Chen, and Xukai Wang in directly developing the discovery platform described in this post, and the great support from all our partners from Growth AI (especially Aastha Jain, Parag Agrawal, Yafei Wang, and Ashwin Murthy), Communities AI (especially Abdulla Al-Qawasmeh, Andrew Hatch), News (especially Lachlan Green, Hari Prasana, and Emilie de Longueau), Content Experience (especially Emily Carrolo), Segments (especially Jiankuan Sun, Bingyu Li, Yi-wen Liu, Xiangyu Fu, and Chunan Zeng), Pages (especially Julia Abelsky), and Groups (especially Maria Popova and Ian Wood). We also would like to thank Xin Sun and Michael Maczka for their continued support.