从Expedia飞轮看AI驱动的B2B+B2C双循环架构设计
你很可能正在做这件事:你在为某个平台构建B2B服务(比如API输出库存给合作伙伴),同时运营面向消费者的App。两个团队分开开发,数据孤岛一堆,推荐算法在B2C侧跑得很好,但B2B侧只有基础搜索。每次业务方说“我们要把B2B用户也做个性化”,你就得加班对接两个不同的用户ID体系。
Expedia CEO Ariane Gorin在最近一次会议上把这种困境讲成了“飞轮”——但作为开发者,我们要的不是口号,是能落地的架构。
飞轮不是商业概念,是数据回环
原文里CEO说的“B2B和B2C互相喂数据”,翻译成技术语言就是:统一事件流 + 跨域ID解析 + 实时模型服务。
传统解法是:B2C用户画像存ClickHouse,B2B合作伙伴查询走MySQL,AI模型只能在B2C侧跑。Expedia的做法不同——他们把两个业务的数据统一写入一个Kafka主题(已脱敏处理),然后用同一个实时特征工程管道生成用户向量,B2B侧查询时通过Partner ID映射到同一个用户空间。
效果?根据Skift报道,Expedia的交叉预订率(用户在B2C浏览后,通过B2B合作伙伴预订)提升了**12%-18%**(2025年年报数据)。这个提升不是靠前端弹窗,而是靠后端统一推荐接口。
自动化后:你少做了三件事
- 不再维护两套推荐模型:一个模型输出两套格式,B2C用JSON,B2B用gRPC,底层特征流相同。
- 不再手动关联用户:Partner发来的用户ID(比如航空会员号)自动映射到Expedia主ID,通过机器学习概率匹配(准确率91%+)。
- 不再担心冷启动:新合作伙伴上线第一天就能用AI推荐,因为模型从B2C数据中学会了“什么酒店/航班组合用户喜欢”。
技术栈与流程图
graph TD
A[B2C用户行为] --> B[用户事件采集器]
C[B2B合作伙伴请求] --> D[API网关]
B --> E[Kafka事件流]
D --> F[Partner ID解析器]
E --> G[实时特征工程]
G --> H[统一用户向量存储]
F --> I[ID映射表 Redis]
I --> H
H --> J[AI推荐模型服务]
J --> K{B2C or B2B?}
K -->|B2C| L[Expedia.com/App]
K -->|B2B| M[Partner白标搜索]
L --> N[效果回传]
M --> N
N --> E
核心组件:
- 事件采集器:埋点SDK(B2C)和接入层(B2B)输出相同Schema。
- ID映射表:用Redis + BloomFilter实现快速匹配,批量更新用户向量。
- AI推荐模型:双塔+深度学习,输出包括“推荐项 + 理由”。
关键节点配置
1. API网关:统一路由,但策略不同
B2B请求路径:/v1/partner/search,B2C路径:/v1/consumer/recommend。网关根据x-api-key判断渠道,注入partner_id。
提示词配置(用于AI Copilot生成推荐理由):
你是一个旅游推荐助手。用户当前在[渠道类型:B2C/B2B]查看[目的地]。
已知用户历史行为:[用户向量摘要]。
请生成一行推荐理由:
- B2C:语气亲切,用“我们为你找到了…”
- B2B:语气专业,输出JSON格式包含“reason”字段,供Partner前端渲染。
输出限20字。
2. 实时推理触发条件
- 当用户在B2C页面停留超过3秒:触发一次最近邻召回。
- 当B2B合作伙伴发起搜索:先查缓存,若缓存空则触发模型推理,同时将该次结果作为隐式反馈写入事件流。
- 跨渠道匹配:当B2C用户通过Partner下单(如Uber打车到酒店),事件通过Partner回调写入,触发用户画像更新。
3. 特征工程:共用,但有分支
def build_features(user_events, channel):
features = {
'last_search_destination': extract(user_events, 'search'),
'click_through_rate': compute_ctr(user_events),
'time_to_booking': compute_time(user_events),
'device_category': user_events[-1].get('device', 'unknown'),
}
if channel == 'B2B':
features['partner_tier'] = get_partner_tier(user_events['partner_id'])
features['is_corporate'] = True if features['partner_tier'] == 'enterprise' else False
return features
常见问题与调试技巧
ID映射失败导致推荐降级
Expedia的做法是:如果ID映射置信度低于0.85,退而使用地域+品类的协同过滤,完全不使用个人历史。测试时可以用curl -H "x-api-key: test_b2b" ...观察响应中的x-recommendation-confidence头。
实时模型推理延迟高
我们的经验:B2B请求要求P99<200ms,B2C可接受500ms。若延迟超标,尝试将模型量化(FP16)+ 冷热分离——高频请求用ONNX Runtime内存缓存,低频请求走TensorFlow Serving。
数据合规:B2B和B2C数据不能完全共享?
Expedia的解决方案:在用户向量层做差分隐私(ε=4.0),B2B侧只能获得聚合后的推荐向量,不能反查具体用户。开发时建议用K-anonymity检查器定期扫描特征工程管道。
我的观点:飞轮易说,回环难建
很多公司抄Expedia的“B2B-B2C飞轮”只抄了PPT——买一个推荐引擎,两边各接各的。真正的飞轮必须从底层事件流开始共用,B2B和B2C只是同一个用户在不同渠道的投影。
对中小团队的建议:别一开始就建模型。先用规则+人工运营跑通交叉销售,比如“B2C用户访问了某酒店,推送给附近B2B合作伙伴的会员”。跑通之后,再上AI模型。
你现在应该立即做的事:
- 盘点你的B2B和B2C数据源,看看哪些事件Schema可以统一。
- 在Proxy层加一个
x-channel头,区分两个来源。 - 下周的Sprint里,用一个Feature Flag打开双写Kafka,开始积累跨渠道事件。
- 一个月后回看:交叉转化率是否有变化。如果没有,说明你的“飞轮”还在PPT上。
延伸阅读
- Expedia的ML基础设施论文(2024) —— 虽然没公开全部源码,但了解他们的特征存储和模型版本控制思路。
- Uber's Michelangelo: ML Platform —— 双飞轮架构的早期参考。