I've spent the last three years building AI systems for marketplace platforms—everything from ride-sharing apps to freelancer marketplaces to B2B procurement platforms. The complexity is brutal. You're not just managing context for one user or one use case. You're orchestrating context across multiple user types, competing business interests, and complex interaction patterns.
Most teams underestimate this complexity until they're six months in and their context system is held together with duct tape and prayer. This post will save you from that fate.
The Marketplace Context Problem
Traditional context management assumes a relatively simple user-to-system relationship. But marketplaces break this assumption in four critical ways:
1. Multi-Actor Complexity
You're not serving one user—you're serving multiple user types with competing interests. A ride-sharing app needs context for drivers, riders, support agents, and the platform itself. Each actor needs different context about the same underlying events.
2. Cross-Actor Context Dependencies
Context isn't isolated between actors. A driver's location context affects a rider's ETA prediction. A seller's inventory context affects a buyer's recommendation engine. Changes in one actor's context ripple through the entire system.
3. Dynamic Trust and Privacy Boundaries
What context you can share depends on the relationship status between actors. Before a booking is confirmed, drivers can't see rider destinations. After payment, different information becomes available. These boundaries shift dynamically.
4. Scale and Performance Constraints
You're not serving one conversation—you're serving thousands of concurrent multi-party interactions. Your context system becomes a distributed systems problem, not just an AI problem.
The Four-Layer Architecture Pattern
After building context systems for platforms that serve millions of users, I've settled on a four-layer architecture that handles marketplace complexity without falling over:
Layer 1: Context Sources (Data Layer)
This layer owns the raw context data and ensures isolation at the source level.
# Each context source is tenant-aware from the ground up
class UserProfileContext:
def get_context(self, user_id, requesting_actor_type, relationship_id=None):
profile = self.get_base_profile(user_id)
# Apply visibility rules based on requesting actor
if requesting_actor_type == "rider":
return self.public_profile_view(profile)
elif requesting_actor_type == "driver" and relationship_id:
return self.active_booking_view(profile, relationship_id)
else:
return self.minimal_profile_view(profile)
Layer 2: Context Aggregation (Composition Layer)
This layer composes contexts from multiple sources while enforcing cross-source privacy rules.
class MarketplaceContextAggregator:
def __init__(self):
self.sources = {
'user_profile': UserProfileContext(),
'booking_history': BookingHistoryContext(),
'location': LocationContext(),
'preferences': PreferencesContext()
}
def build_context(self, actor_id, actor_type, interaction_id=None):
context_builder = ContextBuilder(actor_id, actor_type)
# Base actor context (always available)
context_builder.add_source('user_profile', self.sources['user_profile'])
# Interaction-specific context (conditional)
if interaction_id:
context_builder.add_interaction_context(interaction_id)
# Cross-actor context (with privacy filtering)
if self.interaction_has_other_actors(interaction_id):
context_builder.add_filtered_cross_actor_context(interaction_id)
return context_builder.build()
Layer 3: Context Routing (Distribution Layer)
This layer routes context to the right AI endpoints while managing performance and caching.
class ContextRouter:
def route_context(self, context_request):
# Determine which AI services need this context
endpoints = self.get_relevant_endpoints(context_request)
# Prepare context for each endpoint's specific needs
for endpoint in endpoints:
cached_context = self.get_cached_context(endpoint, context_request)
if cached_context:
yield cached_context
else:
fresh_context = self.prepare_context_for_endpoint(
context_request, endpoint
)
self.cache_context(endpoint, context_request, fresh_context)
yield fresh_context
Layer 4: Context Consumption (AI Layer)
This layer handles AI-specific context formatting and token management.
Isolation Patterns That Actually Work
Marketplace platforms need bulletproof isolation between tenants and actors. Here are the patterns I've battle-tested:
1. Context Namespacing
Every piece of context is tagged with ownership and visibility metadata from the moment it's created.
class ContextItem:
def __init__(self, content, owner_id, owner_type, visibility_rules):
self.content = content
self.owner_id = owner_id
self.owner_type = owner_type # 'rider', 'driver', 'platform'
self.visibility_rules = visibility_rules
self.created_at = datetime.utcnow()
def is_visible_to(self, requesting_actor_id, requesting_actor_type, relationship_id=None):
return self.visibility_rules.check_access(
requesting_actor_id,
requesting_actor_type,
relationship_id
)
2. Dynamic Privacy Boundaries
Privacy rules aren't static—they change based on the relationship state between actors.
class DynamicPrivacyFilter:
def filter_context_for_relationship(self, context_items, relationship):
filtered_items = []
for item in context_items:
privacy_level = self.get_required_privacy_level(item)
relationship_trust = relationship.get_trust_level()
if relationship_trust >= privacy_level:
filtered_items.append(self.maybe_redact_item(item, relationship))
return filtered_items
def get_required_privacy_level(self, item):
# Example: location data requires confirmed booking
if item.type == 'precise_location':
return TrustLevel.CONFIRMED_BOOKING
elif item.type == 'general_location':
return TrustLevel.MATCHED
else:
return TrustLevel.PUBLIC
3. Context Sandboxing
Each AI interaction runs in its own context sandbox with strictly controlled access to cross-tenant data.
class ContextSandbox:
def __init__(self, primary_actor_id, interaction_id):
self.primary_actor_id = primary_actor_id
self.interaction_id = interaction_id
self.allowed_contexts = set()
self.cross_tenant_contexts = set()
def request_cross_tenant_context(self, target_actor_id, context_type, justification):
# Log all cross-tenant requests for audit
audit_logger.log_cross_tenant_request(
requestor=self.primary_actor_id,
target=target_actor_id,
context_type=context_type,
justification=justification,
interaction_id=self.interaction_id
)
# Check if this cross-tenant access is permitted
if self.is_cross_tenant_access_allowed(target_actor_id, context_type):
self.cross_tenant_contexts.add((target_actor_id, context_type))
return True
return False
Scaling Strategies for High-Volume Marketplaces
When your marketplace is processing thousands of context requests per second, standard approaches break down. Here's how to scale:
1. Hierarchical Context Caching
Different types of context have different change frequencies and access patterns. Cache accordingly:
- Static context (hours-days TTL): User profiles, preferences, historical patterns
- Semi-static context (minutes TTL): Location, availability, current session state
- Dynamic context (no cache): Real-time events, notifications, live interaction state
class HierarchicalContextCache:
def __init__(self):
self.l1_cache = Redis() # Hot contexts, 30s TTL
self.l2_cache = Redis() # Warm contexts, 5min TTL
self.l3_cache = Redis() # Cold contexts, 1hr TTL
def get_context(self, context_key):
# Try L1 first (real-time)
context = self.l1_cache.get(context_key)
if context:
return context
# Fall back to L2 (semi-static)
context = self.l2_cache.get(context_key)
if context:
# Promote to L1 for future requests
self.l1_cache.setex(context_key, 30, context)
return context
# Fall back to L3 (static)
context = self.l3_cache.get(context_key)
if context:
self.l2_cache.setex(context_key, 300, context)
self.l1_cache.setex(context_key, 30, context)
return context
# Cache miss - build from sources
return self.build_and_cache_context(context_key)
2. Async Context Pre-computation
Don't wait for AI requests to build context. Pre-compute likely context combinations during low-activity periods:
class ContextPrecomputeEngine:
def precompute_likely_contexts(self):
# Find active interactions that might need AI soon
active_interactions = self.get_active_interactions()
for interaction in active_interactions:
# Predict likely next AI needs
predicted_contexts = self.predict_next_contexts(interaction)
# Pre-compute and cache
for context_spec in predicted_contexts:
if not self.is_cached(context_spec):
self.background_compute_context.delay(context_spec)
def predict_next_contexts(self, interaction):
# Use historical patterns to predict context needs
stage = interaction.get_current_stage()
user_patterns = self.get_user_patterns(interaction.actors)
return self.ml_model.predict_next_contexts(stage, user_patterns)
3. Context Streaming for Real-time Updates
For highly dynamic contexts (like driver locations), stream updates rather than polling:
class ContextStreamManager:
def __init__(self):
self.active_streams = {}
self.redis_pubsub = redis.Redis().pubsub()
def subscribe_to_context_updates(self, interaction_id, context_types):
stream_key = f"context_stream:{interaction_id}"
for context_type in context_types:
channel = f"context_updates:{context_type}"
self.redis_pubsub.subscribe(channel)
self.active_streams[interaction_id] = {
'types': context_types,
'last_update': time.time()
}
def handle_context_update(self, channel, message):
context_type = channel.split(':')[1]
update_data = json.loads(message)
# Find all interactions interested in this context type
interested_interactions = self.get_interactions_for_context_type(context_type)
for interaction_id in interested_interactions:
self.push_update_to_interaction(interaction_id, update_data)
Cross-Platform Context Synchronization
Most marketplaces aren't single applications—they're ecosystems of mobile apps, web platforms, driver apps, admin dashboards, and third-party integrations. Context needs to stay consistent across all these touchpoints.
The Event-Sourced Context Pattern
Instead of trying to keep multiple context stores in sync, treat context changes as events and let each platform rebuild context from the event stream:
class ContextEventStore:
def __init__(self):
self.event_store = EventStore()
self.platform_cursors = {} # Track where each platform is in the event stream
def append_context_event(self, event):
self.event_store.append(event)
# Notify interested platforms
self.notify_platforms(event)
def get_context_for_platform(self, platform_id, interaction_id, since_cursor=None):
cursor = since_cursor or self.platform_cursors.get(platform_id, 0)
# Get relevant events since the cursor
events = self.event_store.get_events_since(cursor,
filter_by_interaction=interaction_id)
# Rebuild context from events
context = self.rebuild_context_from_events(events)
# Update platform cursor
if events:
self.platform_cursors[platform_id] = events[-1].sequence_number
return context
Platform-Specific Context Adaptation
Different platforms need context formatted differently. The mobile driver app needs minimal, action-oriented context. The admin dashboard needs comprehensive, audit-friendly context.
class PlatformContextAdapter:
def adapt_context_for_platform(self, context, platform_type, actor_type):
if platform_type == "mobile_driver":
return self.adapt_for_mobile_driver(context)
elif platform_type == "admin_dashboard":
return self.adapt_for_admin_dashboard(context, actor_type)
elif platform_type == "web_rider":
return self.adapt_for_web_rider(context)
else:
return self.adapt_default(context)
def adapt_for_mobile_driver(self, context):
# Mobile drivers need minimal, action-focused context
return {
'current_booking': context.get('active_booking'),
'next_actions': context.get('suggested_actions'),
'navigation': context.get('route_context'),
'earnings': context.get('session_earnings')
}
def adapt_for_admin_dashboard(self, context, admin_type):
# Admin needs comprehensive context with audit trails
return {
'full_interaction_history': context.get('interaction_timeline'),
'cross_actor_context': context.get('all_actor_contexts'),
'system_context': context.get('platform_state'),
'audit_trail': context.get('context_access_log')
}
Monitoring and Debugging Marketplace Context
When context systems get complex, debugging becomes a nightmare without proper observability. Here's what you need to track:
Context Flow Tracing
class ContextTracer:
def trace_context_flow(self, interaction_id, actor_id):
trace_id = f"ctx_trace_{interaction_id}_{actor_id}_{int(time.time())}"
return ContextTrace(trace_id) \
.track_source_access() \
.track_privacy_filtering() \
.track_aggregation() \
.track_ai_formatting() \
.track_response_generation()
class ContextTrace:
def __init__(self, trace_id):
self.trace_id = trace_id
self.events = []
def track_source_access(self):
event = {
'step': 'source_access',
'timestamp': time.time(),
'sources_accessed': [],
'access_denied': [],
'latency_ms': 0
}
self.events.append(event)
return self
def finalize_step(self, step_name, **kwargs):
for event in reversed(self.events):
if event['step'] == step_name:
event.update(kwargs)
break
Context Quality Metrics
- Context Relevance Score: How much of the provided context was actually useful for the AI response?
- Context Staleness: How old is the context data when it reaches the AI?
- Privacy Boundary Violations: Any instances where context crossed privacy boundaries inappropriately?
- Context Cache Hit Rate: Percentage of context requests served from cache vs. built fresh
Common Marketplace Context Anti-Patterns
1. The God Context Anti-Pattern
Building one massive context object that contains everything about an interaction. This leads to privacy leaks, performance problems, and maintenance nightmares.
Instead: Build focused, role-specific context objects with clear boundaries.
2. The Context Leak Anti-Pattern
Accidentally including context from one actor type when serving another. I've seen systems leak driver personal information to riders because someone forgot to apply actor-specific filtering.
Instead: Apply privacy filtering at the source level, not just at the consumption level.
3. The Context Flooding Anti-Pattern
Including every piece of historical context in every request. Just because you can include 100 previous interactions doesn't mean you should.
Instead: Use intelligent context selection based on relevance scores and recency.
The Future of Marketplace Context
I'm seeing three trends that will reshape how we think about marketplace context:
1. Federated Context Learning
Instead of centralizing all context, platforms will federate context across multiple specialized services. Each service becomes an expert in one type of context and exposes it through well-defined APIs.
2. Predictive Context Pre-loading
ML models will predict what context will be needed and pre-load it before requests arrive. This is especially powerful for mobile apps where network latency matters.
3. Context Rights Management
Platforms will implement sophisticated rights management systems for context, allowing users to grant and revoke access to specific context types dynamically.
Building context systems for marketplaces is hard, but it's also the most impactful AI infrastructure work you can do. When your AI understands the subtle dynamics between different actors in your marketplace, it can provide value that single-user systems simply can't match.
Want to dive deeper into specific patterns? Check out our guide on context management for distributed teams or learn about common anti-patterns to avoid.
Questions about implementing this for your platform? I've made most of the mistakes already. Let me know what you're building.