How the Blending Pipeline Merges Ranked Posts with Ads, Who to Follow, and Prompts in X Algorithm
The Blending Pipeline in home-mixer/selectors/blender_selector.rs partitions heterogeneous feed items by type, applies configurable ad-spacing strategies to blend posts with advertisements, then layers prompts, Who to Follow modules, and rich UI components at predetermined positions to produce the final ordered timeline.
The X Algorithm repository (xai-org/x-algorithm) powers the ranking and serving infrastructure for the platform's main feed. After the Post Pipeline generates ranked content, the Blending Pipeline performs the final assembly step, ensuring that organic posts, sponsored content, and engagement modules appear in the correct sequence with appropriate spacing constraints.
Overview of the Blending Architecture
The Blending Pipeline serves as the terminal orchestration layer within the For You candidate pipeline. Implemented in home-mixer/selectors/blender_selector.rs, it consumes a raw candidates vector containing mixed FeedItem types—including ScoredPost, AdIndexInfo, WhoToFollowModule, and Prompt—and produces a unified SelectResult ready for client consumption.
The pipeline guarantees that:
- Ad spacing rules are enforced through pluggable blender strategies
- High-priority content (prompts, push-to-home posts) receives fixed positional placement
- Tracking metadata captures dropped items for analytics and debugging
Step-by-Step Feed Construction Process
The BlenderSelector executes a deterministic sequence of operations to transform partitioned inputs into the final feed.
Partitioning Incoming Feed Items
The process begins with partition_feed_items (lines 5-13), which iterates through the raw candidate vector and separates items into typed collections:
posts:Vec<ScoredPost>— The organic ranked contentads:Vec<AdIndexInfo>— Sponsored content candidateswtf_modules:Vec<WhoToFollowModule>— Account recommendation modulesprompts:Vec<Prompt>— Interactive engagement promptspush_to_home:Option<PushToHomePost>— Prioritized content requiring top placementframes:Vec<Frame>— Rich UI cards requiring spacing logicfeed_survey:Option<FeedSurvey>— Optional feedback collection module
This type-safe partitioning enables subsequent steps to apply specialized logic to each content category.
Blending Posts with Advertisements
Once partitioned, posts and ads merge through a selected AdsBlender implementation. The blending occurs at line 70:
let mut blended = blender.blend(posts, ads);
The system instantiates the blender based on the request parameter AdsBlenderType (lines 53-68). Available strategies include:
- PartitionOrganicAdsBlender: The default implementation defined in
home-mixer/ads/partition_organic_blender.rs, which partitions organic content around ad slots - SafeGapAdsBlender: Enforces conservative minimum spacing between advertisements
- MultiRiskAdsBlender: Handles tiered risk categories for sensitive content adjacency
- TimeGapAdsBlender: Configurable temporal spacing between sponsored insertions
Each strategy ensures that ads appear at valid intervals without compromising the perceived quality of the organic feed.
Inserting Prompts and Engagement Modules
After the post-ad blend completes, the pipeline layers non-content items at fixed positions:
Prompts receive front-of-feed priority. The insert_prompts function (lines 72-11) places all prompt items at the constant PROMPTS_POSITION defined in home-mixer/params/param.rs, ensuring users see interactive elements before scrolling.
Who to Follow recommendations insert via insert_who_to_follow (lines 73-25). The system places only the first module at the stable WHO_TO_FOLLOW_POSITION. If the target index exceeds the current vector length, the insertion point clamps to the end of the feed to avoid out-of-bounds placement.
Pinning Priority Content and Rich Media
Additional UI components merge in strict sequence:
- Push-to-Home: When a
PushToHomePostexists,pin_push_to_home(lines 74-38) forces it to index 0, overriding standard ordering - Frames: Rich media cards are scheduled using
frames::planto respect mutual spacing rules, then merged viainsert_planned_frames(lines 75-62) - Feed Surveys: Optional surveys attach at the fixed
FEED_SURVEY_POSITION(lines 76-75)
Tracking and Finalization
The selector maintains accountability for content removal. It counts dropped posts and ads during the blending phase (lines 78-85) and constructs placeholder entries for the non_selected response field (lines 88-94). The final SelectResult returned at lines 91-94 contains both the merged selected vector and these tracking placeholders, enabling downstream analytics to reconcile input candidates with served content.
Configuring the Blending Behavior
To utilize the Blending Pipeline in a Rust service:
use xai_home_mixer::selectors::BlenderSelector;
use xai_home_mixer::candidate_pipeline::for_you_candidate_pipeline::ForYouCandidatePipeline;
use xai_home_mixer::models::query::ScoredPostsQuery;
// 1. Configure query parameters
let mut query = ScoredPostsQuery::default();
query.params.set(AdsBlenderType, "partition_organic_low_risk");
// 2. Obtain candidates from upstream ranking (simplified)
// let candidates: Vec<FeedItem> = post_pipeline_result;
// 3. Execute blending
let blender = BlenderSelector::new();
let result = blender.select(&query, candidates);
// 4. Consume the ordered feed
for item in result.selected {
match item {
FeedItem::Post(post) => println!("Post: {}", post.id),
FeedItem::Ad(ad) => println!("Ad: {}", ad.advertiser_id),
FeedItem::Prompt(prompt) => println!("Prompt: {}", prompt.text),
_ => {}
}
}
This implementation demonstrates configuring the AdsBlenderType parameter to select the low-risk organic partitioning strategy, then invoking select to produce the final blended sequence containing posts, ads, and UI modules in their designated order.
Summary
- The Blending Pipeline resides in
home-mixer/selectors/blender_selector.rsand serves as the final feed assembly stage for the X Algorithm - Partitioning logic (
partition_feed_items) separates mixed candidates into typed vectors (posts, ads, prompts, frames) before merging - AdsBlender implementations (selected via
AdsBlenderType) enforce spacing rules, withPartitionOrganicAdsBlenderas the default strategy - Fixed position constants (
PROMPTS_POSITION,WHO_TO_FOLLOW_POSITION,FEED_SURVEY_POSITION) determine placement for non-post content - Push-to-Home content always pins to index 0 when present, processed by
pin_push_to_home - The pipeline tracks removed items and returns both
selectedandnon_selectedentries in theSelectResultfor observability
Frequently Asked Questions
What file contains the core Blending Pipeline implementation?
The primary logic lives in home-mixer/selectors/blender_selector.rs within the xai-org/x-algorithm repository. This file defines the BlenderSelector struct and its select method, which orchestrates the partitioning, blending, and insertion operations that produce the final feed.
How does the system choose which ad spacing strategy to apply?
The strategy is determined by the AdsBlenderType parameter in the request query. The pipeline selects the corresponding implementation—such as PartitionOrganicAdsBlender, SafeGapAdsBlender, or TimeGapAdsBlender—to handle the merge between posts and ads according to specific spacing constraints and risk tolerances.
Where are the insertion positions for prompts and Who to Follow defined?
Constants including PROMPTS_POSITION and WHO_TO_FOLLOW_POSITION are defined in home-mixer/params/param.rs. These values specify the exact indices where prompts (front of feed) and Who to Follow modules appear in the final output sequence.
Can multiple Who to Follow modules appear in a single blended feed?
No. The current implementation in insert_who_to_follow (lines 73-25) processes only the first element of the wtf_modules vector. Additional recommendation modules beyond the first are discarded during the blending process, ensuring at most one Who to Follow insertion per feed request.
Have a question about this repo?
These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:
curl -s "https://instagit.com/install.md" Maintain an open-source project? Get it listed too →