Plan Formation Engine

SOCIAL

A backend that turns the social graph into real-world group plans. The atomic unit is a plan seed: a venue, a group, and a time. The system scores it, propagates it, and books it.

StackPython / FastAPI / PyTorch
TypeBackend + ML

Concentrating demand without
losing personalization

The core problem is simple: the app only works if enough people show up at the same place. But if you just blast generic recommendations, nobody feels like the plan is theirs. You need to manufacture plans that feel organic to each person while quietly concentrating demand for the venue. Recommendations scatter people. Promotions feel transactional. You have to make it feel like the plan happened naturally, even though the system orchestrated it.

Planning sketches and
architecture notes

Before I wrote any code, I started by sketching some thoughts down on how I wanted to develop this solution. Here are some pictures from my notebook:

Reframe as influence
maximization

Instead of recommending venues to individuals, the system generates plan seeds: a venue, a starter group of 2-3 people, and a time slot. Each seed has a conversion probability. Then it propagates through the social graph using greedy submodular influence maximization, picking the order of who to show the plan to so that the most people end up going. Who you ask first actually changes who says yes later.

01
Detect
02
Seed
03
Propagate
04
Momentum
05
Confirm
06
Book

Four learned components

Each model owns one piece of the pipeline. They're small, focused, and trained on interaction data from the social graph.

SocialLGN
LightGCN on a dual user-venue and user-user graph. Produces 64-dim embeddings that encode both taste and social proximity in the same space.
He et al., SIGIR 2020
Epochs
50
Loss
BPR
GroupVenueScorer
Set Transformer for permutation-invariant group scoring. Predicts conversion probability for a group-venue pair as a hyperedge classification task.
Lee et al., ICML 2019
Epochs
50
Loss
BCE
Hawkes Process
Self-exciting point process for cascade dynamics. Tells you when momentum will peak and whether a seed has enough energy to actually convert.
Rizoiu et al., WWW 2017
Fit
MLE
Solver
Nelder-Mead
Contextual Scalarizer
Learns per-context weights for multi-objective feed ranking. Friday dinner for four and Tuesday lunch for two have completely different priorities.
Custom architecture
Objectives
5
Context
12-dim

System diagram

API requests go through FastAPI synchronously. Everything else (cascades, momentum checks, booking) is async through Redis Streams. The request path never blocks on ML inference or external API calls.

Next.js Client
FastAPI Gateway
Graph Engine
Scoring Engine
Propagation Engine
Booking Agent
Redis Streams / Event Bus
PostgreSQL + pgvector
Redis Cache

From interest signal
to booked table

Six stages. Each one compounds the signal from the last. The whole point is that by the time you're asked to join, three of your friends already said yes.

01
Signal Detection
Interaction patterns surface latent interest: repeated views, saves, social co-occurrence near the same venues.
02
Seed Generation
System assembles a plan seed: a venue, a starter group of 2-3 high-probability users, and an optimal time slot.
03
Greedy Propagation
Influence maximization picks who to invite next. Each yes raises the conversion probability for everyone after.
04
Social Momentum
Hawkes process models the self-exciting cascade. When the acceptance rate crosses threshold, the seed goes high-momentum.
05
Group Confirmation
Members lock in. Group scorer re-evaluates cohesion. If the final group clears the bar, it moves to booking.
06
Autonomous Booking
The agent calls the place and books a reservation via API or voice call. No one in the group has to do anything.

Technologies

Technology Role
Python 3.12Backend language, async-first with type hints throughout
FastAPIAPI gateway with automatic OpenAPI docs and Pydantic validation
PostgreSQL + pgvectorPrimary datastore with vector similarity search for embeddings
RedisEvent bus (Streams), caching, and real-time state management
PyTorchModel training and inference for all ML components
PyTorch GeometricGraph neural network layers (LGConv) for SocialLGN
NetworkXSocial graph analysis, influence maximization algorithms
Next.js 14Frontend with App Router, server components, and streaming
Tailwind CSSUtility-first styling for the mobile-first demo UI
Framer MotionPhysics-based animations for feed transitions and interactions
VapiVoice AI for outbound booking calls, integrated via HTTP API
D3-forceForce-directed graph layouts for propagation cascade visualization

Key tradeoffs

Every system is a set of bets. These are the ones I made and why.

Group Scoring
Set Transformer
Avg. Individual
Averaging individual scores misses the point. Alice and Bob together at a jazz bar is not the average of Alice-at-jazz-bar and Bob-at-jazz-bar. Groups have dynamics. The Set Transformer captures them in a single forward pass over the member embeddings.
Feed Model
Plan Seed Projection
Venue Listing
The feed is not a list of venues. Every card is a concrete plan: who, where, when. You're not browsing, you're deciding. This is the single most important design choice in the system because it concentrates attention on action instead of exploration.
Event Processing
Async Redis Streams
Sync in Handlers
Propagation, momentum, and booking are all slow. None of them should block an API response. Redis Streams give ordered, persistent event processing with consumer groups, and they're already running for the cache layer.
Ranking Weights
Learned per Context
Fixed Weights
Fixed weights assume every situation is the same. They're not. Friday night dinner for four cares about group cohesion. Tuesday lunch cares about convenience. The scalarizer learns to shift priorities based on 12 context features.
Booking Agent
Autonomous Actor
Suggestion Engine
The agent doesn't suggest that someone should book a table. It places the reservation itself, via API or voice call. That's the difference between "we should go" and "we're going."

Honest constraints

This system runs on 200 users and 50 venues. At production scale, the main bottlenecks would be influence maximization (NP-hard, needs approximate methods), embedding recomputation (batch vs online training tradeoff), and event throughput (Redis Streams to Kafka). These are known problems with known solutions. The architecture was designed with them in mind.

View Source →