How the X Algorithm Blending Pipeline Interleaves Content and Ads
The blending pipeline converts raw candidate posts and ads into an ordered FeedItem stream by partitioning inputs, selecting a strategy-specific blender via the AdsBlenderType parameter, and interleaving items through gap computation and placement assignment before finalizing positions.
The xai-org/x-algorithm repository implements this orchestration logic in the home-mixer service. The blending pipeline interleaves content and ads through a three-stage Rust pipeline that separates organic content from promotional material, applies configurable spacing strategies, and assembles the final user feed with deterministic positioning.
Stage 1: Partitioning Raw Candidates
The process begins in home-mixer/selectors/blender_selector.rs, where the BlenderSelector::select method receives a heterogeneous Vec<FeedItem> containing mixed candidate types. The internal helper partition_feed_items splits this raw input into distinct collections:
- Organic posts
- Advertisements (
ads) - "Who-to-follow" modules
- Prompts
- Push-to-home posts
- Frames
- Feed surveys
This separation ensures that each content category can be processed with specialized logic before final assembly. The partitioned vectors are then passed to the appropriate blending implementation based on query parameters.
Stage 2: Selecting a Blending Strategy
The pipeline determines interleaving behavior through the AdsBlenderType query parameter. The selector matches this parameter string to a concrete AdsBlender implementation:
safe_gap– Usesself.safe_gap_blenderto enforce minimum safe distances between ads and organic postspartition_organic_low_risk– Employsself.partition_organic_blenderto place ads in slots that split the safe-post pool evenly with additional safety checksmulti_risk– Invokesself.multi_risk_blenderto place ads based on computed risk scorestime_gap– Instantiates aTimeGapAdsBlenderto adjust ad spacing based on temporal configuration
Once selected, the blender's blend method is invoked, which delegates to the strategy-specific blend_inner implementation defined in files such as home-mixer/ads/safe_gap_blender.rs or home-mixer/ads/partition_organic_blender.rs.
Stage 3: Core Interleaving Logic
Each blender produces a partial list where ads are strategically positioned among posts. The specific mechanics vary by strategy.
Safe-Gap Blending
In home-mixer/ads/safe_gap_blender.rs, the blend_impl function executes a four-step placement algorithm:
find_safe_gaps– Identifies valid insertion points in the organic post sequencecompute_spacing– Calculates optimal distance between advertisementsassign_ads_to_gaps– Maps specific ads to specific gap indices based on spacing constraintsinterleave_and_finalize– Merges posts and ads into a single vector, truncates toRESULT_SIZE, removes trailing ads if they occupy the final slot, and assigns sequentialpositionvalues
// safe_gap_blender.rs – blend_impl core logic
let safe_gaps = find_safe_gaps(&scored_posts);
let spacing = compute_spacing(&ads);
let placements = assign_ads_to_gaps(&safe_gaps, ads.len(), &spacing, first_ideal);
interleave_and_finalize(scored_posts, ads, &placements, result_size)
The interleave_and_finalize helper, shared between safe-gap and time-gap blenders, constructs the final FeedItem vector by placing ads at their assigned indices and filling remaining slots with organic content.
Partition-Organic Blending
The partition_organic_blender.rs implementation uses custom assembly logic rather than the generic interleaving helper. It creates ad-post triples (post-ad-post sequences) and distributes filler posts between gaps:
// partition_organic_blender.rs – blend_impl excerpt
for (i, (ad, above, below)) in triples.into_iter().enumerate() {
items.push(FeedItem { item: Some(feed_item::Item::Post(above)), .. });
items.push(FeedItem { item: Some(feed_item::Item::Ad(ad)), .. });
items.push(FeedItem { item: Some(feed_item::Item::Post(below)), .. });
// Insert filler posts between ad slots
for _ in 0..filler_per_gap { /* push filler posts */ }
}
This approach ensures that ads never appear consecutively without organic content buffers, while maintaining even distribution throughout the feed.
Finalizing the Feed Stream
After the core blending completes, the BlenderSelector performs final assembly operations:
- Position Assignment – Each
FeedItemreceives a sequentialpositionfield corresponding to its vector index - UI Element Insertion – Helper functions
insert_prompts,insert_who_to_follow,insert_push_to_home, and related methods inject non-content modules at fixed positions (lines 102-176 inblender_selector.rs) - Placeholder Generation – The
build_non_selected_placeholdersfunction converts dropped posts and ads into placeholderFeedItemobjects, storing them in thenon_selectedvector for analytics and feedback loops
// Final position assignment in safe_gap_blender.rs (lines 94-96)
for (idx, item) in result.iter_mut().enumerate() {
item.position = idx as i32;
}
Summary
- The pipeline starts in
home-mixer/selectors/blender_selector.rsby partitioning mixed candidates into typed vectors viapartition_feed_items - Strategy selection occurs through the
AdsBlenderTypeparameter, with implementations located inhome-mixer/ads/safe_gap_blender.rs,partition_organic_blender.rs, and related files - Core interleaving uses
find_safe_gaps,compute_spacing, andassign_ads_to_gapsutilities defined inhome-mixer/ads/util.rs - Final assembly combines blended content with UI modules and assigns deterministic positions before returning the completed feed
Frequently Asked Questions
What determines which blending strategy is used in the X Algorithm?
The AdsBlenderType query parameter controls strategy selection. According to home-mixer/selectors/blender_selector.rs (lines 52-68), the selector matches string values like "safe_gap" or "partition_organic_low_risk" to specific blender implementations. If no valid type is specified, the system defaults to the partition-organic blender.
How does the safe-gap blender ensure minimum distance between ads?
The safe-gap strategy computes valid insertion points through find_safe_gaps and calculates spacing via compute_spacing in home-mixer/ads/util.rs. The assign_ads_to_gaps function then places ads only at indices that satisfy these distance constraints, ensuring no two ads appear closer than the configured threshold.
What happens to posts and ads that don't make it into the final feed?
Excluded items are preserved as placeholder FeedItem objects. The build_non_selected_placeholders method (lines 78-92 in blender_selector.rs) converts dropped candidates into tracking entries stored in the non_selected vector, allowing the system to record which content was available but not served.
Where is the interleaving logic implemented for time-based ad spacing?
The time-gap blender in home-mixer/ads/time_gap_blender.rs implements temporal spacing logic. Like the safe-gap blender, it uses the shared interleave_and_finalize helper to merge content, but calculates placement gaps based on time-interval configuration rather than raw index spacing.
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 →