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 content
  • ads: Vec<AdIndexInfo> — Sponsored content candidates
  • wtf_modules: Vec<WhoToFollowModule> — Account recommendation modules
  • prompts: Vec<Prompt> — Interactive engagement prompts
  • push_to_home: Option<PushToHomePost> — Prioritized content requiring top placement
  • frames: Vec<Frame> — Rich UI cards requiring spacing logic
  • feed_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 PushToHomePost exists, pin_push_to_home (lines 74-38) forces it to index 0, overriding standard ordering
  • Frames: Rich media cards are scheduled using frames::plan to respect mutual spacing rules, then merged via insert_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.rs and 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, with PartitionOrganicAdsBlender as 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 selected and non_selected entries in the SelectResult for 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:

Share the following with your agent to get started:
curl -s "https://instagit.com/install.md"

Works with
Claude Codex Cursor VS Code OpenClaw Any MCP Client

Maintain an open-source project? Get it listed too →